/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jackrabbit.app; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; import jackrabbit.node.NodeCopier; import jackrabbit.query.Querier; import jackrabbit.repository.RepositoryFactory; import jackrabbit.repository.RepositoryFactoryImpl; import jackrabbit.repository.RepositoryManager; import jackrabbit.session.SessionFactory; import jackrabbit.session.SessionFactoryImpl; import javax.jcr.PathNotFoundException; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.SimpleCredentials; import javax.jcr.query.RowIterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.api.JackrabbitRepository; import org.apache.jackrabbit.commons.cnd.ParseException; public class App { protected static Log log=LogFactory.getLog(App.class); private static String srcRepoDir=""; private static String srcRepoPath="/"; private static String destRepoDir=""; private static String destRepoPath="/"; private static String srcConf=""; private static String destConf=""; private static String cndPath=""; private static String query=""; private static String queryType=""; private static String srcUser=""; private static String srcPasswd=""; private static String destUser=""; private static String destPasswd=""; private static long nodeLimit; private static final String VERSION="0.1"; public static void main(String[] args) { if (args.length == 0 || args.length == 1 && args[0].equals("-h")) { System.out.println("Usage: java -jar ackrabbit-migration-query-tool-"+VERSION+"-jar-with-dependencies.jar " + "--src src --src-conf conf [--src-repo-path path] [--src-user src_user] [--src-passwd src_pw] "+ "[--dest-user dest_user] [--dest-passwd dest_pw] [--dest dest] [--dest-conf conf] [--dest-repo-path path] " + "[--cnd cnd] [--node-limit limit] " + "[--query-type type] [--query query]"); System.out.println("\t --src source repository directory"); System.out.println("\t --src-conf source repository configuration file"); System.out.println("\t --src-repo-path path to source node to copy from; default is \"/\""); System.out.println("\t --src-user source repository login"); System.out.println("\t --src-passwd source repository password"); System.out.println("\t --dest destination repository directory"); System.out.println("\t --dest-conf destination repository configuration file"); System.out.println("\t --dest-repo-path path to destination node to copy to; default is \"/\""); System.out.println("\t --dest-user destination repository login"); System.out.println("\t --dest-passwd destination repository password"); System.out.println("\t --node-limit size to partition nodes with before copying. If it is not supplied, no partitioning is performed"); System.out.println("\t --cnd common node type definition file"); System.out.println("\t --query query to run in src. If --query is specified, then --dest, --dest-conf, --dest-repo-path and --cnd will be ignored."); System.out.println("\t --query-type query type (sql, xpath, JCR-SQL2); default is JCR-SQL2"); return; } for (int i=0;i<args.length;i=i+2) { if (args[i].equals("--src") && i+1<args.length) { srcRepoDir=args[i+1]; } else if (args[i].equals("--dest") && i+1<args.length) { destRepoDir=args[i+1]; } else if (args[i].equals("--src-conf") && i+1<args.length) { srcConf=args[i+1]; } else if (args[i].equals("--dest-conf") && i+1<args.length) { destConf=args[i+1]; } else if (args[i].equals("--src-repo-path") && i+1<args.length) { srcRepoPath=args[i+1]; } else if (args[i].equals("--dest-repo-path") && i+1<args.length) { destRepoPath=args[i+1]; } else if (args[i].equals("--src-user") && i+1<args.length) { srcUser=args[i+1]; } else if (args[i].equals("--src-passwd") && i+1<args.length) { srcPasswd=args[i+1]; } else if (args[i].equals("--dest-user") && i+1<args.length) { destUser=args[i+1]; } else if (args[i].equals("--dest-passwd") && i+1<args.length) { destPasswd=args[i+1]; } else if (args[i].equals("--node-limit") && i+1<args.length) { nodeLimit=Long.parseLong(args[i+1]); } else if (args[i].equals("--cnd") && i+1<args.length) { cndPath=args[i+1]; } else if (args[i].equals("--query") && i+1<args.length) { query=args[i+1]; } else if (args[i].equals("--query-type") && i+1<args.length) { queryType=args[i+1]; } } boolean missingArgs=false; if (srcRepoDir.isEmpty()) { missingArgs=true; log.error("Please specify the --src option."); } if (destRepoDir.isEmpty() && !destConf.isEmpty()) { missingArgs=true; log.error("Please specify the --dest option."); } if (srcConf.isEmpty()) { missingArgs=true; log.error("Please specify the --src-conf option."); } if (destConf.isEmpty() && !destRepoDir.isEmpty()) { missingArgs=true; log.error("Please specify the --dest-conf option."); } if (missingArgs) return; SimpleCredentials credentials=new SimpleCredentials(srcUser, srcPasswd.toCharArray()); SimpleCredentials destCredentials=new SimpleCredentials(destUser, destPasswd.toCharArray()); JackrabbitRepository dest=null; RepositoryFactory destRf=null; RepositoryFactory srcRf=new RepositoryFactoryImpl(srcConf, srcRepoDir); if (!destConf.isEmpty()) { destRf=new RepositoryFactoryImpl(destConf, destRepoDir); } try { final JackrabbitRepository src=srcRf.getRepository(); SessionFactory srcSf=new SessionFactoryImpl(src, credentials); final Session srcSession=srcSf.getSession(); Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { srcSession.logout(); src.shutdown(); } }); if (destConf.isEmpty()) {//query mode BufferedReader in = new BufferedReader(new InputStreamReader(System.in, "UTF-8")); if (query.isEmpty()) { while (true) { System.out.print(">"); String line=in.readLine(); if (line==null || line.isEmpty() || line.equalsIgnoreCase("quit") || line.equalsIgnoreCase("exit")) { break; } try { runQuery(srcSession, line, queryType); } catch (RepositoryException e) { log.error(e.getMessage(), e); } } } else { try { runQuery(srcSession, query, queryType); } catch (RepositoryException e) { log.error(e.getMessage(), e); } } return; } dest=destRf.getRepository(); SessionFactory destSf=new SessionFactoryImpl(dest, destCredentials); Session destSession=destSf.getSession(); try { RepositoryManager.registerCustomNodeTypes(destSession, cndPath); if (nodeLimit == 0) NodeCopier.copy(srcSession, destSession, srcRepoPath, destRepoPath, true); else NodeCopier.copy(srcSession, destSession, srcRepoPath, destRepoPath, nodeLimit, true); log.info("Copying "+srcSession.getWorkspace().getName()+" to "+destSession.getWorkspace().getName()+ " for "+srcRepoDir + " done."); } catch (ParseException e) { log.error(e.getMessage(), e); } catch (IOException e) { log.error(e.getMessage(), e); } catch (PathNotFoundException e) { log.error(e.getMessage(), e); } catch (RepositoryException e) { log.error(e.getMessage(), e); } List<String> destWkspaces=RepositoryManager.getDestinationWorkspaces(srcSession, destSession); for (String workspace:destWkspaces) { Session wsSession=srcSf.getSession(workspace); Session wsDestSession=destSf.getSession(workspace); try { RepositoryManager.registerCustomNodeTypes(wsDestSession, cndPath); if (nodeLimit == 0) NodeCopier.copy(wsSession, wsDestSession, srcRepoPath, destRepoPath, true); else { NodeCopier.copy(wsSession, wsDestSession, srcRepoPath, destRepoPath, nodeLimit, true); } log.info("Copying "+wsSession.getWorkspace().getName()+" to "+wsDestSession.getWorkspace().getName()+ " for " + srcRepoDir + " done."); } catch (IOException e) { log.error(e.getMessage(), e); } catch (ParseException e) { log.error(e.getMessage(), e); } catch (PathNotFoundException e) { log.error(e.getMessage(), e); } catch (RepositoryException e) { log.error(e.getMessage(), e); } finally { wsSession.logout(); wsDestSession.logout(); } } } catch (IOException e) { log.error(e.getMessage(), e); } catch (PathNotFoundException e) { log.error(e.getMessage(), e); } catch (RepositoryException e) { log.error(e.getMessage(), e); } finally { if (dest!=null) dest.shutdown(); } } private static void runQuery(Session srcSession, String query, String queryType) throws RepositoryException { long start=System.currentTimeMillis(); RowIterator rowIt=Querier.queryBySQLRow(srcSession, query, queryType); System.out.println(Querier.formatQueryResults(rowIt)); System.out.println("Time: "+String.valueOf(System.currentTimeMillis()-start) +" milliseeconds"); } }