tags:

views:

121

answers:

1

Once a node has been deleted, how do you locate it so that you can restore it using jackrabbit or the jcr APIs?

+1  A: 

Hi,

I'm not an expert in Jackrabbit versioning, but as far as I know there is no easy way to locate such a node unless you know some of it's data. If you do know, then you can use a query and navigate to the next parent that is an instance of javax.jcr.version.Version, and restore it. If you don't know, then you need to iterate over the version storage and print all the data. You could filter out nodes that are not deleted, but otherwise it's a manual job because the path of a node is not stored in the version storage (unless you add a property that contains the path). Here is an example on how to list all nodes in the version storage. It will restore the last javax.jcr.version.Version it finds:

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.version.Version;
import javax.jcr.version.VersionManager;
import org.apache.jackrabbit.core.TransientRepository;
public class TestRestoreDeleted {
    public static void main(String... args) throws Exception {
        TransientRepository rep = new TransientRepository();
        Session s = rep.login(
                new SimpleCredentials("", new char[0]));
        try {
            // clear the repository first
            if (s.getRootNode().hasNode("test")) {
                s.getRootNode().getNode("test").remove();
                s.save();
            }
            // add test/t1 and check in the change
            Node test = s.getRootNode().addNode("test");
            Node t1 = test.addNode("t1");
            t1.addMixin("mix:versionable");
            s.save();
            VersionManager vm = s.getWorkspace().
                    getVersionManager();
            for(int i=0; i<3; i++) {
                vm.checkout("/test/t1");
                t1.setProperty("data", "Hello" + i);
                s.save();
                vm.checkin("/test/t1");
            }
            // remove the node
            t1.remove();
            s.save();
            // list all versions of all nodes in the repository
            Node vs = s.getRootNode().
                    getNode("jcr:system").
                    getNode("jcr:versionStorage");
            Version v = traverseVersionStorage(vs, 0);
            // restore a version
            vm.restore("/test/t1", v, false);
            // get the node and print the data
            t1 = s.getRootNode().
                    getNode("test").getNode("t1");
            System.out.println("Restored: " +
                    t1.getProperty("data").getString());
        } finally {
            s.logout();
        }
    }

    private static Version traverseVersionStorage(
            Node n, int level) throws Exception {
        Version v = null;
        for (NodeIterator it = n.getNodes(); it.hasNext();) {
            Node n2 = it.nextNode();
            if (n2 instanceof Version
                    && !n2.getName().startsWith("jcr:")) {
                v = (Version) n2;
                System.out.println("version " + n2.getName() +
                        " of node " + n2.getParent().getName() + ":");
                Node n3 = n2.getNode("jcr:frozenNode");
                for (PropertyIterator pt =
                            n3.getProperties(); pt.hasNext();) {
                    Property p = pt.nextProperty();
                    if (!p.getName().startsWith("jcr:")) {
                        System.out.println("  " + p.getName() + "="
                                + (p.isMultiple() ? p.getValues().toString()
                                        : p.getValue().getString()));
                    }
                }
                System.out.println();
            }
            Version v2 = traverseVersionStorage(n2, level + 1);
            v = v == null ? v2 : v;
        }
        return v;
    }

}
Thomas Mueller

related questions