Wednesday, March 17, 2010

7-Zip

The guys at Tom's Hardware have done some benchmarks of recent compression tools.
It turns out 7-Zip is most efficient in terms of compression speed and ratio.
It can also extract many other formats like RAR.
Considering that this tool is also free and open source you may seriously consider switching to it.

Saturday, March 6, 2010

Extracting MPEG2 streams from DVD-RAM

DVD-RAM
Using DVD-RAM discs with camcorders is quite convenient. Recording on this meadia is much more reliable. You can also edit your videos on the camera - delete, cut, join etc. The downside is incompatibility. Most DVD players do not play DVD-RAM discs. But recent PC optical drives do read them. So when I get the disc out of my camera and put it in my PC, it shows this file system


C:\temp>dir e:\DVD_RTAV
 Volume in drive E is DVD_CAMERA
 Volume Serial Number is 57DC-951A

 Directory of e:\DVD_RTAV

31.01.2010  16:42    <DIR>          .
31.01.2010  16:42    <DIR>          ..
03.03.2010  16:49            11 961 VR_MANGR.IFO
03.03.2010  16:49            11 961 VR_MANGR.BUP
03.03.2010  16:49       713 383 936 VR_MOVIE.VRO
               3 File(s)    713 408 142 bytes
               2 Dir(s)     688 580 608 bytes free

Actually it seems the video (and audio) is recorded in MPEG2, just like in ordinary DVD but it is packaged differently (probably to facilitate editing on the disc).

DVD-VR
Fortunately a nice guy Pádraig Brady wrote a simple open source tool dvd-vr that extracts MPEG2 streams from DVD-RAM. It is written for Linux but with cygwin it compiles to dvd-vr.exe. dvd-vr extracts each video clip into a separate .vob file. You can play these directly on your PC. If your media player does not recognize these files, you can rename them to .mpeg.
Having a separate file for each clip is very convenient. You can arrange them as you see fit, much like your photos.
You can also record selected clips on a regular DVD to share with your friends. You can do this with various tools like DVD Flick for example - another free and easy to use app.

Happy shooting!

Tuesday, February 23, 2010

Integrating Wicket and JCR


As requested I will describe briefly my take at integrating Wicket with JCR (Jackrabbit).
It is pretty straightforward.

Open/close JCR repository
My override of org.apache.wicket.protocol.http.WebApplication.init() looks up a javax.jcr.RepositoryFactory implementation via a java.util.ServiceLoader. Then I use this factory to open the repository. I store a reference to the repository in a field of my application class.
My override of producat.wicket.Application.onDestroy() closes the repository via org.apache.jackrabbit.api.JackrabbitRepository.shutdown().

Open/close JCR session
I try to keep a JCR session open only for the duration of a HTTP request.
To achieve this my application class overrides org.apache.wicket.protocol.http.WebApplication.newRequestCycle(Request, Response) to provide a custom request cycle implementation.

    @Override
    public RequestCycle newRequestCycle(Request request, Response response) {
        return new MyRequestCycle(this, (WebRequest) request, response);
    }

My implementation opens JCR session on demand and closes it at the end of the request cycle.
It looks similar to this class.

public class MyRequestCycle extends WebRequestCycle {

    private Session session;

    public MyRequestCycle(WebApplication application, WebRequest request,
            Response response) {
        super(application, request, response);
    }

    @Override
    protected void onEndRequest() {
        if (session != null) {
            session.logout();
            session = null;
        }
    }

    public Session getJcrSession() {
        if (session == null) {
            Repository repository = ((MyApplication) getApplication()).getRepository();
            session = repository.login();
        }
        return session;
    }

    public static MyRequestCycle get() {
        return (MyRequestCycle) RequestCycle.get();
    }
}

Then I use MyRequestCycle.get().getJcrSession() in my page classes to access the repository.
I save the session explicitly in every place where I make changes in the repository. Initially I thought of saving it automatically at the end of the session, but then it turned out to be difficult to handle decently save errors.

Data models and URLs
I try to avoid HTTP session as much as possible so I use BookmarkablePageLink's, passing the UUID of respective JCR node in PageParameters.
Since JCR nodes are not serializable, my models store only the node UUID and load it on demand via javax.jcr.Session.getNodeByIdentifier(String) - kind of LoadableDetachableModel.

Monday, December 7, 2009

Backup

Do you remember that song

Yesterday,
All those backups seemed a waste of pay.
Now my database has gone away.
Oh I believe in yesterday.

