Property changes on: /home/ntoper/workspace/backup2 ___________________________________________________________________ Name: svn:ignore - target + target .classpath .project .settings Index: /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/Backup.java =================================================================== --- /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/Backup.java (revision 423545) +++ /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/Backup.java (working copy) @@ -22,7 +22,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 RepositoryBackup. + * The constructor is called when instantiating the specific backup resource class through ManagerBackup. */ public abstract class Backup { @@ -28,7 +28,6 @@ RepositoryImpl repo; BackupConfig conf; - String name; /** * @@ -40,9 +39,8 @@ this.repo = repo; this.conf = conf; } - - public void setRepo(RepositoryImpl repo) { - this.repo = repo; + + public Backup() { } public RepositoryImpl getRepo() { @@ -48,9 +46,18 @@ public RepositoryImpl getRepo() { return this.repo; } - - public abstract void backup(BackupIOHandler out); - public abstract void restore(BackupIOHandler in); + + /* + * Each ResourceBackup is responsible to handle backup of their content + configuration + * + * For each resource + * Test maxFileSize + * Zip the whole workingFolder + * check the checksum + * Send it to out + */ + public abstract void backup(BackupIOHandler h); + public abstract void restore(BackupIOHandler h); Index: /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/BackupConfig.java =================================================================== --- /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/BackupConfig.java (revision 423545) +++ /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/BackupConfig.java (working copy) @@ -17,16 +17,14 @@ package org.apache.jackrabbit.backup; import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.net.URI; +import java.util.Collection; import java.util.Properties; -import org.apache.jackrabbit.core.RepositoryImpl; import org.apache.jackrabbit.core.config.ConfigurationException; -import org.apache.jackrabbit.core.config.ConfigurationParser; -import org.apache.jackrabbit.core.config.RepositoryConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.apache.jackrabbit.core.config.PersistenceManagerConfig; import org.xml.sax.InputSource; @@ -34,17 +32,16 @@ * Backup configuration. This configuration class is used to * create configured backup objects. *
- * The contained configuration information are: the home directory and name - * of the repository, the access manager, file system and versioning - * configuration, repository index configuration, the workspace directory, - * the default workspace name, and the workspace configuration template. In - * addition the workspace configuration object keeps track of all configured - * workspaces. + * It will send different backup object, according to the expected type + * (ManagerBackup or WorkspaceBackup for instance). + * */ public class BackupConfig { - - /** the default logger */ - private static Logger log = LoggerFactory.getLogger(BackupConfig.class); + + private PersistenceManagerConfig pmc; + private File workFolder; + private Collection allResources; + private String xml; /** * Convenience method that wraps the configuration file name into an @@ -55,12 +52,17 @@ * @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, String home) - throws ConfigurationException { + 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()), home); + return create(new InputSource(uri.toString())); } /** @@ -72,11 +74,16 @@ * @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, String home) - throws ConfigurationException { - return create(new InputSource(uri.toString()), home); + public static BackupConfig create(URI uri) + throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException, IOException { + return create(new InputSource(uri.toString())); } /** @@ -88,11 +95,16 @@ * @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 { - return create(new InputSource(input), home); + throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException, IOException { + return create(new InputSource(input)); } /** @@ -98,11 +110,11 @@ /** * 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. + * home directory workFolder 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 ConfigurationParser} class should be + * directories, etc.). The {@link RepositoryConfigurationParser} class should be * used directly to just parse the configuration. * * @param xml repository configuration document @@ -109,26 +121,51 @@ * @param home repository home directory * @return repository configuration * @throws ConfigurationException on configuration errors + * @throws IllegalAccessException + * @throws InstantiationException + * @throws ClassNotFoundException + * @throws SizeException + * @throws IOException */ - public static BackupConfig create(InputSource xml, String home) - throws ConfigurationException { - Properties variables = new Properties(); - variables.setProperty( - ConfigurationParser.REPOSITORY_HOME_VARIABLE, home); - ConfigurationParser parser = new ConfigurationParser(variables); + public static BackupConfig create(InputSource xml) + throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException, IOException { + BackupConfigurationParser parser = new BackupConfigurationParser(new Properties()); - // TODO: Fix this - // BackupConfig config = parser.parseBackupConfig(xml); - // config.init(); - // return config; - return null; + BackupConfig config = parser.parseBackupConfig(xml); + + return config; + } + + + + //TODO see if path is really useful? + public BackupConfig(PersistenceManagerConfig pmc, File path, Collection allResources) throws IOException { + + //Logic application: not in the parser: this code has to be here + if (!(path.isDirectory() && path.canWrite())) { + throw new IOException(); + } + + this.pmc = pmc; + this.workFolder = path; + this.allResources = allResources; + } + + public Collection getAllResources() { + return allResources; } + public File getWorkFolder() { + return workFolder; + } - public BackupConfig() { - // TODO Auto-generated constructor stub + public PersistenceManagerConfig getPmc() { + return pmc; } + /* + * Useful? + */ public Backup getBackup() { // TODO Auto-generated method stub return null; @@ -134,8 +171,9 @@ return null; } - public void setRepo(RepositoryImpl impl) { - // TODO Auto-generated method stub + public String getXml() { + return xml; } + } Index: /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/BackupConfigurationParser.java =================================================================== --- /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/BackupConfigurationParser.java (revision 0) +++ /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/BackupConfigurationParser.java (revision 0) @@ -0,0 +1,176 @@ +/* + * 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.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.util.Collection; +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"; + + /** + * @param variables + */ + public BackupConfigurationParser(Properties variables) { + 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: + *
+ * 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
+ * @throws IOException
+ * @see #parseBeanConfig(Element, String)
+ * @see #parseVersioningConfig(Element)
+ */
+ public BackupConfig parseBackupConfig(InputSource xml)
+ throws ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException, SizeException, IOException {
+
+ 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 BackupConfig(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 ManagerBackup
+ */
+ 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/backup2/src/main/java/org/apache/jackrabbit/backup/BackupIOHandler.java
===================================================================
--- /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/BackupIOHandler.java (revision 423545)
+++ /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/BackupIOHandler.java (working copy)
@@ -16,11 +16,17 @@
*/
package org.apache.jackrabbit.backup;
+import java.io.FileNotFoundException;
+
public interface BackupIOHandler {
-
- void setMaxFileSize(int i);
- int getMaxFileSize();
+
+ 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();
}
Index: /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/LaunchBackup.java
===================================================================
--- /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/LaunchBackup.java (revision 423545)
+++ /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/LaunchBackup.java (working copy)
@@ -16,7 +16,6 @@
*/
package org.apache.jackrabbit.backup;
-import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
@@ -41,7 +40,7 @@
RepositoryImpl repo;
BackupConfig conf;
RepositoryConfig repoConf;
- RepositoryBackup backup;
+ ManagerBackup backup;
@@ -67,9 +66,13 @@
* @throws RepositoryException
* @throws IOException
* @throws IOException
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ * @throws ClassNotFoundException
+ * @throws SizeException
*
*/
- public static void main(String[] args) throws RepositoryException, AccessDeniedException, IOException {
+ 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;
@@ -93,14 +96,8 @@
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("--size") && !(h != null)){
+ if (args[i].equals("--size") && (h != null)){
Integer max = (new Integer(args[i+ 1]));
h.setMaxFileSize(max.intValue());
@@ -107,7 +104,7 @@
}
- if (args[i].equals("--conf") && !(h != null)){
+ if (args[i].equals("--conf")){
confFile = args[i + 1];
@@ -127,7 +124,7 @@
}
}
- LaunchBackup launch = new LaunchBackup(repoConfFile, home, confFile);
+ LaunchBackup launch = null;
//We need to shutdown properly the repository whatever happens
try {
@@ -133,10 +130,12 @@
try {
//Launch backup
if (isBackup) {
- launch.backup(h);
+ launch = new LaunchBackup(repoConfFile, home, confFile);
+ launch.backup(h);
}
//Launch restore
else if (isRestore) {
+ launch = new LaunchBackup();
launch.restore(h);
}
//Launch nothing (if nothing specified
@@ -146,7 +145,8 @@
}
finally
{
- launch.shutdown();
+ if (launch !=null)
+ launch.shutdown();
}
}
@@ -166,9 +166,13 @@
*
* @param String filename: name of the configuration file
* @throws RepositoryException
- * @throws FileNotFoundException
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ * @throws ClassNotFoundException
+ * @throws SizeException
+ * @throws IOException
*/
- public LaunchBackup(String repoConfFile, String home, String backupConfFile) throws RepositoryException, FileNotFoundException {
+ 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);
@@ -174,19 +178,31 @@
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, home);
- this.backup = RepositoryBackup.create(this.conf);
+ this.conf = BackupConfig.create(xml);
+ this.backup = ManagerBackup.create(this.repo, this.conf);
+ }
+
+ /**
+ * Used for restore operations only
+ *
+ */
+
+ public LaunchBackup() {
+ // TODO Auto-generated constructor stub
}
+
+
/**
* Backup a repository
*
- * @param BackupIOHandler h a reference wher to backup
+ * @param BackupIOHandler h a reference where to backup
*/
public void backup(BackupIOHandler h) throws AccessDeniedException, RepositoryException, IOException {
- this.backup.backup(h);
+ this.backup.backup(h);
}
/**
@@ -195,7 +211,7 @@
* @param BackupIOHandler h a reference to the backup to restore
*/
public void restore(BackupIOHandler h) {
- this.backup.restore(h);
+ this.backup.restore(h);
}
private void shutdown() {
Index: /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/ManagerBackup.java
===================================================================
--- /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/ManagerBackup.java (revision 0)
+++ /home/ntoper/workspace/backup2/src/main/java/org/apache/jackrabbit/backup/ManagerBackup.java (revision 0)
@@ -0,0 +1,88 @@
+/*
+ * 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