Property changes on: /home/ntoper/workspace/backup ___________________________________________________________________ Name: svn:ignore - target + target repository *.settings *.classpath .project repository.xml Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/AllWorkspacesBackup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/AllWorkspacesBackup.java (revision 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/AllWorkspacesBackup.java (revision 0) @@ -0,0 +1,75 @@ +/* + * 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 org.apache.jackrabbit.backup; + +import java.io.IOException; + +import javax.jcr.LoginException; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.Workspace; + +import org.apache.jackrabbit.core.RepositoryImpl; + +/** + * @author ntoper + * + */ +public class AllWorkspacesBackup extends Backup { + + /** + * @param repo + * @param conf + * @throws RepositoryException + * @throws LoginException + */ + public AllWorkspacesBackup(RepositoryImpl repo, BackupConfig conf) throws LoginException, RepositoryException { + super(repo, conf); + } + + public AllWorkspacesBackup() { + super(); + } + + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#backup(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void backup(BackupIOHandler h) throws RepositoryException, + IOException { + Session s = this.getSession(); + Workspace wsp = s.getWorkspace(); + String[] allWsp = wsp.getAccessibleWorkspaceNames(); + + for (int i = 0; i < allWsp.length; i++) { + WorkspaceBackup wspb = new WorkspaceBackup(this.repo, this.conf, allWsp[i]); + wspb.backup(h); + + WorkspaceConfigBackup wspConfb = new WorkspaceConfigBackup(this.repo, this.conf, allWsp[i]); + wspConfb.backup(h); + } + } + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#restore(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void restore(BackupIOHandler h) { + // TODO Auto-generated method stub + + } + +} Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/Backup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/Backup.java (revision 426275) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/Backup.java (working copy) @@ -16,6 +16,13 @@ */ package org.apache.jackrabbit.backup; +import java.io.IOException; + +import javax.jcr.LoginException; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + import org.apache.jackrabbit.core.RepositoryImpl; /** @@ -22,7 +29,7 @@ * This class is the abstract class of all resources to backup. If you need to add a new backuped resource * extend Backup and implement both the save and restore methods. * - * The constructor is called when instantiating the specific backup resource class through ManagerBackup. + * The constructor is called when instantiating the specific backup resource class through BackupManager. */ public abstract class Backup { @@ -28,6 +35,7 @@ RepositoryImpl repo; BackupConfig conf; + Session session; /** * @@ -34,13 +42,27 @@ * @param repo The repository to backup * @param conf The specific BackupConfig object (usually a subset of backup.xml) * @param name Name of the resource to backup. Unique. Useful? + * @throws RepositoryException + * @throws LoginException */ - public Backup(RepositoryImpl repo, BackupConfig conf) { + //TODO Useful? + public Backup(RepositoryImpl repo, BackupConfig conf) throws LoginException, RepositoryException { this.repo = repo; this.conf = conf; + this.session = this.repo.login( + new SimpleCredentials(this.conf.getLogin(), this.conf.getPassword().toCharArray())); + } public Backup() { + + } + + public void init(RepositoryImpl repo, BackupConfig conf) throws LoginException, RepositoryException { + this.repo = repo; + this.conf = conf; + this.session = this.repo.login( + new SimpleCredentials(this.conf.getLogin(), this.conf.getPassword().toCharArray())); } public RepositoryImpl getRepo() { @@ -48,7 +70,12 @@ } /* - * Each ResourceBackup is responsible to handle backup of their content + configuration + * Each ResourceBackup is responsible to handle the backup. + * + * We use file when we cannot assume anything on the size of the data or we know it's big. When + * we know the data is small we store it in RAM. + * + * * * For each resource * Test maxFileSize @@ -56,9 +83,14 @@ * check the checksum * Send it to out */ - public abstract void backup(BackupIOHandler h); + public abstract void backup(BackupIOHandler h) throws RepositoryException, IOException; public abstract void restore(BackupIOHandler h); - + public Session getSession() { + return this.session; + } + + //TODO call sesssion.logout or useless? + } Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupConfig.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupConfig.java (revision 426275) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupConfig.java (working copy) @@ -18,7 +18,6 @@ import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.net.URI; import java.util.Collection; import java.util.Properties; @@ -23,6 +22,7 @@ import java.util.Collection; import java.util.Properties; + import org.apache.jackrabbit.core.config.ConfigurationException; import org.apache.jackrabbit.core.config.PersistenceManagerConfig; import org.xml.sax.InputSource; @@ -33,7 +33,7 @@ * create configured backup objects. *

* It will send different backup object, according to the expected type - * (ManagerBackup or WorkspaceBackup for instance). + * (BackupManager or WorkspaceBackup for instance). * */ public class BackupConfig { @@ -38,76 +38,17 @@ */ public class BackupConfig { + //TODO Useful? private PersistenceManagerConfig pmc; + //Tused to backup a workspace first in a file private File workFolder; private Collection allResources; - private String xml; + private File file; + private File repoConfFile; + private String login; + private String password; /** - * Convenience method that wraps the configuration file name into an - * {@link InputSource} and invokes the - * {@link #create(InputSource, String)} method. - * - * @param file repository configuration file name - * @param home repository home directory - * @return backup configuration - * @throws ConfigurationException on configuration errors - * @throws IllegalAccessException - * @throws InstantiationException - * @throws ClassNotFoundException - * @throws SizeException - * @throws IOException - * @see #create(InputSource, String) - */ - public static BackupConfig create(String file) - throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException, IOException { - URI uri = new File(file).toURI(); - return create(new InputSource(uri.toString())); - } - - /** - * Convenience method that wraps the configuration URI into an - * {@link InputSource} and invokes the - * {@link #create(InputSource, String)} method. - * - * @param uri repository configuration URI - * @param home repository home directory - * @return backup configuration - * @throws ConfigurationException on configuration errors - * @throws IllegalAccessException - * @throws InstantiationException - * @throws ClassNotFoundException - * @throws SizeException - * @throws IOException - * @see #create(InputSource, String) - */ - public static BackupConfig create(URI uri) - throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException, IOException { - return create(new InputSource(uri.toString())); - } - - /** - * Convenience method that wraps the configuration input stream into an - * {@link InputSource} and invokes the - * {@link #create(InputSource, String)} method. - * - * @param input repository configuration input stream - * @param home repository home directory - * @return backup configuration - * @throws ConfigurationException on configuration errors - * @throws IllegalAccessException - * @throws InstantiationException - * @throws ClassNotFoundException - * @throws SizeException - * @throws IOException - * @see #create(InputSource, String) - */ - public static BackupConfig create(InputStream input, String home) - throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException, IOException { - return create(new InputSource(input)); - } - - /** * Parses the given repository configuration document and returns the * parsed and initialized repository configuration. The given repository * home directory workFolder will be used as the ${rep.home} parser variable. @@ -116,6 +57,7 @@ * method also initializes the configuration (creates the configured * directories, etc.). The {@link RepositoryConfigurationParser} class should be * used directly to just parse the configuration. + * @param repoConfFile * * @param xml repository configuration document * @param home repository home directory @@ -124,14 +66,17 @@ * @throws IllegalAccessException * @throws InstantiationException * @throws ClassNotFoundException - * @throws SizeException * @throws IOException */ - public static BackupConfig create(InputSource xml) - throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException, IOException { + public static BackupConfig create(String myFile, String repoConfFile, String login, String password) + throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, IOException { + + URI uri = new File(myFile).toURI(); + InputSource is = new InputSource(uri.toString()); + BackupConfigurationParser parser = new BackupConfigurationParser(new Properties()); - BackupConfig config = parser.parseBackupConfig(xml); + BackupConfig config = parser.parseBackupConfig(is, myFile, repoConfFile, login, password); return config; } @@ -139,7 +84,7 @@ //TODO see if path is really useful? - public BackupConfig(PersistenceManagerConfig pmc, File path, Collection allResources) throws IOException { + public BackupConfig(PersistenceManagerConfig pmc, File path, Collection allResources, String myFile, String repoConfFile, String login, String password) throws IOException { //Logic application: not in the parser: this code has to be here if (!(path.isDirectory() && path.canWrite())) { @@ -149,6 +94,10 @@ this.pmc = pmc; this.workFolder = path; this.allResources = allResources; + this.file = new File(myFile); + this.repoConfFile = new File(repoConfFile); + this.password = password; + this.login = login; } public Collection getAllResources() { @@ -163,17 +112,28 @@ return pmc; } - /* - * Useful? - */ - public Backup getBackup() { - // TODO Auto-generated method stub - return null; + public File getFile() { + return this.file; + } + + + + public File getRepoConfFile() { + return repoConfFile; + } + + + + public String getPassword() { + return this.password; } - public String getXml() { - return xml; + + + public String getLogin() { + return this.login; } + } Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupConfigurationBackup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupConfigurationBackup.java (revision 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupConfigurationBackup.java (revision 0) @@ -0,0 +1,68 @@ +/* + * 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 org.apache.jackrabbit.backup; + +import java.io.File; +import java.io.IOException; + +import javax.jcr.LoginException; +import javax.jcr.RepositoryException; + +import org.apache.jackrabbit.core.RepositoryImpl; + +/** + * Backup/Restore the XML file used to configure this backup. + * + * @author ntoper + * + */ +public class BackupConfigurationBackup extends Backup { + + /** + * @param repo + * @param conf + * @throws RepositoryException + * @throws LoginException + */ + public BackupConfigurationBackup(RepositoryImpl repo, BackupConfig conf) throws LoginException, RepositoryException { + super(repo, conf); + + } + + public BackupConfigurationBackup() { + super(); + } + + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#backup(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void backup(BackupIOHandler h) throws RepositoryException, + IOException { + File file = conf.getFile(); + h.write("backup.xml", file); + } + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#restore(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void restore(BackupIOHandler h) { + // TODO Auto-generated method stub + + } + +} Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupConfigurationParser.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupConfigurationParser.java (revision 426275) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupConfigurationParser.java (working copy) @@ -16,7 +16,6 @@ */ package org.apache.jackrabbit.backup; -import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.util.Collection; @@ -52,30 +51,7 @@ super(variables); } - - /* - * A static method to get the XML conf file and return it as a String. - * It is static since it doesn't have to be used with this configuration XML file. - * - * TODO: where is the best place for this method? - * - * @param the InputSource - */ - public static String toXmlString(InputSource xml) throws IOException { - - String line; - StringBuffer content = new StringBuffer(); - BufferedReader readBuffer = new BufferedReader(xml.getCharacterStream()); - - while((line = readBuffer.readLine()) != null){ - content.append(line); - content.append("\r\n"); - } - readBuffer.close(); - return content.toString(); - } - - + /** * Parses backup? configuration. Backup configuration uses the * following format: @@ -82,6 +58,8 @@ *

* TODO comment. See wiki for format * @param xml repository configuration document + * @param myFile + * @param repoConfFile * @return repository configuration * @throws ConfigurationException if the configuration is broken * @throws IllegalAccessException @@ -87,7 +65,6 @@ * @throws IllegalAccessException * @throws InstantiationException * @throws ClassNotFoundException - * @throws SizeException * @throws IOException * @see #parseBeanConfig(Element, String) * @see #parseVersioningConfig(Element) @@ -92,9 +69,9 @@ * @see #parseBeanConfig(Element, String) * @see #parseVersioningConfig(Element) */ - public BackupConfig parseBackupConfig(InputSource xml) - throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException, IOException { - + public BackupConfig parseBackupConfig(InputSource xml, String myFile, String repoConfFile, String login, String password) + throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, IOException { + //TODO refactor dependency between this method and BackupConfig Element root = parseXML(xml); //Working Folder @@ -108,7 +85,7 @@ Element resources = this.getElement(root, RESOURCES); Collection allResources = this.parseResourcesConfig(resources); - return new BackupConfig(pmc, path, allResources); + return new BackupConfig(pmc, path, allResources, myFile, repoConfFile, login, password); } @@ -145,11 +122,11 @@ /* - * For now only support of all workspace backup. I think it is actually simpler to manage on the end-user side. + * For now only support of all workspace backup. I think it is actually simpler to manage on the end-user side. Be careful the objects aren't usable yet * * Pre-condition: there are resource tags in the conf file (otherwise there is a problem in the backup) */ - private Collection parseResourcesConfig( Element root) throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException { + private Collection parseResourcesConfig(Element root) throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException { /* * For each resource @@ -154,7 +131,7 @@ /* * For each resource * get class and instantiate - * addResource to ManagerBackup + * addResource to BackupManager */ Vector objects = new Vector(); Vector resources = (Vector) this.getElements(root, RESOURCE); @@ -166,9 +143,7 @@ Element resource = (Element) it.next(); String savingClass = resource.getAttribute(SAVING_CLASS); Class c = Class.forName(savingClass); - objects.addElement( (Backup) c.newInstance()); - - + objects.addElement( (Backup) c.newInstance()); } return objects; @@ -173,4 +148,17 @@ return objects; } + + /** + * Parses the PersistenceManager config. + * + * @param parent parent of the PersistenceManager element + * @return persistence manager configuration + * @throws ConfigurationException if the configuration is broken + */ + protected PersistenceManagerConfig parsePersistenceManagerConfig( + Element parent) throws ConfigurationException { + return new PersistenceManagerConfig( + parseBeanConfig(parent, PERSISTENCE_MANAGER_ELEMENT)); + } } Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupIOHandler.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupIOHandler.java (revision 426275) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupIOHandler.java (working copy) @@ -16,17 +16,18 @@ */ package org.apache.jackrabbit.backup; +import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileNotFoundException; +import java.io.IOException;; public interface BackupIOHandler { - int getMaxFileSize(); - void setMaxFileSize(int i); - //Add reference to the file - // How to precise if in or out... Maybe not needed? - void close(); - void initBackup() throws FileNotFoundException; - void initRestore(); - void init(); - + //Add reference to the file + // How to precise if in or out... Maybe not needed? + void close() throws IOException; + void initBackup() throws FileNotFoundException, IOException; + void initRestore() throws FileNotFoundException; + void write(String name, File f) throws IOException; + void write(String name, ByteArrayOutputStream fos) throws IOException; } Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupManager.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupManager.java (revision 423637) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupManager.java (working copy) @@ -17,8 +17,13 @@ package org.apache.jackrabbit.backup; +import java.io.IOException; import java.util.Collection; import java.util.Iterator; + +import javax.jcr.LoginException; +import javax.jcr.RepositoryException; + import org.apache.jackrabbit.core.RepositoryImpl; /** @@ -25,6 +30,8 @@ * This class manages the backup/restore process. It is responsible to transmit it to the BackupIOHandler and to add the repository to the * BackupConfig. * + * It extends Backup since it is based on the same semantics. However it is not at the same type as a ResourceBackup (indicated by different names) + * * It uses a work folder to get first all backup/restore information, zip them and send them to the handler. * * @author ntoper @@ -30,20 +37,24 @@ * @author ntoper * */ -public class ManagerBackup extends Backup { +public class BackupManager extends Backup { - public ManagerBackup(RepositoryImpl repo, BackupConfig conf) { + public BackupManager(RepositoryImpl repo, BackupConfig conf) throws LoginException, RepositoryException { super(repo, conf); - //The repository is a special Resource: it is added here to the list of resource - // It is not in the XML Conf file to make it more generic - this.conf.getAllResources().add(new RepositoryBackup(repo, conf)); + //Initiate correctly all objects in allResources + Iterator it = this.conf.getAllResources().iterator(); + + while(it.hasNext()) { + Backup b = (Backup) it.next(); + b.init(repo, conf); + } } - public static ManagerBackup create(RepositoryImpl impl, BackupConfig conf2) { - return new ManagerBackup(impl, conf2); - } + public static BackupManager create(RepositoryImpl impl, BackupConfig conf2) throws LoginException, RepositoryException { + return new BackupManager(impl, conf2); + } /** * Used to backup the repository and all subclasses. Call all classes when needed. * This class stores the backup config file also. (simplify its fetching and logical since it's not a configurable resource) @@ -51,9 +62,11 @@ * TODO visibility of the conf is huge: each ResourceBackup can get and set others resources modifiers. Is it really bad? * * @param The BackupIOHandler where the backup will be saved + * @throws RepositoryException + * @throws IOException * */ - public void backup(BackupIOHandler h) { + public void backup(BackupIOHandler h) throws RepositoryException, IOException { /* This method calls alternatively each backup method of each Backup. * It is responsible to initiate and close the zipFile. * Each backup method, use the BackupIOHandler to write the file directly. @@ -59,9 +72,10 @@ * Each backup method, use the BackupIOHandler to write the file directly. */ + h.initBackup(); try { - h.init(); + Collection resources = this.conf.getAllResources(); Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/LaunchBackup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/LaunchBackup.java (revision 426275) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/LaunchBackup.java (working copy) @@ -16,10 +16,10 @@ */ package org.apache.jackrabbit.backup; -import java.io.FileReader; import java.io.IOException; import javax.jcr.AccessDeniedException; +import javax.jcr.LoginException; import javax.jcr.RepositoryException; import org.apache.jackrabbit.core.RepositoryImpl; @@ -24,7 +24,6 @@ import org.apache.jackrabbit.core.RepositoryImpl; import org.apache.jackrabbit.core.config.RepositoryConfig; -import org.xml.sax.InputSource; /** * LaunchBackup is a command line tool and a demo tool for the backup tool. To @@ -36,11 +35,11 @@ */ public class LaunchBackup { - static BackupIOHandler h; - RepositoryImpl repo; + static BackupIOHandler h; + RepositoryImpl repo; BackupConfig conf; RepositoryConfig repoConf; - ManagerBackup backup; + BackupManager backup; @@ -47,8 +46,8 @@ /** * The command line tool. * - * LaunchBackup --zip myzip.zip --size 2 --conf backup.xml backup repository.xml repository/ - * LaunchBackup --zip ./myzip.zip --size 2 --conf backup.xml restore repository.xml repository/ + * LaunchBackup --zip myzip.zip --size 2 --conf backup.xml --login nico --password mlypass backup repository.xml repository/ + * LaunchBackup --zip ./myzip.zip --size 2 --conf backup.xml --login nico --password restore repository.xml repository/ * * --zip: where is the zip file (only implemented way to backup for now) * --size in Go @@ -69,15 +68,16 @@ * @throws IllegalAccessException * @throws InstantiationException * @throws ClassNotFoundException - * @throws SizeException * */ - public static void main(String[] args) throws RepositoryException, AccessDeniedException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException { + public static void main(String[] args) throws RepositoryException, AccessDeniedException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { // I have to declare all var here so they are not resetted out of the for. - String zipFile = null; + String zipFile = null; String confFile = null; String home = null; String repoConfFile = null; + String login = null; + String password = null; //2 booleans in case the user specified nothing boolean isBackup = false; @@ -84,8 +84,8 @@ boolean isRestore = false; //Parse the command line. - for (int i = 0; i < args.length; i++) { - + for (int i = 0; i < args.length; i++) { + if ( args[i].equals("--help") || args.length == 0) { usage(); } @@ -91,63 +91,72 @@ } if (args[i].equals("--zip")){ - zipFile = args[i + 1]; - //We put it here because later we might offer other possibilities than only zip - h = new ZipFileBackupIOHandler(zipFile); + zipFile = args[i + 1]; + //We put it here because later we might offer other possibilities than only zip + LaunchBackup.h = new ZipFileBackupIOHandler(zipFile); } + if (args[i].equals("--conf")){ + + confFile = args[i + 1]; + + } - if (args[i].equals("--size") && (h != null)){ - - Integer max = (new Integer(args[i+ 1])); - h.setMaxFileSize(max.intValue()); + if (args[i].equals("--login")){ + + login = args[i + 1]; + } - - if (args[i].equals("--conf")){ - - confFile = args[i + 1]; - + if (args[i].equals("--password")){ + + password = args[i + 1]; + } - if (args[i].equals("backup") && isRestore == false ){ - isBackup = true; - repoConfFile = args[i + 1]; - home = args[i + 2]; - + if (args[i].equals("backup") && isRestore == false ){ + isBackup = true; + repoConfFile = args[i + 1]; + home = args[i + 2]; + } if (args[i].equals("restore") && isBackup == false ){ - isRestore = true; - repoConfFile = args[i + 1]; - home = args[i + 2]; + isRestore = true; + repoConfFile = args[i + 1]; + home = args[i + 2]; } } - - LaunchBackup launch = null; - - //We need to shutdown properly the repository whatever happens - try { - //Launch backup - if (isBackup) { - launch = new LaunchBackup(repoConfFile, home, confFile); + + //Check if login and password are provided otherwise weird thing will happen + if (login == null || password == null) { + throw new LoginException(); + } + + LaunchBackup launch = null; + + //We need to shutdown properly the repository whatever happens + try { + //Launch backup + if (isBackup) { + launch = new LaunchBackup(repoConfFile, home, confFile, login, password); launch.backup(h); - } - //Launch restore - else if (isRestore) { - launch = new LaunchBackup(); - launch.restore(h); - } - //Launch nothing (if nothing specified - else { - usage(); - } - } - finally - { - if (launch !=null) - launch.shutdown(); - } + } + //Launch restore + else if (isRestore) { + launch = new LaunchBackup(); + launch.restore(h); + } + //Launch nothing (if nothing specified + else { + usage(); + } + } + finally + { + if (launch !=null) + launch.shutdown(); + } } @@ -152,7 +161,7 @@ - /** + /** * Auxiliary method for main * */ @@ -169,20 +178,17 @@ * @throws IllegalAccessException * @throws InstantiationException * @throws ClassNotFoundException - * @throws SizeException * @throws IOException */ - public LaunchBackup(String repoConfFile, String home, String backupConfFile) throws RepositoryException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException, IOException { - //Launch first the repository - this.repoConf = RepositoryConfig.create(repoConfFile, home); - this.repo = RepositoryImpl.create(this.repoConf); + public LaunchBackup(String repoConfFile, String home, String backupConfFile, String login, String password) throws RepositoryException, ClassNotFoundException, InstantiationException, IllegalAccessException, IOException { + //Launch first the repository + this.repoConf = RepositoryConfig.create(repoConfFile, home); + this.repo = RepositoryImpl.create(this.repoConf); - //Create the backupConfig object - - FileReader fr = new FileReader(backupConfFile); - InputSource xml = new InputSource(fr); - this.conf = BackupConfig.create(xml); - this.backup = ManagerBackup.create(this.repo, this.conf); + //Create the backupConfig object + this.conf = BackupConfig.create(backupConfFile, repoConfFile, login, password); + this.backup = BackupManager.create(this.repo, this.conf); + } /** @@ -215,7 +221,7 @@ } private void shutdown() { - this.repo.shutdown(); - } + this.repo.shutdown(); + } } Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/ManagerBackup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/ManagerBackup.java (revision 426275) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/ManagerBackup.java (working copy) @@ -1,88 +0,0 @@ -/* - * 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 org.apache.jackrabbit.backup; - - -import java.util.Collection; -import java.util.Iterator; -import org.apache.jackrabbit.core.RepositoryImpl; - -/** - * This class manages the backup/restore process. It is responsible to transmit it to the BackupIOHandler and to add the repository to the - * BackupConfig. - * - * It uses a work folder to get first all backup/restore information, zip them and send them to the handler. - * - * @author ntoper - * - */ -public class ManagerBackup extends Backup { - - public ManagerBackup(RepositoryImpl repo, BackupConfig conf) { - super(repo, conf); - - //The repository is a special Resource: it is added here to the list of resource - // It is not in the XML Conf file to make it more generic - this.conf.getAllResources().add(new RepositoryBackup(repo, conf)); - } - - - public static ManagerBackup create(RepositoryImpl impl, BackupConfig conf2) { - return new ManagerBackup(impl, conf2); - } - /** - * Used to backup the repository and all subclasses. Call all classes when needed. - * This class stores the backup config file also. (simplify its fetching and logical since it's not a configurable resource) - * - * TODO visibility of the conf is huge: each ResourceBackup can get and set others resources modifiers. Is it really bad? - * - * @param The BackupIOHandler where the backup will be saved - * - */ - public void backup(BackupIOHandler h) { - /* This method calls alternatively each backup method of each Backup. - * It is responsible to initiate and close the zipFile. - * Each backup method, use the BackupIOHandler to write the file directly. - */ - - try { - - h.init(); - Collection resources = this.conf.getAllResources(); - - - Iterator it = resources.iterator(); - - while (it.hasNext()) { - Backup b = (Backup) it.next(); - b.backup(h); - } - } - finally { - h.close(); - } - } - - public void restore(BackupIOHandler h) { - // TODO Auto-generated method stub - - } - - - - -} Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/NamespaceBackup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/NamespaceBackup.java (revision 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/NamespaceBackup.java (revision 0) @@ -0,0 +1,128 @@ +/* + * 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 org.apache.jackrabbit.backup; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.HashMap; + +import javax.jcr.LoginException; +import javax.jcr.NamespaceRegistry; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.Workspace; + +import org.apache.jackrabbit.core.RepositoryImpl; + + + +/** + * This class handles backup of the namespaces of the repository. + * + * This class needs to be serializable so the internal class can be serialized (does anybody know why?) + * + * @author ntoper + * + */ +public class NamespaceBackup extends Backup implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 4703796138774238005L; + + /** + * This class holds all namespaces in a serializable way. We only put the relevant information. + * (Do not change this class or you might lose backward compatibility; instead use another version) + * + */ + private class Namespaces implements Serializable { + + private static final long serialVersionUID = 8384076353482950602L; + + HashMap h; + + + public Namespaces() { + h = new HashMap(); + } + + public void addNamespace(String prefix, String uri) { + h.put(prefix, uri); + } + + } + + /** + * @param repo + * @param conf + * @throws RepositoryException + * @throws LoginException + */ + public NamespaceBackup(RepositoryImpl repo, BackupConfig conf) throws LoginException, RepositoryException { + super(repo, conf); + + + + } + + public NamespaceBackup() { + super(); + } + + + /* (non-Javadoc) + * TODO where do I find the local ns? + * TODO use a ByteArrayOutputStream? + * @see org.apache.jackrabbit.backup.Backup#backup(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void backup(BackupIOHandler h) throws RepositoryException, IOException { + + Session s = this.getSession(); + Workspace wsp = s.getWorkspace(); + NamespaceRegistry ns = wsp.getNamespaceRegistry(); + + Namespaces myNs = new Namespaces(); + + String[] allPrefixes = ns.getPrefixes(); + + for (int i = 0; i < allPrefixes.length; i++) { + String prefix = allPrefixes[i]; + myNs.addNamespace(prefix, ns.getURI(prefix)); + } + + String name = this.getClass().toString(); + + ByteArrayOutputStream fos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(myNs); + h.write(name, fos); + } + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#restore(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void restore(BackupIOHandler h) { + // TODO Auto-generated method stub + + } + + + +} Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/NodeTypeBackup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/NodeTypeBackup.java (revision 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/NodeTypeBackup.java (revision 0) @@ -0,0 +1,100 @@ +/* + * 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 org.apache.jackrabbit.backup; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import javax.jcr.LoginException; +import javax.jcr.NamespaceRegistry; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.Workspace; +import javax.jcr.nodetype.NoSuchNodeTypeException; + +import org.apache.jackrabbit.core.RepositoryImpl; +import org.apache.jackrabbit.core.nodetype.NodeTypeDef; +import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl; +import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; +import org.apache.jackrabbit.core.nodetype.xml.NodeTypeWriter; +import org.apache.jackrabbit.name.QName; + +/** + * @author ntoper + * + */ +public class NodeTypeBackup extends Backup { + + /** + * @param repo + * @param conf + * @throws RepositoryException + * @throws LoginException + */ + public NodeTypeBackup(RepositoryImpl repo, BackupConfig conf) throws LoginException, RepositoryException { + super(repo, conf); + } + + public NodeTypeBackup() { + super(); + } + + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#backup(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void backup(BackupIOHandler h) throws IOException, RepositoryException { + //Can we assume the default wsp always exist? + Session s = this.getSession(); + Workspace wsp = s.getWorkspace(); + + NodeTypeManagerImpl ntm = (NodeTypeManagerImpl) wsp.getNodeTypeManager(); + NodeTypeRegistry ntreg = ntm.getNodeTypeRegistry(); + NamespaceRegistry ns = wsp.getNamespaceRegistry(); + NodeTypeDef[] ntd = getRegisteredNodesTypesDefs(ntreg); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + NodeTypeWriter.write(out, ntd, ns); + h.write("NodeType", out); + } + + + /** + * Returns the nodes types definitions of all registered node types. + * + * @return the node type definition of all registered node types. + * @throws NoSuchNodeTypeException + */ + private static NodeTypeDef[] getRegisteredNodesTypesDefs(NodeTypeRegistry ntreg) throws NoSuchNodeTypeException { + QName[] qn = ntreg.getRegisteredNodeTypes(); + NodeTypeDef[] ntd = new NodeTypeDef[qn.length]; + + for (int i=0; i < qn.length; i++) { + ntd[i] = ntreg.getNodeTypeDef(qn[i]); + } + return ntd; + } + + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#restore(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void restore(BackupIOHandler h) { + // TODO Auto-generated method stub + + } + +} Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/NodeVersionHistoriesBackup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/NodeVersionHistoriesBackup.java (revision 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/NodeVersionHistoriesBackup.java (revision 0) @@ -0,0 +1,79 @@ +/* + * 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 org.apache.jackrabbit.backup; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import javax.jcr.LoginException; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.jackrabbit.core.RepositoryImpl; + +/** + * @author ntoper + * + */ +public class NodeVersionHistoriesBackup extends Backup { + + /** + * @param repo + * @param conf + * @throws RepositoryException + * @throws LoginException + */ + public NodeVersionHistoriesBackup(RepositoryImpl repo, BackupConfig conf) throws LoginException, RepositoryException { + super(repo, conf); + // TODO Auto-generated constructor stub + } + + public NodeVersionHistoriesBackup() { + super(); + // TODO Auto-generated constructor stub + } + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#backup(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void backup(BackupIOHandler h) throws RepositoryException, + IOException { + Session s = this.getSession(); + + File temp = new File(this.conf.getWorkFolder() + "history.xml"); + + try { + FileOutputStream out = new FileOutputStream(temp); + s.exportSystemView("/jcr:system/jcr:versionStorage", out, false, false); + h.write("history.xml", temp); + } + finally { + temp.delete(); + } + } + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#restore(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void restore(BackupIOHandler h) { + //TODO find a way to put /jcr:system/jcr:versionStorage probably by instanciating as a repo/wsp the versioning pm + + + } + +} Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/RepositoryBackup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/RepositoryBackup.java (revision 426275) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/RepositoryBackup.java (working copy) @@ -16,6 +16,18 @@ */ package org.apache.jackrabbit.backup; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.util.Properties; + +import javax.jcr.LoginException; +import javax.jcr.RepositoryException; + + +import org.apache.jackrabbit.core.NodeId; +import org.apache.jackrabbit.core.NodeImpl; import org.apache.jackrabbit.core.RepositoryImpl; /** @@ -24,28 +36,54 @@ */ public class RepositoryBackup extends Backup { + /** * @param repo * @param conf + * @throws RepositoryException + * @throws LoginException */ - public RepositoryBackup(RepositoryImpl repo, BackupConfig conf) { + public RepositoryBackup(RepositoryImpl repo, BackupConfig conf) throws LoginException, RepositoryException { super(repo, conf); - // TODO Auto-generated constructor stub } - - /** - * - */ + public RepositoryBackup() { super(); - // TODO Auto-generated constructor stub } + /** + * Backup the repository config file + * + * TODO Backup properties? Metadata store? Other ressources? + * @throws IOException + * @throws RepositoryException + * + * + */ + public void backup(BackupIOHandler h) throws IOException, RepositoryException { + + File file = this.conf.getRepoConfFile(); - public void backup(BackupIOHandler h) { - // TODO Auto-generated method stub + //Backup repository.xml + h.write("repository_xml", file); + + //Properties + Properties p = this.repo.loadRepProps(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + p.storeToXML(bos,""); + h.write("repository_properties", bos); + // Root node ID + NodeImpl nod = (NodeImpl) this.getSession().getRootNode(); + NodeId n = nod.getNodeId(); + + //We persist the string as a serialized object to avoid compatibility issue + String s = n.toString(); + ByteArrayOutputStream fos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(s); + h.write("repository_rootNode", fos); } public void restore(BackupIOHandler h) { Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/RepositoryConfigBackup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/RepositoryConfigBackup.java (revision 426275) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/RepositoryConfigBackup.java (working copy) @@ -1,36 +0,0 @@ -package org.apache.jackrabbit.backup; - -public class RepositoryConfigBackup extends Backup { - - public RepositoryConfigBackup() { - super(); - // TODO Auto-generated constructor stub - } - - - - - - public void backup(BackupIOHandler h) { - - /*if (h.getClass().toString().equals("ZipFileBackupIOHandler")) - { - } - else - */ - } - - - - public void restore(BackupIOHandler h) { - // TODO Auto-generated method stub - - } - - - - - - - -} Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/SizeException.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/SizeException.java (revision 426275) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/SizeException.java (working copy) @@ -1,30 +0,0 @@ -package org.apache.jackrabbit.backup; - -public class SizeException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public SizeException() { - super(); - // TODO Auto-generated constructor stub - } - - public SizeException(String arg0) { - super(arg0); - // TODO Auto-generated constructor stub - } - - public SizeException(String arg0, Throwable arg1) { - super(arg0, arg1); - // TODO Auto-generated constructor stub - } - - public SizeException(Throwable arg0) { - super(arg0); - // TODO Auto-generated constructor stub - } - -} Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/WorkspaceBackup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/WorkspaceBackup.java (revision 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/WorkspaceBackup.java (revision 0) @@ -0,0 +1,85 @@ +/* + * 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 org.apache.jackrabbit.backup; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import javax.jcr.LoginException; +import javax.jcr.RepositoryException; +import javax.jcr.SimpleCredentials; + +import org.apache.jackrabbit.core.RepositoryImpl; +import org.apache.jackrabbit.core.SessionImpl; + +//TODO Wiki doc to update +/** + * @author ntoper + * + */ +public class WorkspaceBackup extends Backup { + + private static int called = 0; + private String wspName; + + /** + * @param repo + * @param conf + * @throws RepositoryException + * @throws LoginException + */ + public WorkspaceBackup(RepositoryImpl repo, BackupConfig conf, String name) throws LoginException, RepositoryException { + super(repo, conf); + this.wspName = name; + } + + public void init(RepositoryImpl repo, BackupConfig conf, String name) throws LoginException, RepositoryException { + super.init(repo, conf); + this.wspName = name; + } + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#backup(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void backup(BackupIOHandler h) throws RepositoryException, + IOException { + SessionImpl s = (SessionImpl) repo.login(new SimpleCredentials(this.conf.getLogin(), this.conf.getPassword().toCharArray()), this.wspName); + + File temp = new File(this.conf.getWorkFolder() + "wsp.xml"); + + try { + FileOutputStream out = new FileOutputStream(temp); + s.exportSystemView("/", out, false, false, true ); + h.write("export"+ called +".xml", temp); + } + finally { + temp.delete(); + called += 1; + } + + } + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#restore(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void restore(BackupIOHandler h) { + // TODO Auto-generated method stub + + } + +} Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/WorkspaceConfigBackup.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/WorkspaceConfigBackup.java (revision 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/WorkspaceConfigBackup.java (revision 0) @@ -0,0 +1,85 @@ +/* + * 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 org.apache.jackrabbit.backup; + +import java.io.File; +import java.io.IOException; + +import javax.jcr.LoginException; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + +import org.apache.jackrabbit.core.RepositoryImpl; +import org.apache.jackrabbit.core.WorkspaceImpl; +import org.apache.jackrabbit.core.config.WorkspaceConfig; +import org.apache.jackrabbit.backup.Backup; + +/** + * @author ntoper + * + */ +public class WorkspaceConfigBackup extends Backup { + + private static int called = 0; + private String wspName; + + /** + * @param repo + * @param conf + * @throws RepositoryException + * @throws LoginException + */ + public WorkspaceConfigBackup(RepositoryImpl repo, BackupConfig conf, String name) throws LoginException, RepositoryException { + super(repo, conf); + this.wspName = name; + } + + public void init(RepositoryImpl repo, BackupConfig conf, String name) throws LoginException, RepositoryException { + super.init(repo, conf); + this.wspName = name; + } + + public WorkspaceConfigBackup() { + super(); + } + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#backup(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void backup(BackupIOHandler h) throws RepositoryException, + IOException { + Session s = repo.login(new SimpleCredentials(this.conf.getLogin(), this.conf.getPassword().toCharArray()), this.wspName); + + WorkspaceImpl wsp = (WorkspaceImpl) s.getWorkspace(); + WorkspaceConfig c = wsp.getConfig(); + + String home = c.getHomeDir(); + File wspXml = new File (home + "/workspace.xml"); + h.write("WspConf" + called , wspXml); + called += 1; + } + + /* (non-Javadoc) + * @see org.apache.jackrabbit.backup.Backup#restore(org.apache.jackrabbit.backup.BackupIOHandler) + */ + public void restore(BackupIOHandler h) { + // TODO Auto-generated method stub + + } + +} Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/ZipFileBackupIOHandler.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/ZipFileBackupIOHandler.java (revision 426275) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/ZipFileBackupIOHandler.java (working copy) @@ -16,6 +16,8 @@ */ package org.apache.jackrabbit.backup; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -20,8 +22,14 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Array; +import java.util.zip.CRC32; +import java.util.zip.CheckedInputStream; +import java.util.zip.Checksum; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * Question: ZipFile @@ -30,57 +38,48 @@ * */ public class ZipFileBackupIOHandler implements BackupIOHandler { - - int maxFileSize; - File zip; - FileInputStream fin; - FileChannel fc; - private ByteBuffer buffer; - private FileOutputStream fout; - - - public ZipFileBackupIOHandler(String zipFile) { - this.zip = new File(zipFile); - this.buffer = ByteBuffer.allocateDirect(2048); - } - - public void setMaxFileSize(int i) { - this.maxFileSize = i; - } + + private static int BUFFER_SIZE = 1024; - public int getMaxFileSize() { - return this.maxFileSize; + private File zip; + // private FileInputStream fin; + // private ByteBuffer buffer; + private FileOutputStream fout; + private ZipOutputStream zipOut; + + + public ZipFileBackupIOHandler(String zipFile) throws FileNotFoundException { + this.zip = new File(zipFile); + // this.buffer = ByteBuffer.allocateDirect(2048); } - public void close() { - // TODO Auto-generated method stub - + public void close() throws IOException { + zipOut.finish(); + zipOut.close(); } - public void init() { + /// private void init() { //Useful? - this.buffer.clear(); - } + // this.buffer.clear(); + //} - public void initBackup() throws FileNotFoundException { + public void initBackup() throws IOException { + boolean a = this.zip.createNewFile(); + + if (!a) { + throw new IOException(); + } + this.fout = new FileOutputStream(this.zip); - this.fc = this.fin.getChannel(); + this.zipOut = new ZipOutputStream(this.fout); } - public void initRestore() { - try { - this.fin = new FileInputStream(this.zip); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - this.fc = this.fin.getChannel(); - + public void initRestore() throws FileNotFoundException { + // this.fin = new FileInputStream(this.zip); + // this.fcin = this.fin.getChannel(); + //Restore zipFile } - - - /** * Create a directory per resources * Backup the resource and zip it @@ -87,7 +86,7 @@ * @param string * @param content */ - /* private void writeFile(String string, String content) { + /*private void writeFile(String string, String content) { File conf = new File(); FileWriter fw = new FileWriter(cheminAbstraitSortie); BufferedWriter tamponEcriture = new BufferedWriter(fluxEcritureTexte); @@ -96,5 +95,67 @@ tamponEcriture.close(); } */ + + public void read() { + } + + + public void write(String name, File f) throws IOException { + zipOut.flush(); + ZipEntry e = new ZipEntry(name); + zipOut.putNextEntry(e); + + Checksum crc = new CRC32(); + CheckedInputStream i = new CheckedInputStream(new FileInputStream(f), crc); + + byte[] buffer = new byte[BUFFER_SIZE]; + + int len; + while ( (len = i.read(buffer, 0, BUFFER_SIZE)) != -1) { + zipOut.write(buffer,0, len); + } + + //Checksum management + // TODO Is crc up to date? To be checked... + long check = crc.getValue(); + e.setCrc(check); + zipOut.closeEntry(); + } + + + /** + * + * TODO: refactor this method with the one upper. + * + * + * Used for small I/O operations (no NIO used there). Take a file and zip it. + * + * Most I/O operations are operated on RAM. + * + */ + public void write(String name, ByteArrayOutputStream fos) throws IOException { + zipOut.flush(); + ZipEntry e = new ZipEntry(name); + zipOut.putNextEntry(e); + + Checksum crc = new CRC32(); + + InputStream io = new ByteArrayInputStream(fos.toByteArray()); + + CheckedInputStream i = new CheckedInputStream(io, crc); + + byte[] buffer = new byte[BUFFER_SIZE]; + int len; + while ( (len = i.read(buffer, 0, BUFFER_SIZE)) != -1) { + zipOut.write(buffer,0, len); + } + + //Checksum management + // TODO Is crc up to date? To be checked... + long check = crc.getValue(); + e.setCrc(check); + zipOut.closeEntry(); + } + } Index: /home/ntoper/workspace/backup/src/test/backup.xml =================================================================== --- /home/ntoper/workspace/backup/src/test/backup.xml (revision 0) +++ /home/ntoper/workspace/backup/src/test/backup.xml (revision 0) @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file Index: /home/ntoper/workspace/backup/src/test/java/org/apache/jackrabbit/backup/BackupTest.java =================================================================== --- /home/ntoper/workspace/backup/src/test/java/org/apache/jackrabbit/backup/BackupTest.java (revision 0) +++ /home/ntoper/workspace/backup/src/test/java/org/apache/jackrabbit/backup/BackupTest.java (revision 0) @@ -0,0 +1,156 @@ +/* + * 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 org.apache.jackrabbit.backup; + +import javax.jcr.*; +import javax.jcr.nodetype.NodeTypeManager; + +import org.apache.jackrabbit.core.TransientRepository; +import org.apache.jackrabbit.core.WorkspaceImpl; +import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException; +import org.apache.jackrabbit.core.nodetype.NodeTypeDef; +import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl; +import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; +import org.apache.jackrabbit.name.QName; + +import java.io.File; +import java.io.FileInputStream; + +//TODO provide options to start up and put relative path + +/** + * Third Jackrabbit example application. Imports an example XML file + * and outputs the contents of the entire workspace. + */ +public class BackupTest { + + /** Runs the ThirdHop example. */ + public static void main(String[] args) throws Exception { + // Set up a Jackrabbit repository with the specified + // configuration file and repository directory + Repository repository = new TransientRepository(); + + // Login to the default workspace as a dummy user + Session session = repository.login( + new SimpleCredentials("username", "password".toCharArray())); + try { + // Use the root node as a starting point + Node root = session.getRootNode(); + + // Import the XML file unless already imported + if (!root.hasNode("importxml")) { + System.out.print("Importing xml... "); + // Create an unstructured node under which to import the XML + root.addNode("importxml", "nt:unstructured"); + // Import the file "test.xml" under the created node + FileInputStream xml = new FileInputStream("/home/ntoper/workspace/backup/src/test/test.xml"); + session.importXML( + "/importxml", xml, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW); + xml.close(); + // Save the changes to the repository + session.save(); + System.out.println("done."); + } + + //Versionning + //create versionable node + Node n = root.addNode("childNode", "nt:unstructured"); + n.addMixin("mix:versionable"); + n.setProperty("anyProperty", "Blah"); + session.save(); + n.checkin(); + + //add new version + Node child = root.getNode("childNode"); + child.checkout(); + child.setProperty("anyProperty", "Blah2"); + session.save(); + child.checkin(); + + //Creating a second workspace + Workspace wsp = session.getWorkspace(); + String[] allWsp = wsp.getAccessibleWorkspaceNames(); + + if (allWsp.length < 2) { + ((WorkspaceImpl)wsp).createWorkspace("secondTest"); + session.logout(); + Session session2 = repository.login(new SimpleCredentials("username", "password".toCharArray()), "secondTest"); + root = session2.getRootNode(); + + System.out.print("Importing xml in workspace secondTest... "); + + // Create an unstructured node under which to import the XML + root.addNode("importxml", "nt:unstructured"); + // Import the file "test.xml" under the created node + FileInputStream xml = new FileInputStream("/home/ntoper/workspace/backup/src/test/test.xml"); + session2.importXML( + "/importxml", xml, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW); + xml.close(); + // Save the changes to the repository + session2.save(); + System.out.println("done."); + + } + + + + //Registering a NodeType + /* System.out.print("Registering a test nodeType...\r\n "); + + NodeTypeDef ntd = new NodeTypeDef(); + ntd.setMixin(true); + ntd.setName(new QName("http://www.jcp.org/jcr/nt/1.0", "example")); + registerNodeType(ntd, session); + + */ + + System.out.print("Launching backup...\r\n "); + + /* Tested params: + * --zip myzip.zip --size 2 --conf /home/ntoper/workspace/testJrBackup/backup.xml backup /home/ntoper/workspace/testJrBackup/repository.xml /home/ntoper/workspace/testJrBackup/repository/ + */ + + //Delete the zip file if existing + File zip = new File("myzip.zip"); + zip.delete(); + + String[] argsBackup ="--zip myzip.zip --login username --password password --conf /home/ntoper/workspace/backup/src/test/backup.xml backup /home/ntoper/workspace/backup/repository.xml /home/ntoper/workspace/backup/repository/".split(" "); + LaunchBackup.main(argsBackup); + System.out.print("Backup done. "); + + + } finally { + session.logout(); + } + } + + private static void registerNodeType(NodeTypeDef nodeTypeDef, Session session) throws RepositoryException, InvalidNodeTypeDefException + { + //NodeTypeRegistry object + Workspace wsp = session.getWorkspace(); + NodeTypeManager ntMgr = wsp.getNodeTypeManager(); + + //non-JSR 170 - jackrabbit specific + NodeTypeRegistry ntReg = + ((NodeTypeManagerImpl) ntMgr).getNodeTypeRegistry(); + + ntReg.registerNodeType(nodeTypeDef); + } + + +} \ No newline at end of file Index: /home/ntoper/workspace/backup/src/test/test.xml =================================================================== --- /home/ntoper/workspace/backup/src/test/test.xml (revision 0) +++ /home/ntoper/workspace/backup/src/test/test.xml (revision 0) @@ -0,0 +1,70 @@ + + + 3 + org.apache.jackrabbit + jackrabbit-backup + Jackrabbit Backup + SNAPSHOT + 2006 + org.apache.jackrabbit.backup.* + Backup tool for Jackrabbit repositories + + + + The Apache Software License, Version 2.0 + /LICENSE.txt + repo + + + + + + jsr170 + jcr + 1.0 + http://jcp.org/en/jsr/detail?id=170 + + + org.apache.jackrabbit + jackrabbit-core + 1.0-SNAPSHOT + + + junit + junit + 3.8.1 + + + org.slf4j + slf4j-log4j12 + 1.0 + http://www.slf4j.org/download.html + + + log4j + log4j + 1.2.8 + http://logging.apache.org/log4j + + + + + src/main/java + src/test/java + + + META-INF + . + + README.txt + + + + + + **/*Test.java + + + + +