...

Recently I've decided it's high time I set up a decent backup for my growing collection of photos, videos and of course my projects.

So I got a nifty Samsung S2 USB HDD.
As most external 2.5" drives, it is powered by the USB, so I have only one cable plug in.
Although it came with backup software, it didn't quite meet my expectations.
I was looking for a simple yet efficient solution. Then robocopy came into my mind. I knew it was the heavy-lifting tool for moving files around in Windows environment. Then I was pleasantly surprised it has become a standard Windows tool since Vista. Then it turned out /MIR option does exactly what I need - mirror a directory tree.
In couple of minutes I came up with a simple .bat file that replicates a set of directories. It looks something like this (triple percent sign is no typo)

SET TARGET=F:\BACKUP
FOR /F "eol=#" %%I IN (backup.lst) DO robocopy %%I %TARGET%%%~pnI /mir


Here backup.lst contains a list of directories to backup, e.g.
#  Backup list
D:\Photos
D:\projects
D:\Video


These are replicated to

F:\BACKUP\Photos
F:\BACKUP\projects
F:\BACKUP\Video

respectively

First run does take some time to copy about 100G at ~20M/s. But after that it's quite fast as it copies only what has changed. Using external HDD for backup allows to go without compression which improves performance and also the backup can be readily used if necessary.

Now my important data feels safer.

Friday, November 27, 2009

Liberate your code

Do you still read your portable Java code in proprietary Microsoft fonts?
If so, you can consider liberating it from corporate license chains.

Some time ago the folks at Red Hat decided to create free equivalents for popular Microsoft fonts.
The result was Liberation fonts.You can download them for free from here. For Windows you would need the ttf flavor.
Once you install the new fonts, you can start using them in Eclipse.
Open Window > Preferences. In the dialog navigate to General > Appearance > Colors and Fonts. On the right expand Basic, select Text Font and change it to Liberation Mono.


Liberation Mono is the equivalent of Courier New® but looks cleaner and is more condensed vertically so more code will fit on your screen.
Here is a sample


Enjoy!

Thursday, November 19, 2009

Yet another fast Java decompiler

Today a colleague of mine pointed me to a really nice piece of software JD Java Decompiler.
Besides .class files it also opens .jar files and here is where it shines. All known types are hyperlink-ed so you can quickly jump between classes in the same .jar. You have Open Type, Java Search, Type Hierarchy, etc. - it's a mini Eclipse.
Speaking of Eclipse, JD also provides a plug-in for the ubiquitous Java IDE.

Did I mention it's very fast? That's because it is powered by native C++ ;). (Don't worry Linux version is also available.)

And it's also free. Still you are encouraged to support the author if you find it useful.

My .jar's have been associated with WinRar for years - time for a change.

Saturday, November 7, 2009

Serving images and other resources with wicket

It took me couple of days and mailing list posts to figure out how to display images with wicket in a satisfactory way.
In my case images are stored in JCR but this could be any other repository like db or file system where arbitrary images could be added or removed over time.
I also want that images have stable (bookmarkable) URLs, which makes them suitable for indexing by web crawlers and caching by web browsers.
I first checked the wicket "bible" Wicket in Action but this use case is not treated there.

Finally it turned out wicket does provide a way to do it in simple Java - shared resource with parameters.

Define a class to serve images
Create a class e.g. Images extending WebResource. Essentially this class has to implement the method getResourceStream(), which should return an IResourceStream implementation. (IResourceStream provides the actual data stream in terms of InputStream, data size, content type, etc.) The important thing here is that Images class can call inherited method getParameters() to get the query parameters (as ValueMap) from the URL. These parameters can be used to identify the specific image to be streamed. Something like this
    String imageId = getParameters().getString("id");

Bind the image serving class
The Images class created above can be bound to a specific URL, so whenever this URL is requested, the bound object is used to stream the response. This is done in the application init() method.
    getSharedResources().add("images", new Images());
This would produce image URLs like resources/org.apache.wicket.Application/images. To shorten the URLs to resources/global/images, add this again in init() method
    getSharedResources().putClassAlias(
        org.apache.wicket.Application.class, "global");

Display an image
Finally, use this to put an image on a page
    new Image("image", new ResourceReference("images"), 
        new ValueMap("id=" + imageId))
This will result in image URL like resources/global/images?id=image105

Of course this mechanism could be used for any kind of resource (e.g. PDF documents). It is only a matter of Content-Type.