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 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/Backup.java (revision 0) @@ -0,0 +1,59 @@ +/* + * 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 org.apache.jackrabbit.core.RepositoryImpl; + +/** + * 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 RepositoryBackup. + */ +public abstract class Backup { + + RepositoryImpl repo; + RepositoryBackupConfig conf; + + /** + * + * @param repo The repository to backup + * @param conf The specific RepositoryBackupConfig object (usually a subset of backup.xml) + * @param name Name of the resource to backup. Unique. Useful? + */ + public Backup(RepositoryImpl repo, RepositoryBackupConfig conf) { + this.repo = repo; + this.conf = conf; + } + + public Backup() { + } + + public void setRepo(RepositoryImpl repo) { + this.repo = repo; + } + + public RepositoryImpl getRepo() { + return this.repo; + } + + public abstract void backup(BackupIOHandler out); + public abstract void restore(BackupIOHandler in); + + + +} 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 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupConfigurationParser.java (revision 0) @@ -0,0 +1,152 @@ +/* + * 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.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import org.apache.jackrabbit.core.config.ConfigurationException; +import org.apache.jackrabbit.core.config.ConfigurationParser; +import org.apache.jackrabbit.core.config.PersistenceManagerConfig; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +/** + * @author ntoper + * + */ +public class BackupConfigurationParser extends ConfigurationParser { + + private static final String WORKING_FOLDER = "WorkingFolder"; + private static final String WORKING_FOLDER_ATTRIBUTE = "path"; + private static final String RESOURCES = "Resources"; + private static final String RESOURCE = "Resource"; + private static final String SAVING_CLASS = "savingClass"; + private static final int MAX_RESOURCE = 20; + + + + /** + * @param variables + */ + public BackupConfigurationParser(Properties variables) { + super(variables); + } + + /** + * Parses backup? configuration. Backup configuration uses the + * following format: + *

+ * TODO comment. See wiki for format + * @param xml repository configuration document + * @return repository configuration + * @throws ConfigurationException if the configuration is broken + * @throws IllegalAccessException + * @throws InstantiationException + * @throws ClassNotFoundException + * @throws SizeException + * @see #parseBeanConfig(Element, String) + * @see #parseVersioningConfig(Element) + */ + public RepositoryBackupConfig parseBackupConfig(InputSource xml) + throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException { + Element root = parseXML(xml); + + //Working Folder + Element workingFolder = getElement(root, WORKING_FOLDER); + File path = new File(workingFolder.getAttribute(WORKING_FOLDER_ATTRIBUTE)); + + //Persistence Manager + PersistenceManagerConfig pmc = this.parsePersistenceManagerConfig(root); + + //Management of resources tag + Element resources = this.getElement(root, RESOURCES); + Collection allResources = this.parseResourcesConfig(resources); + + return new RepositoryBackupConfig(pmc, path, allResources ); + } + + + /** + * TODO: to put in ConfigurationParser? + * + * Returns the named children of the given parent element. + * + * @param parent parent element + * @param name name of the child element + * @param required indicates if the child element is required + * @return named children elements, or null if not found + */ + protected List getElements(Element parent, String name) { + NodeList children = parent.getChildNodes(); + Vector selected = new Vector(10, 10); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE + && name.equals(child.getNodeName())) { + + selected.addElement((Element) child); + } + } + if (selected.size() == 0){ + return null; + } + else + { + selected.trimToSize(); + return selected; + } + } + + + /* + * For now only support of all workspace backup. I think it is actually simpler to manage on the end-user side. + * + * 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 { + + /* + * For each resource + * get class and instantiate + * addResource to RepositoryBackup + */ + Vector objects = new Vector(); + Vector resources = (Vector) this.getElements(root, RESOURCE); + Iterator it = resources.iterator(); + + while (it.hasNext()) { + //We don't care about the name. It is here only for humans: only the savingClass is important + //Instantiate it and put it in the collection. + Element resource = (Element) it.next(); + String savingClass = resource.getAttribute(SAVING_CLASS); + Class c = Class.forName(savingClass); + objects.addElement( (Backup) c.newInstance()); + + + } + return objects; + + } +} 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 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/BackupIOHandler.java (revision 0) @@ -0,0 +1,26 @@ +/* + * 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; + +public interface BackupIOHandler { + + void setMaxFileSize(int i); + int getMaxFileSize(); + //Add reference to the file + // How to precise if in or out... Maybe not needed? + +} 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 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/LaunchBackup.java (revision 0) @@ -0,0 +1,208 @@ +/* + * 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.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +import javax.jcr.AccessDeniedException; +import javax.jcr.RepositoryException; + +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 + * get all available options please type LaunchBackup --help + * Used to launch a backup while the repository is inactive. + * + * @author Nicolas Toper + * Date: 23-jun-06 + */ +public class LaunchBackup { + + static BackupIOHandler h; + RepositoryImpl repo; + RepositoryBackupConfig conf; + RepositoryConfig repoConf; + RepositoryBackup backup; + + + + /** + * 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/ + * + * --zip: where is the zip file (only implemented way to backup for now) + * --size in Go + * + * --conf: path to the config file for the backup tool + * + * backup/restore: whether you want a backup or a restore + * + * repository.xml: path to the config file of the repository + * + * repository/ is the name of the repository + * + * + * --help for help option + * @throws RepositoryException + * @throws IOException + * @throws IOException + * @throws IllegalAccessException + * @throws InstantiationException + * @throws ClassNotFoundException + * @throws SizeException + * + */ + public static void main(String[] args) throws RepositoryException, AccessDeniedException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException { + // I have to declare all var here so they are not resetted out of the for. + String zipFile = null; + String confFile = null; + String home = null; + String repoConfFile = null; + + //2 booleans in case the user specified nothing + boolean isBackup = false; + boolean isRestore = false; + + //Parse the command line. + for (int i = 0; i < args.length; i++) { + + if ( args[i].equals("--help") || args.length == 0) { + usage(); + } + + 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); + } + + + if (args[i].equals("--size") && (h != null)){ + + Integer max = (new Integer(args[i+ 1])); + h.setMaxFileSize(max.intValue()); + } + + + if (args[i].equals("--conf")){ + + confFile = args[i + 1]; + + } + + 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]; + } + } + + LaunchBackup launch = new LaunchBackup(repoConfFile, home, confFile); + + //We need to shutdown properly the repository whatever happens + try { + //Launch backup + if (isBackup) { + launch.backup(h); + } + //Launch restore + else if (isRestore) { + launch.restore(h); + } + //Launch nothing (if nothing specified + else { + usage(); + } + } + finally + { + launch.shutdown(); + } + } + + + + /** + * Auxiliary method for main + * + */ + private static void usage(){ + System.out.println("todo: cut and paste of the comment when the project is over"); + System.exit(0); + } + + /** + * Constructor of LaunchBackup. Initiate the repository. + * + * @param String filename: name of the configuration file + * @throws RepositoryException + * @throws FileNotFoundException + * @throws IllegalAccessException + * @throws InstantiationException + * @throws ClassNotFoundException + * @throws SizeException + */ + public LaunchBackup(String repoConfFile, String home, String backupConfFile) throws RepositoryException, FileNotFoundException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException { + //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 = RepositoryBackupConfig.create(xml); + this.backup = RepositoryBackup.create(this.repo, this.conf); + } + + /** + * Backup a repository + * + * @param BackupIOHandler h a reference wher to backup + */ + public void backup(BackupIOHandler h) throws AccessDeniedException, RepositoryException, IOException { + this.backup.backup(h); + } + + /** + *Restore a repository + * + * @param BackupIOHandler h a reference to the backup to restore + */ + public void restore(BackupIOHandler h) { + this.backup.restore(h); + } + + private void shutdown() { + this.repo.shutdown(); + } + +} 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 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/RepositoryBackup.java (revision 0) @@ -0,0 +1,59 @@ +/* + * 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 org.apache.jackrabbit.core.RepositoryImpl; + +/** + * @author ntoper + * + */ +public class RepositoryBackup extends Backup { + + Collection resources = null; + + + + public RepositoryBackup(RepositoryImpl repo, RepositoryBackupConfig conf) { + super(repo, conf); + + } + +// @Override + public void backup(BackupIOHandler out, RepositoryBackupConfig conf) { + // TODO Auto-generated method stub + } + +// @Override + public void restore(BackupIOHandler in) { + // TODO Auto-generated method stub + + } + + public static RepositoryBackup create(RepositoryImpl impl, RepositoryBackupConfig conf2 ) { + return new RepositoryBackup(impl, conf2); + } + + public void backup(BackupIOHandler out) { + // TODO Auto-generated method stub + + } + +} Index: /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/RepositoryBackupConfig.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/RepositoryBackupConfig.java (revision 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/RepositoryBackupConfig.java (revision 0) @@ -0,0 +1,164 @@ +/* + * 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.InputStream; +import java.net.URI; +import java.util.Collection; +import java.util.Properties; + +import org.apache.jackrabbit.core.config.ConfigurationException; +import org.apache.jackrabbit.core.config.PersistenceManagerConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.InputSource; + + +/** + * Backup configuration. This configuration class is used to + * create configured backup objects. + *

+ * It will send different backup object, according to the expected type + * (RepositoryBackup or WorkspaceBackup for instance). + * + */ +public class RepositoryBackupConfig { + + private PersistenceManagerConfig pmc; + private File path; + private Collection allResources; + + /** the default logger */ + private static Logger log = LoggerFactory.getLogger(RepositoryBackupConfig.class); + + /** + * 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 + * @see #create(InputSource, String) + */ + public static RepositoryBackupConfig create(String file) + throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException { + 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 + * @see #create(InputSource, String) + */ + public static RepositoryBackupConfig create(URI uri) + throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException { + 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 + * @see #create(InputSource, String) + */ + public static RepositoryBackupConfig create(InputStream input, String home) + throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException { + return create(new InputSource(input)); + } + + /** + * Parses the given repository configuration document and returns the + * parsed and initialized repository configuration. The given repository + * home directory path will be used as the ${rep.home} parser variable. + *

+ * Note that in addition to parsing the repository configuration, this + * method also initializes the configuration (creates the configured + * directories, etc.). The {@link RepositoryConfigurationParser} class should be + * used directly to just parse the configuration. + * + * @param xml repository configuration document + * @param home repository home directory + * @return repository configuration + * @throws ConfigurationException on configuration errors + * @throws IllegalAccessException + * @throws InstantiationException + * @throws ClassNotFoundException + * @throws SizeException + */ + public static RepositoryBackupConfig create(InputSource xml) + throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException { + BackupConfigurationParser parser = new BackupConfigurationParser(new Properties()); + + RepositoryBackupConfig config = parser.parseBackupConfig(xml); + return config; + } + + + public RepositoryBackupConfig(PersistenceManagerConfig pmc, File path, Collection allResources) { + this.pmc = pmc; + this.path = path; + this.allResources = allResources; + } + + public Collection getAllResources() { + return allResources; + } + + public File getPath() { + return path; + } + + public PersistenceManagerConfig getPmc() { + return pmc; + } + + /* + * Useful? + */ + public Backup getBackup() { + // TODO Auto-generated method stub + return null; + } + +} 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 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/RepositoryConfigBackup.java (revision 0) @@ -0,0 +1,20 @@ +package org.apache.jackrabbit.backup; + +public class RepositoryConfigBackup extends Backup { + + public RepositoryConfigBackup() { + super(); + // TODO Auto-generated constructor stub + } + + public void backup(BackupIOHandler out) { + // TODO Auto-generated method stub + + } + + public void restore(BackupIOHandler in) { + // 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 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/SizeException.java (revision 0) @@ -0,0 +1,30 @@ +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/ZipFileBackupIOHandler.java =================================================================== --- /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/ZipFileBackupIOHandler.java (revision 0) +++ /home/ntoper/workspace/backup/src/main/java/org/apache/jackrabbit/backup/ZipFileBackupIOHandler.java (revision 0) @@ -0,0 +1,35 @@ +/* + * 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; + +public class ZipFileBackupIOHandler implements BackupIOHandler { + + int maxFileSize; + + public ZipFileBackupIOHandler(String zipFile) { + // TODO Auto-generated constructor stub + } + + public void setMaxFileSize(int i) { + this.maxFileSize = i; + } + + public int getMaxFileSize() { + return this.maxFileSize; + } + +}