package au.com.infomedix.mode_1613; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import javax.jcr.LoginException; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import org.apache.log4j.BasicConfigurator; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.modeshape.jcr.ModeShapeEngine; import org.modeshape.jcr.RepositoryConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Hello world! * */ public class Test1613 { private static Logger log = LoggerFactory.getLogger(Test1613.class); private Repository repository; private ModeShapeEngine engine; @BeforeClass public static void classInit() { BasicConfigurator.configure(); } @Before public void init() throws Exception { RepositoryConfiguration config = RepositoryConfiguration.read("repositoryConfig.json"); engine = new ModeShapeEngine(); engine.start(); engine.deploy(config); repository = (Repository) engine.getRepository("DataRepository"); } @After public void unInit() throws Exception { Future result = engine.shutdown(true); result.get(10, TimeUnit.SECONDS); } @Test(timeout = 10000) public void oneMoveTest() { try { create(2, 3); log.info("Nodes created"); // there are 6 child nodes under two parent nodes, paths are // /testRoot/parent0/child /testRoot/parent0/child[2] /testRoot/parent0/child[3] // /testRoot/parent1/child /testRoot/parent1/child[1] /testRoot/parent1/child[2] // move /testRoot/parent0/child[2] to /testRoot/parent1. move(getId("/testRoot/parent0/child[1]"), getId("/testRoot/parent1"),"child"); } catch(Throwable e) { log.error("Failed test", e); fail("Exception during test:" + e.getMessage()); } } /** * Create a tree of nodes that have same name siblings at the leaves. * Tree is root -> parents(parentcount) -> snssibs(sibscount) * @param parentcount the number of nodes created under the root node * @param sibscount the number of nodes created under each parent * @return */ public Map> create(int parentcount, int sibscount) { Session session = null; Map> nodeIds = new HashMap>(parentcount); try { session = repository.login(); Node testRoot = session.getRootNode().addNode("testRoot"); for(int i = 0; i < parentcount; i++) { nodeIds.put(testRoot.addNode("parent" + i).getIdentifier(), new ArrayList(sibscount)); } for(Map.Entry> entry : nodeIds.entrySet()) { List childrenIDs = entry.getValue(); Node parent = session.getNodeByIdentifier(entry.getKey()); for(int c = 0; c < sibscount; c++) { Node child = parent.addNode("child"); childrenIDs.add(child.getIdentifier()); child.addNode("subchild"); } } session.save(); } catch(LoginException e) { throw new RuntimeException("Failed to login to repository", e); } catch(RepositoryException e) { throw new RuntimeException("Error using repository", e); } finally { if(session != null) { session.logout(); } } return nodeIds; } private void printNodes(Session session, NodeIterator result) throws RepositoryException, Exception { for(NodeIterator itr = result; itr.hasNext();) { log.debug("============"); // get a node from the list and print its identifier and path. javax.jcr.Node node = itr.nextNode(); log.debug(" Node " + node.getIdentifier() + " path=" + node.getPath()); // now get the same node using its path and print out the identifier and path again javax.jcr.Node n2 = session.getNode(node.getPath()); log.debug(" N2 " + n2.getIdentifier() + " path=" + n2.getPath()); } log.debug("============"); } public String getId(String path) { Session session = null; try { session = repository.login(); return session.getNode(path).getIdentifier(); } catch(RepositoryException e) { throw new RuntimeException(e); } finally { if(session != null) { session.logout(); } } } public void move(String srcid, String destid, String destNodeName) { Session session = null; try { session = repository.login(); log.info("move " + srcid + " to " + destid); Node targetNode = session.getNodeByIdentifier(destid); String targetNodePath = targetNode.getPath(); targetNode = session.getNode(targetNodePath); Node sourceNode = session.getNodeByIdentifier(srcid); String sourceNodePath = sourceNode.getPath(); sourceNode = session.getNode(sourceNodePath); log.info("move " + sourceNodePath + " to " + targetNodePath); log.info("Source Nodes Before Move"); Node sourceParent = sourceNode.getParent(); printNodes(session, sourceParent.getNodes()); log.info("Target Nodes Before Move"); printNodes(session, targetNode.getNodes()); session.move(sourceNodePath, targetNodePath+"/"+destNodeName); session.save(); try { // cheap and nasty "ignore the exception" log.info("Source Nodes After Move"); printNodes(session, sourceParent.getNodes()); } catch(Exception e) { log.error("Failed to print source nodes " + e.getMessage()); throw e; } finally { // print the target regardless of any exception above. // may throw another exception, don't care! try { log.info("Target Nodes After Move"); printNodes(session, targetNode.getNodes()); } catch(Exception e) { log.error("Failed to print target nodes " + e.getMessage()); throw e; } } } catch(Exception e) { throw new RuntimeException(e); } finally { if(session != null) { session.logout(); } } } }