exo-jcr SVN: r3896 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-01-27 09:24:27 -0500 (Thu, 27 Jan 2011)
New Revision: 3896
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
Log:
EXOJCR-1153: fix merger initalization
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-01-27 10:27:37 UTC (rev 3895)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-01-27 14:24:27 UTC (rev 3896)
@@ -266,8 +266,7 @@
removeDeletable();
// initialize IndexMerger
- // initialize IndexMerger
- IndexMerger merger = new IndexMerger(this);
+ merger = new IndexMerger(this);
merger.setMaxMergeDocs(handler.getMaxMergeDocs());
merger.setMergeFactor(handler.getMergeFactor());
merger.setMinMergeDocs(handler.getMinMergeDocs());
@@ -1189,7 +1188,7 @@
*/
private IndexMerger doInitIndexMerger() throws IOException
{
- IndexMerger merger = new IndexMerger(this);
+ merger = new IndexMerger(this);
merger.setMaxMergeDocs(handler.getMaxMergeDocs());
merger.setMergeFactor(handler.getMergeFactor());
merger.setMinMergeDocs(handler.getMinMergeDocs());
13 years, 3 months
exo-jcr SVN: r3895 - ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl.
by do-not-reply@jboss.org
Author: aparfonov
Date: 2011-01-27 05:27:37 -0500 (Thu, 27 Jan 2011)
New Revision: 3895
Modified:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestDispatcher.java
Log:
EXOJCR-1176
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestDispatcher.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestDispatcher.java 2011-01-26 18:20:20 UTC (rev 3894)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestDispatcher.java 2011-01-27 10:27:37 UTC (rev 3895)
@@ -68,7 +68,7 @@
/**
* Lookup resource which can serve request.
- *
+ *
* @author <a href="mailto:andrew00x@gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
@@ -455,7 +455,7 @@
/**
* Dispatch {@link ContainerRequest} to resource which can serve request.
- *
+ *
* @param request See {@link GenericContainerRequest}
* @param response See {@link GenericContainerResponse}
*/
@@ -517,9 +517,9 @@
/**
* Get last element from path parameters. This element will be used as
* request path for child resources.
- *
+ *
* @param parameterValues See
- * {@link ApplicationContextImpl#getParameterValues()}
+ * {@link ApplicationContextImpl#getParameterValues()}
* @return last element from given list or empty string if last element is
* null
*/
@@ -532,16 +532,16 @@
/**
* Process resource methods, sub-resource methods and sub-resource locators
* to find the best one for serve request.
- *
+ *
* @param request See {@link GenericContainerRequest}
* @param response See {@link GenericContainerResponse}
* @param context See {@link ApplicationContextImpl}
* @param resourceFactory the root resource factory or resource factory which
- * was created by previous sub-resource locator
+ * was created by previous sub-resource locator
* @param resource instance of resource class
* @param requestPath request path, it is relative path to the base URI or
- * other resource which was called before (one of sub-resource
- * locators)
+ * other resource which was called before (one of sub-resource
+ * locators)
*/
private void dispatch(GenericContainerRequest request, GenericContainerResponse response,
ApplicationContext context, ObjectFactory<AbstractResourceDescriptor> resourceFactory, Object resource,
@@ -612,7 +612,7 @@
/**
* Invoke resource methods.
- *
+ *
* @param rmd See {@link ResourceMethodDescriptor}
* @param resource instance of resource class
* @param context See {@link ApplicationContextImpl}
@@ -633,7 +633,7 @@
/**
* Invoke sub-resource methods.
- *
+ *
* @param requestPath request path
* @param srmd See {@link SubResourceMethodDescriptor}
* @param resource instance of resource class
@@ -660,7 +660,7 @@
/**
* Invoke sub-resource locators.
- *
+ *
* @param requestPath request path
* @param srld See {@link SubResourceLocatorDescriptor}
* @param resource instance of resource class
@@ -703,7 +703,7 @@
* SubResourceLocatorDescriptor has higher priority. And finally if zero was
* returned then UriPattern is equals, in this case
* SubResourceMethodDescriptor must be selected.
- *
+ *
* @param srmd See {@link SubResourceMethodDescriptor}
* @param srld See {@link SubResourceLocatorDescriptor}
* @return result of comparison sub-resources
@@ -722,7 +722,7 @@
/**
* Process result of invoked method, and set {@link Response} parameters
* dependent of returned object.
- *
+ *
* @param o result of invoked method
* @param returnType type of returned object
* @param request See {@link GenericContainerRequest}
@@ -764,7 +764,7 @@
/**
* Process resource methods.
- *
+ *
* @param <T> ResourceMethodDescriptor extension
* @param rmm See {@link ResourceMethodMap}
* @param request See {@link GenericContainerRequest}
@@ -775,11 +775,13 @@
private static <T extends ResourceMethodDescriptor> boolean processResourceMethod(ResourceMethodMap<T> rmm,
GenericContainerRequest request, GenericContainerResponse response, List<T> methods)
{
- List<T> rmds = rmm.getList(request.getMethod());
+ String method = request.getMethod();
+ List<T> rmds = rmm.getList(method);
if (rmds == null || rmds.size() == 0)
{
response.setResponse(Response.status(405).header("Allow", HeaderHelper.convertToString(rmm.getAllow()))
- .entity("Method not allowed.").type(MediaType.TEXT_PLAIN).build());
+ .entity(method + " method is not allowed for resource " + ApplicationContextImpl.getCurrent().getPath())
+ .type(MediaType.TEXT_PLAIN).build());
return false;
}
MediaType contentType = request.getMediaType();
@@ -800,8 +802,8 @@
if (methods.isEmpty())
{
- response.setResponse(Response.status(Response.Status.UNSUPPORTED_MEDIA_TYPE).entity(
- "Media type " + contentType + " is not supported.").type(MediaType.TEXT_PLAIN).build());
+ response.setResponse(Response.status(Response.Status.UNSUPPORTED_MEDIA_TYPE)
+ .entity("Media type " + contentType + " is not supported.").type(MediaType.TEXT_PLAIN).build());
return false;
}
@@ -842,21 +844,21 @@
return true;
}
- response.setResponse(Response.status(Response.Status.NOT_ACCEPTABLE).entity("Not Acceptable").type(
- MediaType.TEXT_PLAIN).build());
+ response.setResponse(Response.status(Response.Status.NOT_ACCEPTABLE).entity("Not Acceptable")
+ .type(MediaType.TEXT_PLAIN).build());
return false;
}
/**
* Process sub-resource methods.
- *
+ *
* @param srmm See {@link SubResourceLocatorMap}
* @param requestedPath part of requested path
* @param request See {@link GenericContainerRequest}
* @param response See {@link GenericContainerResponse}
* @param capturingValues the list for keeping template values. See
- * {@link javax.ws.rs.core.UriInfo#getPathParameters()}
+ * {@link javax.ws.rs.core.UriInfo#getPathParameters()}
* @param methods list for method resources
* @return true if at least one sub-resource method found false otherwise
*/
@@ -883,8 +885,9 @@
if (rmm == null)
{
- response.setResponse(Response.status(Status.NOT_FOUND).entity(
- "There is no any resources matched to request path " + requestedPath).type(MediaType.TEXT_PLAIN).build());
+ response.setResponse(Response.status(Status.NOT_FOUND)
+ .entity("There is no any resources matched to request path " + requestedPath).type(MediaType.TEXT_PLAIN)
+ .build());
return false;
}
@@ -906,7 +909,7 @@
/**
* Process sub-resource locators.
- *
+ *
* @param srlm See {@link SubResourceLocatorMap}
* @param requestedPath part of requested path
* @param capturingValues the list for keeping template values
@@ -929,12 +932,12 @@
/**
* Get root resource.
- *
+ *
* @param parameterValues is taken from context
* @param requestPath is taken from context
* @return root resource
* @throws WebApplicationException if there is no matched root resources.
- * Exception with prepared error response with 'Not Found' status
+ * Exception with prepared error response with 'Not Found' status
*/
protected ObjectFactory<AbstractResourceDescriptor> getRootResourse(List<String> parameterValues, String requestPath)
{
@@ -945,8 +948,9 @@
if (LOG.isDebugEnabled())
LOG.debug("Root resource not found for " + requestPath);
// Stop here, there is no matched root resource
- throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).entity(
- "There is no any resources matched to request path " + requestPath).type(MediaType.TEXT_PLAIN).build());
+ throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND)
+ .entity("There is no any resources matched to request path " + requestPath).type(MediaType.TEXT_PLAIN)
+ .build());
}
return resourceFactory;
}
13 years, 3 months
exo-jcr SVN: r3894 - jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-01-26 13:20:20 -0500 (Wed, 26 Jan 2011)
New Revision: 3894
Modified:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
Log:
EXOJCR-1100: RDBMS backup documentation
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml 2011-01-26 16:25:31 UTC (rev 3893)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml 2011-01-26 18:20:20 UTC (rev 3894)
@@ -392,7 +392,7 @@
<para>Will be configured BackupWorkspaceInitializer in all
configurations workspaces of the Repository to restore the Repository
- from backup over initializer. </para>
+ from backup over initializer.</para>
<para></para>
@@ -898,4 +898,55 @@
interactive operations via Backup API (e.g. console) and backup set files
for portability (e.g. on another server).</para>
</section>
+
+ <section>
+ <title>RDBMS backup</title>
+
+ <para>RDBMS backup It is another implementation of full backup job for
+ BackupManager service. It is useful in case when database is used to store
+ data. </para>
+
+ <para>Brings such advantages:</para>
+
+ <para><itemizedlist>
+ <listitem>
+ <para>fast: backup takes only several minutes to perform full backup
+ of repository with 1 million rows in tables;</para>
+ </listitem>
+
+ <listitem>
+ <para>atomic restore: restore process into existing
+ workspace/repository with same configuration is atomic, it means you
+ don’t loose the data when restore failed, the original data
+ remains;</para>
+ </listitem>
+
+ <listitem>
+ <para>cluster aware: it is possible to make backup/restore in
+ cluster environment into existing workspace/repository with same
+ configuration;</para>
+ </listitem>
+
+ <listitem>
+ <para>consistence backup: all threads make waiting until backup is
+ finished and then continue to work, so, there are no data
+ modification during backup process;</para>
+ </listitem>
+ </itemizedlist>Configuration:</para>
+
+ <para><programlisting><component>
+ <key>org.exoplatform.services.jcr.ext.backup.BackupManager</key>
+ <type>org.exoplatform.services.jcr.ext.backup.impl.BackupManagerImpl</type>
+ <init-params>
+ <properties-param>
+ <name>backup-properties</name>
+ <property name="default-incremental-job-period" value="3600" /> <!-- set default incremental period = 60 minutes -->
+ <property name="full-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs..rdbms.FullBackupJob" />
+ <property name="incremental-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob" />
+ <property name="backup-dir" value="target/backup" />
+ </properties-param>
+ </init-params>
+</component>
+</programlisting></para>
+ </section>
</chapter>
13 years, 3 months
exo-jcr SVN: r3893 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-01-26 11:25:31 -0500 (Wed, 26 Jan 2011)
New Revision: 3893
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/
Removed:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/
Log:
EXOJCR-1153: Support atomic restore
EXOJCR-1147: Make backup/restore to be cluster aware
Copied: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup (from rev 3892, jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b)
13 years, 3 months
exo-jcr SVN: r3892 - jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-01-26 11:20:27 -0500 (Wed, 26 Jan 2011)
New Revision: 3892
Modified:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/db-cleaner-service.xml
Log:
EXOJCR-1153: Support atomic restore
EXOJCR-1147: Make backup/restore to be cluster aware
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/db-cleaner-service.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/db-cleaner-service.xml 2011-01-26 16:19:28 UTC (rev 3891)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/db-cleaner-service.xml 2011-01-26 16:20:27 UTC (rev 3892)
@@ -4,7 +4,7 @@
<chapter id="JCR.DBCleanerService">
<?dbhtml filename="ch-db-cleaner-service.html"?>
- <title>DBCleanerService</title>
+ <title>DBCleanService</title>
<section>
<title>API</title>
@@ -12,11 +12,11 @@
<para>It is special service for removing data from database.</para>
<note>
- <para>Code that invokes methods of DBCleanerService must have
+ <para>Code that invokes methods of DBCleanService must have
JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION permission;</para>
</note>
- <para>There are two methods of DBCleanerService:</para>
+ <para>There are three methods of DBCleanerService:</para>
<table>
<title>API</title>
@@ -24,7 +24,7 @@
<tgroup cols="2">
<tbody>
<row>
- <entry>public void cleanWorkspaceData(WorkspaceEntry
+ <entry>public static void cleanWorkspaceData(WorkspaceEntry
wsEntry)</entry>
<entry>Clean workspace data from database. Tables will be removed
@@ -33,33 +33,22 @@
</row>
<row>
- <entry>public void cleanRepositoryData(RepositoryEntry
+ <entry>public static void cleanRepositoryData(RepositoryEntry
repoEntry)</entry>
<entry>Cleanup repository data from database.</entry>
</row>
+
+ <row>
+ <entry>public static getDBCleaner(Connection jdbcConn,
+ WorkspaceEntry wsEntry)</entry>
+
+ <entry>Returns DBClean object with defined connection that allow
+ to manual invoke clean method on it. Note: DBClean doesn't perform
+ commit or close connection. It should be done manually.</entry>
+ </row>
</tbody>
</tgroup>
</table>
</section>
-
- <section>
- <title>How it works</title>
-
- <para>cleanRepositoryData takes workspaces configs from RepositoryEntry
- and clean each workspace using cleanWorkspaceData method.</para>
-
- <para>Lets see cleanWorkspaceData in detail:<itemizedlist>
- <listitem>
- <para>at first, it resolves container name (workspace name),
- database dialect, data source and isMultiDB parameter;</para>
- </listitem>
-
- <listitem>
- <para>then based on database dialect creates instanse of database
- cleaner (implements DBCleaner interface) and invokes clean()
- method;</para>
- </listitem>
- </itemizedlist></para>
- </section>
</chapter>
13 years, 3 months
exo-jcr SVN: r3891 - in jcr/trunk/exo.jcr.component.ext: src/main/java/org/exoplatform/services/jcr/ext/backup/impl and 6 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-01-26 11:19:28 -0500 (Wed, 26 Jan 2011)
New Revision: 3891
Added:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestoreSameConfig.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestoreSameConfig.java
Modified:
jcr/trunk/exo.jcr.component.ext/pom.xml
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestore.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestore.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobWorkspaceRestore.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/fs/IncrementalBackupJob.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/FullBackupJob.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupTestCase.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsWorkspaceInitializer.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/load/TestLoadBackup.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgentTest.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/TesterRdbmsWorkspaceInitializer.java
Log:
EXOJCR-1153: Support atomic restore
EXOJCR-1147: Make backup/restore to be cluster aware
Modified: jcr/trunk/exo.jcr.component.ext/pom.xml
===================================================================
--- jcr/trunk/exo.jcr.component.ext/pom.xml 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/pom.xml 2011-01-26 16:19:28 UTC (rev 3891)
@@ -1,192 +1,192 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright (C) 2009 eXo Platform SAS.
-
- This is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of
- the License, or (at your option) any later version.
-
- This software is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this software; if not, write to the Free
- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.exoplatform.jcr</groupId>
- <artifactId>jcr-parent</artifactId>
- <version>1.14.0-CR1-SNAPSHOT</version>
- </parent>
- <artifactId>exo.jcr.component.ext</artifactId>
- <name>eXo JCR :: Component :: Extension Service</name>
- <description>eXo JCR Services extension</description>
- <dependencies>
- <dependency>
- <groupId>org.exoplatform.kernel</groupId>
- <artifactId>exo.kernel.commons</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.kernel</groupId>
- <artifactId>exo.kernel.container</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.kernel</groupId>
- <artifactId>exo.kernel.component.command</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.kernel</groupId>
- <artifactId>exo.kernel.commons.test</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.core</groupId>
- <artifactId>exo.core.component.database</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.core</groupId>
- <artifactId>exo.core.component.document</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.core</groupId>
- <artifactId>exo.core.component.organization.api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.core</groupId>
- <artifactId>exo.core.component.security.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.jcr</groupId>
- <artifactId>exo.jcr.component.core</artifactId>
- <exclusions>
- <exclusion>
- <groupId>xerces</groupId>
- <artifactId>xerces</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.core</groupId>
- <artifactId>exo.core.component.script.groovy</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.ws</groupId>
- <artifactId>exo.ws.rest.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.ws</groupId>
- <artifactId>exo.ws.rest.ext</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.ws</groupId>
- <artifactId>exo.ws.commons</artifactId>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.ws</groupId>
- <artifactId>exo.ws.frameworks.json</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.jcr</groupId>
- <artifactId>jcr</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.annotation</groupId>
- <artifactId>jsr250-api</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-chain</groupId>
- <artifactId>commons-chain</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jgroups</groupId>
- <artifactId>jgroups</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.ws.rs</groupId>
- <artifactId>jsr311-api</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-fileupload</groupId>
- <artifactId>commons-fileupload</artifactId>
- </dependency>
- <dependency>
- <groupId>picocontainer</groupId>
- <artifactId>picocontainer</artifactId>
- </dependency>
- <dependency>
- <groupId>xml-apis</groupId>
- <artifactId>xml-apis</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.xml.stream</groupId>
- <artifactId>stax-api</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- </dependency>
-
- <dependency>
- <groupId>hsqldb</groupId>
- <artifactId>hsqldb</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <testResources>
- <testResource>
- <directory>src/test/resources</directory>
- <includes>
- <include>**/*.pdf</include>
- <include>**/*.xml</include>
- <include>**/*.xls</include>
- <include>**/*.groovy</include>
- <include>**/login.conf</include>
- </includes>
- </testResource>
- </testResources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <addClasspath>true</addClasspath>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <argLine>${env.MAVEN_OPTS} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
- <includes>
- <include>**/actions/*Test.java</include>
- <include>**/metadata/*Test.java</include>
- <include>**/owner/*Test.java</include>
- <include>**/registry/*Test.java</include>
- <include>**/app/*Test.java</include>
- <include>**/resource/*Test.java</include>
- <include>**/groovy/*Test.java</include>
- <include>**/replication/*.java</include>
- <include>**/replication/external/*.java</include>
- <include>**/replication/async/**/*.java</include>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.exoplatform.jcr</groupId>
+ <artifactId>jcr-parent</artifactId>
+ <version>1.14.0-CR1-SNAPSHOT</version>
+ </parent>
+ <artifactId>exo.jcr.component.ext</artifactId>
+ <name>eXo JCR :: Component :: Extension Service</name>
+ <description>eXo JCR Services extension</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.exoplatform.kernel</groupId>
+ <artifactId>exo.kernel.commons</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.kernel</groupId>
+ <artifactId>exo.kernel.container</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.kernel</groupId>
+ <artifactId>exo.kernel.component.command</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.kernel</groupId>
+ <artifactId>exo.kernel.commons.test</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.core</groupId>
+ <artifactId>exo.core.component.database</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.core</groupId>
+ <artifactId>exo.core.component.document</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.core</groupId>
+ <artifactId>exo.core.component.organization.api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.core</groupId>
+ <artifactId>exo.core.component.security.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.jcr</groupId>
+ <artifactId>exo.jcr.component.core</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>xerces</groupId>
+ <artifactId>xerces</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.core</groupId>
+ <artifactId>exo.core.component.script.groovy</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.ws</groupId>
+ <artifactId>exo.ws.rest.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.ws</groupId>
+ <artifactId>exo.ws.rest.ext</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.ws</groupId>
+ <artifactId>exo.ws.commons</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.ws</groupId>
+ <artifactId>exo.ws.frameworks.json</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.jcr</groupId>
+ <artifactId>jcr</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId>jsr250-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-chain</groupId>
+ <artifactId>commons-chain</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jgroups</groupId>
+ <artifactId>jgroups</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-fileupload</groupId>
+ <artifactId>commons-fileupload</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>picocontainer</groupId>
+ <artifactId>picocontainer</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.xml.stream</groupId>
+ <artifactId>stax-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <testResources>
+ <testResource>
+ <directory>src/test/resources</directory>
+ <includes>
+ <include>**/*.pdf</include>
+ <include>**/*.xml</include>
+ <include>**/*.xls</include>
+ <include>**/*.groovy</include>
+ <include>**/login.conf</include>
+ </includes>
+ </testResource>
+ </testResources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <addClasspath>true</addClasspath>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>${env.MAVEN_OPTS} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
+ <includes>
+ <include>**/actions/*Test.java</include>
+ <include>**/metadata/*Test.java</include>
+ <include>**/owner/*Test.java</include>
+ <include>**/registry/*Test.java</include>
+ <include>**/app/*Test.java</include>
+ <include>**/resource/*Test.java</include>
+ <include>**/groovy/*Test.java</include>
+ <include>**/replication/*.java</include>
+ <include>**/replication/external/*.java</include>
+ <include>**/replication/async/**/*.java</include>
+ <include>**/backup/load/TestLoadBackup.java</include>
<include>**/backup/*.java</include>
- <include>**/backup/server/*.java</include>
+ <include>**/backup/server/*.java</include>
</includes>
<excludes>
<exclude>**/BaseStandaloneTest.java</exclude>
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -31,12 +31,6 @@
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.config.WorkspaceInitializerEntry;
import org.exoplatform.services.jcr.core.WorkspaceContainerFacade;
-import org.exoplatform.services.jcr.dataflow.ChangesLogIterator;
-import org.exoplatform.services.jcr.dataflow.ItemState;
-import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
-import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
-import org.exoplatform.services.jcr.dataflow.TransactionChangesLog;
-import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.ext.backup.BackupChain;
import org.exoplatform.services.jcr.ext.backup.BackupChainLog;
import org.exoplatform.services.jcr.ext.backup.BackupConfig;
@@ -57,32 +51,26 @@
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.jcr.ext.registry.RegistryEntry;
import org.exoplatform.services.jcr.ext.registry.RegistryService;
-import org.exoplatform.services.jcr.ext.replication.FixupStream;
+import org.exoplatform.services.jcr.impl.backup.JCRRestor;
import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
-import org.exoplatform.services.jcr.impl.core.SessionImpl;
import org.exoplatform.services.jcr.impl.core.SysViewWorkspaceInitializer;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
-import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
-import org.exoplatform.services.jcr.impl.storage.JCRItemExistsException;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
-import org.exoplatform.services.jcr.impl.util.io.SpoolFile;
-import org.exoplatform.services.jcr.observation.ExtendedEvent;
import org.exoplatform.services.jcr.util.IdGenerator;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import org.exoplatform.ws.frameworks.json.impl.JsonException;
+import org.exoplatform.ws.frameworks.json.impl.JsonGeneratorImpl;
import org.picocontainer.Startable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
@@ -949,211 +937,14 @@
throws RepositoryException, RepositoryConfigurationException, BackupOperationException, FileNotFoundException,
IOException, ClassNotFoundException
{
- SessionImpl sesion = (SessionImpl)repoService.getRepository(repositoryName).getSystemSession(workspaceName);
WorkspacePersistentDataManager dataManager =
- (WorkspacePersistentDataManager)sesion.getContainer().getComponentInstanceOfType(
- WorkspacePersistentDataManager.class);
+ (WorkspacePersistentDataManager)repoService.getRepository(repositoryName).getWorkspaceContainer(workspaceName)
+ .getComponent(WorkspacePersistentDataManager.class);
- ObjectInputStream ois = null;
- File backupFile = null;
- try
- {
- backupFile = new File(pathBackupFile);
- ois = new ObjectInputStream(PrivilegedFileHelper.fileInputStream(backupFile));
-
- while (true)
- {
- TransactionChangesLog changesLog = readExternal(ois);
-
- ChangesLogIterator cli = changesLog.getLogIterator();
- while (cli.hasNextLog())
- {
- if (cli.nextLog().getEventType() == ExtendedEvent.LOCK)
- cli.removeLog();
- }
-
- saveChangesLog(dataManager, changesLog);
- }
- }
- catch (EOFException ioe)
- {
- // ok - reading all data from backup file;
- }
- finally
- {
- if (sesion != null)
- sesion.logout();
- }
+ JCRRestor restorer = new JCRRestor(dataManager, fileCleaner);
+ restorer.incrementalRestore(new File(pathBackupFile));
}
- private void saveChangesLog(WorkspacePersistentDataManager dataManager, TransactionChangesLog changesLog)
- throws RepositoryException, BackupOperationException
- {
- try
- {
- dataManager.save(changesLog);
- }
- catch (JCRInvalidItemStateException e)
- {
- TransactionChangesLog normalizeChangesLog =
- getNormalizedChangesLog(e.getIdentifier(), e.getState(), changesLog);
- if (normalizeChangesLog != null)
- saveChangesLog(dataManager, normalizeChangesLog);
- else
- throw new BackupOperationException(
- "Collisions found during save of restore changes log, but caused item is not found by ID "
- + e.getIdentifier() + ". " + e, e);
- }
- catch (JCRItemExistsException e)
- {
- TransactionChangesLog normalizeChangesLog =
- getNormalizedChangesLog(e.getIdentifier(), e.getState(), changesLog);
- if (normalizeChangesLog != null)
- saveChangesLog(dataManager, normalizeChangesLog);
- else
- throw new RepositoryException(
- "Collisions found during save of restore changes log, but caused item is not found by ID "
- + e.getIdentifier() + ". " + e, e);
- }
-
- }
-
- private TransactionChangesLog getNormalizedChangesLog(String collisionID, int state, TransactionChangesLog changesLog)
- {
- ItemState citem = changesLog.getItemState(collisionID);
-
- if (citem != null)
- {
-
- TransactionChangesLog result = new TransactionChangesLog();
- result.setSystemId(changesLog.getSystemId());
-
- ChangesLogIterator cli = changesLog.getLogIterator();
- while (cli.hasNextLog())
- {
- ArrayList<ItemState> normalized = new ArrayList<ItemState>();
- PlainChangesLog next = cli.nextLog();
- for (ItemState change : next.getAllStates())
- {
- if (state == change.getState())
- {
- ItemData item = change.getData();
- // targeted state
- if (citem.isNode())
- {
- // Node... by ID and desc path
- if (!item.getIdentifier().equals(collisionID)
- && !item.getQPath().isDescendantOf(citem.getData().getQPath()))
- normalized.add(change);
- }
- else if (!item.getIdentifier().equals(collisionID))
- {
- // Property... by ID
- normalized.add(change);
- }
- }
- else
- // another state
- normalized.add(change);
- }
-
- PlainChangesLog plog = new PlainChangesLogImpl(normalized, next.getSessionId(), next.getEventType());
- result.addLog(plog);
- }
-
- return result;
- }
-
- return null;
- }
-
- private TransactionChangesLog readExternal(ObjectInputStream in) throws IOException, ClassNotFoundException
- {
- int changesLogType = in.readInt();
-
- TransactionChangesLog transactionChangesLog = null;
-
- if (changesLogType == PendingChangesLog.Type.CHANGESLOG_WITH_STREAM)
- {
-
- // read ChangesLog
- transactionChangesLog = (TransactionChangesLog)in.readObject();
-
- // read FixupStream count
- int iFixupStream = in.readInt();
-
- ArrayList<FixupStream> listFixupStreams = new ArrayList<FixupStream>();
-
- for (int i = 0; i < iFixupStream; i++)
- {
- FixupStream fs = new FixupStream();
- fs.readExternal(in);
- listFixupStreams.add(fs);
- }
- // listFixupStreams.add((FixupStream) in.readObject());
-
- // read stream data
- int iStreamCount = in.readInt();
- ArrayList<File> listFiles = new ArrayList<File>();
-
- for (int i = 0; i < iStreamCount; i++)
- {
-
- // read file size
- long fileSize = in.readLong();
-
- // read content file
- File contentFile = getAsFile(in, fileSize);
- listFiles.add(contentFile);
- }
-
- PendingChangesLog pendingChangesLog =
- new PendingChangesLog(transactionChangesLog, listFixupStreams, listFiles, fileCleaner);
-
- pendingChangesLog.restore();
-
- TransactionChangesLog log = pendingChangesLog.getItemDataChangesLog();
-
- }
- else if (changesLogType == PendingChangesLog.Type.CHANGESLOG_WITHOUT_STREAM)
- {
- transactionChangesLog = (TransactionChangesLog)in.readObject();
- }
-
- return transactionChangesLog;
- }
-
- private File getAsFile(ObjectInputStream ois, long fileSize) throws IOException
- {
- int bufferSize = /* 8191 */1024 * 8;
- byte[] buf = new byte[bufferSize];
-
- File tempFile = SpoolFile.createTempFile("" + System.currentTimeMillis(), ".stmp", tempDir);
- FileOutputStream fos = PrivilegedFileHelper.fileOutputStream(tempFile);
- long readBytes = fileSize;
-
- while (readBytes > 0)
- {
- // long longTemp = readByte - bufferSize;
- if (readBytes >= bufferSize)
- {
- ois.readFully(buf);
- fos.write(buf);
- }
- else if (readBytes < bufferSize)
- {
- ois.readFully(buf, 0, (int)readBytes);
- fos.write(buf, 0, (int)readBytes);
- }
- readBytes -= bufferSize;
- }
-
- fos.flush();
- fos.close();
-
- return tempFile;
- }
-
/**
* Write parameters to RegistryService.
*
@@ -1695,7 +1486,7 @@
* {@inheritDoc}
*/
public void restoreExistingRepository(RepositoryBackupChainLog rblog, RepositoryEntry repositoryEntry,
- boolean asynchronous) throws BackupOperationException, BackupConfigurationException
+ boolean asynchronous) throws BackupOperationException, BackupConfigurationException
{
try
{
@@ -1748,9 +1539,48 @@
}
}
- JobExistedRepositoryRestore jobExistedRepositoryRestore =
- new JobExistedRepositoryRestore(repoService, this, repositoryEntry, workspacesMapping, rblog);
+ // check if need to restore with same configuration or not
+ boolean isSameConfig = false;
+ try
+ {
+ String newConf = new JsonGeneratorImpl().createJsonObject(repositoryEntry).toString();
+ String currnetConf =
+ new JsonGeneratorImpl().createJsonObject(
+ repoService.getRepository(repositoryEntry.getName()).getConfiguration()).toString();
+ isSameConfig = newConf.equals(currnetConf);
+ }
+ catch (JsonException e)
+ {
+ this.log.error("Can't get JSON object from wokrspace configuration", e);
+ }
+ catch (RepositoryException e)
+ {
+ this.log.error(e);
+ }
+ catch (RepositoryConfigurationException e)
+ {
+ this.log.error(e);
+ }
+
+ // check if we have deal with RDBMS backup
+ boolean isRDBMSBackup = false;
+ try
+ {
+ isRDBMSBackup =
+ (Class.forName(workspacesMapping.get(repositoryEntry.getWorkspaceEntries().get(0).getName())
+ .getFullBackupType()).equals(org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob.class));
+ }
+ catch (ClassNotFoundException e)
+ {
+ this.log.error(e);
+ }
+
+ JobRepositoryRestore jobExistedRepositoryRestore =
+ isSameConfig && isRDBMSBackup ? new JobExistedRepositoryRestoreSameConfig(repoService, this, repositoryEntry,
+ workspacesMapping, rblog) : new JobExistedRepositoryRestore(repoService, this, repositoryEntry,
+ workspacesMapping, rblog);
+
restoreRepositoryJobs.add(jobExistedRepositoryRestore);
if (asynchronous)
{
@@ -1760,7 +1590,6 @@
{
jobExistedRepositoryRestore.restore();
}
-
}
/**
@@ -1793,7 +1622,7 @@
* {@inheritDoc}
*/
public void restoreExistingWorkspace(BackupChainLog log, String repositoryName, WorkspaceEntry workspaceEntry,
- boolean asynchronous) throws BackupOperationException, BackupConfigurationException
+ boolean asynchronous) throws BackupOperationException, BackupConfigurationException
{
try
{
@@ -1814,20 +1643,73 @@
{
throw new WorkspaceRestoreException("Repository \"" + repositoryName + "\" should be existed", e);
}
-
- JobExistedWorkspaceRestore jobRestore =
- new JobExistedWorkspaceRestore(repoService, this, repositoryName, log, workspaceEntry);
+
+ // check if need to restore with same configuration or not
+ boolean isSameConfig = false;
+ try
+ {
+ WorkspaceEntry currentWsEntry = null;
+ for (WorkspaceEntry wsEntry : repoService.getRepository(repositoryName).getConfiguration().getWorkspaceEntries())
+ {
+ if (wsEntry.getName().equals(workspaceEntry.getName()))
+ {
+ currentWsEntry = wsEntry;
+ break;
+ }
+ }
+
+ String newConf = new JsonGeneratorImpl().createJsonObject(workspaceEntry).toString();
+ String currnetConf = new JsonGeneratorImpl().createJsonObject(currentWsEntry).toString();
+
+ isSameConfig = newConf.equals(currnetConf);
+ }
+ catch (JsonException e)
+ {
+ this.log.error("Can't get JSON object from wokrspace configuration", e);
+ }
+ catch (RepositoryException e)
+ {
+ this.log.error(e);
+ }
+ catch (RepositoryConfigurationException e)
+ {
+ this.log.error(e);
+ }
+
+ // check if we have deal with RDBMS backup
+ boolean isRDBMSBackup = false;
+ try
+ {
+ isRDBMSBackup =
+ (Class.forName(log.getFullBackupType())
+ .equals(org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob.class));
+ }
+ catch (ClassNotFoundException e)
+ {
+ this.log.error(e);
+ }
+
+ JobWorkspaceRestore jobRestore =
+ isSameConfig && isRDBMSBackup ? new JobExistedWorkspaceRestoreSameConfig(repoService, this, repositoryName,
+ log, workspaceEntry) : new JobExistedWorkspaceRestore(repoService, this, repositoryName, log,
+ workspaceEntry);
restoreJobs.add(jobRestore);
-
+
if (asynchronous)
{
jobRestore.start();
}
else
{
- jobRestore.restore();
+ try
+ {
+ jobRestore.restore();
+ }
+ catch (Throwable e)
+ {
+ throw new BackupOperationException(e);
+ }
}
-
}
/**
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestore.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestore.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -26,9 +26,8 @@
import org.exoplatform.services.jcr.ext.backup.RepositoryBackupChainLog;
import org.exoplatform.services.jcr.ext.backup.RepositoryRestoreExeption;
import org.exoplatform.services.jcr.impl.RepositoryServiceImpl;
+import org.exoplatform.services.jcr.impl.backup.Backupable;
import org.exoplatform.services.jcr.impl.core.SessionRegistry;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.DataCleaner;
import java.util.ArrayList;
import java.util.List;
@@ -48,16 +47,6 @@
{
/**
- * Value storage cleaner.
- */
- private final ValueStorageCleanHelper valueStorageCleanHelper;
-
- /**
- * Index storage cleaner.
- */
- private final IndexCleanHelper indexCleanHelper;
-
- /**
* JobExistedRepositoryRestore constructor.
*/
public JobExistedRepositoryRestore(RepositoryService repoService, BackupManagerImpl backupManagerImpl,
@@ -65,9 +54,6 @@
RepositoryBackupChainLog backupChainLog)
{
super(repoService, backupManagerImpl, repositoryEntry, workspacesMapping, backupChainLog);
-
- this.valueStorageCleanHelper = new ValueStorageCleanHelper();
- this.indexCleanHelper = new IndexCleanHelper();
}
@Override
@@ -76,6 +62,9 @@
*/
protected void restoreRepository() throws RepositoryRestoreExeption
{
+ // list of components to clean
+ List<Backupable> backupable = new ArrayList<Backupable>();
+
try
{
// get current repository configuration
@@ -91,32 +80,24 @@
boolean isDefault =
repositoryService.getDefaultRepository().getConfiguration().getName().equals(repositoryEntry.getName());
+ String systemWsName =
+ repositoryService.getRepository(this.repositoryEntry.getName()).getConfiguration().getSystemWorkspaceName();
+
//Create local copy of WorkspaceEntry for all workspaces
ArrayList<WorkspaceEntry> workspaceList = new ArrayList<WorkspaceEntry>();
workspaceList.addAll(repositoryEntry.getWorkspaceEntries());
- //close all session
+ // get all backupable components
for (WorkspaceEntry wEntry : workspaceList)
{
- forceCloseSession(repositoryEntry.getName(), wEntry.getName());
+ backupable.addAll(repositoryService.getRepository(this.repositoryEntry.getName())
+ .getWorkspaceContainer(wEntry.getName()).getComponentInstancesOfType(Backupable.class));
}
- List<DataCleaner> dataCleaners = new ArrayList<DataCleaner>();
-
- // collect all DataCleaners
+ //close all session
for (WorkspaceEntry wEntry : workspaceList)
{
forceCloseSession(repositoryEntry.getName(), wEntry.getName());
-
- List<Backupable> backupable =
- repositoryService.getRepository(this.repositoryEntry.getName()).getWorkspaceContainer(wEntry.getName())
- .getComponentInstancesOfType(Backupable.class);
-
-
- for (Backupable component : backupable)
- {
- dataCleaners.add(component.getDataCleaner());
- }
}
//remove repository
@@ -129,25 +110,12 @@
repositoryService.removeRepository(repositoryEntry.getName());
}
- //clean database
- for (DataCleaner cleaner : dataCleaners)
+ // clean
+ for (Backupable component : backupable)
{
- cleaner.clean();
+ component.clean();
}
- //clean index
- for (WorkspaceEntry wEntry : workspaceList)
- {
- indexCleanHelper.removeWorkspaceIndex(wEntry,
- repositoryEntry.getSystemWorkspaceName().equals(wEntry.getName()));
- }
-
- //clean value storage
- for (WorkspaceEntry wEntry : workspaceList)
- {
- valueStorageCleanHelper.removeWorkspaceValueStorage(wEntry);
- }
-
super.restoreRepository();
}
catch (Throwable t)
@@ -157,7 +125,16 @@
}
/**
- * forceCloseSession. Close sessions on specific workspace.
+ * {@inheritDoc}
+ */
+ @Override
+ protected void removeRepository(RepositoryService repositoryService, String repositoryName)
+ throws RepositoryException, RepositoryConfigurationException
+ {
+ }
+
+ /**
+ * Close sessions on specific workspace.
*
* @param repositoryName
* repository name
@@ -179,5 +156,4 @@
return sessionRegistry.closeSessions(workspaceName);
}
-
}
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestoreSameConfig.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestoreSameConfig.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestoreSameConfig.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.ext.backup.impl;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.RepositoryService;
+import org.exoplatform.services.jcr.config.RepositoryEntry;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.dataflow.DataManager;
+import org.exoplatform.services.jcr.ext.backup.BackupChainLog;
+import org.exoplatform.services.jcr.ext.backup.RepositoryBackupChainLog;
+import org.exoplatform.services.jcr.ext.backup.RepositoryRestoreExeption;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.backup.Backupable;
+import org.exoplatform.services.jcr.impl.backup.DataRestor;
+import org.exoplatform.services.jcr.impl.backup.JCRRestor;
+import org.exoplatform.services.jcr.impl.backup.ResumeException;
+import org.exoplatform.services.jcr.impl.backup.Suspendable;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
+import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
+
+import java.io.File;
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.sql.DataSource;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 24 01 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: JobExistedRepositoryRestoreSameConfig.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class JobExistedRepositoryRestoreSameConfig extends JobRepositoryRestore
+{
+
+ /**
+ * JobExistedRepositoryRestoreSameConfig constructor.
+ */
+ public JobExistedRepositoryRestoreSameConfig(RepositoryService repoService, BackupManagerImpl backupManagerImpl,
+ RepositoryEntry repositoryEntry, Map<String, BackupChainLog> workspacesMapping,
+ RepositoryBackupChainLog backupChainLog)
+ {
+ super(repoService, backupManagerImpl, repositoryEntry, workspacesMapping, backupChainLog);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void restoreRepository() throws RepositoryRestoreExeption
+ {
+ // list of data restorers
+ List<DataRestor> dataRestorer = new ArrayList<DataRestor>();
+
+ // the list of components to resume
+ List<Suspendable> resumeComponents = new ArrayList<Suspendable>();
+
+ try
+ {
+ WorkspaceEntry wsEntry = repositoryEntry.getWorkspaceEntries().get(0);
+
+ // define one common connection for all restores and cleaners for single db case
+ Connection jdbcConn = null;
+ if (!Boolean.parseBoolean(wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.MULTIDB)))
+ {
+ String dsName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+ final DataSource ds = (DataSource)new InitialContext().lookup(dsName);
+ if (ds == null)
+ {
+ throw new NameNotFoundException("Data source " + dsName + " not found");
+ }
+
+ jdbcConn = SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+ {
+ public Connection run() throws Exception
+ {
+ return ds.getConnection();
+
+ }
+ });
+ jdbcConn.setAutoCommit(false);
+ }
+
+ // suspend all components
+ for (WorkspaceEntry wEntry : repositoryEntry.getWorkspaceEntries())
+ {
+ List<Suspendable> suspendableComponents =
+ repositoryService.getRepository(this.repositoryEntry.getName()).getWorkspaceContainer(wEntry.getName())
+ .getComponentInstancesOfType(Suspendable.class);
+
+ for (Suspendable component : suspendableComponents)
+ {
+ component.suspend();
+ resumeComponents.add(component);
+ }
+ }
+
+ // collect all restorers
+ for (WorkspaceEntry wEntry : repositoryEntry.getWorkspaceEntries())
+ {
+ // get all backupable components
+ List<Backupable> backupable =
+ repositoryService.getRepository(this.repositoryEntry.getName()).getWorkspaceContainer(wEntry.getName())
+ .getComponentInstancesOfType(Backupable.class);
+
+ File fullBackupDir =
+ JCRRestor.getFullBackupFile(workspacesMapping.get(wEntry.getName()).getBackupConfig().getBackupDir());
+
+ for (Backupable component : backupable)
+ {
+ dataRestorer.add(component.getDataRestorer(fullBackupDir, jdbcConn));
+ }
+ }
+
+ for (DataRestor restorer : dataRestorer)
+ {
+ restorer.clean();
+ }
+
+ for (DataRestor restorer : dataRestorer)
+ {
+ restorer.restore();
+ }
+
+ for (DataRestor restorer : dataRestorer)
+ {
+ restorer.commit();
+ }
+
+ // resume components
+ for (int i = 0; i < resumeComponents.size() - 1; i++)
+ {
+ try
+ {
+ resumeComponents.remove(i).resume();
+ }
+ catch (ResumeException e)
+ {
+ log.error("Can't resume component", e);
+ }
+ }
+
+ // incremental restore
+ for (WorkspaceEntry wEntry : repositoryEntry.getWorkspaceEntries())
+ {
+ repositoryService.getRepository(this.repositoryEntry.getName()).getWorkspaceContainer(wEntry.getName())
+ .getComponentInstancesOfType(Backupable.class);
+
+ DataManager dataManager =
+ (WorkspacePersistentDataManager)repositoryService.getRepository(this.repositoryEntry.getName())
+ .getWorkspaceContainer(wEntry.getName()).getComponent(WorkspacePersistentDataManager.class);
+
+ FileCleanerHolder fileCleanHolder =
+ (FileCleanerHolder)repositoryService.getRepository(this.repositoryEntry.getName())
+ .getWorkspaceContainer(wEntry.getName()).getComponent(FileCleanerHolder.class);
+
+ File storageDir =
+ JCRRestor.getFullBackupFile(workspacesMapping.get(wEntry.getName()).getBackupConfig().getBackupDir());
+
+ JCRRestor restorer = new JCRRestor(dataManager, fileCleanHolder.getFileCleaner());
+ for (File incrBackupFile : JCRRestor.getIncrementalFiles(storageDir))
+ {
+ restorer.incrementalRestore(incrBackupFile);
+ }
+ }
+ }
+ catch (Throwable t)
+ {
+ // rollback
+ for (DataRestor restorer : dataRestorer)
+ {
+ try
+ {
+ restorer.rollback();
+ }
+ catch (BackupException e)
+ {
+ log.error("Can't rollback changes", e);
+ }
+ }
+
+ throw new RepositoryRestoreExeption("Repository " + repositoryEntry.getName() + " was not restored", t);
+ }
+ finally
+ {
+ // close
+ for (DataRestor restorer : dataRestorer)
+ {
+ try
+ {
+ restorer.close();
+ }
+ catch (BackupException e)
+ {
+ log.error("Can't close restorer", e);
+ }
+ }
+
+ for (Suspendable component : resumeComponents)
+ {
+ try
+ {
+ component.resume();
+ }
+ catch (ResumeException e)
+ {
+ log.error("Can't resume component " + component.getClass(), e);
+ }
+ }
+ }
+ }
+}
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestore.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestore.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -24,13 +24,11 @@
import org.exoplatform.services.jcr.ext.backup.BackupChainLog;
import org.exoplatform.services.jcr.ext.backup.BackupManager;
import org.exoplatform.services.jcr.ext.backup.WorkspaceRestoreException;
+import org.exoplatform.services.jcr.impl.backup.Backupable;
import org.exoplatform.services.jcr.impl.core.SessionRegistry;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.DataCleaner;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import java.util.ArrayList;
import java.util.List;
import javax.jcr.RepositoryException;
@@ -51,25 +49,12 @@
private static Log log = ExoLogger.getLogger("exo.jcr.component.ext.JobExistedWorkspaceRestore");
/**
- * Value storage cleaner.
- */
- private final ValueStorageCleanHelper valueStorageCleaner;
-
- /**
- * Index cleaner.
- */
- private final IndexCleanHelper indexCleanHelper;
-
- /**
* JobExistedWorkspaceRestore constructor.
*/
public JobExistedWorkspaceRestore(RepositoryService repositoryService, BackupManager backupManager,
String repositoryName, BackupChainLog log, WorkspaceEntry wEntry)
{
super(repositoryService, backupManager, repositoryName, log, wEntry);
-
- this.valueStorageCleaner = new ValueStorageCleanHelper();
- this.indexCleanHelper = new IndexCleanHelper();
}
/**
@@ -98,38 +83,22 @@
+ " did not found in current repository " + repositoryName + " configuration");
}
- boolean isSystem =
- repositoryService.getRepository(repositoryName).getConfiguration().getSystemWorkspaceName()
- .equals(wEntry.getName());
-
- List<DataCleaner> dataCleaners = new ArrayList<DataCleaner>();
-
+ // get all backupable components
List<Backupable> backupable =
repositoryService.getRepository(repositoryName).getWorkspaceContainer(wEntry.getName())
.getComponentInstancesOfType(Backupable.class);
- for (Backupable component : backupable)
- {
- dataCleaners.add(component.getDataCleaner());
- }
-
- //close all session
+ // close all session
forceCloseSession(repositoryName, wEntry.getName());
repositoryService.getRepository(repositoryName).removeWorkspace(wEntry.getName());
- //clean database
- for (DataCleaner cleaner : dataCleaners)
+ // clean
+ for (Backupable component : backupable)
{
- cleaner.clean();
+ component.clean();
}
- //clean index
- indexCleanHelper.removeWorkspaceIndex(wEntry, isSystem);
-
- //clean value storage
- valueStorageCleaner.removeWorkspaceValueStorage(wEntry);
-
super.restore();
}
catch (Throwable t)
@@ -139,7 +108,15 @@
}
/**
- * forceCloseSession. Close sessions on specific workspace.
+ * {@inheritDoc}
+ */
+ @Override
+ protected void removeWorkspace(ManageableRepository mr, String workspaceName) throws RepositoryException
+ {
+ }
+
+ /**
+ * Close sessions on specific workspace.
*
* @param repositoryName
* repository name
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestoreSameConfig.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestoreSameConfig.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestoreSameConfig.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.ext.backup.impl;
+
+import org.exoplatform.services.jcr.RepositoryService;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.dataflow.DataManager;
+import org.exoplatform.services.jcr.ext.backup.BackupChainLog;
+import org.exoplatform.services.jcr.ext.backup.BackupManager;
+import org.exoplatform.services.jcr.ext.backup.WorkspaceRestoreException;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.backup.Backupable;
+import org.exoplatform.services.jcr.impl.backup.DataRestor;
+import org.exoplatform.services.jcr.impl.backup.JCRRestor;
+import org.exoplatform.services.jcr.impl.backup.ResumeException;
+import org.exoplatform.services.jcr.impl.backup.Suspendable;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
+import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 24 01 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: JobExistedWorkspaceRestoreSameConfig.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class JobExistedWorkspaceRestoreSameConfig extends JobWorkspaceRestore
+{
+ /**
+ * The logger.
+ */
+ private static Log log = ExoLogger.getLogger("exo.jcr.component.ext.JobExistedWorkspaceRestoreSameConfig");
+
+ /**
+ * JobExistedWorkspaceRestore constructor.
+ */
+ public JobExistedWorkspaceRestoreSameConfig(RepositoryService repositoryService, BackupManager backupManager,
+ String repositoryName, BackupChainLog log, WorkspaceEntry wEntry)
+ {
+ super(repositoryService, backupManager, repositoryName, log, wEntry);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void restore() throws WorkspaceRestoreException
+ {
+ // list of data restorers
+ List<DataRestor> dataRestorer = new ArrayList<DataRestor>();
+
+ // the list of components to resume
+ List<Suspendable> resumeComponents = new ArrayList<Suspendable>();
+
+ try
+ {
+ // suspend all components
+ List<Suspendable> suspendableComponents =
+ repositoryService.getRepository(repositoryName).getWorkspaceContainer(wEntry.getName())
+ .getComponentInstancesOfType(Suspendable.class);
+
+ for (Suspendable component : suspendableComponents)
+ {
+ component.suspend();
+ resumeComponents.add(component);
+ }
+
+ // get all restorers
+ List<Backupable> backupable =
+ repositoryService.getRepository(repositoryName).getWorkspaceContainer(wEntry.getName())
+ .getComponentInstancesOfType(Backupable.class);
+
+ File storageDir = backupChainLog.getBackupConfig().getBackupDir();
+
+ for (Backupable component : backupable)
+ {
+ File fullBackupDir = JCRRestor.getFullBackupFile(storageDir);
+ dataRestorer.add(component.getDataRestorer(fullBackupDir, null));
+ }
+
+ for (DataRestor restorer : dataRestorer)
+ {
+ restorer.clean();
+ }
+
+ for (DataRestor restorer : dataRestorer)
+ {
+ restorer.restore();
+ }
+
+ for (DataRestor restorer : dataRestorer)
+ {
+ restorer.commit();
+ }
+
+ // resume components
+ for (int i = 0; i < resumeComponents.size() - 1; i++)
+ {
+ try
+ {
+ resumeComponents.remove(i).resume();
+ }
+ catch (ResumeException e)
+ {
+ log.error("Can't resume component", e);
+ }
+ }
+
+ // incremental restore
+ DataManager dataManager =
+ (WorkspacePersistentDataManager)repositoryService.getRepository(repositoryName)
+ .getWorkspaceContainer(wEntry.getName()).getComponent(WorkspacePersistentDataManager.class);
+
+ FileCleanerHolder fileCleanHolder =
+ (FileCleanerHolder)repositoryService.getRepository(repositoryName).getWorkspaceContainer(wEntry.getName())
+ .getComponent(FileCleanerHolder.class);
+
+ JCRRestor restorer = new JCRRestor(dataManager, fileCleanHolder.getFileCleaner());
+ for (File incrBackupFile : JCRRestor.getIncrementalFiles(storageDir))
+ {
+ restorer.incrementalRestore(incrBackupFile);
+ }
+ }
+ catch (Throwable t)
+ {
+ // rollback
+ for (DataRestor restorer : dataRestorer)
+ {
+ try
+ {
+ restorer.rollback();
+ }
+ catch (BackupException e)
+ {
+ log.error("Can't rollback changes", e);
+ }
+ }
+
+ throw new WorkspaceRestoreException("Workspace " + wEntry.getName() + " was not restored", t);
+ }
+ finally
+ {
+ // close
+ for (DataRestor restorer : dataRestorer)
+ {
+ try
+ {
+ restorer.close();
+ }
+ catch (BackupException e)
+ {
+ log.error("Can't close restorer", e);
+ }
+ }
+
+ for (Suspendable component : resumeComponents)
+ {
+ try
+ {
+ component.resume();
+ }
+ catch (ResumeException e)
+ {
+ log.error("Can't resume component", e);
+ }
+ }
+ }
+ }
+}
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -19,6 +19,7 @@
import org.exoplatform.services.jcr.RepositoryService;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.SimpleParameterEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
@@ -60,7 +61,7 @@
/**
* The apache logger.
*/
- private static Log log = ExoLogger.getLogger("exo.jcr.component.ext.JobRepositoryRestore");
+ protected static Log log = ExoLogger.getLogger("exo.jcr.component.ext.JobRepositoryRestore");
/**
* REPOSITORY_RESTORE_STARTED. The state of start restore.
@@ -108,7 +109,7 @@
protected RepositoryEntry repositoryEntry;
- private Map<String, BackupChainLog> workspacesMapping;
+ protected Map<String, BackupChainLog> workspacesMapping;
private RepositoryBackupChainLog repositoryBackupChainLog;
@@ -245,23 +246,7 @@
{
try
{
- ManageableRepository mr = null;
-
- try
- {
- mr = repositoryService.getRepository(repositoryEntry.getName());
- }
- catch (RepositoryException e)
- {
- // The repository not exist.
- }
-
- if (mr != null)
- {
- closeAllSession(mr);
- repositoryService.removeRepository(repositoryEntry.getName());
- repositoryService.getConfig().retain(); // save configuration to persistence (file or persister)
- }
+ removeRepository(repositoryService, repositoryEntry.getName());
}
catch (Throwable thr)
{
@@ -272,6 +257,40 @@
}
}
+ /**
+ * Remove repository.
+ *
+ * @param repositoryService
+ * RepositoryService, the repository service
+ * @param repositoryName
+ * String, the repository name
+ * @throws RepositoryException
+ * will be generated the RepositoryException
+ * @throws RepositoryConfigurationException
+ */
+ protected void removeRepository(RepositoryService repositoryService, String repositoryName)
+ throws RepositoryException,
+ RepositoryConfigurationException
+ {
+ ManageableRepository mr = null;
+
+ try
+ {
+ mr = repositoryService.getRepository(repositoryName);
+ }
+ catch (RepositoryException e)
+ {
+ // The repository not exist.
+ }
+
+ if (mr != null)
+ {
+ closeAllSession(mr);
+ repositoryService.removeRepository(repositoryName);
+ repositoryService.getConfig().retain(); // save configuration to persistence (file or persister)
+ }
+ }
+
private WorkspaceInitializerEntry getWorkspaceInitializerEntry(BackupChainLog systemBackupChainLog)
throws BackupOperationException, ClassNotFoundException
{
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobWorkspaceRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobWorkspaceRestore.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobWorkspaceRestore.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -115,7 +115,7 @@
/**
* The BackupChainLog for restore.
*/
- private final BackupChainLog backupChainLog;
+ protected final BackupChainLog backupChainLog;
/**
* JobWorkspaceRestore constructor.
@@ -145,6 +145,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void run()
{
try
@@ -210,11 +211,10 @@
}
}
}
-
}
/**
- * removeWorkspace.
+ * Remove workspace.
*
* @param mr
* ManageableRepository, the manageable repository
@@ -223,7 +223,7 @@
* @throws RepositoryException
* will be generated the RepositoryException
*/
- private void removeWorkspace(ManageableRepository mr, String workspaceName) throws RepositoryException
+ protected void removeWorkspace(ManageableRepository mr, String workspaceName) throws RepositoryException
{
boolean isExists = false;
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/fs/IncrementalBackupJob.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/fs/IncrementalBackupJob.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/fs/IncrementalBackupJob.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -124,8 +124,7 @@
}
}
- public void writeExternal(ObjectOutputStream out, TransactionChangesLog changesLog,
- FileCleaner fileCleaner)
+ public void writeExternal(ObjectOutputStream out, TransactionChangesLog changesLog, FileCleaner fileCleaner)
throws IOException
{
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/FullBackupJob.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/FullBackupJob.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/FullBackupJob.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -19,35 +19,29 @@
package org.exoplatform.services.jcr.ext.backup.impl.rdbms;
import org.exoplatform.commons.utils.PrivilegedFileHelper;
-import org.exoplatform.services.jcr.config.QueryHandlerParams;
-import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
-import org.exoplatform.services.jcr.config.ValueStorageEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.ext.backup.BackupConfig;
-import org.exoplatform.services.jcr.ext.backup.BackupOperationException;
import org.exoplatform.services.jcr.ext.backup.impl.AbstractFullBackupJob;
import org.exoplatform.services.jcr.ext.backup.impl.FileNameProducer;
-import org.exoplatform.services.jcr.impl.core.query.SystemSearchManager;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.BackupException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.ResumeException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.SuspendException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Suspendable;
-import org.exoplatform.services.jcr.impl.storage.value.fs.FileValueStorage;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.backup.Backupable;
+import org.exoplatform.services.jcr.impl.backup.ResumeException;
+import org.exoplatform.services.jcr.impl.backup.SuspendException;
+import org.exoplatform.services.jcr.impl.backup.Suspendable;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
import java.net.URL;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
+import javax.jcr.RepositoryException;
+
/**
* Created by The eXo Platform SARL Author : Alex Reshetnyak alex.reshetnyak(a)exoplatform.com.ua Nov
* 21, 2007
@@ -55,26 +49,16 @@
public class FullBackupJob extends AbstractFullBackupJob
{
/**
- * Index directory in full backup storage.
- */
- public static final String INDEX_DIR = "index";
+ * Logger.
+ */
+ protected static Log log = ExoLogger.getLogger("exo.jcr.component.ext.FullBackupJob");
/**
- * System index directory in full backup storage.
+ * Workspace configuration.
*/
- public static final String SYSTEM_INDEX_DIR = INDEX_DIR + "_" + SystemSearchManager.INDEX_DIR_SUFFIX;
+ private WorkspaceEntry workspaceEntry;
/**
- * Value storage directory in full backup storage.
- */
- public static final String VALUE_STORAGE_DIR = "values";
-
- /**
- * Logger.
- */
- protected static Log log = ExoLogger.getLogger("exo.jcr.component.ext.FullBackupJob");
-
- /**
* {@inheritDoc}
*/
@Override
@@ -120,15 +104,14 @@
{
notifyListeners();
- List<Backupable> backupableComponents =
- repository.getWorkspaceContainer(workspaceName).getComponentInstancesOfType(Backupable.class);
-
List<Suspendable> suspendableComponents =
repository.getWorkspaceContainer(workspaceName).getComponentInstancesOfType(Suspendable.class);
+ // the list of components to resume
+ List<Suspendable> resumeComponents = new ArrayList<Suspendable>();
+
try
{
- WorkspaceEntry workspaceEntry = null;
for (WorkspaceEntry entry : repository.getConfiguration().getWorkspaceEntries())
{
if (entry.getName().equals(workspaceName))
@@ -140,30 +123,25 @@
if (workspaceEntry == null)
{
- throw new RepositoryConfigurationException("Workpace name " + workspaceName
- + " not found in repository configuration");
+ throw new RepositoryException("Workpace [" + workspaceName + "] is absent in repository configuration");
}
// suspend all components
for (Suspendable component : suspendableComponents)
{
component.suspend();
+ resumeComponents.add(component);
}
+ List<Backupable> backupableComponents =
+ repository.getWorkspaceContainer(workspaceName).getComponentInstancesOfType(Backupable.class);
+
// backup all components
for (Backupable component : backupableComponents)
{
component.backup(new File(getStorageURL().getFile()));
}
-
- backupValueStorage(workspaceEntry);
- backupIndex(workspaceEntry);
}
- catch (RepositoryConfigurationException e)
- {
- log.error("Full backup failed " + getStorageURL().getPath(), e);
- notifyError("Full backup failed", e);
- }
catch (SuspendException e)
{
log.error("Full backup failed " + getStorageURL().getPath(), e);
@@ -174,19 +152,14 @@
log.error("Full backup failed " + getStorageURL().getPath(), e);
notifyError("Full backup failed", e);
}
- catch (BackupOperationException e)
+ catch (RepositoryException e)
{
log.error("Full backup failed " + getStorageURL().getPath(), e);
notifyError("Full backup failed", e);
}
- catch (IOException e)
- {
- log.error("Full backup failed " + getStorageURL().getPath(), e);
- notifyError("Full backup failed", e);
- }
finally
{
- for (Suspendable component : suspendableComponents)
+ for (Suspendable component : resumeComponents)
{
try
{
@@ -205,147 +178,10 @@
}
/**
- * Backup index files.
- *
- * @param workspaceEntry
- * @throws RepositoryConfigurationException
- * @throws BackupOperationException
- * @throws IOException
- */
- protected void backupIndex(WorkspaceEntry workspaceEntry) throws RepositoryConfigurationException,
- BackupOperationException, IOException
- {
- if (workspaceEntry.getQueryHandler() != null)
- {
- File srcDir = new File(workspaceEntry.getQueryHandler().getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR));
- if (!PrivilegedFileHelper.exists(srcDir))
- {
- throw new BackupOperationException("Can't backup index. Directory " + srcDir.getName() + " doesn't exists");
- }
- else
- {
- File destDir = new File(getStorageURL().getFile(), INDEX_DIR);
- copyDirectory(srcDir, destDir);
- }
-
- if (repository.getConfiguration().getSystemWorkspaceName().equals(workspaceName))
- {
- srcDir =
- new File(PrivilegedFileHelper.getCanonicalPath(srcDir) + "_" + SystemSearchManager.INDEX_DIR_SUFFIX);
- if (!PrivilegedFileHelper.exists(srcDir))
- {
- throw new BackupOperationException("Can't backup system index. Directory " + srcDir.getName()
- + " doesn't exists");
- }
- else
- {
- File destDir = new File(getStorageURL().getFile(), SYSTEM_INDEX_DIR);
- copyDirectory(srcDir, destDir);
- }
- }
- }
- }
-
- /**
- * Backup value storage files.
- *
- * @param workspaceEntry
- * @throws RepositoryConfigurationException
- * @throws BackupOperationException
- * @throws IOException
- */
- protected void backupValueStorage(WorkspaceEntry workspaceEntry) throws RepositoryConfigurationException,
- BackupOperationException, IOException
- {
- if (workspaceEntry.getContainer().getValueStorages() != null)
- {
- for (ValueStorageEntry valueStorage : workspaceEntry.getContainer().getValueStorages())
- {
- File srcDir = new File(valueStorage.getParameterValue(FileValueStorage.PATH));
- if (!PrivilegedFileHelper.exists(srcDir))
- {
- throw new BackupOperationException("Can't backup value storage. Directory " + srcDir.getName()
- + " doesn't exists");
- }
- else
- {
- File destValuesDir = new File(getStorageURL().getFile(), VALUE_STORAGE_DIR);
- File destDir = new File(destValuesDir, valueStorage.getId());
-
- copyDirectory(srcDir, destDir);
- }
- }
- }
- }
-
- /**
* {@inheritDoc}
*/
public void stop()
{
log.info("Stop requested " + getStorageURL().getPath());
}
-
- /**
- * Copy directory.
- *
- * @param srcPath
- * source path
- * @param dstPath
- * destination path
- * @throws IOException
- * if any exception occurred
- */
- private void copyDirectory(File srcPath, File dstPath) throws IOException
- {
- if (PrivilegedFileHelper.isDirectory(srcPath))
- {
- if (!PrivilegedFileHelper.exists(dstPath))
- {
- PrivilegedFileHelper.mkdirs(dstPath);
- }
-
- String files[] = PrivilegedFileHelper.list(srcPath);
- for (int i = 0; i < files.length; i++)
- {
- copyDirectory(new File(srcPath, files[i]), new File(dstPath, files[i]));
- }
- }
- else
- {
- InputStream in = null;
- ZipOutputStream out = null;
-
- try
- {
- in = PrivilegedFileHelper.fileInputStream(srcPath);
- out = PrivilegedFileHelper.zipOutputStream(dstPath);
- out.putNextEntry(new ZipEntry(srcPath.getName()));
-
- // Transfer bytes from in to out
- byte[] buf = new byte[2048];
-
- int len;
-
- while ((len = in.read(buf)) > 0)
- {
- out.write(buf, 0, len);
- }
- }
- finally
- {
- if (in != null)
- {
- in.close();
- }
-
- if (out != null)
- {
- out.flush();
- out.closeEntry();
- out.close();
- }
- }
- }
- }
-}
+}
\ No newline at end of file
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -21,18 +21,18 @@
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.JCRRestor;
import org.exoplatform.services.jcr.impl.core.LocationFactory;
import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
import org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.CleanException;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import javax.jcr.PathNotFoundException;
@@ -59,62 +59,42 @@
public RdbmsBackupWorkspaceInitializer(WorkspaceEntry config, RepositoryEntry repConfig,
CacheableWorkspaceDataManager dataManager, NamespaceRegistryImpl namespaceRegistry,
LocationFactory locationFactory, NodeTypeManagerImpl nodeTypeManager, ValueFactoryImpl valueFactory,
- AccessManager accessManager, RepositoryService repositoryService, FileCleanerHolder cleanerHolder)
- throws RepositoryConfigurationException,
- PathNotFoundException, RepositoryException
+ AccessManager accessManager, RepositoryService repositoryService, FileCleanerHolder cleanerHolder)
+ throws RepositoryConfigurationException, PathNotFoundException, RepositoryException
{
super(config, repConfig, dataManager, namespaceRegistry, locationFactory, nodeTypeManager, valueFactory,
- accessManager, repositoryService, cleanerHolder);
+ accessManager, repositoryService, cleanerHolder);
}
/**
* {@inheritDoc}
*/
@Override
- public NodeData initWorkspace() throws RepositoryException
+ protected void restoreAction() throws RepositoryException
{
- if (isWorkspaceInitialized())
- {
- return (NodeData)dataManager.getItemData(Constants.ROOT_UUID);
- }
+ // restore from full rdbms backup
+ fullRdbmsRestore();
- long start = System.currentTimeMillis();
-
- try
+ // restore from incremental backup
+ JCRRestor restorer = new JCRRestor(dataManager, fileCleaner);
+ for (File incrBackupFile : JCRRestor.getIncrementalFiles(new File(restoreDir)))
{
- // restore from full rdbms backup
- fullRdbmsRestore();
-
- // restore from incremental backup
- incrementalRead();
- }
- catch (Throwable e)
- {
try
{
- rollback();
+ restorer.incrementalRestore(incrBackupFile);
}
- catch (RepositoryConfigurationException e1)
+ catch (FileNotFoundException e)
{
- log.error("Can't rollback changes", e1);
+ throw new RepositoryException(e);
}
- catch (CleanException e1)
+ catch (IOException e)
{
- log.error("Can't rollback changes", e1);
+ throw new RepositoryException(e);
}
- catch (IOException e1)
+ catch (ClassNotFoundException e)
{
- log.error("Can't rollback changes", e1);
+ throw new RepositoryException(e);
}
- throw new RepositoryException(e);
}
-
- final NodeData root = (NodeData)dataManager.getItemData(Constants.ROOT_UUID);
-
- log.info("Workspace [" + workspaceName + "] restored from storage " + restorePath + " in "
- + (System.currentTimeMillis() - start) * 1d / 1000 + "sec");
-
- return root;
}
-
}
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -18,41 +18,30 @@
*/
package org.exoplatform.services.jcr.ext.backup.impl.rdbms;
-import org.exoplatform.commons.utils.PrivilegedFileHelper;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.access.AccessManager;
-import org.exoplatform.services.jcr.config.QueryHandlerParams;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.RepositoryEntry;
-import org.exoplatform.services.jcr.config.ValueStorageEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.core.ManageableRepository;
-import org.exoplatform.services.jcr.core.WorkspaceContainerFacade;
import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.ext.backup.impl.IndexCleanHelper;
-import org.exoplatform.services.jcr.ext.backup.impl.ValueStorageCleanHelper;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.backup.Backupable;
+import org.exoplatform.services.jcr.impl.backup.DataRestor;
import org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer;
import org.exoplatform.services.jcr.impl.core.LocationFactory;
import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
-import org.exoplatform.services.jcr.impl.core.SessionRegistry;
import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
-import org.exoplatform.services.jcr.impl.core.query.SystemSearchManager;
import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
import org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.CleanException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.RestoreException;
-import org.exoplatform.services.jcr.impl.storage.value.fs.FileValueStorage;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.List;
-import java.util.zip.ZipInputStream;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
@@ -73,19 +62,17 @@
*/
protected final RepositoryService repositoryService;
-
/**
* Constructor RdbmsWorkspaceInitializer.
*/
public RdbmsWorkspaceInitializer(WorkspaceEntry config, RepositoryEntry repConfig,
CacheableWorkspaceDataManager dataManager, NamespaceRegistryImpl namespaceRegistry,
LocationFactory locationFactory, NodeTypeManagerImpl nodeTypeManager, ValueFactoryImpl valueFactory,
- AccessManager accessManager, RepositoryService repositoryService, FileCleanerHolder cleanerHolder)
- throws RepositoryConfigurationException,
- PathNotFoundException, RepositoryException
+ AccessManager accessManager, RepositoryService repositoryService, FileCleanerHolder cleanerHolder)
+ throws RepositoryConfigurationException, PathNotFoundException, RepositoryException
{
super(config, repConfig, dataManager, namespaceRegistry, locationFactory, nodeTypeManager, valueFactory,
- accessManager, cleanerHolder);
+ accessManager, cleanerHolder);
this.repositoryService = repositoryService;
}
@@ -103,30 +90,7 @@
long start = System.currentTimeMillis();
- try
- {
- fullRdbmsRestore();
- }
- catch (Throwable e)
- {
- try
- {
- rollback();
- }
- catch (RepositoryConfigurationException e1)
- {
- log.error("Can't rollback changes", e1);
- }
- catch (CleanException e1)
- {
- log.error("Can't rollback changes", e1);
- }
- catch (IOException e1)
- {
- log.error("Can't rollback changes", e1);
- }
- throw new RepositoryException(e);
- }
+ restoreAction();
final NodeData root = (NodeData)dataManager.getItemData(Constants.ROOT_UUID);
@@ -137,10 +101,22 @@
}
/**
+ * Calls restoring methods.
+ *
+ * @throws RepositoryException if any Exception is occurred
+ */
+ protected void restoreAction() throws RepositoryException
+ {
+ fullRdbmsRestore();
+ }
+
+ /**
* Restore from full rdbms backup.
*/
protected void fullRdbmsRestore() throws RepositoryException
{
+ List<DataRestor> dataRestorers = new ArrayList<DataRestor>();
+
ManageableRepository repository = null;
try
{
@@ -159,240 +135,47 @@
// restore all components
for (Backupable component : backupableComponents)
{
- component.restore(new File(restorePath));
+ dataRestorers.add(component.getDataRestorer(new File(restorePath), null));
}
- restoreValueStorage();
- restoreIndex();
- }
- catch (RestoreException e)
- {
- throw new RepositoryException(e);
- }
- catch (RepositoryConfigurationException e)
- {
- throw new RepositoryException(e);
- }
- catch (IOException e)
- {
- throw new RepositoryException(e);
- }
- }
-
- /**
- * Restore index from backup.
- */
- protected void restoreIndex() throws RepositoryConfigurationException, IOException
- {
- File indexDir = new File(restorePath, FullBackupJob.INDEX_DIR);
- File systemIndexDir = new File(restorePath, FullBackupJob.SYSTEM_INDEX_DIR);
-
- if (workspaceEntry.getQueryHandler() != null)
- {
- if (!PrivilegedFileHelper.exists(indexDir))
+ for (DataRestor restorer : dataRestorers)
{
- throw new RepositoryConfigurationException("Can't restore index. Directory " + indexDir.getName()
- + " doesn't exists");
+ restorer.restore();
}
- else
- {
- File destDir =
- new File(workspaceEntry.getQueryHandler().getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR));
- copyDirectory(indexDir, destDir);
- }
- // try to restore system index
- if (repositoryEntry.getSystemWorkspaceName().equals(workspaceName))
+ for (DataRestor restorer : dataRestorers)
{
- if (!PrivilegedFileHelper.exists(systemIndexDir))
- {
- throw new RepositoryConfigurationException("Can't restore system index. Directory "
- + systemIndexDir.getName() + " doesn't exists");
- }
- else
- {
- File destDir =
- new File(workspaceEntry.getQueryHandler().getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR) + "_"
- + SystemSearchManager.INDEX_DIR_SUFFIX);
- copyDirectory(systemIndexDir, destDir);
- }
+ restorer.commit();
}
- else if (PrivilegedFileHelper.exists(systemIndexDir))
- {
- throw new RepositoryConfigurationException("Workspace [" + workspaceName
- + "] is not a system in repository configuration but system index backup files exist");
- }
}
- else
+ catch (Throwable e)
{
- if (PrivilegedFileHelper.exists(indexDir) || PrivilegedFileHelper.exists(systemIndexDir))
+ for (DataRestor restorer : dataRestorers)
{
- throw new RepositoryConfigurationException("Query handler didn't configure in workspace [" + workspaceName
- + "] configuration but index backup files exist");
- }
- }
- }
-
- /**
- * Rollback changes due to errors.
- *
- * @throws RepositoryConfigurationException
- * @throws RepositoryException
- * @throws CleanException
- * @throws IOException
- */
- protected void rollback() throws RepositoryException, RepositoryConfigurationException, CleanException,
- IOException
- {
- boolean isSystem =
- repositoryService.getRepository(repositoryEntry.getName()).getConfiguration().getSystemWorkspaceName()
- .equals(workspaceEntry.getName());
-
- //close all session
- forceCloseSession(repositoryEntry.getName(), workspaceEntry.getName());
-
- List<Backupable> backupable =
- repositoryService.getRepository(repositoryEntry.getName()).getWorkspaceContainer(workspaceEntry.getName())
- .getComponentInstancesOfType(Backupable.class);
-
- //clean database
- for (Backupable component : backupable)
- {
- component.getDataCleaner().clean();
- }
-
- //clean index
- new IndexCleanHelper().removeWorkspaceIndex(workspaceEntry, isSystem);
-
- //clean value storage
- new ValueStorageCleanHelper().removeWorkspaceValueStorage(workspaceEntry);
- }
-
- /**
- * Close sessions on specific workspace.
- *
- * @param repositoryName
- * repository name
- * @param workspaceName
- * workspace name
- * @return int return the how many sessions was closed
- * @throws RepositoryConfigurationException
- * will be generate RepositoryConfigurationException
- * @throws RepositoryException
- * will be generate RepositoryException
- */
- private int forceCloseSession(String repositoryName, String workspaceName) throws RepositoryException,
- RepositoryConfigurationException
- {
- ManageableRepository mr = repositoryService.getRepository(repositoryName);
- WorkspaceContainerFacade wc = mr.getWorkspaceContainer(workspaceName);
-
- SessionRegistry sessionRegistry = (SessionRegistry)wc.getComponent(SessionRegistry.class);
-
- return sessionRegistry.closeSessions(workspaceName);
- }
-
- /**
- * Restoring value storage from backup.
- */
- protected void restoreValueStorage() throws RepositoryConfigurationException, IOException
- {
- File backupValueStorageDir = new File(restorePath, FullBackupJob.VALUE_STORAGE_DIR);
- if (workspaceEntry.getContainer().getValueStorages() != null)
- {
- List<ValueStorageEntry> valueStorages = workspaceEntry.getContainer().getValueStorages();
- String[] valueStoragesFiles = PrivilegedFileHelper.list(backupValueStorageDir);
-
- if ((valueStoragesFiles == null && valueStorages.size() != 0)
- || (valueStoragesFiles != null && valueStoragesFiles.length != valueStorages.size()))
- {
- throw new RepositoryConfigurationException("Workspace configuration [" + workspaceName
- + "] has a different amount of value storages than exist in backup");
- }
-
- for (ValueStorageEntry valueStorage : valueStorages)
- {
- File srcDir = new File(backupValueStorageDir, valueStorage.getId());
- if (!PrivilegedFileHelper.exists(srcDir))
+ try
{
- throw new RepositoryConfigurationException("Can't restore value storage. Directory " + srcDir.getName()
- + " doesn't exists");
+ restorer.rollback();
}
- else
+ catch (BackupException e1)
{
- File destDir = new File(valueStorage.getParameterValue(FileValueStorage.PATH));
-
- copyDirectory(srcDir, destDir);
+ log.error("Can't rollback restorer", e);
}
}
- }
- else
- {
- if (PrivilegedFileHelper.exists(backupValueStorageDir))
- {
- throw new RepositoryConfigurationException("Value storage didn't configure in workspace [" + workspaceName
- + "] configuration but value storage backup files exist");
- }
- }
- }
- /**
- * Copy directory.
- *
- * @param srcPath
- * source path
- * @param dstPath
- * destination path
- * @throws IOException
- * if any exception occurred
- */
- private void copyDirectory(File srcPath, File dstPath) throws IOException
- {
- if (PrivilegedFileHelper.isDirectory(srcPath))
- {
- if (!PrivilegedFileHelper.exists(dstPath))
- {
- PrivilegedFileHelper.mkdirs(dstPath);
- }
-
- String files[] = PrivilegedFileHelper.list(srcPath);
- for (int i = 0; i < files.length; i++)
- {
- copyDirectory(new File(srcPath, files[i]), new File(dstPath, files[i]));
- }
+ throw new RepositoryException(e);
}
- else
+ finally
{
- ZipInputStream in = null;
- OutputStream out = null;
-
- try
+ for (DataRestor restorer : dataRestorers)
{
- in = PrivilegedFileHelper.zipInputStream(srcPath);
- in.getNextEntry();
- out = PrivilegedFileHelper.fileOutputStream(dstPath);
-
- // Transfer bytes from in to out
- byte[] buf = new byte[2048];
-
- int len;
-
- while ((len = in.read(buf)) > 0)
+ try
{
- out.write(buf, 0, len);
+ restorer.close();
}
- }
- finally
- {
- if (in != null)
+ catch (BackupException e)
{
- in.close();
+ log.error("Can't close restorer", e);
}
-
- if (out != null)
- {
- out.close();
- }
}
}
}
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupTestCase.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupTestCase.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupTestCase.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.jcr.ext.backup;
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
import org.exoplatform.services.jcr.config.ContainerEntry;
import org.exoplatform.services.jcr.config.QueryHandlerEntry;
import org.exoplatform.services.jcr.config.QueryHandlerParams;
@@ -30,25 +31,24 @@
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.core.WorkspaceContainerFacade;
import org.exoplatform.services.jcr.ext.BaseStandaloneTest;
-import org.exoplatform.services.jcr.ext.backup.impl.IndexCleanHelper;
-import org.exoplatform.services.jcr.ext.backup.impl.ValueStorageCleanHelper;
import org.exoplatform.services.jcr.impl.RepositoryServiceImpl;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
import org.exoplatform.services.jcr.impl.core.SessionRegistry;
+import org.exoplatform.services.jcr.impl.core.query.SystemSearchManager;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.DataCleaner;
+import org.exoplatform.services.jcr.impl.storage.value.fs.FileValueStorage;
import java.io.File;
import java.io.FileFilter;
+import java.io.IOException;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import javax.jcr.ItemExistsException;
@@ -94,16 +94,6 @@
protected String workspaceNameToRestore = "ws1backup";
- /**
- * Value storage cleaner.
- */
- private ValueStorageCleanHelper valueStorageCleanHelper = new ValueStorageCleanHelper();
-
- /**
- * Index storage cleaner.
- */
- private IndexCleanHelper indexCleanHelper = new IndexCleanHelper();
-
class LogFilter
implements FileFilter
{
@@ -521,11 +511,24 @@
conn.close();
}
- //clean index
- indexCleanHelper.removeWorkspaceIndex(wEntry, isSystem);
+ if (wEntry.getContainer().getValueStorages() != null)
+ {
+ for (ValueStorageEntry valueStorage : wEntry.getContainer().getValueStorages())
+ {
+ removeDirectory(new File(valueStorage.getParameterValue(FileValueStorage.PATH)));
+ }
+ }
- //clean value storage
- valueStorageCleanHelper.removeWorkspaceValueStorage(wEntry);
+ if (wEntry.getQueryHandler() != null)
+ {
+ removeDirectory(new File(wEntry.getQueryHandler().getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR, null)));
+ if (isSystem)
+ {
+ removeDirectory(new File(wEntry.getQueryHandler().getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR,
+ null)
+ + "_" + SystemSearchManager.INDEX_DIR_SUFFIX));
+ }
+ }
}
protected void removeWorkspaceFullySingleDB(String repositoryName, String workspaceName) throws Exception
@@ -552,33 +555,31 @@
repositoryService.getRepository(repositoryName).getConfiguration().getSystemWorkspaceName()
.equals(wEntry.getName());
- List<DataCleaner> dataCleaners = new ArrayList<DataCleaner>();
-
- List<Backupable> backupable =
- repositoryService.getRepository(repositoryName).getWorkspaceContainer(wEntry.getName())
- .getComponentInstancesOfType(Backupable.class);
-
- for (Backupable component : backupable)
- {
- dataCleaners.add(component.getDataCleaner());
- }
-
//close all session
forceCloseSession(repositoryName, wEntry.getName());
repositoryService.getRepository(repositoryName).removeWorkspace(wEntry.getName());
- //clean database
- for (DataCleaner cleaner : dataCleaners)
+ DBCleanService.cleanWorkspaceData(wEntry);
+
+ if (wEntry.getContainer().getValueStorages() != null)
{
- cleaner.clean();
+ for (ValueStorageEntry valueStorage : wEntry.getContainer().getValueStorages())
+ {
+ removeDirectory(new File(valueStorage.getParameterValue(FileValueStorage.PATH)));
+ }
}
- //clean index
- indexCleanHelper.removeWorkspaceIndex(wEntry, isSystem);
-
- //clean value storage
- valueStorageCleanHelper.removeWorkspaceValueStorage(wEntry);
+ if (wEntry.getQueryHandler() != null)
+ {
+ removeDirectory(new File(wEntry.getQueryHandler().getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR, null)));
+ if (isSystem)
+ {
+ removeDirectory(new File(wEntry.getQueryHandler().getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR,
+ null)
+ + "_" + SystemSearchManager.INDEX_DIR_SUFFIX));
+ }
+ }
}
protected void removeRepositoryFully(String repositoryName) throws Exception
@@ -604,52 +605,45 @@
forceCloseSession(repositoryEntry.getName(), wEntry.getName());
}
- List<DataCleaner> dataCleaners = new ArrayList<DataCleaner>();
+ String systemWorkspaceName =
+ repositoryService.getRepository(repositoryName).getConfiguration().getSystemWorkspaceName();
- // collect all DataCleaners
- for (WorkspaceEntry wEntry : workspaceList)
- {
- forceCloseSession(repositoryEntry.getName(), wEntry.getName());
-
- List<Backupable> backupable =
- repositoryService.getRepository(repositoryEntry.getName()).getWorkspaceContainer(wEntry.getName())
- .getComponentInstancesOfType(Backupable.class);
-
- for (Backupable component : backupable)
- {
- dataCleaners.add(component.getDataCleaner());
- }
- }
-
//remove repository
if (isDefault)
{
- ((RepositoryServiceImpl) repositoryService).removeDefaultRepository();
+ ((RepositoryServiceImpl)repositoryService).removeDefaultRepository();
}
else
{
repositoryService.removeRepository(repositoryEntry.getName());
}
- //clean database
- for (DataCleaner cleaner : dataCleaners)
- {
- cleaner.clean();
- }
-
- //clean index
for (WorkspaceEntry wEntry : workspaceList)
{
- indexCleanHelper.removeWorkspaceIndex(wEntry, repositoryEntry.getSystemWorkspaceName()
- .equals(wEntry.getName()));
- }
+ DBCleanService.cleanWorkspaceData(wEntry);
- //clean value storage
- for (WorkspaceEntry wEntry : workspaceList)
- {
- valueStorageCleanHelper.removeWorkspaceValueStorage(wEntry);
+ if (wEntry.getContainer().getValueStorages() != null)
+ {
+ for (ValueStorageEntry valueStorage : wEntry.getContainer().getValueStorages())
+ {
+ removeDirectory(new File(valueStorage.getParameterValue(FileValueStorage.PATH)));
+ }
+ }
+
+ boolean isSystem = systemWorkspaceName.equals(wEntry.getName());
+
+ if (wEntry.getQueryHandler() != null)
+ {
+ removeDirectory(new File(wEntry.getQueryHandler().getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR,
+ null)));
+ if (isSystem)
+ {
+ removeDirectory(new File(wEntry.getQueryHandler().getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR,
+ null)
+ + "_" + SystemSearchManager.INDEX_DIR_SUFFIX));
+ }
+ }
}
-
}
/**
@@ -676,4 +670,34 @@
return sessionRegistry.closeSessions(workspaceName);
}
+ /**
+ * Remove directory.
+ *
+ * @param dir
+ * directory to remove
+ * @throws IOException
+ * if any exception occurred
+ */
+ private void removeDirectory(File dir) throws IOException
+ {
+ if (PrivilegedFileHelper.isDirectory(dir))
+ {
+ for (File subFile : PrivilegedFileHelper.listFiles(dir))
+ {
+ removeDirectory(subFile);
+ }
+
+ if (!PrivilegedFileHelper.delete(dir))
+ {
+ throw new IOException("Can't remove folder : " + PrivilegedFileHelper.getCanonicalPath(dir));
+ }
+ }
+ else
+ {
+ if (!PrivilegedFileHelper.delete(dir))
+ {
+ throw new IOException("Can't remove file : " + PrivilegedFileHelper.getCanonicalPath(dir));
+ }
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -44,8 +44,7 @@
* @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
* @version $Id$
*/
-public abstract class AbstractBackupUseCasesTest
- extends AbstractBackupTestCase
+public abstract class AbstractBackupUseCasesTest extends AbstractBackupTestCase
{
private static volatile long uuIndex;
@@ -87,8 +86,7 @@
fail("Can't get fullBackup chain");
// restore
- RepositoryEntry re =
- (RepositoryEntry) ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
+ RepositoryEntry re = (RepositoryEntry)ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
WorkspaceEntry ws1back = makeWorkspaceEntry(workspaceNameToRestore, dataSourceToWorkspaceRestore);
// BackupChainLog bchLog = new BackupChainLog(backDir, rconfig);
@@ -106,10 +104,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToRestore);
+ back1 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToRestore);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -168,8 +166,7 @@
fail("Can't get fullBackup chain");
// restore
- RepositoryEntry re =
- (RepositoryEntry) ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
+ RepositoryEntry re = (RepositoryEntry)ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
WorkspaceEntry ws1back = makeWorkspaceEntry(workspaceNameToRestore, dataSourceToWorkspaceRestore);
File backLog = new File(bch.getLogFilePath());
@@ -186,16 +183,16 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToRestore);
+ back1 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToRestore);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertFalse("Node should be removed", ws1backTestRoot.hasNode("node_3"));
assertFalse("Node should be removed", ws1backTestRoot.hasNode("node_4"));
assertFalse("Node should be removed", ws1backTestRoot.hasNode("node_5"));
assertEquals("Restored content should be same", "property #3", ws1backTestRoot.getNode("node #3")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
assertEquals("Restored content should be same", "property #5", ws1backTestRoot.getNode("node #5")
- .getProperty("exo:extraData").getString());
+ .getProperty("exo:extraData").getString());
assertFalse("Proeprty should be removed", ws1backTestRoot.getNode("node #5").hasProperty("exo:data"));
}
@@ -252,12 +249,12 @@
// BLOBs for incr
ws1TestRoot.getNode("node_1").setProperty("exo:extraData", new FileInputStream(tempf));
ws1TestRoot.getNode("node_5").setProperty("exo:data", new FileInputStream(tempf));
-
ws1TestRoot.addNode("node_101").setProperty("exo:data", new FileInputStream(tempf));
ws1TestRoot.addNode("node_102").setProperty("exo:data", new FileInputStream(tempf));
+
ws1TestRoot.save(); // log here via listener
- ws1TestRoot.getNode("node_2").setProperty("exo:data", (Value) null); // remove property
+ ws1TestRoot.getNode("node_2").setProperty("exo:data", (Value)null); // remove property
ws1TestRoot.getNode("node_3").setProperty("exo:data", new ByteArrayInputStream("aaa".getBytes())); // set
// aaa
// bytes
@@ -268,7 +265,7 @@
ws1TestRoot.save(); // log here via listener
Lock n107lock = ws1TestRoot.getNode("node_5").lock(true, false);
ws1TestRoot.getSession().move(ws1TestRoot.getNode("node #53").getPath(),
- ws1TestRoot.getNode("node_5").getPath() + "/node #53");
+ ws1TestRoot.getNode("node_5").getPath() + "/node #53");
ws1TestRoot.save(); // log here via listener
ws1TestRoot.getNode("node_6").addMixin("mix:referenceable");
@@ -276,8 +273,8 @@
ws1TestRoot.save(); // log here via listener
// before(*), log here via listener
- ws1TestRoot.getSession().getWorkspace().move(ws1TestRoot.getNode("node_6").getPath(),
- ws1TestRoot.getPath() + "/node_4"); // in place of
+ ws1TestRoot.getSession().getWorkspace()
+ .move(ws1TestRoot.getNode("node_6").getPath(), ws1TestRoot.getPath() + "/node_4"); // in place of
// 4 removed
// stop all
@@ -287,8 +284,7 @@
fail("Can't get fullBackup chain");
// restore
- RepositoryEntry re =
- (RepositoryEntry) ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
+ RepositoryEntry re = (RepositoryEntry)ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
WorkspaceEntry ws1back = makeWorkspaceEntry(workspaceNameToRestore, dataSourceToWorkspaceRestore);
File backLog = new File(bch.getLogFilePath());
@@ -305,12 +301,12 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToRestore);
+ back1 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToRestore);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertTrue("Node should exists", ws1backTestRoot.getNode("node_5").hasNode("node #53"));
assertTrue("Property should exists", ws1backTestRoot.getNode("node_5")
- .hasProperty("node #53/exo:extraData"));
+ .hasProperty("node #53/exo:extraData"));
assertTrue("Node should exists", ws1backTestRoot.hasNode("node_7"));
assertTrue("Property should exists", ws1backTestRoot.hasProperty("node_5/exo:data"));
@@ -318,20 +314,20 @@
assertTrue("Node should exists", ws1backTestRoot.hasNode("node_102"));
compareStream(new FileInputStream(tempf), ws1backTestRoot.getNode("node_5").getProperty("exo:data")
- .getStream());
+ .getStream());
compareStream(new FileInputStream(tempf), ws1backTestRoot.getNode("node_1").getProperty("exo:extraData")
- .getStream());
+ .getStream());
assertFalse("Property should be removed", ws1backTestRoot.getNode("node_2").hasProperty("exo:data"));
- compareStream(new ByteArrayInputStream("aaa".getBytes()), ws1backTestRoot.getNode("node_3").getProperty(
- "exo:data").getStream());
+ compareStream(new ByteArrayInputStream("aaa".getBytes()),
+ ws1backTestRoot.getNode("node_3").getProperty("exo:data").getStream());
assertTrue("Node should be mix:lockable ", ws1backTestRoot.getNode("node_5").isNodeType("mix:lockable"));
assertFalse("Node should be not locked ", ws1backTestRoot.getNode("node_5").isLocked());
- assertEquals("Node should be mix:referenceable and UUID should be " + id6, id6, ws1backTestRoot.getNode(
- "node_4").getUUID());
+ assertEquals("Node should be mix:referenceable and UUID should be " + id6, id6,
+ ws1backTestRoot.getNode("node_4").getUUID());
}
catch (Exception e)
{
@@ -350,9 +346,9 @@
public void testFullBackupRestoreAsync() throws Exception
{
- SessionImpl sessionWS1 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToBackup);
- sessionWS1.getRootNode().getNode("backupTest").getNode("node_5").setProperty("exo:data",
- "Restored content should be same");
+ SessionImpl sessionWS1 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToBackup);
+ sessionWS1.getRootNode().getNode("backupTest").getNode("node_5")
+ .setProperty("exo:data", "Restored content should be same");
sessionWS1.save();
// backup
@@ -398,23 +394,23 @@
backup.restore(bchLog, repositoryNameToBackup, ws1back, true);
while (backup.getLastRestore(repositoryNameToBackup, workspaceNameToRestore).getStateRestore() != JobWorkspaceRestore.RESTORE_SUCCESSFUL
- && backup.getLastRestore(repositoryNameToBackup, workspaceNameToRestore).getStateRestore() != JobWorkspaceRestore.RESTORE_FAIL)
+ && backup.getLastRestore(repositoryNameToBackup, workspaceNameToRestore).getStateRestore() != JobWorkspaceRestore.RESTORE_FAIL)
{
Thread.sleep(50);
}
if (backup.getLastRestore(repositoryNameToBackup, workspaceNameToRestore).getStateRestore() == JobWorkspaceRestore.RESTORE_FAIL)
- throw (Exception) backup.getLastRestore(repositoryNameToBackup, workspaceNameToRestore)
- .getRestoreException();
+ throw (Exception)backup.getLastRestore(repositoryNameToBackup, workspaceNameToRestore)
+ .getRestoreException();
// check
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToRestore);
+ back1 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToRestore);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
- assertEquals("Restored content should be same", "Restored content should be same", ws1backTestRoot.getNode(
- "node_5").getProperty("exo:data").getString());
+ assertEquals("Restored content should be same", "Restored content should be same",
+ ws1backTestRoot.getNode("node_5").getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -527,10 +523,10 @@
public void testTwoRestores() throws Exception
{
{
- SessionImpl sessionWS1 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToBackup);
+ SessionImpl sessionWS1 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToBackup);
- sessionWS1.getRootNode().addNode("asdasdasda", "nt:unstructured").setProperty("data",
- new FileInputStream(createBLOBTempFile(1024)));
+ sessionWS1.getRootNode().addNode("asdasdasda", "nt:unstructured")
+ .setProperty("data", new FileInputStream(createBLOBTempFile(1024)));
sessionWS1.save();
// 1-st backup
@@ -563,12 +559,12 @@
backup.restore(bchLog, repositoryNameToBackup, ws1_restore_1, false);
// check
- SessionImpl back1 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToRestore);
+ SessionImpl back1 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToRestore);
assertNotNull(back1.getRootNode().getNode("asdasdasda").getProperty("data"));
// add date to restored workspace
- back1.getRootNode().addNode("gdfgrghfhf", "nt:unstructured").setProperty("data",
- new FileInputStream(createBLOBTempFile(1024)));
+ back1.getRootNode().addNode("gdfgrghfhf", "nt:unstructured")
+ .setProperty("data", new FileInputStream(createBLOBTempFile(1024)));
back1.save();
}
else
@@ -608,7 +604,7 @@
backup.restore(bchLog, repositoryNameToBackup, ws1_restore_2, false);
// check
- SessionImpl back2 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToRestore);
+ SessionImpl back2 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToRestore);
assertNotNull(back2.getRootNode().getNode("gdfgrghfhf").getProperty("data"));
}
else
@@ -723,8 +719,7 @@
fail("Can't get fullBackup chain");
// restore
- RepositoryEntry re =
- (RepositoryEntry) ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
+ RepositoryEntry re = (RepositoryEntry)ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
WorkspaceEntry ws1back = makeWorkspaceEntry(workspaceNameToRestore, dataSourceToWorkspaceRestore + "NOT_EXIST");
File backLog = new File(bch.getLogFilePath());
@@ -750,10 +745,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToRestore);
+ back1 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToRestore);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -799,8 +794,8 @@
// restore
RepositoryEntry newRepositoryEntry =
- makeRepositoryEntry(repositoryNameToRestore, getReposityToBackup().getConfiguration(),
- dataSourceToRepositoryRestore, null);
+ makeRepositoryEntry(repositoryNameToRestore, getReposityToBackup().getConfiguration(),
+ dataSourceToRepositoryRestore, null);
File backLog = new File(bch.getLogFilePath());
if (backLog.exists())
@@ -811,8 +806,8 @@
assertNotNull(bchLog.getFinishedTime());
backup.restore(bchLog, newRepositoryEntry, false);
- assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, backup.getLastRepositoryRestore(
- newRepositoryEntry.getName()).getStateRestore());
+ assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL,
+ backup.getLastRepositoryRestore(newRepositoryEntry.getName()).getStateRestore());
// check
ManageableRepository restoredRepository = repositoryService.getRepository(repositoryNameToRestore);
@@ -822,10 +817,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -870,8 +865,8 @@
//will be saved in incremental backup
//will be saved in incremental backup
Session wsSession = getReposityToBackup().login(credentials, "ws");
- wsSession.getRootNode().getNode("backupTest").addNode("binary_data").setProperty("data",
- new FileInputStream(createBLOBTempFile(500)));
+ wsSession.getRootNode().getNode("backupTest").addNode("binary_data")
+ .setProperty("data", new FileInputStream(createBLOBTempFile(500)));
wsSession.save();
// stop fullBackup
@@ -879,8 +874,8 @@
// restore
RepositoryEntry newRepositoryEntry =
- makeRepositoryEntry(repositoryNameToRestore, getReposityToBackup().getConfiguration(),
- dataSourceToRepositoryRestore, null);
+ makeRepositoryEntry(repositoryNameToRestore, getReposityToBackup().getConfiguration(),
+ dataSourceToRepositoryRestore, null);
File backLog = new File(bch.getLogFilePath());
if (backLog.exists())
@@ -900,10 +895,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
if (wsName.equals("ws"))
{
@@ -956,8 +951,8 @@
// restore
RepositoryEntry newRepositoryEntry =
- makeRepositoryEntry(repositoryNameToRestore, getReposityToBackup().getConfiguration(),
- dataSourceToRepositoryRestore, null);
+ makeRepositoryEntry(repositoryNameToRestore, getReposityToBackup().getConfiguration(),
+ dataSourceToRepositoryRestore, null);
File backLog = new File(bch.getLogFilePath());
if (backLog.exists())
@@ -972,7 +967,7 @@
JobRepositoryRestore job = backup.getLastRepositoryRestore(repositoryNameToRestore);
while (job.getStateRestore() != JobRepositoryRestore.REPOSITORY_RESTORE_SUCCESSFUL
- || job.getStateRestore() == JobRepositoryRestore.REPOSITORY_RESTORE_FAIL)
+ || job.getStateRestore() == JobRepositoryRestore.REPOSITORY_RESTORE_FAIL)
{
Thread.yield();
Thread.sleep(50);
@@ -986,10 +981,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -1036,8 +1031,8 @@
// restore
RepositoryEntry newRepositoryEntry =
- makeRepositoryEntry(repositoryNameToRestore, getReposityToBackup().getConfiguration(),
- dataSourceToRepositoryRestore, null);
+ makeRepositoryEntry(repositoryNameToRestore, getReposityToBackup().getConfiguration(),
+ dataSourceToRepositoryRestore, null);
// create workspace mappingS
Map<String, String> workspaceMapping = new HashedMap();
@@ -1072,7 +1067,7 @@
JobRepositoryRestore job = backup.getLastRepositoryRestore(repositoryNameToRestore);
while (job.getStateRestore() != JobRepositoryRestore.REPOSITORY_RESTORE_SUCCESSFUL
- || job.getStateRestore() == JobRepositoryRestore.REPOSITORY_RESTORE_FAIL)
+ || job.getStateRestore() == JobRepositoryRestore.REPOSITORY_RESTORE_FAIL)
{
Thread.yield();
Thread.sleep(50);
@@ -1086,10 +1081,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, workspaceMapping.get(wsName));
+ back1 = (SessionImpl)restoredRepository.login(credentials, workspaceMapping.get(wsName));
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -1167,8 +1162,7 @@
// restore
RepositoryEntry newRepositoryEntry =
- makeRepositoryEntry(repoName, getReposityToBackup().getConfiguration(), dataSourceToRepositoryRestore,
- null);
+ makeRepositoryEntry(repoName, getReposityToBackup().getConfiguration(), dataSourceToRepositoryRestore, null);
//create broken system workspaceEntry
newRepositoryEntry.getWorkspaceEntries().get(0).getQueryHandler().setType("gg");
@@ -1261,7 +1255,7 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToRestore);
+ back1 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToRestore);
Node node_101 = back1.getRootNode().getNode("node_101");
assertNotNull(node_101);
@@ -1328,8 +1322,7 @@
fail("Can't get fullBackup chain");
// restore
- RepositoryEntry re =
- (RepositoryEntry) ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
+ RepositoryEntry re = (RepositoryEntry)ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
WorkspaceEntry ws1 = null;
for (WorkspaceEntry we : re.getWorkspaceEntries())
{
@@ -1373,9 +1366,9 @@
fail("There are no backup files in " + backDir.getAbsolutePath());
}
- public void testExistedWorkspaceRestore() throws Exception
+ public void ExistedWorkspaceRestore() throws Exception
{
- SessionImpl ws1Session = (SessionImpl) repositoryService.getRepository("db7").login(credentials, "ws1");
+ SessionImpl ws1Session = (SessionImpl)repositoryService.getRepository("db7").login(credentials, "ws1");
// backup
File backDir = new File("target/backup/" + getUUIndex());
@@ -1407,8 +1400,7 @@
fail("Can't get fullBackup chain");
// restore
- RepositoryEntry re =
- (RepositoryEntry) ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
+ RepositoryEntry re = (RepositoryEntry)ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
WorkspaceEntry ws1 = null;
for (WorkspaceEntry we : re.getWorkspaceEntries())
{
@@ -1433,10 +1425,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) repositoryService.getRepository("db7").login(credentials, "ws1");
+ back1 = (SessionImpl)repositoryService.getRepository("db7").login(credentials, "ws1");
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -1485,8 +1477,7 @@
fail("Can't get fullBackup chain");
// restore
- RepositoryEntry re =
- (RepositoryEntry) ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
+ RepositoryEntry re = (RepositoryEntry)ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
WorkspaceEntry ws1 = null;
for (WorkspaceEntry we : re.getWorkspaceEntries())
{
@@ -1508,7 +1499,7 @@
backup.restoreExistingWorkspace(bchLog, repositoryNameToBackup, ws1, true);
while (backup.getLastRestore(repositoryNameToBackup, ws1.getName()).getStateRestore() != JobWorkspaceRestore.RESTORE_SUCCESSFUL
- && backup.getLastRestore(repositoryNameToBackup, ws1.getName()).getStateRestore() != JobWorkspaceRestore.RESTORE_FAIL)
+ && backup.getLastRestore(repositoryNameToBackup, ws1.getName()).getStateRestore() != JobWorkspaceRestore.RESTORE_FAIL)
{
Thread.sleep(50);
}
@@ -1518,11 +1509,11 @@
try
{
back1 =
- (SessionImpl) repositoryService.getRepository(repositoryNameToBackup).login(credentials,
- workspaceNameToBackup);
+ (SessionImpl)repositoryService.getRepository(repositoryNameToBackup).login(credentials,
+ workspaceNameToBackup);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -1572,8 +1563,7 @@
fail("Can't get fullBackup chain");
// restore
- RepositoryEntry re =
- (RepositoryEntry) ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
+ RepositoryEntry re = (RepositoryEntry)ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
WorkspaceEntry ws1 = null;
for (WorkspaceEntry we : re.getWorkspaceEntries())
{
@@ -1595,7 +1585,7 @@
backup.restoreExistingWorkspace(bchLog.getBackupId(), repositoryNameToBackup, ws1, true);
while (backup.getLastRestore(repositoryNameToBackup, ws1.getName()).getStateRestore() != JobWorkspaceRestore.RESTORE_SUCCESSFUL
- && backup.getLastRestore(repositoryNameToBackup, ws1.getName()).getStateRestore() != JobWorkspaceRestore.RESTORE_FAIL)
+ && backup.getLastRestore(repositoryNameToBackup, ws1.getName()).getStateRestore() != JobWorkspaceRestore.RESTORE_FAIL)
{
Thread.sleep(50);
}
@@ -1605,11 +1595,11 @@
try
{
back1 =
- (SessionImpl) repositoryService.getRepository(repositoryNameToBackup).login(credentials,
- workspaceNameToBackup);
+ (SessionImpl)repositoryService.getRepository(repositoryNameToBackup).login(credentials,
+ workspaceNameToBackup);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -1655,7 +1645,7 @@
// restore
RepositoryEntry re =
- makeRepositoryEntry(repositoryNameToBackup, getReposityToBackup().getConfiguration(), null, null);
+ makeRepositoryEntry(repositoryNameToBackup, getReposityToBackup().getConfiguration(), null, null);
File backLog = new File(bch.getLogFilePath());
if (backLog.exists())
@@ -1668,7 +1658,7 @@
backup.restoreExistingRepository(bchLog, re, false);
assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, backup.getLastRepositoryRestore(repositoryNameToBackup)
- .getStateRestore());
+ .getStateRestore());
// check
ManageableRepository restoredRepository = repositoryService.getRepository(repositoryNameToBackup);
@@ -1678,10 +1668,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -1701,8 +1691,8 @@
public void testExistedRepositoryRestoreSingelDB() throws Exception
{
- RepositoryImpl repositoryDB7 = (RepositoryImpl) repositoryService.getRepository(repositoryNameToBackupSingleDB);
- SessionImpl sessionWS = (SessionImpl) repositoryDB7.login(credentials, workspaceNameToBackup);
+ RepositoryImpl repositoryDB7 = (RepositoryImpl)repositoryService.getRepository(repositoryNameToBackupSingleDB);
+ SessionImpl sessionWS = (SessionImpl)repositoryDB7.login(credentials, workspaceNameToBackup);
// backup
File backDir = new File("target/backup/" + getUUIndex());
@@ -1731,7 +1721,7 @@
// restore
RepositoryEntry baseRE =
- (RepositoryEntry) sessionWS.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
+ (RepositoryEntry)sessionWS.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
RepositoryEntry re = makeRepositoryEntry(baseRE.getName(), baseRE, null, null);
File backLog = new File(bch.getLogFilePath());
@@ -1745,7 +1735,7 @@
backup.restoreExistingRepository(bchLog, re, false);
assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, backup.getLastRepositoryRestore(re.getName())
- .getStateRestore());
+ .getStateRestore());
// check
ManageableRepository restoredRepository = repositoryService.getRepository(repositoryNameToBackupSingleDB);
@@ -1755,10 +1745,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -1805,7 +1795,7 @@
// restore
RepositoryEntry re =
- makeRepositoryEntry(repositoryNameToBackup, getReposityToBackup().getConfiguration(), null, null);
+ makeRepositoryEntry(repositoryNameToBackup, getReposityToBackup().getConfiguration(), null, null);
File backLog = new File(bch.getLogFilePath());
if (backLog.exists())
@@ -1820,13 +1810,13 @@
JobRepositoryRestore job = backup.getLastRepositoryRestore(repositoryNameToBackup);
while (job.getStateRestore() != JobRepositoryRestore.REPOSITORY_RESTORE_SUCCESSFUL
- && job.getStateRestore() != JobRepositoryRestore.REPOSITORY_RESTORE_FAIL)
+ && job.getStateRestore() != JobRepositoryRestore.REPOSITORY_RESTORE_FAIL)
{
Thread.sleep(50);
}
- assertEquals(JobRepositoryRestore.REPOSITORY_RESTORE_SUCCESSFUL, backup.getLastRepositoryRestore(
- repositoryNameToBackup).getStateRestore());
+ assertEquals(JobRepositoryRestore.REPOSITORY_RESTORE_SUCCESSFUL,
+ backup.getLastRepositoryRestore(repositoryNameToBackup).getStateRestore());
// check
ManageableRepository restoredRepository = repositoryService.getRepository(repositoryNameToBackup);
@@ -1836,10 +1826,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -1886,7 +1876,7 @@
// restore
RepositoryEntry re =
- makeRepositoryEntry(repositoryNameToBackup, getReposityToBackup().getConfiguration(), null, null);
+ makeRepositoryEntry(repositoryNameToBackup, getReposityToBackup().getConfiguration(), null, null);
File backLog = new File(bch.getLogFilePath());
if (backLog.exists())
@@ -1901,13 +1891,13 @@
JobRepositoryRestore job = backup.getLastRepositoryRestore(repositoryNameToBackup);
while (job.getStateRestore() != JobRepositoryRestore.REPOSITORY_RESTORE_SUCCESSFUL
- && job.getStateRestore() != JobRepositoryRestore.REPOSITORY_RESTORE_FAIL)
+ && job.getStateRestore() != JobRepositoryRestore.REPOSITORY_RESTORE_FAIL)
{
Thread.sleep(50);
}
assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, backup.getLastRepositoryRestore(repositoryNameToBackup)
- .getStateRestore());
+ .getStateRestore());
// check
ManageableRepository restoredRepository = repositoryService.getRepository(repositoryNameToBackup);
@@ -1917,10 +1907,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -1940,8 +1930,8 @@
public void testExistedWorkspaceRestoreSingelDB() throws Exception
{
- RepositoryImpl repositoryDB7 = (RepositoryImpl) repositoryService.getRepository(repositoryNameToBackupSingleDB);
- SessionImpl sessionWS = (SessionImpl) repositoryDB7.login(credentials, workspaceNameToBackup);
+ RepositoryImpl repositoryDB7 = (RepositoryImpl)repositoryService.getRepository(repositoryNameToBackupSingleDB);
+ SessionImpl sessionWS = (SessionImpl)repositoryDB7.login(credentials, workspaceNameToBackup);
// backup
File backDir = new File("target/backup/" + getUUIndex());
@@ -1973,7 +1963,7 @@
fail("Can't get fullBackup chain");
// restore
- RepositoryEntry re = (RepositoryEntry) sessionWS.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
+ RepositoryEntry re = (RepositoryEntry)sessionWS.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
WorkspaceEntry ws1 = null;
for (WorkspaceEntry we : re.getWorkspaceEntries())
{
@@ -1998,11 +1988,11 @@
SessionImpl back1 = null;
try
{
- repositoryDB7 = (RepositoryImpl) repositoryService.getRepository(repositoryNameToBackupSingleDB);
- back1 = (SessionImpl) repositoryDB7.login(credentials, workspaceNameToBackup);
+ repositoryDB7 = (RepositoryImpl)repositoryService.getRepository(repositoryNameToBackupSingleDB);
+ back1 = (SessionImpl)repositoryDB7.login(credentials, workspaceNameToBackup);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -2066,11 +2056,11 @@
try
{
back1 =
- (SessionImpl) repositoryService.getRepository(repositoryNameToBackup).login(credentials,
- workspaceNameToBackup);
+ (SessionImpl)repositoryService.getRepository(repositoryNameToBackup).login(credentials,
+ workspaceNameToBackup);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -2128,7 +2118,7 @@
backup.restoreExistingRepository(bchLog.getBackupId(), false);
assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, backup.getLastRepositoryRestore(repositoryNameToBackup)
- .getStateRestore());
+ .getStateRestore());
// check
ManageableRepository restoredRepository = repositoryService.getRepository(repositoryNameToBackup);
@@ -2138,10 +2128,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -2208,10 +2198,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) repositoryService.getRepository(repositoryNameToBackup).login(credentials, "ws1");
+ back1 = (SessionImpl)repositoryService.getRepository(repositoryNameToBackup).login(credentials, "ws1");
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -2271,7 +2261,7 @@
backup.restoreRepository(bchLog.getBackupId(), false);
assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, backup.getLastRepositoryRestore(repositoryNameToBackup)
- .getStateRestore());
+ .getStateRestore());
// check
ManageableRepository restoredRepository = repositoryService.getRepository(repositoryNameToBackup);
@@ -2281,10 +2271,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -2345,7 +2335,7 @@
backup.restore(bchLog, null, false);
assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, backup.getLastRepositoryRestore(repositoryNameToBackup)
- .getStateRestore());
+ .getStateRestore());
// check
ManageableRepository restoredRepository = repositoryService.getRepository(repositoryNameToBackup);
@@ -2355,10 +2345,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -2434,10 +2424,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToBackup);
+ back1 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToBackup);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -2500,10 +2490,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) getReposityToBackup().login(credentials, workspaceNameToBackup);
+ back1 = (SessionImpl)getReposityToBackup().login(credentials, workspaceNameToBackup);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -2561,7 +2551,7 @@
backup.restoreExistingRepository(bchLog.getBackupConfig().getBackupDir(), false);
assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, backup.getLastRepositoryRestore(repositoryNameToBackup)
- .getStateRestore());
+ .getStateRestore());
// check
ManageableRepository restoredRepository = repositoryService.getRepository(repositoryNameToBackup);
@@ -2571,10 +2561,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -2640,10 +2630,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) getReposityToBackup().login(credentials, "ws1");
+ back1 = (SessionImpl)getReposityToBackup().login(credentials, "ws1");
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
@@ -2703,7 +2693,7 @@
backup.restoreRepository(bchLog.getBackupConfig().getBackupDir(), false);
assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, backup.getLastRepositoryRestore(repositoryNameToBackup)
- .getStateRestore());
+ .getStateRestore());
// check
ManageableRepository restoredRepository = repositoryService.getRepository(repositoryNameToBackup);
@@ -2713,10 +2703,10 @@
SessionImpl back1 = null;
try
{
- back1 = (SessionImpl) restoredRepository.login(credentials, wsName);
+ back1 = (SessionImpl)restoredRepository.login(credentials, wsName);
Node ws1backTestRoot = back1.getRootNode().getNode("backupTest");
assertEquals("Restored content should be same", "property-5", ws1backTestRoot.getNode("node_5")
- .getProperty("exo:data").getString());
+ .getProperty("exo:data").getString());
}
catch (Exception e)
{
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -19,6 +19,7 @@
package org.exoplatform.services.jcr.ext.backup;
import org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob;
+import org.exoplatform.services.jcr.impl.core.query.SystemSearchManager;
import java.io.File;
import java.net.URL;
@@ -48,17 +49,17 @@
URL url = job.getStorageURL();
assertNotNull(url);
- File valuesDir = new File(url.getFile(), FullBackupJob.VALUE_STORAGE_DIR);
+ File valuesDir = new File(url.getFile(), "values");
assertTrue(valuesDir.exists());
String values[] = valuesDir.list();
assertEquals(values.length, 1);
assertTrue(new File(valuesDir, values[0]).isDirectory());
- File indexesDir = new File(url.getFile(), FullBackupJob.INDEX_DIR);
+ File indexesDir = new File(url.getFile(), "index");
assertTrue(indexesDir.exists());
- indexesDir = new File(url.getFile(), FullBackupJob.SYSTEM_INDEX_DIR);
+ indexesDir = new File(url.getFile(), "index" + "_" + SystemSearchManager.INDEX_DIR_SUFFIX);
assertTrue(indexesDir.exists());
assertTrue(new File(url.getFile(), "JCR_MITEM.dump").exists());
@@ -88,13 +89,13 @@
URL url = job.getStorageURL();
assertNotNull(url);
- File valuesDir = new File(url.getFile(), FullBackupJob.VALUE_STORAGE_DIR);
+ File valuesDir = new File(url.getFile(), "values");
assertFalse(valuesDir.exists());
- File indexesDir = new File(url.getFile(), FullBackupJob.INDEX_DIR);
+ File indexesDir = new File(url.getFile(), "index");
assertTrue(indexesDir.exists());
- indexesDir = new File(url.getFile(), FullBackupJob.SYSTEM_INDEX_DIR);
+ indexesDir = new File(url.getFile(), "index" + "_" + SystemSearchManager.INDEX_DIR_SUFFIX);
assertFalse(indexesDir.exists());
assertTrue(new File(url.getFile(), "JCR_MITEM.dump").exists());
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsWorkspaceInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsWorkspaceInitializer.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsWorkspaceInitializer.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -45,114 +45,6 @@
{
TesterConfigurationHelper helper = TesterConfigurationHelper.getInstence();
- public void testRDBMSInitializerSystemWorkspace() throws Exception
- {
- FullBackupJob job = new FullBackupJob();
- BackupConfig config = new BackupConfig();
- config.setRepository("db1");
- config.setWorkspace("ws");
- config.setBackupDir(new File("target/backup/testJob/testRDBMSInitializerSystemWorkspace"));
-
- Calendar calendar = Calendar.getInstance();
-
- job.init(repositoryService.getRepository("db1"), "ws", config, calendar);
- job.run();
-
- URL url = job.getStorageURL();
-
- for (WorkspaceEntry workspaceEntry : repositoryService.getRepository("db1").getConfiguration()
- .getWorkspaceEntries())
- {
- if (workspaceEntry.getName().equals("ws"))
- {
- String newValueStoragePath = "target/temp/values/" + IdGenerator.generate();
- String newIndexPath = "target/temp/index/" + IdGenerator.generate();
-
- // set the initializer
- WorkspaceEntry newEntry =
- helper.getNewWs("ws", true, null, newValueStoragePath, newIndexPath, workspaceEntry.getContainer(),
- workspaceEntry.getContainer().getValueStorages());
-
- WorkspaceInitializerEntry wiEntry = new WorkspaceInitializerEntry();
- wiEntry.setType(RdbmsWorkspaceInitializer.class.getCanonicalName());
-
- List<SimpleParameterEntry> wieParams = new ArrayList<SimpleParameterEntry>();
- wieParams.add(new SimpleParameterEntry(SysViewWorkspaceInitializer.RESTORE_PATH_PARAMETER, new File(url
- .getFile()).getParent()));
-
- wiEntry.setParameters(wieParams);
-
- newEntry.setInitializer(wiEntry);
-
- TesterRdbmsWorkspaceInitializer initializer =
- new TesterRdbmsWorkspaceInitializer(newEntry, repositoryService.getRepository("db1").getConfiguration(),
- cacheableDataManager, null, null, null, (ValueFactoryImpl)valueFactory, null, repositoryService, new FileCleanerHolder());
-
- initializer.restoreValueFiles();
- assertTrue(new File(newValueStoragePath).list().length > 0);
-
- initializer.restoreIndexFiles();
- assertTrue(new File(newIndexPath).list().length > 0);
- assertTrue(new File(newIndexPath + "_" + SystemSearchManager.INDEX_DIR_SUFFIX).exists());
- assertTrue(new File(newIndexPath + "_" + SystemSearchManager.INDEX_DIR_SUFFIX).list().length > 0);
- }
- }
- }
-
- public void testRDBMSInitializer() throws Exception
- {
- FullBackupJob job = new FullBackupJob();
- BackupConfig config = new BackupConfig();
- config.setRepository("db1");
- config.setWorkspace("ws1");
- config.setBackupDir(new File("target/backup/testJob/testRDBMSInitializer"));
-
- Calendar calendar = Calendar.getInstance();
-
- job.init(repositoryService.getRepository("db1"), "ws1", config, calendar);
- job.run();
-
- URL url = job.getStorageURL();
-
- for (WorkspaceEntry workspaceEntry : repositoryService.getRepository("db1").getConfiguration()
- .getWorkspaceEntries())
- {
- if (workspaceEntry.getName().equals("ws1"))
- {
- String newValueStoragePath = "target/temp/values/" + IdGenerator.generate();
- String newIndexPath = "target/temp/index/" + IdGenerator.generate();
-
- // set the initializer
- WorkspaceEntry newEntry =
- helper.getNewWs("ws1", true, null, newValueStoragePath, newIndexPath, workspaceEntry.getContainer(),
- workspaceEntry.getContainer().getValueStorages());
-
- WorkspaceInitializerEntry wiEntry = new WorkspaceInitializerEntry();
- wiEntry.setType(RdbmsWorkspaceInitializer.class.getCanonicalName());
-
- List<SimpleParameterEntry> wieParams = new ArrayList<SimpleParameterEntry>();
- wieParams.add(new SimpleParameterEntry(SysViewWorkspaceInitializer.RESTORE_PATH_PARAMETER, new File(url
- .getFile()).getParent()));
-
- wiEntry.setParameters(wieParams);
-
- newEntry.setInitializer(wiEntry);
-
- TesterRdbmsWorkspaceInitializer initializer =
- new TesterRdbmsWorkspaceInitializer(newEntry, repositoryService.getRepository("db1").getConfiguration(),
- cacheableDataManager, null, null, null, (ValueFactoryImpl)valueFactory, null, repositoryService,
- new FileCleanerHolder());
-
- initializer.restoreValueFiles();
- assertFalse(new File(newValueStoragePath).exists());
-
- initializer.restoreIndexFiles();
- assertTrue(new File(newIndexPath).list().length > 0);
- assertFalse(new File(newIndexPath + "_" + SystemSearchManager.INDEX_DIR_SUFFIX).exists());
- }
- }
- }
-
public void testRDBMSInitializerRestoreTablesMultiDB() throws Exception
{
FullBackupJob job = new FullBackupJob();
@@ -221,6 +113,10 @@
repositoryService.getRepository("db1").configWorkspace(newEntry);
repositoryService.getRepository("db1").createWorkspace(newEntry.getName());
+
+ assertFalse(new File(newValueStoragePath).exists());
+ assertTrue(new File(newIndexPath).list().length > 0);
+ assertFalse(new File(newIndexPath + "_" + SystemSearchManager.INDEX_DIR_SUFFIX).exists());
}
break;
@@ -299,6 +195,10 @@
repositoryService.getRepository("db1").configWorkspace(newEntry);
repositoryService.getRepository("db1").createWorkspace(newEntry.getName());
+
+ assertFalse(new File(newValueStoragePath).exists());
+ assertTrue(new File(newIndexPath).list().length > 0);
+ assertFalse(new File(newIndexPath + "_" + SystemSearchManager.INDEX_DIR_SUFFIX).exists());
}
break;
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/load/TestLoadBackup.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/load/TestLoadBackup.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/load/TestLoadBackup.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -33,6 +33,9 @@
import org.exoplatform.services.jcr.ext.backup.BackupJob;
import org.exoplatform.services.jcr.ext.backup.BackupManager;
import org.exoplatform.services.jcr.ext.backup.ExtendedBackupManager;
+import org.exoplatform.services.jcr.ext.backup.RepositoryBackupChain;
+import org.exoplatform.services.jcr.ext.backup.RepositoryBackupChainLog;
+import org.exoplatform.services.jcr.ext.backup.RepositoryBackupConfig;
import org.exoplatform.services.jcr.ext.backup.impl.BackupManagerImpl;
import org.exoplatform.services.jcr.ext.backup.impl.JobWorkspaceRestore;
import org.exoplatform.services.jcr.impl.Constants;
@@ -43,8 +46,6 @@
import java.io.File;
import java.io.FileInputStream;
-import java.sql.Connection;
-import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -57,8 +58,6 @@
import javax.jcr.Value;
import javax.jcr.version.VersionException;
import javax.jcr.version.VersionHistory;
-import javax.naming.InitialContext;
-import javax.sql.DataSource;
/**
* Created by The eXo Platform SAS.
@@ -70,11 +69,13 @@
*/
public class TestLoadBackup extends BaseStandaloneTest
{
- protected final String REPOSITORY_NAME = "db7";
+ protected final String REPOSITORY_NAME_SINGLE_DB = "db7";
+ protected final String REPOSITORY_NAME_MULTI_DB = "db8";
+
protected final String WORKSPACE_NAME = "ws1";
- protected final int WRITER_COUNT = 100;
+ protected final int WRITER_COUNT = 0;
protected final String FULL_BACKUP_TYPE = "org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob";
@@ -120,7 +121,7 @@
*
* @throws Exception
*/
- public void testBackupRestore() throws Exception
+ public void _testBackupRestore() throws Exception
{
BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
@@ -130,7 +131,8 @@
//writers
for (int i = 0; i < WRITER_COUNT; i++)
{
- Session writerSession = repositoryService.getRepository(REPOSITORY_NAME).login(credentials, WORKSPACE_NAME);
+ Session writerSession =
+ repositoryService.getRepository(REPOSITORY_NAME_SINGLE_DB).login(credentials, WORKSPACE_NAME);
TreeWriterThread writer = new TreeWriterThread(writerSession, "subnode" + i);
writer.start();
threads.add(writer);
@@ -149,14 +151,14 @@
backupManagerImpl.start();
BackupConfig config = new BackupConfig();
- config.setRepository(REPOSITORY_NAME);
+ config.setRepository(REPOSITORY_NAME_SINGLE_DB);
config.setWorkspace(WORKSPACE_NAME);
config.setBackupType(BACKUP_TYPE);
config.setBackupDir(backDir);
backupManagerImpl.startBackup(config);
- bch = backupManagerImpl.findBackup(REPOSITORY_NAME, WORKSPACE_NAME);
+ bch = backupManagerImpl.findBackup(REPOSITORY_NAME_SINGLE_DB, WORKSPACE_NAME);
// wait till full backup will be stopped
while (bch.getFullBackupState() != BackupJob.FINISHED)
@@ -191,7 +193,7 @@
{
fail("Can't get fullBackup chain");
}
- Thread.sleep(5 * 1000);
+ Thread.sleep(10 * 1000);
System.out.println(" ============ BACKUP FINISHED ============");
@@ -208,9 +210,9 @@
assertNotNull(bchLog.getStartedTime());
assertNotNull(bchLog.getFinishedTime());
- backupManagerImpl.restore(bchLog, REPOSITORY_NAME, ws1back, false);
+ backupManagerImpl.restore(bchLog, REPOSITORY_NAME_SINGLE_DB, ws1back, false);
- JobWorkspaceRestore restore = backupManagerImpl.getLastRestore(REPOSITORY_NAME, ws1back.getName());
+ JobWorkspaceRestore restore = backupManagerImpl.getLastRestore(REPOSITORY_NAME_SINGLE_DB, ws1back.getName());
if (restore != null)
{
while (restore.getStateRestore() == JobWorkspaceRestore.RESTORE_FAIL
@@ -233,10 +235,442 @@
System.out.println(" ============ CHECKING INTEGRITY ============");
- checkIntegrity((NodeImpl)repositoryService.getRepository(REPOSITORY_NAME).login(credentials, "ws1back")
+ checkIntegrity((NodeImpl)repositoryService.getRepository(REPOSITORY_NAME_SINGLE_DB).login(credentials, "ws1back")
.getRootNode());
}
+ /**
+ * Test Backup/Restore.
+ *
+ * @throws Exception
+ */
+ public void testBackupRestoreExistingWorkspaceSingleDB() throws Exception
+ {
+ WorkspaceEntry entry = null;
+ for (WorkspaceEntry en : repositoryService.getRepository(REPOSITORY_NAME_SINGLE_DB).getConfiguration()
+ .getWorkspaceEntries())
+ {
+ if (en.getName().equals(WORKSPACE_NAME))
+ {
+ entry = en;
+ break;
+ }
+ }
+
+ BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
+
+ List<TreeWriterThread> threads = new ArrayList<TreeWriterThread>();
+ List<Session> sessions = new ArrayList<Session>();
+
+ //writers
+ for (int i = 0; i < WRITER_COUNT; i++)
+ {
+ Session writerSession =
+ repositoryService.getRepository(REPOSITORY_NAME_SINGLE_DB).login(credentials, WORKSPACE_NAME);
+ TreeWriterThread writer = new TreeWriterThread(writerSession, "subnode" + i);
+ writer.start();
+ threads.add(writer);
+ sessions.add(writerSession);
+ }
+
+ // backup
+ File backDir = new File("target/backup/ws1");
+ backDir.mkdirs();
+ BackupChain bch = null;
+
+ backupManagerImpl.start();
+
+ BackupConfig config = new BackupConfig();
+ config.setRepository(REPOSITORY_NAME_SINGLE_DB);
+ config.setWorkspace(WORKSPACE_NAME);
+ config.setBackupType(BACKUP_TYPE);
+ config.setBackupDir(backDir);
+
+ Thread.sleep(5 * 1000);
+
+ System.out.println(" ============ BACKUP START ============");
+
+ backupManagerImpl.startBackup(config);
+
+ bch = backupManagerImpl.findBackup(REPOSITORY_NAME_SINGLE_DB, WORKSPACE_NAME);
+
+ // wait till full backup will be stopped
+ while (bch.getFullBackupState() != BackupJob.FINISHED)
+ {
+ Thread.yield();
+ Thread.sleep(30);
+ }
+
+ if (bch != null)
+ {
+ backupManagerImpl.stopBackup(bch);
+ }
+ else
+ {
+ fail("Can't get fullBackup chain");
+ }
+
+ System.out.println(" ============ BACKUP FINISHED ============");
+
+ // restore
+ File backLog = new File(bch.getLogFilePath());
+ if (backLog.exists())
+ {
+ BackupChainLog bchLog = new BackupChainLog(backLog);
+
+ System.out.println(" ============ RESTORE START ============");
+
+ assertNotNull(bchLog.getStartedTime());
+ assertNotNull(bchLog.getFinishedTime());
+
+ backupManagerImpl.restoreExistingWorkspace(bchLog, REPOSITORY_NAME_SINGLE_DB, entry, false);
+
+ JobWorkspaceRestore restore = backupManagerImpl.getLastRestore(REPOSITORY_NAME_SINGLE_DB, WORKSPACE_NAME);
+ if (restore != null)
+ {
+ while (restore.getStateRestore() == JobWorkspaceRestore.RESTORE_FAIL
+ || restore.getStateRestore() == JobWorkspaceRestore.RESTORE_SUCCESSFUL)
+ {
+ Thread.sleep(1000);
+ }
+
+ if (restore.getStateRestore() == JobWorkspaceRestore.RESTORE_FAIL)
+ {
+ restore.getRestoreException().printStackTrace();
+ fail(restore.getRestoreException().getMessage());
+ }
+ }
+ }
+ else
+ {
+ fail("There are no backup files in " + backDir.getAbsolutePath());
+ }
+
+ System.out.println(" ============ CHECKING INTEGRITY ============");
+
+ checkIntegrity((NodeImpl)repositoryService.getRepository(REPOSITORY_NAME_SINGLE_DB)
+ .login(credentials, WORKSPACE_NAME)
+ .getRootNode());
+ }
+
+ /**
+ * Test Backup/Restore.
+ *
+ * @throws Exception
+ */
+ public void testBackupRestoreExistingRepositorySingleDB() throws Exception
+ {
+
+ BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
+
+ List<TreeWriterThread> threads = new ArrayList<TreeWriterThread>();
+ List<Session> sessions = new ArrayList<Session>();
+
+ //writers
+ for (int i = 0; i < WRITER_COUNT; i++)
+ {
+ Session writerSession =
+ repositoryService.getRepository(REPOSITORY_NAME_SINGLE_DB).login(credentials, WORKSPACE_NAME);
+ TreeWriterThread writer = new TreeWriterThread(writerSession, "subnode" + i);
+ writer.start();
+ threads.add(writer);
+ sessions.add(writerSession);
+ }
+
+ // backup
+ File backDir = new File("target/backup/db7");
+ backDir.mkdirs();
+ RepositoryBackupChain bch = null;
+
+ backupManagerImpl.start();
+
+ RepositoryBackupConfig config = new RepositoryBackupConfig();
+ config.setRepository(REPOSITORY_NAME_SINGLE_DB);
+ config.setBackupType(BACKUP_TYPE);
+ config.setBackupDir(backDir);
+
+ Thread.sleep(5 * 1000);
+
+ System.out.println(" ============ BACKUP START ============");
+
+ backupManagerImpl.startBackup(config);
+
+ bch = backupManagerImpl.findRepositoryBackup(REPOSITORY_NAME_SINGLE_DB);
+
+ // wait till full backup will be stopped
+ while (bch.getState() != BackupJob.FINISHED)
+ {
+ Thread.yield();
+ Thread.sleep(30);
+ }
+
+ if (bch != null)
+ {
+ backupManagerImpl.stopBackup(bch);
+ }
+
+ System.out.println(" ============ BACKUP FINISHED ============");
+
+ // restore
+ File backLog = new File(bch.getLogFilePath());
+ if (backLog.exists())
+ {
+ RepositoryBackupChainLog bchLog = new RepositoryBackupChainLog(backLog);
+
+ System.out.println(" ============ RESTORE START ============");
+
+ assertNotNull(bchLog.getStartedTime());
+ assertNotNull(bchLog.getFinishedTime());
+
+ backupManagerImpl.restoreExistingRepository(bchLog, repositoryService.getRepository(REPOSITORY_NAME_SINGLE_DB)
+ .getConfiguration(), false);
+
+ JobWorkspaceRestore restore = backupManagerImpl.getLastRestore(REPOSITORY_NAME_SINGLE_DB, WORKSPACE_NAME);
+ if (restore != null)
+ {
+ while (restore.getStateRestore() == JobWorkspaceRestore.RESTORE_FAIL
+ || restore.getStateRestore() == JobWorkspaceRestore.RESTORE_SUCCESSFUL)
+ {
+ Thread.sleep(1000);
+ }
+
+ if (restore.getStateRestore() == JobWorkspaceRestore.RESTORE_FAIL)
+ {
+ restore.getRestoreException().printStackTrace();
+ fail(restore.getRestoreException().getMessage());
+ }
+ }
+ }
+ else
+ {
+ fail("There are no backup files in " + backDir.getAbsolutePath());
+ }
+
+ System.out.println(" ============ CHECKING INTEGRITY ============");
+
+ for (String wsName : repositoryService.getRepository(REPOSITORY_NAME_SINGLE_DB).getWorkspaceNames())
+ {
+ checkIntegrity((NodeImpl)repositoryService.getRepository(REPOSITORY_NAME_SINGLE_DB).login(credentials, wsName)
+ .getRootNode());
+ }
+ }
+
+ /**
+ * Test Backup/Restore.
+ *
+ * @throws Exception
+ */
+ public void testBackupRestoreExistingWorkspaceMultiDB() throws Exception
+ {
+ WorkspaceEntry entry = null;
+ for (WorkspaceEntry en : repositoryService.getRepository(REPOSITORY_NAME_MULTI_DB).getConfiguration()
+ .getWorkspaceEntries())
+ {
+ if (en.getName().equals(WORKSPACE_NAME))
+ {
+ entry = en;
+ break;
+ }
+ }
+
+ BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
+
+ List<TreeWriterThread> threads = new ArrayList<TreeWriterThread>();
+ List<Session> sessions = new ArrayList<Session>();
+
+ //writers
+ for (int i = 0; i < WRITER_COUNT; i++)
+ {
+ Session writerSession =
+ repositoryService.getRepository(REPOSITORY_NAME_MULTI_DB).login(credentials, WORKSPACE_NAME);
+ TreeWriterThread writer = new TreeWriterThread(writerSession, "subnode" + i);
+ writer.start();
+ threads.add(writer);
+ sessions.add(writerSession);
+ }
+
+ // backup
+ File backDir = new File("target/backup/ws1");
+ backDir.mkdirs();
+ BackupChain bch = null;
+
+ backupManagerImpl.start();
+
+ BackupConfig config = new BackupConfig();
+ config.setRepository(REPOSITORY_NAME_MULTI_DB);
+ config.setWorkspace(WORKSPACE_NAME);
+ config.setBackupType(BACKUP_TYPE);
+ config.setBackupDir(backDir);
+
+ Thread.sleep(5 * 1000);
+
+ System.out.println(" ============ BACKUP START ============");
+
+ backupManagerImpl.startBackup(config);
+
+ bch = backupManagerImpl.findBackup(REPOSITORY_NAME_MULTI_DB, WORKSPACE_NAME);
+
+ // wait till full backup will be stopped
+ while (bch.getFullBackupState() != BackupJob.FINISHED)
+ {
+ Thread.yield();
+ Thread.sleep(30);
+ }
+
+ if (bch != null)
+ {
+ backupManagerImpl.stopBackup(bch);
+ }
+ else
+ {
+ fail("Can't get fullBackup chain");
+ }
+
+ System.out.println(" ============ BACKUP FINISHED ============");
+
+ // restore
+ File backLog = new File(bch.getLogFilePath());
+ if (backLog.exists())
+ {
+ BackupChainLog bchLog = new BackupChainLog(backLog);
+
+ System.out.println(" ============ RESTORE START ============");
+
+ assertNotNull(bchLog.getStartedTime());
+ assertNotNull(bchLog.getFinishedTime());
+
+ backupManagerImpl.restoreExistingWorkspace(bchLog, REPOSITORY_NAME_MULTI_DB, entry, false);
+
+ JobWorkspaceRestore restore = backupManagerImpl.getLastRestore(REPOSITORY_NAME_MULTI_DB, WORKSPACE_NAME);
+ if (restore != null)
+ {
+ while (restore.getStateRestore() == JobWorkspaceRestore.RESTORE_FAIL
+ || restore.getStateRestore() == JobWorkspaceRestore.RESTORE_SUCCESSFUL)
+ {
+ Thread.sleep(1000);
+ }
+
+ if (restore.getStateRestore() == JobWorkspaceRestore.RESTORE_FAIL)
+ {
+ restore.getRestoreException().printStackTrace();
+ fail(restore.getRestoreException().getMessage());
+ }
+ }
+ }
+ else
+ {
+ fail("There are no backup files in " + backDir.getAbsolutePath());
+ }
+
+ System.out.println(" ============ CHECKING INTEGRITY ============");
+
+ checkIntegrity((NodeImpl)repositoryService.getRepository(REPOSITORY_NAME_MULTI_DB)
+ .login(credentials, WORKSPACE_NAME)
+ .getRootNode());
+ }
+
+ /**
+ * Test Backup/Restore.
+ *
+ * @throws Exception
+ */
+ public void testBackupRestoreExistingRepositoryMultiDB() throws Exception
+ {
+
+ BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
+
+ List<TreeWriterThread> threads = new ArrayList<TreeWriterThread>();
+ List<Session> sessions = new ArrayList<Session>();
+
+ //writers
+ for (int i = 0; i < WRITER_COUNT; i++)
+ {
+ Session writerSession =
+ repositoryService.getRepository(REPOSITORY_NAME_MULTI_DB).login(credentials, WORKSPACE_NAME);
+ TreeWriterThread writer = new TreeWriterThread(writerSession, "subnode" + i);
+ writer.start();
+ threads.add(writer);
+ sessions.add(writerSession);
+ }
+
+ // backup
+ File backDir = new File("target/backup/db7");
+ backDir.mkdirs();
+ RepositoryBackupChain bch = null;
+
+ backupManagerImpl.start();
+
+ RepositoryBackupConfig config = new RepositoryBackupConfig();
+ config.setRepository(REPOSITORY_NAME_MULTI_DB);
+ config.setBackupType(BACKUP_TYPE);
+ config.setBackupDir(backDir);
+
+ Thread.sleep(5 * 1000);
+
+ System.out.println(" ============ BACKUP START ============");
+
+ backupManagerImpl.startBackup(config);
+
+ bch = backupManagerImpl.findRepositoryBackup(REPOSITORY_NAME_MULTI_DB);
+
+ // wait till full backup will be stopped
+ while (bch.getState() != BackupJob.FINISHED)
+ {
+ Thread.yield();
+ Thread.sleep(30);
+ }
+
+ if (bch != null)
+ {
+ backupManagerImpl.stopBackup(bch);
+ }
+
+ System.out.println(" ============ BACKUP FINISHED ============");
+
+ // restore
+ File backLog = new File(bch.getLogFilePath());
+ if (backLog.exists())
+ {
+ RepositoryBackupChainLog bchLog = new RepositoryBackupChainLog(backLog);
+
+ System.out.println(" ============ RESTORE START ============");
+
+ assertNotNull(bchLog.getStartedTime());
+ assertNotNull(bchLog.getFinishedTime());
+
+ backupManagerImpl.restoreExistingRepository(bchLog, repositoryService.getRepository(REPOSITORY_NAME_MULTI_DB)
+ .getConfiguration(), false);
+
+ JobWorkspaceRestore restore = backupManagerImpl.getLastRestore(REPOSITORY_NAME_MULTI_DB, WORKSPACE_NAME);
+ if (restore != null)
+ {
+ while (restore.getStateRestore() == JobWorkspaceRestore.RESTORE_FAIL
+ || restore.getStateRestore() == JobWorkspaceRestore.RESTORE_SUCCESSFUL)
+ {
+ Thread.sleep(1000);
+ }
+
+ if (restore.getStateRestore() == JobWorkspaceRestore.RESTORE_FAIL)
+ {
+ restore.getRestoreException().printStackTrace();
+ fail(restore.getRestoreException().getMessage());
+ }
+ }
+ }
+ else
+ {
+ fail("There are no backup files in " + backDir.getAbsolutePath());
+ }
+
+ System.out.println(" ============ CHECKING INTEGRITY ============");
+
+ for (String wsName : repositoryService.getRepository(REPOSITORY_NAME_SINGLE_DB).getWorkspaceNames())
+ {
+ checkIntegrity((NodeImpl)repositoryService.getRepository(REPOSITORY_NAME_MULTI_DB).login(credentials, wsName)
+ .getRootNode());
+ }
+ }
+
protected void addChilds(Session session, Node root, int layer) throws Exception
{
if (layer == 4)
@@ -330,39 +764,11 @@
}
}
- public void _testTableLock() throws Exception
- {
- Session writerSession = repositoryService.getRepository(REPOSITORY_NAME).login(credentials, WORKSPACE_NAME);
- // TreeWriterThread writer = new TreeWriterThread(writerSession, "subnode");
- // writer.start();
-
- DataSource ds = (DataSource)new InitialContext().lookup("jdbcjcr_to_repository_restore_singel_db");
- Connection conn = ds.getConnection();
-
- Thread.sleep(2 * 1000);
-
- Statement st = conn.createStatement();
- st.executeQuery("SET PROPERTY \"readonly\" TRUE");
- System.out.println("LOCK TABLES JCR_SITEM WRITE");
- Thread.sleep(5 * 1000);
-
- // st.executeQuery("SET READONLY FALSE");
- // System.out.println("UNLOCK TABLES");
- // Thread.sleep(5 * 1000);
-
- st.close();
- conn.close();
- System.out.println("Con closed");
- Thread.sleep(5 * 1000);
-
- addChilds(writerSession, writerSession.getRootNode(), 0);
- }
-
protected WorkspaceEntry makeWorkspaceEntry(String name, String sourceName) throws LoginException,
NoSuchWorkspaceException, RepositoryException, RepositoryConfigurationException
{
SessionImpl session =
- (SessionImpl)repositoryService.getRepository(REPOSITORY_NAME).login(credentials, WORKSPACE_NAME);
+ (SessionImpl)repositoryService.getRepository(REPOSITORY_NAME_SINGLE_DB).login(credentials, WORKSPACE_NAME);
WorkspaceEntry ws1e = (WorkspaceEntry)session.getContainer().getComponentInstanceOfType(WorkspaceEntry.class);
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgentTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgentTest.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgentTest.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -99,6 +99,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void setUp() throws Exception
{
super.setUp();
@@ -1470,10 +1471,10 @@
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
headers.putSingle("Content-Type", "application/json; charset=UTF-8");
ContainerRequestUserRole creq =
- new ContainerRequestUserRole("POST", new URI(HTTP_BACKUP_AGENT_PATH
- + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "db6" + "/"
- + backupSetPath + "/" + "true"), new URI(""), new ByteArrayInputStream(json.toString()
- .getBytes("UTF-8")), new InputHeadersMap(headers));
+ new ContainerRequestUserRole("POST", new URI(HTTP_BACKUP_AGENT_PATH
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "db6" + "/" + backupSetPath + "/"
+ + "true"), new URI(""), new ByteArrayInputStream(json.toString().getBytes("UTF-8")),
+ new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
ContainerResponse cres = new ContainerResponse(responseWriter);
@@ -3003,6 +3004,7 @@
return sessionRegistry.closeSessions(workspaceName);
}
+ @Override
protected WorkspaceEntry makeWorkspaceEntry(WorkspaceEntry defWEntry, String repoNmae, String wsName,
String sourceName)
{
@@ -3086,6 +3088,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected ExtendedBackupManager getBackupManager()
{
return (ExtendedBackupManager) container.getComponentInstanceOfType(BackupManager.class);
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/TesterRdbmsWorkspaceInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/TesterRdbmsWorkspaceInitializer.java 2011-01-26 16:18:11 UTC (rev 3890)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/TesterRdbmsWorkspaceInitializer.java 2011-01-26 16:19:28 UTC (rev 3891)
@@ -29,8 +29,6 @@
import org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
-import java.io.IOException;
-
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
@@ -58,16 +56,6 @@
accessManager, repositoryService, cleanerHolder);
}
- public void restoreValueFiles() throws RepositoryConfigurationException, IOException
- {
- super.restoreValueStorage();
- }
-
- public void restoreIndexFiles() throws RepositoryConfigurationException, IOException
- {
- super.restoreIndex();
- }
-
@Override
public void fullRdbmsRestore() throws RepositoryException
{
13 years, 3 months
exo-jcr SVN: r3890 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/b and 22 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-01-26 11:18:11 -0500 (Wed, 26 Jan 2011)
New Revision: 3890
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/BackupException.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/Backupable.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/ComplexDataRestor.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/DataRestor.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/DummyDataRestor.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/JCRRestor.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/ResumeException.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/SuspendException.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/Suspendable.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DBBackup.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DBRestor.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DirectoryRestor.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/RestoreTableRule.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/DirectoryHelper.java
Removed:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/RepositoryImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexInfos.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryContainerImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/PrivilegedJBossCacheHelper.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/DataContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceDataContainer.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java
jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-configuration.xml
jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml
jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration.xml
Log:
EXOJCR-1153: Support atomic restore
EXOJCR-1147: Make backup/restore to be cluster aware
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -245,7 +245,7 @@
final boolean isSystem = config.getSystemWorkspaceName().equals(wsConfig.getName());
if (getWorkspaceContainer(wsConfig.getName()) != null)
- throw new RepositoryException("Workspace " + wsConfig.getName() + " already registred");
+ throw new RepositoryException("Workspace " + wsConfig.getName() + " already registered");
WorkspaceContainer workspaceContainer = new WorkspaceContainer(this, wsConfig);
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/BackupException.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/BackupException.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/BackupException.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.backup;
+
+/**
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy Bazko</a>
+ * @version $Id: BackupException.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class BackupException extends Exception
+{
+ /**
+ * Constructor BackupException.
+ *
+ * @param message
+ * the message
+ */
+ public BackupException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Constructor BackupException.
+ *
+ * @param cause
+ * the cause
+ */
+ public BackupException(Throwable cause)
+ {
+ super(cause);
+ }
+
+ /**
+ * Constructor BackupException.
+ *
+ * @param message
+ * the message
+ * @param cause
+ * the cause
+ */
+ public BackupException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/Backupable.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/Backupable.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/Backupable.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.backup;
+
+import java.io.File;
+import java.sql.Connection;
+
+/**
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy Bazko</a>
+ * @version $Id: Backupable.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public interface Backupable
+{
+ /**
+ * Backup data.
+ *
+ * @param storageDir
+ * the directory to store backup
+ * @throws BackupException
+ * if any exception occurred
+ */
+ void backup(File storageDir) throws BackupException;
+
+ /**
+ * Clean data.
+ *
+ * @throws BackupException
+ * if any exception occurred
+ */
+ void clean() throws BackupException;
+
+ /**
+ * Get data restorer to support atomic restore.
+ *
+ * @param storageDir
+ * the directory where backup is stored
+ * @param jdbcConn
+ * the shared connection to database if need, may be null
+ * @throws RestoreException
+ * if any exception occurred
+ */
+ DataRestor getDataRestorer(File storageDir, Connection jdbcConn) throws BackupException;
+
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/ComplexDataRestor.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/ComplexDataRestor.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/ComplexDataRestor.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.backup;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 21 01 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: ComplexDataRestor.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class ComplexDataRestor implements DataRestor
+{
+
+ /**
+ * List of restorers.
+ */
+ private List<DataRestor> restorers = new ArrayList<DataRestor>();
+
+ /**
+ * Constructor ComplexDataRestor.
+ *
+ * @param restorers
+ */
+ public ComplexDataRestor(List<DataRestor> restorers)
+ {
+ this.restorers.addAll(restorers);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clean() throws BackupException
+ {
+ for (DataRestor restorer : restorers)
+ {
+ restorer.clean();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void restore() throws BackupException
+ {
+ for (DataRestor restorer : restorers)
+ {
+ restorer.restore();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void commit() throws BackupException
+ {
+ for (DataRestor restorer : restorers)
+ {
+ restorer.commit();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rollback() throws BackupException
+ {
+ for (DataRestor restorer : restorers)
+ {
+ restorer.rollback();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws BackupException
+ {
+ try
+ {
+ for (DataRestor restorer : restorers)
+ {
+ restorer.close();
+ }
+ }
+ finally
+ {
+ restorers.clear();
+ }
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/DataRestor.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/DataRestor.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/DataRestor.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.backup;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 22 01 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: DataRestor.java.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public interface DataRestor
+{
+
+ /**
+ * Clean old data from the storage.
+ *
+ * @throws RestoreException
+ * if any exception is occurred
+ */
+ void clean() throws BackupException;
+
+ /**
+ * Restore new data into storage.
+ *
+ * @throws RestoreException
+ * if any exception is occurred
+ */
+ void restore() throws BackupException;
+
+ /**
+ * Commit changes.
+ *
+ * @throws RestoreException
+ * if any exception is occurred
+ */
+ void commit() throws BackupException;
+
+ /**
+ * Rollback changes.
+ *
+ * @throws RestoreException
+ * if any exception is occurred
+ */
+ void rollback() throws BackupException;
+
+ /**
+ * Close DataRestor.
+ *
+ * @throws RestoreException
+ * if any exception is occurred
+ */
+ void close() throws BackupException;
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/DummyDataRestor.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/DummyDataRestor.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/DummyDataRestor.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.backup;
+
+/***
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 21 01 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: DummyDataRestor.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class DummyDataRestor implements DataRestor
+{
+ /**
+ * {@inheritDoc}
+ */
+ public void restore() throws BackupException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clean() throws BackupException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void commit() throws BackupException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rollback() throws BackupException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws BackupException
+ {
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/JCRRestor.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/JCRRestor.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/JCRRestor.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.backup;
+
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.commons.utils.PrivilegedSystemHelper;
+import org.exoplatform.services.jcr.dataflow.ChangesLogIterator;
+import org.exoplatform.services.jcr.dataflow.DataManager;
+import org.exoplatform.services.jcr.dataflow.ItemState;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
+import org.exoplatform.services.jcr.dataflow.TransactionChangesLog;
+import org.exoplatform.services.jcr.dataflow.persistent.PersistedPropertyData;
+import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.datamodel.ValueData;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.StreamPersistedValueData;
+import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
+import org.exoplatform.services.jcr.impl.storage.JCRItemExistsException;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.impl.util.io.SpoolFile;
+import org.exoplatform.services.jcr.observation.ExtendedEvent;
+
+import java.io.EOFException;
+import java.io.Externalizable;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 24 01 2011
+ *
+ * Class contains commons method for JCR restore operation.
+ * - get path to full backup<br>
+ * - get list of incremental backup files<br>
+ * - perform incremental restore function<br>
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: JCRRestorerHelper.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class JCRRestor
+{
+
+ private final DataManager dataManager;
+
+ private final FileCleaner fileCleaner;
+
+ private final File tempDir = new File(PrivilegedSystemHelper.getProperty("java.io.tmpdir"));
+
+ public JCRRestor(DataManager dataManager, FileCleaner fileCleaner)
+ {
+ this.dataManager = dataManager;
+ this.fileCleaner = fileCleaner;
+ }
+
+ /**
+ * Returns file with full backup. In case of RDBMS backup
+ * it may be a directory.
+ *
+ * @param restoreDir
+ * @return
+ */
+ public static File getFullBackupFile(File restoreDir)
+ {
+ Pattern p = Pattern.compile(".+\\.0");
+
+ for (File f : PrivilegedFileHelper.listFiles(restoreDir, new FileFilter()
+ {
+ public boolean accept(File pathname)
+ {
+ Pattern p = Pattern.compile(".+\\.[0-9]+");
+ Matcher m = p.matcher(pathname.getName());
+ return m.matches();
+ }
+ }))
+ {
+ Matcher m = p.matcher(f.getName());
+ if (m.matches())
+ {
+ return f;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Get list of incremental backup files.
+ *
+ * @param restoreDir
+ * @return list of files
+ */
+ public static List<File> getIncrementalFiles(File restoreDir)
+ {
+ ArrayList<File> list = new ArrayList<File>();
+
+ Pattern fullBackupPattern = Pattern.compile(".+\\.0");
+
+ for (File f : PrivilegedFileHelper.listFiles(restoreDir, new FileFilter()
+ {
+ public boolean accept(File pathname)
+ {
+ Pattern p = Pattern.compile(".+\\.[0-9]+");
+ Matcher m = p.matcher(pathname.getName());
+ return m.matches();
+ }
+ }))
+ {
+ if (fullBackupPattern.matcher(f.getName()).matches() == false)
+ {
+ list.add(f);
+ }
+ }
+
+ return list;
+ }
+
+ /**
+ * Perform incremental restore operation.
+ *
+ * @param incrementalBackupFile
+ * incremental backup file
+ * @throws FileNotFoundException
+ * @throws IOException
+ * @throws ClassNotFoundException
+ * @throws RepositoryException
+ */
+ public void incrementalRestore(File incrementalBackupFile) throws FileNotFoundException, IOException,
+ ClassNotFoundException, RepositoryException
+ {
+ ObjectInputStream ois = null;
+ try
+ {
+ ois = new ObjectInputStream(PrivilegedFileHelper.fileInputStream(incrementalBackupFile));
+
+ while (true)
+ {
+ TransactionChangesLog changesLog = readExternal(ois);
+ changesLog.setSystemId(Constants.JCR_CORE_RESTORE_WORKSPACE_INITIALIZER_SYSTEM_ID); // mark changes
+
+ ChangesLogIterator cli = changesLog.getLogIterator();
+ while (cli.hasNextLog())
+ {
+ if (cli.nextLog().getEventType() == ExtendedEvent.LOCK)
+ cli.removeLog();
+ }
+
+ saveChangesLog(changesLog);
+ }
+ }
+ catch (EOFException ioe)
+ {
+ // ok - reading all data from backup file;
+ }
+ }
+
+ private void saveChangesLog(TransactionChangesLog changesLog) throws RepositoryException
+ {
+ try
+ {
+ dataManager.save(changesLog);
+ }
+ catch (JCRInvalidItemStateException e)
+ {
+ TransactionChangesLog normalizeChangesLog =
+ getNormalizedChangesLog(e.getIdentifier(), e.getState(), changesLog);
+ if (normalizeChangesLog != null)
+ saveChangesLog(normalizeChangesLog);
+ else
+ throw new RepositoryException(
+ "Collisions found during save of restore changes log, but caused item is not found by ID "
+ + e.getIdentifier() + ". " + e, e);
+ }
+ catch (JCRItemExistsException e)
+ {
+ TransactionChangesLog normalizeChangesLog =
+ getNormalizedChangesLog(e.getIdentifier(), e.getState(), changesLog);
+ if (normalizeChangesLog != null)
+ saveChangesLog(normalizeChangesLog);
+ else
+ throw new RepositoryException(
+ "Collisions found during save of restore changes log, but caused item is not found by ID "
+ + e.getIdentifier() + ". " + e, e);
+ }
+ }
+
+ private TransactionChangesLog getNormalizedChangesLog(String collisionID, int state, TransactionChangesLog changesLog)
+ {
+ ItemState citem = changesLog.getItemState(collisionID);
+
+ if (citem != null)
+ {
+
+ TransactionChangesLog result = new TransactionChangesLog();
+ result.setSystemId(changesLog.getSystemId());
+
+ ChangesLogIterator cli = changesLog.getLogIterator();
+ while (cli.hasNextLog())
+ {
+ ArrayList<ItemState> normalized = new ArrayList<ItemState>();
+ PlainChangesLog next = cli.nextLog();
+ for (ItemState change : next.getAllStates())
+ {
+ if (state == change.getState())
+ {
+ ItemData item = change.getData();
+ // targeted state
+ if (citem.isNode())
+ {
+ // Node... by ID and desc path
+ if (!item.getIdentifier().equals(collisionID)
+ && !item.getQPath().isDescendantOf(citem.getData().getQPath()))
+ normalized.add(change);
+ }
+ else if (!item.getIdentifier().equals(collisionID))
+ {
+ // Property... by ID
+ normalized.add(change);
+ }
+ }
+ else
+ // another state
+ normalized.add(change);
+ }
+
+ PlainChangesLog plog = new PlainChangesLogImpl(normalized, next.getSessionId(), next.getEventType());
+ result.addLog(plog);
+ }
+
+ return result;
+ }
+
+ return null;
+ }
+
+ private TransactionChangesLog readExternal(ObjectInputStream in) throws IOException, ClassNotFoundException
+ {
+ int changesLogType = in.readInt();
+
+ TransactionChangesLog transactionChangesLog = null;
+
+ if (changesLogType == RestoreChangesLog.Type.ItemDataChangesLog_with_Streams)
+ {
+
+ // read ChangesLog
+ transactionChangesLog = (TransactionChangesLog)in.readObject();
+
+ // read FixupStream count
+ int iFixupStream = in.readInt();
+
+ ArrayList<FixupStream> listFixupStreams = new ArrayList<FixupStream>();
+
+ for (int i = 0; i < iFixupStream; i++)
+ {
+ FixupStream fs = new FixupStream();
+ fs.readExternal(in);
+ listFixupStreams.add(fs);
+ }
+
+ // read stream data
+ int iStreamCount = in.readInt();
+ ArrayList<File> listFiles = new ArrayList<File>();
+
+ for (int i = 0; i < iStreamCount; i++)
+ {
+
+ // read file size
+ long fileSize = in.readLong();
+
+ // read content file
+ File contentFile = getAsFile(in, fileSize);
+ listFiles.add(contentFile);
+ }
+
+ RestoreChangesLog restoreChangesLog =
+ new RestoreChangesLog(transactionChangesLog, listFixupStreams, listFiles, fileCleaner);
+
+ restoreChangesLog.restore();
+
+ }
+ else if (changesLogType == RestoreChangesLog.Type.ItemDataChangesLog_without_Streams)
+ {
+ transactionChangesLog = (TransactionChangesLog)in.readObject();
+ }
+
+ return transactionChangesLog;
+ }
+
+ private File getAsFile(ObjectInputStream ois, long fileSize) throws IOException
+ {
+ int bufferSize = 1024 * 8;
+ byte[] buf = new byte[bufferSize];
+
+ File tempFile = SpoolFile.createTempFile("vdincb" + System.currentTimeMillis(), ".stmp", tempDir);
+ FileOutputStream fos = PrivilegedFileHelper.fileOutputStream(tempFile);
+ long readBytes = fileSize;
+
+ while (readBytes > 0)
+ {
+ // long longTemp = readByte - bufferSize;
+ if (readBytes >= bufferSize)
+ {
+ ois.readFully(buf);
+ fos.write(buf);
+ }
+ else if (readBytes < bufferSize)
+ {
+ ois.readFully(buf, 0, (int)readBytes);
+ fos.write(buf, 0, (int)readBytes);
+ }
+ readBytes -= bufferSize;
+ }
+
+ fos.flush();
+ fos.close();
+
+ return tempFile;
+ }
+
+ class RestoreChangesLog
+ {
+ public class Type
+ {
+ public static final int ItemDataChangesLog_without_Streams = 1;
+
+ public static final int ItemDataChangesLog_with_Streams = 2;
+ }
+
+ private TransactionChangesLog itemDataChangesLog;
+
+ private List<FixupStream> listFixupStream;
+
+ private List<File> listFile;
+
+ private FileCleaner fileCleaner;
+
+ public RestoreChangesLog(TransactionChangesLog transactionChangesLog, List<FixupStream> listFixupStreams,
+ List<File> listFiles, FileCleaner fileCleaner)
+ {
+ this.itemDataChangesLog = transactionChangesLog;
+ this.listFixupStream = listFixupStreams;
+ this.listFile = listFiles;
+ this.fileCleaner = fileCleaner;
+ }
+
+ public TransactionChangesLog getItemDataChangesLog()
+ {
+ return itemDataChangesLog;
+ }
+
+ public void restore() throws IOException
+ {
+ List<ItemState> listItemState = itemDataChangesLog.getAllStates();
+ for (int i = 0; i < this.listFixupStream.size(); i++)
+ {
+ ItemState itemState = listItemState.get(listFixupStream.get(i).getItemSateId());
+ ItemData itemData = itemState.getData();
+
+ PersistedPropertyData propertyData = (PersistedPropertyData)itemData;
+ ValueData vd = (propertyData.getValues().get(listFixupStream.get(i).getValueDataId()));
+
+ // re-init the value
+ propertyData.getValues().set(listFixupStream.get(i).getValueDataId(),
+ new StreamPersistedValueData(vd.getOrderNumber(), new SpoolFile(listFile.get(i).getAbsolutePath())));
+ }
+
+ for (int i = 0; i < listFile.size(); i++)
+ fileCleaner.addFile(listFile.get(i));
+ }
+ }
+
+ class FixupStream implements Externalizable
+ {
+ int iItemStateId = -1;
+
+ int iValueDataId = -1;
+
+ public FixupStream()
+ {
+ }
+
+ public FixupStream(int itemState_, int valueData_)
+ {
+ iItemStateId = itemState_;
+ iValueDataId = valueData_;
+ }
+
+ public int getItemSateId()
+ {
+ return iItemStateId;
+ }
+
+ public int getValueDataId()
+ {
+ return iValueDataId;
+ }
+
+ public boolean compare(FixupStream fs)
+ {
+ boolean b = true;
+ if (fs.getItemSateId() != this.getItemSateId())
+ b = false;
+ if (fs.getValueDataId() != this.getValueDataId())
+ b = false;
+ return b;
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+ {
+ iItemStateId = in.readInt();
+ iValueDataId = in.readInt();
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException
+ {
+ out.writeInt(iItemStateId);
+ out.writeInt(iValueDataId);
+ }
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/ResumeException.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/ResumeException.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/ResumeException.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.backup;
+
+/**
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy Bazko</a>
+ * @version $Id: ResumeException.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class ResumeException extends Exception
+{
+ /**
+ * Constructor ResumeException.
+ *
+ * @param cause
+ * the cause
+ */
+ public ResumeException(Throwable cause)
+ {
+ super(cause);
+ }
+
+ /**
+ * Constructor ResumeException.
+ *
+ * @param message
+ * the message
+ */
+ public ResumeException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Constructor ResumeException.
+ *
+ * @param message
+ * the message
+ * @param cause
+ * the cause
+ */
+ public ResumeException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/SuspendException.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/SuspendException.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/SuspendException.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.backup;
+
+/**
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy Bazko</a>
+ * @version $Id: SuspendException.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class SuspendException extends Exception
+{
+ /**
+ * Constructor SuspendException.
+ *
+ * @param cause
+ * the cause
+ */
+ public SuspendException(Throwable cause)
+ {
+ super(cause);
+ }
+
+ /**
+ * Constructor SuspendException.
+ *
+ * @param message
+ * the message
+ */
+ public SuspendException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Constructor SuspendException.
+ *
+ * @param message
+ * the message
+ * @param cause
+ * the cause
+ */
+ public SuspendException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/Suspendable.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/Suspendable.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/Suspendable.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.backup;
+
+/**
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy Bazko</a>
+ * @version $Id: Suspendable.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public interface Suspendable
+{
+
+ /**
+ * Suspend component.
+ *
+ * @throws SuspendException of error occurred
+ */
+ void suspend() throws SuspendException;
+
+ /**
+ * Resume component.
+ *
+ * @throws ResumeException of error occurred
+ */
+ void resume() throws ResumeException;
+
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DBBackup.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DBBackup.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DBBackup.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.backup.rdbms;
+
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectZipWriterImpl;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.zip.ZipEntry;
+
+/**
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy Bazko</a>
+ * @version $Id: DBBackup.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class DBBackup
+{
+ /**
+ * Suffix for content file.
+ */
+ public static final String CONTENT_FILE_SUFFIX = ".dump";
+
+ /**
+ * Suffix for content length file.
+ */
+ public static final String CONTENT_LEN_FILE_SUFFIX = ".len";
+
+ /**
+ * MySQL dialect.
+ */
+ public static final int DB_DIALECT_MYSQL = DBConstants.DB_DIALECT_MYSQL.hashCode();
+
+ /**
+ * MySQL-UTF8 dialect.
+ */
+ public static final int DB_DIALECT_MYSQL_UTF8 = DBConstants.DB_DIALECT_MYSQL_UTF8.hashCode();
+
+ /**
+ * DB2 dialect.
+ */
+ public static final int DB_DIALECT_DB2 = DBConstants.DB_DIALECT_DB2.hashCode();
+
+ /**
+ * DB2V8 dialect.
+ */
+ public static final int DB_DIALECT_DB2V8 = DBConstants.DB_DIALECT_DB2V8.hashCode();
+
+ /**
+ * PGSQL dialect.
+ */
+ public static final int DB_DIALECT_PGSQL = DBConstants.DB_DIALECT_PGSQL.hashCode();
+
+ /**
+ * SYBASE dialect.
+ */
+ public static final int DB_DIALECT_SYBASE = DBConstants.DB_DIALECT_SYBASE.hashCode();
+
+ /**
+ * Backup tables.
+ *
+ * @param storageDir
+ * the directory to store data
+ * @param jdbcConn
+ * the connection to database
+ * @param scripts
+ * map which contains table name and respective SQL query to get data
+ * @throws BackupException
+ * if any exception occurred
+ */
+ public static void backup(File storageDir, Connection jdbcConn, Map<String, String> scripts) throws BackupException
+ {
+ try
+ {
+ for (Entry<String, String> entry : scripts.entrySet())
+ {
+ dumpTable(jdbcConn, entry.getKey(), entry.getValue(), storageDir);
+ }
+ }
+ catch (IOException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (SQLException e)
+ {
+ SQLException next = e.getNextException();
+ String errorTrace = "";
+ while (next != null)
+ {
+ errorTrace += next.getMessage() + "; ";
+ next = next.getNextException();
+ }
+
+ Throwable cause = e.getCause();
+ String msg = "SQL Exception: " + errorTrace + (cause != null ? " (Cause: " + cause.getMessage() + ")" : "");
+
+ throw new BackupException(msg, e);
+ }
+ finally
+ {
+ if (jdbcConn != null)
+ {
+ try
+ {
+ jdbcConn.close();
+ }
+ catch (SQLException e)
+ {
+ throw new BackupException(e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Dump table.
+ *
+ * @throws IOException
+ * @throws SQLException
+ */
+ private static void dumpTable(Connection jdbcConn, String tableName, String script, File storageDir)
+ throws IOException, SQLException
+ {
+ // Need privileges
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
+ }
+
+ ObjectZipWriterImpl contentWriter = null;
+ ObjectZipWriterImpl contentLenWriter = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ {
+ File contentFile = new File(storageDir, tableName + CONTENT_FILE_SUFFIX);
+ contentWriter = new ObjectZipWriterImpl(PrivilegedFileHelper.zipOutputStream(contentFile));
+ contentWriter.putNextEntry(new ZipEntry(tableName));
+
+ File contentLenFile = new File(storageDir, tableName + CONTENT_LEN_FILE_SUFFIX);
+ contentLenWriter = new ObjectZipWriterImpl(PrivilegedFileHelper.zipOutputStream(contentLenFile));
+ contentLenWriter.putNextEntry(new ZipEntry(tableName));
+
+ stmt = jdbcConn.prepareStatement(script);
+ rs = stmt.executeQuery();
+ ResultSetMetaData metaData = rs.getMetaData();
+
+ int columnCount = metaData.getColumnCount();
+ int[] columnType = new int[columnCount];
+
+ contentWriter.writeInt(columnCount);
+ for (int i = 0; i < columnCount; i++)
+ {
+ columnType[i] = metaData.getColumnType(i + 1);
+ contentWriter.writeInt(columnType[i]);
+ contentWriter.writeString(metaData.getColumnName(i + 1));
+ }
+
+ // Now we can output the actual data
+ while (rs.next())
+ {
+ for (int i = 0; i < columnCount; i++)
+ {
+ InputStream value;
+ if (columnType[i] == Types.VARBINARY || columnType[i] == Types.LONGVARBINARY
+ || columnType[i] == Types.BLOB || columnType[i] == Types.BINARY || columnType[i] == Types.OTHER)
+ {
+ value = rs.getBinaryStream(i + 1);
+ }
+ else
+ {
+ String str = rs.getString(i + 1);
+ value = str == null ? null : new ByteArrayInputStream(str.getBytes(Constants.DEFAULT_ENCODING));
+ }
+
+ if (value == null)
+ {
+ contentLenWriter.writeLong(-1);
+ }
+ else
+ {
+ long len = 0;
+ int read = 0;
+ byte[] tmpBuff = new byte[2048];
+
+ while ((read = value.read(tmpBuff)) >= 0)
+ {
+ contentWriter.write(tmpBuff, 0, read);
+ len += read;
+ }
+ contentLenWriter.writeLong(len);
+ }
+ }
+ }
+ }
+ finally
+ {
+ if (contentWriter != null)
+ {
+ contentWriter.closeEntry();
+ contentWriter.close();
+ }
+
+ if (contentLenWriter != null)
+ {
+ contentLenWriter.closeEntry();
+ contentLenWriter.close();
+ }
+
+ if (rs != null)
+ {
+ rs.close();
+ }
+
+ if (stmt != null)
+ {
+ stmt.close();
+ }
+ }
+ }
+
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DBRestor.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DBRestor.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DBRestor.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,661 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.backup.rdbms;
+
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.commons.utils.PrivilegedSystemHelper;
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
+import org.exoplatform.services.jcr.dataflow.serialization.ObjectReader;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.backup.DataRestor;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBClean;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
+import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectZipReaderImpl;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 22 01 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: DBRestor.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class DBRestor implements DataRestor
+{
+ /**
+ * List of temporary files.
+ */
+ private final List<File> spoolFileList = new ArrayList<File>();
+
+ /**
+ * The file cleaner.
+ */
+ private final FileCleaner fileCleaner;
+
+ /**
+ * Temporary directory.
+ */
+ private final File tempDir = new File(PrivilegedSystemHelper.getProperty("java.io.tmpdir"));
+
+ /**
+ * Maximum buffer size.
+ */
+ private final int maxBufferSize;
+
+ /**
+ * Logger.
+ */
+ protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBRestor");
+
+ /**
+ * Connection to database.
+ */
+ private final Connection jdbcConn;
+
+ /**
+ * Directory with tables dump.
+ */
+ private final File storageDir;
+
+ /**
+ * Restore table rules.
+ */
+ private final Map<String, RestoreTableRule> tables;
+
+ /**
+ * Database cleaner.
+ */
+ private final DBClean dbClean;
+
+ /**
+ * Constructor DBRestor.
+ *
+ * @throws NamingException
+ * @throws SQLException
+ * @throws RepositoryConfigurationException
+ */
+ public DBRestor(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
+ WorkspaceEntry wsConfig, FileCleaner fileCleaner) throws NamingException, SQLException,
+ RepositoryConfigurationException
+ {
+ String dsName = wsConfig.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+ if (jdbcConn == null)
+ {
+ final DataSource ds = (DataSource)new InitialContext().lookup(dsName);
+ if (ds == null)
+ {
+ throw new NameNotFoundException("Data source " + dsName + " not found");
+ }
+
+ this.jdbcConn = SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+ {
+ public Connection run() throws Exception
+ {
+ return ds.getConnection();
+
+ }
+ });
+ this.jdbcConn.setAutoCommit(false);
+ }
+ else
+ {
+ this.jdbcConn = jdbcConn;
+ }
+
+ this.fileCleaner = fileCleaner;
+ this.maxBufferSize =
+ wsConfig.getContainer().getParameterInteger(JDBCWorkspaceDataContainer.MAXBUFFERSIZE_PROP,
+ JDBCWorkspaceDataContainer.DEF_MAXBUFFERSIZE);
+
+ this.storageDir = storageDir;
+ this.tables = tables;
+ this.dbClean = DBCleanService.getDBCleaner(this.jdbcConn, wsConfig);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clean() throws BackupException
+ {
+ try
+ {
+ dbClean.clean();
+ }
+ catch (SQLException e)
+ {
+ throw new BackupException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void restore() throws BackupException
+ {
+ Statement st = null;
+
+ try
+ {
+ int dialect = DialectDetecter.detect(jdbcConn.getMetaData()).hashCode();
+
+ for (Entry<String, RestoreTableRule> entry : tables.entrySet())
+ {
+ String tableName = entry.getKey();
+ RestoreTableRule restoreRule = entry.getValue();
+
+ String constraint = null;
+ if (tableName.equals("JCR_SITEM") || tableName.equals("JCR_MITEM"))
+ {
+ if (dialect != DBBackup.DB_DIALECT_MYSQL && dialect != DBBackup.DB_DIALECT_MYSQL_UTF8
+ && dialect != DBBackup.DB_DIALECT_SYBASE)
+ {
+ // resolve constraint name depends on database
+ String constraintName;
+ if (dialect == DBBackup.DB_DIALECT_DB2 || dialect == DBBackup.DB_DIALECT_DB2V8)
+ {
+ constraintName = "JCR_FK_" + (restoreRule.getDstMultiDb() ? "M" : "S") + "ITEM_PAREN";
+ }
+ else
+ {
+ constraintName = "JCR_FK_" + (restoreRule.getDstMultiDb() ? "M" : "S") + "ITEM_PARENT";
+ }
+ constraint =
+ "CONSTRAINT " + constraintName + " FOREIGN KEY(PARENT_ID) REFERENCES " + tableName + "(ID)";
+
+ // drop constraint
+ st = jdbcConn.createStatement();
+ st.execute("ALTER TABLE " + tableName + " DROP CONSTRAINT " + constraintName);
+ }
+ }
+
+ restoreTable(storageDir, jdbcConn, tableName, restoreRule);
+
+ if (constraint != null)
+ {
+ // add constraint
+ st.execute("ALTER TABLE " + tableName + " ADD " + constraint);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (SQLException e)
+ {
+ SQLException next = e.getNextException();
+ String errorTrace = "";
+ while (next != null)
+ {
+ errorTrace += next.getMessage() + "; ";
+ next = next.getNextException();
+ }
+
+ Throwable cause = e.getCause();
+ String msg = "SQL Exception: " + errorTrace + (cause != null ? " (Cause: " + cause.getMessage() + ")" : "");
+
+ throw new BackupException(msg, e);
+ }
+ finally
+ {
+ if (st != null)
+ {
+ try
+ {
+ st.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.warn("Can't close statemnt", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void commit() throws BackupException
+ {
+ try
+ {
+ jdbcConn.commit();
+ }
+ catch (SQLException e)
+ {
+ throw new BackupException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rollback() throws BackupException
+ {
+ try
+ {
+ jdbcConn.rollback();
+ }
+ catch (SQLException e)
+ {
+ throw new BackupException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws BackupException
+ {
+ try
+ {
+ // in case for shared connection
+ if (!jdbcConn.isClosed())
+ {
+ jdbcConn.close();
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new BackupException(e);
+ }
+ }
+
+ /**
+ * Restore table.
+ */
+ private void restoreTable(File storageDir, Connection jdbcConn, String tableName, RestoreTableRule restoreRule)
+ throws IOException, SQLException
+ {
+ // Need privileges
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
+ }
+
+ ObjectZipReaderImpl contentReader = null;
+ ObjectZipReaderImpl contentLenReader = null;
+
+ PreparedStatement insertNode = null;
+ ResultSet tableMetaData = null;
+
+ int dialect = DialectDetecter.detect(jdbcConn.getMetaData()).hashCode();
+
+ // switch table name to lower case
+ if (dialect == DBBackup.DB_DIALECT_PGSQL)
+ {
+ tableName = tableName.toLowerCase();
+ }
+
+ try
+ {
+ contentReader = new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(restoreRule.getContentFile()));
+ contentReader.getNextEntry();
+
+ contentLenReader =
+ new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(restoreRule.getContentLenFile()));
+ contentLenReader.getNextEntry();
+
+ // get information about source table
+ int sourceColumnCount = contentReader.readInt();
+
+ List<Integer> columnType = new ArrayList<Integer>();
+ List<String> columnName = new ArrayList<String>();
+
+ for (int i = 0; i < sourceColumnCount; i++)
+ {
+ columnType.add(contentReader.readInt());
+ columnName.add(contentReader.readString());
+ }
+
+ int targetColumnCount = sourceColumnCount;
+ if (restoreRule.getDeleteColumnIndex() != null)
+ {
+ targetColumnCount--;
+ }
+ else if (restoreRule.getNewColumnIndex() != null)
+ {
+ targetColumnCount++;
+
+ columnType.add(restoreRule.getNewColumnIndex(), restoreRule.getNewColumnType());
+
+ String newColumnName =
+ dialect == DBBackup.DB_DIALECT_PGSQL ? restoreRule.getNewColumnName().toLowerCase() : restoreRule
+ .getNewColumnName();
+ columnName.add(restoreRule.getNewColumnIndex(), newColumnName);
+ }
+
+ // construct statement
+ String names = "";
+ String parameters = "";
+ for (int i = 0; i < targetColumnCount; i++)
+ {
+ if (restoreRule.getSkipColumnIndex() != null && restoreRule.getSkipColumnIndex() == i)
+ {
+ continue;
+ }
+ names += columnName.get(i) + (i == targetColumnCount - 1 ? "" : ",");
+ parameters += "?" + (i == targetColumnCount - 1 ? "" : ",");
+ }
+ insertNode =
+ jdbcConn.prepareStatement("INSERT INTO " + tableName + " (" + names + ") VALUES(" + parameters + ")");
+
+ // set data
+ outer : while (true)
+ {
+ for (int i = 0, targetIndex = 0; i < columnType.size(); i++, targetIndex++)
+ {
+ InputStream stream;
+ long len;
+
+ if (restoreRule.getNewColumnIndex() != null && restoreRule.getNewColumnIndex() == i)
+ {
+ stream =
+ new ByteArrayInputStream(restoreRule.getDstContainerName().getBytes(Constants.DEFAULT_ENCODING));
+ len = ((ByteArrayInputStream)stream).available();
+ }
+ else
+ {
+ try
+ {
+ len = contentLenReader.readLong();
+ }
+ catch (EOFException e)
+ {
+ if (i == 0)
+ {
+ // content length file is empty check content file
+ try
+ {
+ contentReader.readByte();
+ }
+ catch (EOFException e1)
+ {
+ break outer;
+ }
+ }
+
+ throw new IOException("Content length file is empty but content still present", e);
+ }
+ stream = len == -1 ? null : spoolInputStream(contentReader, len);
+ }
+
+ if (restoreRule.getSkipColumnIndex() != null && restoreRule.getSkipColumnIndex() == i)
+ {
+ targetIndex--;
+ continue;
+ }
+ else if (restoreRule.getDeleteColumnIndex() != null && restoreRule.getDeleteColumnIndex() == i)
+ {
+ targetIndex--;
+ continue;
+ }
+
+ // set
+ if (stream != null)
+ {
+ if (restoreRule.getConvertColumnIndex() != null && restoreRule.getConvertColumnIndex().contains(i))
+ {
+ // convert column value
+ ByteArrayInputStream ba = (ByteArrayInputStream)stream;
+ byte[] readBuffer = new byte[ba.available()];
+ ba.read(readBuffer);
+
+ String currentValue = new String(readBuffer, Constants.DEFAULT_ENCODING);
+ if (currentValue.equals(Constants.ROOT_PARENT_UUID))
+ {
+ stream = new ByteArrayInputStream(Constants.ROOT_PARENT_UUID.getBytes());
+ }
+ else
+ {
+ if (restoreRule.getDstMultiDb())
+ {
+ if (!restoreRule.getSrcMultiDb())
+ {
+ stream =
+ new ByteArrayInputStream(new String(readBuffer, Constants.DEFAULT_ENCODING).substring(
+ restoreRule.getSrcContainerName().length()).getBytes());
+ }
+ }
+ else
+ {
+ if (restoreRule.getSrcMultiDb())
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(restoreRule.getDstContainerName());
+ builder.append(currentValue);
+
+ stream = new ByteArrayInputStream(builder.toString().getBytes());
+ }
+ else
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(restoreRule.getDstContainerName());
+ builder.append(new String(readBuffer, Constants.DEFAULT_ENCODING).substring(restoreRule
+ .getSrcContainerName().length()));
+
+ stream = new ByteArrayInputStream(builder.toString().getBytes());
+ }
+ }
+ }
+
+ len = ((ByteArrayInputStream)stream).available();
+ }
+
+ if (columnType.get(i) == Types.INTEGER || columnType.get(i) == Types.BIGINT
+ || columnType.get(i) == Types.SMALLINT || columnType.get(i) == Types.TINYINT)
+ {
+ ByteArrayInputStream ba = (ByteArrayInputStream)stream;
+ byte[] readBuffer = new byte[ba.available()];
+ ba.read(readBuffer);
+
+ String value = new String(readBuffer, Constants.DEFAULT_ENCODING);
+ insertNode.setLong(targetIndex + 1, Integer.parseInt(value));
+ }
+ else if (columnType.get(i) == Types.BIT)
+ {
+ ByteArrayInputStream ba = (ByteArrayInputStream)stream;
+ byte[] readBuffer = new byte[ba.available()];
+ ba.read(readBuffer);
+
+ String value = new String(readBuffer);
+ if (dialect == DBBackup.DB_DIALECT_PGSQL)
+ {
+ insertNode.setBoolean(targetIndex + 1, value.equals("t"));
+ }
+ else
+ {
+ insertNode.setBoolean(targetIndex + 1, value.equals("1"));
+ }
+ }
+ else if (columnType.get(i) == Types.BOOLEAN)
+ {
+ ByteArrayInputStream ba = (ByteArrayInputStream)stream;
+ byte[] readBuffer = new byte[ba.available()];
+ ba.read(readBuffer);
+
+ String value = new String(readBuffer);
+ insertNode.setBoolean(targetIndex + 1, value.equals("true"));
+ }
+ else if (columnType.get(i) == Types.VARBINARY || columnType.get(i) == Types.LONGVARBINARY
+ || columnType.get(i) == Types.BLOB || columnType.get(i) == Types.BINARY
+ || columnType.get(i) == Types.OTHER)
+ {
+ insertNode.setBinaryStream(targetIndex + 1, stream, (int)len);
+ }
+ else
+ {
+ byte[] readBuffer = new byte[(int)len];
+ stream.read(readBuffer);
+
+ insertNode.setString(targetIndex + 1, new String(readBuffer, Constants.DEFAULT_ENCODING));
+ }
+ }
+ else
+ {
+ insertNode.setNull(targetIndex + 1, columnType.get(i));
+ }
+ }
+ insertNode.addBatch();
+ }
+
+ insertNode.executeBatch();
+ }
+ finally
+ {
+ if (contentReader != null)
+ {
+ contentReader.close();
+ }
+
+ if (contentLenReader != null)
+ {
+ contentLenReader.close();
+ }
+
+ if (insertNode != null)
+ {
+ insertNode.close();
+ }
+
+ // delete all temporary files
+ for (File file : spoolFileList)
+ {
+ if (!PrivilegedFileHelper.delete(file))
+ {
+ fileCleaner.addFile(file);
+ }
+ }
+
+ if (tableMetaData != null)
+ {
+ tableMetaData.close();
+ }
+ }
+ }
+
+ /**
+ * Spool input stream.
+ */
+ private InputStream spoolInputStream(ObjectReader in, long contentLen) throws IOException
+ {
+ byte[] buffer = new byte[0];
+ byte[] tmpBuff;
+ long readLen = 0;
+ File sf = null;
+ OutputStream sfout = null;
+
+ try
+ {
+ while (true)
+ {
+ int needToRead = contentLen - readLen > 2048 ? 2048 : (int)(contentLen - readLen);
+ tmpBuff = new byte[needToRead];
+
+ if (needToRead == 0)
+ {
+ break;
+ }
+
+ in.readFully(tmpBuff);
+
+ if (sfout != null)
+ {
+ sfout.write(tmpBuff);
+ }
+ else if (readLen + needToRead > maxBufferSize && fileCleaner != null)
+ {
+ sf = PrivilegedFileHelper.createTempFile("jcrvd", null, tempDir);
+ sfout = PrivilegedFileHelper.fileOutputStream(sf);
+
+ sfout.write(buffer);
+ sfout.write(tmpBuff);
+ buffer = null;
+ }
+ else
+ {
+ // reallocate new buffer and spool old buffer contents
+ byte[] newBuffer = new byte[(int)(readLen + needToRead)];
+ System.arraycopy(buffer, 0, newBuffer, 0, (int)readLen);
+ System.arraycopy(tmpBuff, 0, newBuffer, (int)readLen, needToRead);
+ buffer = newBuffer;
+ }
+
+ readLen += needToRead;
+ }
+
+ if (buffer != null)
+ {
+ return new ByteArrayInputStream(buffer);
+ }
+ else
+ {
+ return PrivilegedFileHelper.fileInputStream(sf);
+ }
+ }
+ finally
+ {
+ if (sfout != null)
+ {
+ sfout.close();
+ }
+
+ if (sf != null)
+ {
+ spoolFileList.add(sf);
+ }
+ }
+ }
+}
+
+
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DirectoryRestor.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DirectoryRestor.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/DirectoryRestor.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.backup.rdbms;
+
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.commons.utils.PrivilegedSystemHelper;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.backup.DataRestor;
+import org.exoplatform.services.jcr.impl.util.io.DirectoryHelper;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy Bazko</a>
+ * @version $Id: DirectoryRestorer.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class DirectoryRestor implements DataRestor
+{
+
+ /**
+ * Logger.
+ */
+ protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DirectoryRestorer");
+
+ /**
+ * The list of directories with actual data.
+ */
+ protected final List<File> dataDirs = new ArrayList<File>();
+
+ /**
+ * The list of directories with backuped data.
+ */
+ protected final List<File> backupDirs = new ArrayList<File>();
+
+ /**
+ * The list of temporary directories.
+ */
+ private final List<File> tmpDirs = new ArrayList<File>();
+
+ /**
+ * Java temporary directory.
+ */
+ protected final File tempDir = new File(PrivilegedSystemHelper.getProperty("java.io.tmpdir"));
+
+ /**
+ * The prefix for temporary directories.
+ */
+ private static final String PREFIX = "fsrestorer";
+
+ /**
+ * Constructor DirectoryRestorer.
+ *
+ * @param dataDirs
+ * @param backupDirs
+ */
+ public DirectoryRestor(List<File> dataDirs, List<File> backupDirs)
+ {
+ this.dataDirs.addAll(dataDirs);
+ this.backupDirs.addAll(backupDirs);
+ }
+
+ /**
+ * Constructor DirectoryRestorer.
+ *
+ * @param dataDir
+ * @param backupDir
+ */
+ public DirectoryRestor(File dataDir, File backupDir)
+ {
+ this.dataDirs.add(dataDir);
+ this.backupDirs.add(backupDir);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clean() throws BackupException
+ {
+ for (File dataDir : dataDirs)
+ {
+ try
+ {
+ File tmpDir = new File(tempDir, PREFIX + System.currentTimeMillis());
+ DirectoryHelper.copyDirectory(dataDir, tmpDir);
+
+ tmpDirs.add(tmpDir);
+
+ DirectoryHelper.removeDirectory(dataDir);
+ }
+ catch (IOException e)
+ {
+ throw new BackupException(e);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void restore() throws BackupException
+ {
+ for (int i = 0; i < backupDirs.size(); i++)
+ {
+ File backupDir = backupDirs.get(i);
+ File dataDir = dataDirs.get(i);
+
+ try
+ {
+ DirectoryHelper.uncompressDirectory(backupDir, dataDir);
+ }
+ catch (IOException e)
+ {
+ throw new BackupException(e);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void commit() throws BackupException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rollback() throws BackupException
+ {
+ for (int i = 0; i < tmpDirs.size(); i++)
+ {
+ try
+ {
+ File tmpDir = tmpDirs.get(i);
+ File dataDir = dataDirs.get(i);
+
+ if (PrivilegedFileHelper.exists(dataDir))
+ {
+ DirectoryHelper.removeDirectory(dataDir);
+ }
+
+ DirectoryHelper.copyDirectory(tmpDir, dataDir);
+ }
+ catch (IOException e)
+ {
+ throw new BackupException(e);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws BackupException
+ {
+ for (File tmpDir : tmpDirs)
+ {
+ try
+ {
+ DirectoryHelper.removeDirectory(tmpDir);
+ }
+ catch (IOException e)
+ {
+ LOG.error("Can't remove temporary directory " + PrivilegedFileHelper.getAbsolutePath(tmpDir), e);
+ }
+ }
+
+ dataDirs.clear();
+ backupDirs.clear();
+ tmpDirs.clear();
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/RestoreTableRule.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/RestoreTableRule.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/b/rdbms/RestoreTableRule.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.backup.rdbms;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy Bazko</a>
+ * @version $Id: RestoreTableRule.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class RestoreTableRule
+{
+ private File contentFile;
+
+ private File contentLenFile;
+
+ private Integer deleteColumnIndex = null;
+
+ private Integer skipColumnIndex = null;
+
+ private Integer newColumnIndex = null;
+
+ private String newColumnName = null;
+
+ private Integer newColumnType = null;
+
+ private Set<Integer> convertColumnIndex = new HashSet<Integer>();
+
+ private String srcContainerName = null;
+
+ private String dstContainerName = null;
+
+ private Boolean srcMultiDb = null;
+
+ private Boolean dstMultiDb = null;
+
+ public File getContentFile()
+ {
+ return contentFile;
+ }
+
+ public void setContentFile(File contentFile)
+ {
+ this.contentFile = contentFile;
+ }
+
+ public File getContentLenFile()
+ {
+ return contentLenFile;
+ }
+
+ public void setContentLenFile(File contentLenFile)
+ {
+ this.contentLenFile = contentLenFile;
+ }
+
+ public Integer getDeleteColumnIndex()
+ {
+ return deleteColumnIndex;
+ }
+
+ public void setDeleteColumnIndex(Integer deleteColumnIndex)
+ {
+ this.deleteColumnIndex = deleteColumnIndex;
+ }
+
+ public Integer getSkipColumnIndex()
+ {
+ return skipColumnIndex;
+ }
+
+ public void setSkipColumnIndex(Integer skipColumnIndex)
+ {
+ this.skipColumnIndex = skipColumnIndex;
+ }
+
+ public Integer getNewColumnIndex()
+ {
+ return newColumnIndex;
+ }
+
+ public void setNewColumnIndex(Integer newColumnIndex)
+ {
+ this.newColumnIndex = newColumnIndex;
+ }
+
+ public Set<Integer> getConvertColumnIndex()
+ {
+ return convertColumnIndex;
+ }
+
+ public void setConvertColumnIndex(Set<Integer> convertColumnIndex)
+ {
+ this.convertColumnIndex = convertColumnIndex;
+ }
+
+ public String getSrcContainerName()
+ {
+ return srcContainerName;
+ }
+
+ public void setSrcContainerName(String srcContainerName)
+ {
+ this.srcContainerName = srcContainerName;
+ }
+
+ public String getDstContainerName()
+ {
+ return dstContainerName;
+ }
+
+ public void setDstContainerName(String dstContainerName)
+ {
+ this.dstContainerName = dstContainerName;
+ }
+
+ public Boolean getSrcMultiDb()
+ {
+ return srcMultiDb;
+ }
+
+ public void setSrcMultiDb(Boolean srcMultiDb)
+ {
+ this.srcMultiDb = srcMultiDb;
+ }
+
+ public Boolean getDstMultiDb()
+ {
+ return dstMultiDb;
+ }
+
+ public void setDstMultiDb(Boolean dstMultiDb)
+ {
+ this.dstMultiDb = dstMultiDb;
+ }
+
+ public String getNewColumnName()
+ {
+ return newColumnName;
+ }
+
+ public void setNewColumnName(String newColumnName)
+ {
+ this.newColumnName = newColumnName;
+ }
+
+ public Integer getNewColumnType()
+ {
+ return newColumnType;
+ }
+
+ public void setNewColumnType(Integer newColumnType)
+ {
+ this.newColumnType = newColumnType;
+ }
+
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.clean.rdbms;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
+import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializer;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The goal of this class is removing workspace data from database.
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: DBClean.java 3769 2011-01-04 15:36:06Z areshetnyak $
+ */
+public class DBClean
+{
+ /**
+ * Logger.
+ */
+ protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBClean");
+
+ /**
+ * Connection to database.
+ */
+ protected final Connection connection;
+
+ /**
+ * Pattern for JCR tables.
+ */
+ protected final Pattern dbObjectNamePattern;
+
+ /**
+ * Common clean scripts for database.
+ */
+ protected final List<String> cleanScripts = new ArrayList<String>();
+
+ /**
+ * DB clean helper.
+ */
+ protected final DBCleanHelper dbCleanHelper;
+
+ /**
+ * WorkspaceDBCleaner constructor.
+ *
+ * @param containerName
+ * container name (workspace name)
+ * @param connection
+ * connection to database where workspace tables is placed
+ */
+ public DBClean(Connection connection, List<String> cleanScripts)
+ {
+ this(connection, cleanScripts, null);
+ }
+
+ /**
+ * WorkspaceDBCleaner constructor.
+ *
+ * @param containerName
+ * container name (workspace name)
+ * @param connection
+ * connection to database where workspace tables is placed
+ * @param dbCleanHelper
+ */
+ public DBClean(Connection connection, List<String> cleanScripts, DBCleanHelper dbCleanHelper)
+ {
+ this.dbObjectNamePattern = Pattern.compile(DBInitializer.SQL_OBJECTNAME, Pattern.CASE_INSENSITIVE);
+ this.connection = connection;
+ this.cleanScripts.addAll(cleanScripts);
+ this.dbCleanHelper = dbCleanHelper;
+ }
+
+ /**
+ * Clean data from database. The method doesn't close connection or perform commit.
+ *
+ * @throws SQLException
+ * if any errors occurred
+ */
+ public void clean() throws SQLException
+ {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
+ }
+
+ String sql = null;
+ Statement st = null;
+ try
+ {
+ st = connection.createStatement();
+ for (String scr : cleanScripts)
+ {
+ String s = cleanWhitespaces(scr.trim());
+ if (s.length() > 0)
+ {
+ if (!canExecuteQuery(sql = s))
+ {
+ // table from query not found, so try drop other
+ continue;
+ }
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Execute script: \n[" + sql + "]");
+ }
+ executeQuery(st, sql);
+ }
+ }
+
+ if (dbCleanHelper != null)
+ {
+ dbCleanHelper.clean();
+ }
+ }
+ finally
+ {
+ if (st != null)
+ {
+ try
+ {
+ st.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close the Statement." + e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Check if we can execute query.
+ * If tables used in query does not exists, we can not execute query.
+ */
+ protected boolean canExecuteQuery(String sql) throws SQLException
+ {
+ Matcher tMatcher = dbObjectNamePattern.matcher(sql);
+ while (tMatcher.find())
+ {
+ // get table name
+ String tableName = sql.substring(tMatcher.start(), tMatcher.end());
+ if (!isTableExists(connection, tableName))
+ {
+ LOG.warn("Table [" + tableName + "] from query [" + sql + "] was not found. So query will not be executed.");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Execute query.
+ */
+ protected void executeQuery(final Statement statement, final String sql) throws SQLException
+ {
+ SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ statement.executeUpdate(sql);
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Indicates if table exists or not.
+ */
+ protected boolean isTableExists(Connection conn, String tableName) throws SQLException
+ {
+ ResultSet trs = conn.getMetaData().getTables(null, null, tableName, null);
+ try
+ {
+ boolean res = false;
+ while (trs.next())
+ {
+ res = true; // check for columns/table type matching etc.
+ }
+ return res;
+ }
+ finally
+ {
+ try
+ {
+ trs.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close the ResultSet: " + e);
+ }
+ }
+ }
+
+ /**
+ * Cleans redundant whitespaces from query.
+ */
+ private String cleanWhitespaces(String string)
+ {
+ if (string != null)
+ {
+ char[] cc = string.toCharArray();
+ for (int ci = cc.length - 1; ci > 0; ci--)
+ {
+ if (Character.isWhitespace(cc[ci]))
+ {
+ cc[ci] = ' ';
+ }
+ }
+ return new String(cc);
+ }
+ return string;
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.clean.rdbms;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ *
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 21.01.2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: DBCleanHelper.java.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class DBCleanHelper
+{
+
+ /**
+ * Logger.
+ */
+ protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBCleanHelper");
+
+ /**
+ * Select items query.
+ */
+ private final String selectItems;
+
+ /**
+ * Remove items query.
+ */
+ private final String removeItems;
+
+ /**
+ * Connection to database.
+ */
+ protected final Connection connection;
+
+ /**
+ * DBCleanerHelper constructor.
+ */
+ public DBCleanHelper(Connection connection, String selectItemds, String removeItems)
+ {
+ this.connection = connection;
+ this.selectItems = selectItemds;
+ this.removeItems = removeItems;
+ }
+
+ /**
+ * Removing rows from table. Some database do not support cascade delete,
+ * or need special sittings. In such case will be used deleting like
+ * visitor does. First traverse to the bottom of the tree and then go up to the root
+ * and perform deleting children.
+ *
+ * @throws SQLException
+ * SQL exception.
+ */
+ public void clean() throws SQLException
+ {
+ recursiveClean(Constants.ROOT_PARENT_UUID);
+ }
+
+ private void recursiveClean(String parentID) throws SQLException
+ {
+ PreparedStatement selectStatement = null;
+ PreparedStatement removeStatement = null;
+ ResultSet result = null;
+
+ try
+ {
+ selectStatement = connection.prepareStatement(this.selectItems);
+ selectStatement.setString(1, parentID);
+
+ final PreparedStatement fSelectStatement = selectStatement;
+ result = (ResultSet)SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ return fSelectStatement.executeQuery();
+ }
+ });
+
+ // recursive traversing to the bottom of the tree
+ if (result.next())
+ {
+ do
+ {
+ recursiveClean(result.getString(1));
+ }
+ while (result.next());
+
+ // go up to the root and remove all nodes
+ removeStatement = connection.prepareStatement(this.removeItems);
+ removeStatement.setString(1, parentID);
+
+ final PreparedStatement fRemoveStatement = removeStatement;
+ SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ fRemoveStatement.executeUpdate();
+ return null;
+ }
+ });
+ }
+ }
+ finally
+ {
+ if (selectStatement != null)
+ {
+ selectStatement.close();
+ }
+
+ if (removeStatement != null)
+ {
+ removeStatement.close();
+ }
+
+ if (result != null)
+ {
+ result.close();
+ }
+ }
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.clean.rdbms;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.RepositoryEntry;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
+
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 24 01 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: DBCleanService.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class DBCleanService
+{
+ /**
+ * Cleans workspace data from database.
+ *
+ * @param wsEntry
+ * workspace configuration
+ * @throws RepositoryConfigurationException
+ * @throws NamingException
+ * @throws SQLException
+ */
+ public static void cleanWorkspaceData(WorkspaceEntry wsEntry) throws RepositoryConfigurationException,
+ NamingException, SQLException
+ {
+ String dsName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+ final DataSource ds = (DataSource)new InitialContext().lookup(dsName);
+ if (ds == null)
+ {
+ throw new NameNotFoundException("Data source " + dsName + " not found");
+ }
+
+ Connection jdbcConn = SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+ {
+ public Connection run() throws Exception
+ {
+ return ds.getConnection();
+
+ }
+ });
+ jdbcConn.setAutoCommit(false);
+
+ try
+ {
+ getDBCleaner(jdbcConn, wsEntry).clean();
+ jdbcConn.commit();
+ }
+ catch (SQLException e)
+ {
+ jdbcConn.rollback();
+ }
+ finally
+ {
+ jdbcConn.close();
+ }
+ }
+
+ /**
+ * Cleans repository data from database.
+ *
+ * @param rEntry
+ * the repository configuration
+ * @throws RepositoryConfigurationException
+ * @throws NamingException
+ * @throws SQLException
+ */
+ public static void cleanRepositoryData(RepositoryEntry rEntry) throws RepositoryConfigurationException,
+ NamingException, SQLException
+ {
+ for (WorkspaceEntry wsEntry : rEntry.getWorkspaceEntries())
+ {
+ cleanWorkspaceData(wsEntry);
+ }
+ }
+
+ /**
+ * Returns database cleaner for manual cleaning.
+ *
+ * @param jdbcConn
+ * database connection which need to use
+ * @param wsEntry
+ * workspace configuration
+ * @return
+ * @throws SQLException
+ * @throws RepositoryConfigurationException
+ */
+ public static DBClean getDBCleaner(Connection jdbcConn, WorkspaceEntry wsEntry) throws SQLException,
+ RepositoryConfigurationException
+ {
+ boolean multiDb =
+ Boolean.parseBoolean(wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.MULTIDB));
+
+ String containerName = wsEntry.getName();
+
+ String dialect = DialectDetecter.detect(jdbcConn.getMetaData());
+
+ List<String> cleanScripts = new ArrayList<String>();
+ if (multiDb)
+ {
+ cleanScripts.add("delete from JCR_MVALUE");
+ cleanScripts.add("delete from JCR_MREF");
+
+ if (dialect.equals(DBConstants.DB_DIALECT_HSQLDB))
+ {
+ cleanScripts.add("delete from JCR_MITEM where I_CLASS=2");
+
+ String selectItems = "select ID from JCR_MITEM where I_CLASS=1 and PARENT_ID=?";
+ String deleteItems = "delete from JCR_MITEM where I_CLASS=1 and PARENT_ID=?";
+
+ return new DBClean(jdbcConn, cleanScripts, new DBCleanHelper(jdbcConn, selectItems, deleteItems));
+ }
+
+ cleanScripts.add("delete from JCR_MITEM where JCR_MITEM.name <> '" + Constants.ROOT_PARENT_NAME + "'");
+ }
+ else
+ {
+ cleanScripts
+ .add("delete from JCR_SVALUE where exists(select * from JCR_SITEM where JCR_SITEM.ID=JCR_SVALUE.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
+ + containerName + "')");
+ cleanScripts
+ .add("delete from JCR_SREF where exists(select * from JCR_SITEM where JCR_SITEM.ID=JCR_SREF.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
+ + containerName + "')");
+
+ if (dialect.equals(DBConstants.DB_DIALECT_HSQLDB))
+ {
+ cleanScripts.add("delete from JCR_SITEM where I_CLASS=2 and CONTAINER_NAME='" + containerName + "'");
+
+ String selectItems =
+ "select ID from JCR_SITEM where I_CLASS=1 and CONTAINER_NAME='" + containerName + "' and PARENT_ID=?";
+ String deleteItems =
+ "delete from JCR_SITEM where I_CLASS=1 and CONTAINER_NAME='" + containerName + "' and PARENT_ID=?";
+
+ return new DBClean(jdbcConn, cleanScripts, new DBCleanHelper(jdbcConn, selectItems, deleteItems));
+ }
+
+ cleanScripts.add("delete from JCR_SITEM where CONTAINER_NAME='" + containerName + "'");
+ }
+
+ if (dialect.equals(DBConstants.DB_DIALECT_PGSQL))
+ {
+ return new PgSQLDBClean(jdbcConn, cleanScripts);
+ }
+ else if (dialect.equals(DBConstants.DB_DIALECT_INGRES))
+ {
+ return new IngresSQLDBClean(jdbcConn, cleanScripts);
+ }
+ else if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+ {
+ return new OracleDBClean(jdbcConn, cleanScripts);
+ }
+ else
+ {
+ return new DBClean(jdbcConn, cleanScripts);
+ }
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.clean.rdbms;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date:
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: IngresSQLDBClean.java 3655 2010-12-10 08:25:41Z tolusha $
+ */
+public class IngresSQLDBClean extends DBClean
+{
+
+ /**
+ * IngresSQLDBClean constructor.
+ */
+ public IngresSQLDBClean(Connection connection, List<String> cleanScripts)
+ {
+ super(connection, cleanScripts);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isTableExists(Connection conn, String tableName) throws SQLException
+ {
+ return super.isTableExists(conn, tableName.toLowerCase());
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.clean.rdbms;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date:
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: OracleDBClean.java 3655 2010-12-10 08:25:41Z tolusha $
+ */
+public class OracleDBClean extends DBClean
+{
+
+ /**
+ * PgSQLDBClean constructor.
+ */
+ public OracleDBClean(Connection connection, List<String> cleanScripts)
+ {
+ super(connection, cleanScripts);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isTableExists(Connection conn, String tableName) throws SQLException
+ {
+ Statement st = null;
+ try
+ {
+ st = conn.createStatement();
+ st.executeUpdate("SELECT 1 FROM " + tableName);
+ return true;
+ }
+ catch (SQLException e)
+ {
+ // check: ORA-00942: table or view does not exist
+ if (e.getMessage().indexOf("ORA-00942") >= 0)
+ return false;
+ throw e;
+ }
+ finally
+ {
+ if (st != null)
+ {
+ try
+ {
+ st.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close the Statement: " + e);
+ }
+ }
+ }
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.clean.rdbms;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date:
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: PgSQLDBClean.java 3655 2010-12-10 08:25:41Z tolusha $
+ */
+public class PgSQLDBClean extends DBClean
+{
+
+ /**
+ * PgSQLDBClean constructor.
+ */
+ public PgSQLDBClean(Connection connection, List<String> cleanScripts)
+ {
+ super(connection, cleanScripts);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isTableExists(Connection conn, String tableName) throws SQLException
+ {
+ return super.isTableExists(conn, tableName.toLowerCase());
+ }
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -23,42 +23,19 @@
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.dataflow.ChangesLogIterator;
-import org.exoplatform.services.jcr.dataflow.ItemState;
import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
-import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
import org.exoplatform.services.jcr.dataflow.TransactionChangesLog;
-import org.exoplatform.services.jcr.dataflow.persistent.PersistedPropertyData;
import org.exoplatform.services.jcr.datamodel.IllegalNameException;
-import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.JCRRestor;
import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
import org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
-import org.exoplatform.services.jcr.impl.dataflow.persistent.StreamPersistedValueData;
-import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
-import org.exoplatform.services.jcr.impl.storage.JCRItemExistsException;
-import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
-import org.exoplatform.services.jcr.impl.util.io.SpoolFile;
-import org.exoplatform.services.jcr.observation.ExtendedEvent;
-import java.io.EOFException;
-import java.io.Externalizable;
import java.io.File;
-import java.io.FileFilter;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutput;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
@@ -78,15 +55,15 @@
public BackupWorkspaceInitializer(WorkspaceEntry config, RepositoryEntry repConfig,
CacheableWorkspaceDataManager dataManager, NamespaceRegistryImpl namespaceRegistry,
LocationFactory locationFactory, NodeTypeManagerImpl nodeTypeManager, ValueFactoryImpl valueFactory,
- AccessManager accessManager, FileCleanerHolder cleanerHolder) throws RepositoryConfigurationException,
- PathNotFoundException, RepositoryException
+ AccessManager accessManager, FileCleanerHolder cleanerHolder) throws RepositoryConfigurationException,
+ PathNotFoundException, RepositoryException
{
super(config, repConfig, dataManager, namespaceRegistry, locationFactory, nodeTypeManager, valueFactory,
accessManager, cleanerHolder);
restoreDir = restorePath;
- String fullBackupPath = getFullBackupPath();
+ String fullBackupPath = PrivilegedFileHelper.getAbsolutePath(JCRRestor.getFullBackupFile(new File(restoreDir)));
if (fullBackupPath == null)
{
@@ -120,7 +97,11 @@
dataManager.save(tLog);
// restore from incremental backup
- incrementalRead();
+ JCRRestor restorer = new JCRRestor(dataManager, fileCleaner);
+ for (File incrBackupFile : JCRRestor.getIncrementalFiles(new File(restoreDir)))
+ {
+ restorer.incrementalRestore(incrBackupFile);
+ }
final NodeData root = (NodeData)dataManager.getItemData(Constants.ROOT_UUID);
@@ -145,367 +126,9 @@
{
throw new RepositoryException(e);
}
- }
-
- protected void incrementalRead() throws RepositoryException
- {
- try
- {
- for (File incrBackupFile : getIncrementalFiles())
- {
- incrementalRestore(incrBackupFile);
- }
- }
- catch (FileNotFoundException e)
- {
- throw new RepositoryException("Restore of incremental backup file error " + e, e);
- }
- catch (IOException e)
- {
- throw new RepositoryException("Restore of incremental backup file I/O error " + e, e);
- }
catch (ClassNotFoundException e)
{
- throw new RepositoryException("Restore of incremental backup error " + e, e);
+ throw new RepositoryException(e);
}
}
-
- private void incrementalRestore(File incrementalBackupFile) throws FileNotFoundException, IOException,
- ClassNotFoundException, RepositoryException
- {
- ObjectInputStream ois = null;
- try
- {
- ois = new ObjectInputStream(PrivilegedFileHelper.fileInputStream(incrementalBackupFile));
-
- while (true)
- {
- TransactionChangesLog changesLog = readExternal(ois);
- changesLog.setSystemId(Constants.JCR_CORE_RESTORE_WORKSPACE_INITIALIZER_SYSTEM_ID); // mark changes
-
- ChangesLogIterator cli = changesLog.getLogIterator();
- while (cli.hasNextLog())
- {
- if (cli.nextLog().getEventType() == ExtendedEvent.LOCK)
- cli.removeLog();
- }
-
- saveChangesLog(changesLog);
- }
- }
- catch (EOFException ioe)
- {
- // ok - reading all data from backup file;
- }
- }
-
- private void saveChangesLog(TransactionChangesLog changesLog) throws RepositoryException
- {
- try
- {
- dataManager.save(changesLog);
- }
- catch (JCRInvalidItemStateException e)
- {
- TransactionChangesLog normalizeChangesLog =
- getNormalizedChangesLog(e.getIdentifier(), e.getState(), changesLog);
- if (normalizeChangesLog != null)
- saveChangesLog(normalizeChangesLog);
- else
- throw new RepositoryException(
- "Collisions found during save of restore changes log, but caused item is not found by ID "
- + e.getIdentifier() + ". " + e, e);
- }
- catch (JCRItemExistsException e)
- {
- TransactionChangesLog normalizeChangesLog =
- getNormalizedChangesLog(e.getIdentifier(), e.getState(), changesLog);
- if (normalizeChangesLog != null)
- saveChangesLog(normalizeChangesLog);
- else
- throw new RepositoryException(
- "Collisions found during save of restore changes log, but caused item is not found by ID "
- + e.getIdentifier() + ". " + e, e);
- }
-
- }
-
- private TransactionChangesLog getNormalizedChangesLog(String collisionID, int state, TransactionChangesLog changesLog)
- {
- ItemState citem = changesLog.getItemState(collisionID);
-
- if (citem != null)
- {
-
- TransactionChangesLog result = new TransactionChangesLog();
- result.setSystemId(changesLog.getSystemId());
-
- ChangesLogIterator cli = changesLog.getLogIterator();
- while (cli.hasNextLog())
- {
- ArrayList<ItemState> normalized = new ArrayList<ItemState>();
- PlainChangesLog next = cli.nextLog();
- for (ItemState change : next.getAllStates())
- {
- if (state == change.getState())
- {
- ItemData item = change.getData();
- // targeted state
- if (citem.isNode())
- {
- // Node... by ID and desc path
- if (!item.getIdentifier().equals(collisionID)
- && !item.getQPath().isDescendantOf(citem.getData().getQPath()))
- normalized.add(change);
- }
- else if (!item.getIdentifier().equals(collisionID))
- {
- // Property... by ID
- normalized.add(change);
- }
- }
- else
- // another state
- normalized.add(change);
- }
-
- PlainChangesLog plog = new PlainChangesLogImpl(normalized, next.getSessionId(), next.getEventType());
- result.addLog(plog);
- }
-
- return result;
- }
-
- return null;
- }
-
- private List<File> getIncrementalFiles()
- {
- ArrayList<File> list = new ArrayList<File>();
-
- File rDir = new File(restoreDir);
- Pattern fullBackupPattern = Pattern.compile(".+\\.0");
-
- for (File f : PrivilegedFileHelper.listFiles(rDir, new BackupFilesFilter()))
- {
- if (fullBackupPattern.matcher(f.getName()).matches() == false)
- {
- list.add(f);
- }
- }
-
- return list;
- }
-
- class BackupFilesFilter implements FileFilter
- {
- public boolean accept(File pathname)
- {
- Pattern p = Pattern.compile(".+\\.[0-9]+");
- Matcher m = p.matcher(pathname.getName());
- return m.matches();
- }
- }
-
- private String getFullBackupPath()
- {
- File rDir = new File(restoreDir);
- Pattern p = Pattern.compile(".+\\.0");
-
- for (File f : PrivilegedFileHelper.listFiles(rDir, new BackupFilesFilter()))
- {
- Matcher m = p.matcher(f.getName());
- if (m.matches())
- {
- return PrivilegedFileHelper.getAbsolutePath(f);
- }
- }
-
- return null;
- }
-
- private TransactionChangesLog readExternal(ObjectInputStream in) throws IOException, ClassNotFoundException
- {
- int changesLogType = in.readInt();
-
- TransactionChangesLog transactionChangesLog = null;
-
- if (changesLogType == RestoreChangesLog.Type.ItemDataChangesLog_with_Streams)
- {
-
- // read ChangesLog
- transactionChangesLog = (TransactionChangesLog)in.readObject();
-
- // read FixupStream count
- int iFixupStream = in.readInt();
-
- ArrayList<FixupStream> listFixupStreams = new ArrayList<FixupStream>();
-
- for (int i = 0; i < iFixupStream; i++)
- {
- FixupStream fs = new FixupStream();
- fs.readExternal(in);
- listFixupStreams.add(fs);
- }
-
- // read stream data
- int iStreamCount = in.readInt();
- ArrayList<File> listFiles = new ArrayList<File>();
-
- for (int i = 0; i < iStreamCount; i++)
- {
-
- // read file size
- long fileSize = in.readLong();
-
- // read content file
- File contentFile = getAsFile(in, fileSize);
- listFiles.add(contentFile);
- }
-
- RestoreChangesLog restoreChangesLog =
- new RestoreChangesLog(transactionChangesLog, listFixupStreams, listFiles, fileCleaner);
-
- restoreChangesLog.restore();
-
- }
- else if (changesLogType == RestoreChangesLog.Type.ItemDataChangesLog_without_Streams)
- {
- transactionChangesLog = (TransactionChangesLog)in.readObject();
- }
-
- return transactionChangesLog;
- }
-
- private File getAsFile(ObjectInputStream ois, long fileSize) throws IOException
- {
- int bufferSize = 1024 * 8;
- byte[] buf = new byte[bufferSize];
-
- File tempFile = SpoolFile.createTempFile("vdincb" + System.currentTimeMillis(), ".stmp", tempDir);
- FileOutputStream fos = PrivilegedFileHelper.fileOutputStream(tempFile);
- long readBytes = fileSize;
-
- while (readBytes > 0)
- {
- // long longTemp = readByte - bufferSize;
- if (readBytes >= bufferSize)
- {
- ois.readFully(buf);
- fos.write(buf);
- }
- else if (readBytes < bufferSize)
- {
- ois.readFully(buf, 0, (int)readBytes);
- fos.write(buf, 0, (int)readBytes);
- }
- readBytes -= bufferSize;
- }
-
- fos.flush();
- fos.close();
-
- return tempFile;
- }
-
- class RestoreChangesLog
- {
- public class Type
- {
- public static final int ItemDataChangesLog_without_Streams = 1;
-
- public static final int ItemDataChangesLog_with_Streams = 2;
- }
-
- private TransactionChangesLog itemDataChangesLog;
-
- private List<FixupStream> listFixupStream;
-
- private List<File> listFile;
-
- private FileCleaner fileCleaner;
-
- public RestoreChangesLog(TransactionChangesLog transactionChangesLog, List<FixupStream> listFixupStreams,
- List<File> listFiles, FileCleaner fileCleaner)
- {
- this.itemDataChangesLog = transactionChangesLog;
- this.listFixupStream = listFixupStreams;
- this.listFile = listFiles;
- this.fileCleaner = fileCleaner;
- }
-
- public TransactionChangesLog getItemDataChangesLog()
- {
- return itemDataChangesLog;
- }
-
- public void restore() throws IOException
- {
- List<ItemState> listItemState = itemDataChangesLog.getAllStates();
- for (int i = 0; i < this.listFixupStream.size(); i++)
- {
- ItemState itemState = listItemState.get(listFixupStream.get(i).getItemSateId());
- ItemData itemData = itemState.getData();
-
- PersistedPropertyData propertyData = (PersistedPropertyData)itemData;
- ValueData vd = (propertyData.getValues().get(listFixupStream.get(i).getValueDataId()));
-
- // re-init the value
- propertyData.getValues().set(listFixupStream.get(i).getValueDataId(),
- new StreamPersistedValueData(vd.getOrderNumber(), new SpoolFile(listFile.get(i).getAbsolutePath())));
- }
-
- for (int i = 0; i < listFile.size(); i++)
- fileCleaner.addFile(listFile.get(i));
- }
- }
-
- class FixupStream implements Externalizable
- {
- int iItemStateId = -1;
-
- int iValueDataId = -1;
-
- public FixupStream()
- {
- }
-
- public FixupStream(int itemState_, int valueData_)
- {
- iItemStateId = itemState_;
- iValueDataId = valueData_;
- }
-
- public int getItemSateId()
- {
- return iItemStateId;
- }
-
- public int getValueDataId()
- {
- return iValueDataId;
- }
-
- public boolean compare(FixupStream fs)
- {
- boolean b = true;
- if (fs.getItemSateId() != this.getItemSateId())
- b = false;
- if (fs.getValueDataId() != this.getValueDataId())
- b = false;
- return b;
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
- {
- iItemStateId = in.readInt();
- iValueDataId = in.readInt();
- }
-
- public void writeExternal(ObjectOutput out) throws IOException
- {
- out.writeInt(iItemStateId);
- out.writeInt(iValueDataId);
- }
- }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/RepositoryImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/RepositoryImpl.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/RepositoryImpl.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -456,21 +456,17 @@
security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
}
- WorkspaceContainer workspaceContainer = null;
- if (isWorkspaceInitialized(workspaceName))
+ WorkspaceContainer workspaceContainer = repositoryContainer.getWorkspaceContainer(workspaceName);
+ try
{
- workspaceContainer = repositoryContainer.getWorkspaceContainer(workspaceName);
- try
- {
- workspaceContainer.stop();
- }
- catch (Exception e)
- {
- throw new RepositoryException(e);
- }
- repositoryContainer.unregisterComponentByInstance(workspaceContainer);
- repositoryContainer.unregisterComponent(workspaceName);
+ workspaceContainer.stop();
}
+ catch (Exception e)
+ {
+ throw new RepositoryException(e);
+ }
+ repositoryContainer.unregisterComponentByInstance(workspaceContainer);
+ repositoryContainer.unregisterComponent(workspaceName);
}
/**
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -16,8 +16,7 @@
*/
package org.exoplatform.services.jcr.impl.core.lock.cacheable;
-import org.exoplatform.commons.utils.PrivilegedSystemHelper;
-import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
import org.exoplatform.management.annotations.Managed;
import org.exoplatform.management.annotations.ManagedDescription;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
@@ -37,6 +36,10 @@
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.backup.Backupable;
+import org.exoplatform.services.jcr.impl.backup.DataRestor;
+import org.exoplatform.services.jcr.impl.backup.rdbms.DBBackup;
import org.exoplatform.services.jcr.impl.core.SessionDataManager;
import org.exoplatform.services.jcr.impl.core.lock.LockRemover;
import org.exoplatform.services.jcr.impl.core.lock.LockRemoverHolder;
@@ -45,44 +48,32 @@
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.BackupException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.CleanException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.DataCleaner;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.RestoreException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.BackupTables;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.RestoreTableRule;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.RestoreTables;
-import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.DBCleaner;
import org.exoplatform.services.jcr.observation.ExtendedEvent;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.IdentityConstants;
+import org.jboss.cache.Cache;
import org.picocontainer.Startable;
+import java.io.BufferedOutputStream;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.security.PrivilegedExceptionAction;
import java.sql.Connection;
-import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.jcr.RepositoryException;
import javax.jcr.lock.LockException;
-import javax.naming.InitialContext;
-import javax.naming.NameNotFoundException;
-import javax.naming.NamingException;
-import javax.sql.DataSource;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
@@ -812,104 +803,182 @@
/**
* {@inheritDoc}
*/
- public void backup(File storageDir) throws BackupException
+ public void clean() throws BackupException
{
- Map<String, String> scripts = new HashMap<String, String>();
- for (String tableName : getTableNames())
- {
- scripts.put(tableName, "SELECT * FROM " + tableName);
- }
-
- BackupTables.backup(storageDir, getDatasourceName(), scripts);
+ cleanCacheDirectly();
}
/**
* {@inheritDoc}
*/
- public void restore(File storageDir) throws RestoreException
+ public void backup(File storageDir) throws BackupException
{
- Map<String, RestoreTableRule> tables = new LinkedHashMap<String, RestoreTableRule>();
- for (String tableName : getTableNames())
+ ObjectOutputStream out = null;
+ try
{
- RestoreTableRule restoreTableRule = new RestoreTableRule();
- restoreTableRule.setSrcContainerName(null);
- restoreTableRule.setSrcMultiDb(null);
- restoreTableRule.setDstContainerName(null);
- restoreTableRule.setDstMultiDb(null);
- restoreTableRule.setSkipColumnIndex(null);
- restoreTableRule.setDeleteColumnIndex(null);
- restoreTableRule.setNewColumnIndex(null);
- restoreTableRule.setConvertColumnIndex(null);
- restoreTableRule.setContentFile(new File(storageDir, tableName + BackupTables.CONTENT_FILE_SUFFIX));
- restoreTableRule.setContentLenFile(new File(storageDir, tableName + BackupTables.CONTENT_LEN_FILE_SUFFIX));
+ File contentFile = new File(storageDir, "CacheLocks" + DBBackup.CONTENT_FILE_SUFFIX);
+ out = new ObjectOutputStream(new BufferedOutputStream(PrivilegedFileHelper.fileOutputStream(contentFile)));
+
+ List<LockData> locks = getLockList();
- tables.put(tableName, restoreTableRule);
+ out.writeInt(locks.size());
+ for (LockData lockData : locks)
+ {
+ lockData.writeExternal(out);
+ }
}
+ catch (FileNotFoundException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (IOException e)
+ {
+ throw new BackupException(e);
+ }
+ finally
+ {
+ if (out != null)
+ {
+ try
+ {
+ out.flush();
+ out.close();
+ }
+ catch (IOException e)
+ {
+ LOG.error("Can't close output stream", e);
+ }
+ }
+ }
+ }
- File tempDir = new File(PrivilegedSystemHelper.getProperty("java.io.tmpdir"));
- int maxBufferSize =
- config.getContainer().getParameterInteger(JDBCWorkspaceDataContainer.MAXBUFFERSIZE_PROP,
- JDBCWorkspaceDataContainer.DEF_MAXBUFFERSIZE);
-
- RestoreTables restoreTable = new RestoreTables(null, tempDir, maxBufferSize);
- restoreTable.restore(storageDir, getDatasourceName(), tables);
- }
-
/**
* {@inheritDoc}
*/
- public DataCleaner getDataCleaner() throws CleanException
+ public DataRestor getDataRestorer(File storageDir, Connection jdbcConn) throws BackupException
{
+ List<LockData> locks = new ArrayList<LockData>();
+
+ ObjectInputStream in = null;
try
{
- String dsName = getDatasourceName();
+ File contentFile = new File(storageDir, "CacheLocks" + DBBackup.CONTENT_FILE_SUFFIX);
+ in = new ObjectInputStream(PrivilegedFileHelper.fileInputStream(contentFile));
- final DataSource ds = (DataSource)new InitialContext().lookup(dsName);
- if (ds == null)
+ int count = in.readInt();
+ for (int i = 0; i < count; i++)
{
- throw new NameNotFoundException("Data source " + dsName + " not found");
+ LockData lockData = new LockData();
+ lockData.readExternal(in);
+
+ locks.add(lockData);
}
-
- Connection jdbcConn =
- SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (IOException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new BackupException(e);
+ }
+ finally
+ {
+ if (in != null)
+ {
+ try
{
- public Connection run() throws Exception
- {
- return ds.getConnection();
+ in.close();
+ }
+ catch (IOException e)
+ {
+ LOG.error("Can't close output stream", e);
+ }
+ }
+ }
- }
- });
+ return new CacheLocksRestor(locks);
+ }
- List<String> cleanScripts = new ArrayList<String>();
- for (String tableName : getTableNames())
+ /**
+ * Cache restorer.
+ */
+ protected class CacheLocksRestor implements DataRestor
+ {
+
+ final private List<LockData> backupLocks = new ArrayList<LockData>();
+
+ private List<LockData> actualLocks;
+
+ CacheLocksRestor(final List<LockData> backupLocks)
+ {
+ this.backupLocks.addAll(backupLocks);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clean() throws BackupException
+ {
+ actualLocks.addAll(getLockList());
+ cleanCacheDirectly();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void restore() throws BackupException
+ {
+ for (LockData lockData : backupLocks)
{
- cleanScripts.add("drop table " + tableName);
+ putDirectly(lockData);
}
+ }
- return new DBCleaner(jdbcConn, cleanScripts);
+ /**
+ * {@inheritDoc}
+ */
+ public void commit() throws BackupException
+ {
}
- catch (SQLException e)
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rollback() throws BackupException
{
- throw new CleanException(e);
+ cleanCacheDirectly();
+ for (LockData lockData : actualLocks)
+ {
+ putDirectly(lockData);
+ }
}
- catch (NamingException e)
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws BackupException
{
- throw new CleanException(e);
+ backupLocks.clear();
+ actualLocks.clear();
}
}
/**
- * Get list of tables names used by CacheableLockManager.
+ * Puts lock data directly into cache.
*
- * @return List
+ * @param lockData
+ * the lock data to put
*/
- protected abstract List<String> getTableNames();
+ protected abstract void putDirectly(LockData lockData);
/**
- * Get data source name used by CacheableLockManager.
- *
- * @return String
+ * Clean cache directly.
*/
- protected abstract String getDatasourceName();
+ protected abstract void cleanCacheDirectly();
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -21,10 +21,8 @@
import org.exoplatform.management.annotations.Managed;
import org.exoplatform.management.jmx.annotations.NameTemplate;
import org.exoplatform.management.jmx.annotations.Property;
-import org.exoplatform.services.jcr.config.LockManagerEntry;
import org.exoplatform.services.jcr.config.MappedParametrizedObjectEntry;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
-import org.exoplatform.services.jcr.config.SimpleParameterEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.impl.core.lock.LockRemoverHolder;
import org.exoplatform.services.jcr.impl.core.lock.cacheable.AbstractCacheableLockManager;
@@ -33,7 +31,6 @@
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
import org.exoplatform.services.jcr.infinispan.ISPNCacheFactory;
import org.exoplatform.services.jcr.infinispan.PrivilegedISPNCacheHelper;
import org.exoplatform.services.log.ExoLogger;
@@ -64,7 +61,7 @@
*/
@Managed
@NameTemplate(@Property(key = "service", value = "lockmanager"))
-public class ISPNCacheableLockManagerImpl extends AbstractCacheableLockManager implements Backupable
+public class ISPNCacheableLockManagerImpl extends AbstractCacheableLockManager
{
/**
@@ -399,48 +396,20 @@
}
/**
- * {@inheritDoc}
- */
+ * {@inheritDoc}
+ */
@Override
- protected List<String> getTableNames()
+ protected void putDirectly(LockData lockData)
{
- List<String> tableNames = new ArrayList<String>();
-
- LockManagerEntry lockManagerEntry = config.getLockManager();
- if (lockManagerEntry != null)
- {
- for (SimpleParameterEntry entry : lockManagerEntry.getParameters())
- {
- if (entry.getName().equals(INFINISPAN_JDBC_TABLE_NAME))
- {
- tableNames.add(entry.getValue());
-
- return tableNames;
- }
- }
- }
-
- return tableNames;
+ PrivilegedISPNCacheHelper.putIfAbsent(cache, lockData.getNodeIdentifier(), lockData);
}
/**
* {@inheritDoc}
*/
@Override
- protected String getDatasourceName()
+ protected void cleanCacheDirectly()
{
- LockManagerEntry lockManagerEntry = config.getLockManager();
- if (lockManagerEntry != null)
- {
- for (SimpleParameterEntry entry : lockManagerEntry.getParameters())
- {
- if (entry.getName().equals(INFINISPAN_JDBC_CL_DATASOURCE))
- {
- return entry.getValue();
- }
- }
- }
-
- return null;
+ cache.clear();
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -20,10 +20,8 @@
import org.exoplatform.management.annotations.Managed;
import org.exoplatform.management.jmx.annotations.NameTemplate;
import org.exoplatform.management.jmx.annotations.Property;
-import org.exoplatform.services.jcr.config.LockManagerEntry;
import org.exoplatform.services.jcr.config.MappedParametrizedObjectEntry;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
-import org.exoplatform.services.jcr.config.SimpleParameterEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.impl.core.lock.LockRemoverHolder;
import org.exoplatform.services.jcr.impl.core.lock.cacheable.AbstractCacheableLockManager;
@@ -165,8 +163,6 @@
{
super(dataManager, config, transactionManager, lockRemoverHolder);
- lockRoot = Fqn.fromElements(LOCKS);
-
// make cache
if (config.getLockManager() != null)
{
@@ -180,6 +176,9 @@
cache = factory.createCache(config.getLockManager());
Fqn<String> rootFqn = Fqn.fromElements(config.getUniqueName());
+
+ lockRoot = Fqn.fromRelativeElements(rootFqn, LOCKS);
+
shareable =
config.getLockManager().getParameterBoolean(JBOSSCACHE_SHAREABLE, JBOSSCACHE_SHAREABLE_DEFAULT)
.booleanValue();
@@ -575,45 +574,22 @@
/**
* {@inheritDoc}
*/
- protected List<String> getTableNames()
+ @Override
+ protected void putDirectly(LockData lockData)
{
- List<String> tableNames = new ArrayList<String>();
+ Fqn<String> lockPath = makeLockFqn(lockData.getNodeIdentifier());
- LockManagerEntry lockManagerEntry = config.getLockManager();
- if (lockManagerEntry != null)
- {
- for (SimpleParameterEntry entry : lockManagerEntry.getParameters())
- {
- if (entry.getName().equals(JBOSSCACHE_JDBC_TABLE_NAME))
- {
- tableNames.add(entry.getValue());
- tableNames.add(entry.getValue() + "_D");
-
- return tableNames;
- }
- }
- }
-
- return tableNames;
+ Node<Serializable, Object> node = cache.getRoot().addChild(lockPath);
+ node.putIfAbsent(LOCK_DATA, lockData);
}
-
+
/**
* {@inheritDoc}
*/
- protected String getDatasourceName()
+ @Override
+ protected void cleanCacheDirectly()
{
- LockManagerEntry lockManagerEntry = config.getLockManager();
- if (lockManagerEntry != null)
- {
- for (SimpleParameterEntry entry : lockManagerEntry.getParameters())
- {
- if (entry.getName().equals(JBOSSCACHE_JDBC_CL_DATASOURCE))
- {
- return entry.getValue();
- }
- }
- }
-
- return null;
+ cache.removeNode(lockRoot);
+ createStructuredNode(lockRoot);
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -74,7 +74,7 @@
*/
protected IndexInfos indexInfos;
- private IndexUpdateMonitor indexUpdateMonitor;
+ protected IndexUpdateMonitor indexUpdateMonitor;
public boolean isInitialized()
{
@@ -209,6 +209,7 @@
*
* @param idleTime the query handler idle time.
*/
+ @Deprecated
public void setIdleTime(String idleTime)
{
log.warn("Parameter 'idleTime' is not supported anymore. "
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -21,6 +21,7 @@
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.WildcardQuery;
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.services.document.DocumentReaderService;
import org.exoplatform.services.jcr.config.QueryHandlerEntry;
@@ -39,6 +40,13 @@
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.backup.Backupable;
+import org.exoplatform.services.jcr.impl.backup.DataRestor;
+import org.exoplatform.services.jcr.impl.backup.ResumeException;
+import org.exoplatform.services.jcr.impl.backup.SuspendException;
+import org.exoplatform.services.jcr.impl.backup.Suspendable;
+import org.exoplatform.services.jcr.impl.backup.rdbms.DirectoryRestor;
import org.exoplatform.services.jcr.impl.core.LocationFactory;
import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
import org.exoplatform.services.jcr.impl.core.SessionDataManager;
@@ -52,17 +60,23 @@
import org.exoplatform.services.jcr.impl.core.value.PathValue;
import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.ResumeException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.SuspendException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Suspendable;
+import org.exoplatform.services.jcr.impl.util.io.DirectoryHelper;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import org.exoplatform.services.rpc.RPCException;
+import org.exoplatform.services.rpc.RPCService;
+import org.exoplatform.services.rpc.RemoteCommand;
+import org.exoplatform.services.rpc.TopologyChangeEvent;
+import org.exoplatform.services.rpc.TopologyChangeListener;
import org.jboss.cache.factories.annotations.NonVolatile;
import org.picocontainer.Startable;
+import java.io.File;
import java.io.IOException;
+import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -89,7 +103,8 @@
* @version $Id: SearchManager.java 1008 2009-12-11 15:14:51Z nzamosenchuk $
*/
@NonVolatile
-public class SearchManager implements Startable, MandatoryItemsPersistenceListener, Suspendable
+public class SearchManager implements Startable, MandatoryItemsPersistenceListener, Suspendable, Backupable,
+ TopologyChangeListener
{
/**
@@ -145,6 +160,36 @@
protected final String wsId;
/**
+ * The service for executing commands on all nodes of cluster.
+ */
+ protected final RPCService rpcService;
+
+ /**
+ * Indicates if component suspended or not.
+ */
+ protected boolean isSuspended = false;
+
+ /**
+ * Indicates that node keep responsible for resuming.
+ */
+ protected Boolean isResponsibleForResuming = false;
+
+ /**
+ * Suspend remote command.
+ */
+ private RemoteCommand suspend;
+
+ /**
+ * Resume remote command.
+ */
+ private RemoteCommand resume;
+
+ /**
+ * Request to all nodes to check if there is someone who responsible for resuming.
+ */
+ private RemoteCommand requestForResponsibleForResuming;
+
+ /**
* Creates a new <code>SearchManager</code>.
*
* @param config
@@ -168,11 +213,47 @@
* @throws RepositoryConfigurationException
*/
- public SearchManager(WorkspaceEntry wsConfig, QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
- WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
+ public SearchManager(WorkspaceEntry wsConfig, QueryHandlerEntry config, NamespaceRegistryImpl nsReg,
+ NodeTypeDataManager ntReg, WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
DocumentReaderService extractor, ConfigurationManager cfm, final RepositoryIndexSearcherHolder indexSearcherHolder)
throws RepositoryException, RepositoryConfigurationException
{
+ this(wsConfig, config, nsReg, ntReg, itemMgr, parentSearchManager, extractor, cfm, indexSearcherHolder, null);
+ }
+
+ /**
+ * Creates a new <code>SearchManager</code>.
+ *
+ * @param config
+ * the search configuration.
+ * @param nsReg
+ * the namespace registry.
+ * @param ntReg
+ * the node type registry.
+ * @param itemMgr
+ * the shared item state manager.
+ * @param rootNodeId
+ * the id of the root node.
+ * @param parentMgr
+ * the parent search manager or <code>null</code> if there is no
+ * parent search manager.
+ * @param excludedNodeId
+ * id of the node that should be excluded from indexing. Any
+ * descendant of that node will also be excluded from indexing.
+ * @param rpcService
+ * the service for executing commands on all nodes of cluster
+ * @throws RepositoryException
+ * if the search manager cannot be initialized
+ * @throws RepositoryConfigurationException
+ */
+
+ public SearchManager(WorkspaceEntry wsConfig, QueryHandlerEntry config, NamespaceRegistryImpl nsReg,
+ NodeTypeDataManager ntReg, WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
+ DocumentReaderService extractor, ConfigurationManager cfm,
+ final RepositoryIndexSearcherHolder indexSearcherHolder, RPCService rpcService) throws RepositoryException,
+ RepositoryConfigurationException
+ {
+ this.rpcService = rpcService;
this.wsId = wsConfig.getUniqueName();
this.extractor = extractor;
indexSearcherHolder.addIndexSearcher(this);
@@ -187,6 +268,11 @@
{
((WorkspacePersistentDataManager)this.itemMgr).addItemPersistenceListener(this);
}
+
+ if (rpcService != null)
+ {
+ doInitRemoteCommands();
+ }
}
public void createNewOrAdd(String key, ItemState state, Map<String, List<ItemState>> updatedNodes)
@@ -459,7 +545,6 @@
indexingTree = new IndexingTree(indexingRootData, excludedPath);
}
initializeQueryHandler();
-
}
catch (RepositoryException e)
{
@@ -578,7 +663,7 @@
{
QueryHandlerContext context =
- new QueryHandlerContext(itemMgr, indexingTree, nodeTypeDataManager, nsReg, parentHandler, getIndexDir(),
+ new QueryHandlerContext(itemMgr, indexingTree, nodeTypeDataManager, nsReg, parentHandler, getIndexDirectory(),
extractor, true, virtualTableResolver);
return context;
}
@@ -862,10 +947,27 @@
*/
public void suspend() throws SuspendException
{
- if (handler instanceof Suspendable)
+ isResponsibleForResuming = true;
+
+ if (rpcService != null)
{
- ((Suspendable)handler).suspend();
+ try
+ {
+ rpcService.executeCommandOnAllNodes(suspend, true);
+ }
+ catch (SecurityException e)
+ {
+ throw new SuspendException(e);
+ }
+ catch (RPCException e)
+ {
+ throw new SuspendException(e);
+ }
}
+ else
+ {
+ suspendLocally();
+ }
}
/**
@@ -873,10 +975,257 @@
*/
public void resume() throws ResumeException
{
+ if (rpcService != null)
+ {
+ try
+ {
+ rpcService.executeCommandOnAllNodes(resume, true);
+ }
+ catch (SecurityException e)
+ {
+ throw new ResumeException(e);
+ }
+ catch (RPCException e)
+ {
+ throw new ResumeException(e);
+ }
+ }
+ else
+ {
+ resumeLocally();
+ }
+
+ isResponsibleForResuming = false;
+ }
+
+ /**
+ * Register remote commands.
+ */
+ private void doInitRemoteCommands()
+ {
+ // register commands
+ suspend = rpcService.registerCommand(new RemoteCommand()
+ {
+
+ public String getId()
+ {
+ return "org.exoplatform.services.jcr.impl.core.query.SearchManager-suspend-" + wsId;
+ }
+
+ public Serializable execute(Serializable[] args) throws Throwable
+ {
+ suspendLocally();
+ return null;
+ }
+ });
+
+ resume = rpcService.registerCommand(new RemoteCommand()
+ {
+
+ public String getId()
+ {
+ return "org.exoplatform.services.jcr.impl.core.query.SearchManager-resume-" + wsId;
+ }
+
+ public Serializable execute(Serializable[] args) throws Throwable
+ {
+ resumeLocally();
+ return null;
+ }
+ });
+
+ requestForResponsibleForResuming = rpcService.registerCommand(new RemoteCommand()
+ {
+
+ public String getId()
+ {
+ return "org.exoplatform.services.jcr.impl.core.query.SearchManager-requestForResponsibilityForResuming-"
+ + wsId;
+ }
+
+ public Serializable execute(Serializable[] args) throws Throwable
+ {
+ return isResponsibleForResuming;
+ }
+ });
+
+ rpcService.registerTopologyChangeListener(this);
+ }
+
+ protected void suspendLocally() throws SuspendException
+ {
+ if (isSuspended)
+ {
+ throw new SuspendException("Component already suspended.");
+ }
+
+ isSuspended = true;
+
+ stop();
+
if (handler instanceof Suspendable)
{
+ ((Suspendable)handler).suspend();
+ }
+ }
+
+ protected void resumeLocally() throws ResumeException
+ {
+ if (!isSuspended)
+ {
+ throw new ResumeException("Component is not suspended.");
+ }
+
+ start();
+
+ if (handler instanceof Suspendable)
+ {
((Suspendable)handler).resume();
}
+
+ isSuspended = false;
}
+ /**
+ * {@inheritDoc}
+ */
+ public void onChange(TopologyChangeEvent event)
+ {
+ if (isSuspended)
+ {
+ new Thread()
+ {
+ @Override
+ public synchronized void run()
+ {
+ try
+ {
+ List<Object> results = rpcService.executeCommandOnAllNodes(requestForResponsibleForResuming, true);
+
+ for (Object result : results)
+ {
+ if ((Boolean)result)
+ {
+ return;
+ }
+ }
+
+ // node which was responsible for resuming leave the cluster, so resume component
+ try
+ {
+ resumeLocally();
+ }
+ catch (ResumeException e)
+ {
+ log.error("Can not resume component", e);
+ }
+ }
+ catch (SecurityException e1)
+ {
+ log.error("You haven't privileges to execute remote command", e1);
+ }
+ catch (RPCException e1)
+ {
+ log.error("Exception during command execution", e1);
+ }
+ }
+ }.start();
+ }
+ }
+
+ /**
+ * {@inheritDoc}}
+ */
+ public void clean() throws BackupException
+ {
+ try
+ {
+ DirectoryHelper.removeDirectory(new File(getIndexDirectory()));
+ }
+ catch (IOException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (RepositoryConfigurationException e)
+ {
+ throw new BackupException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}}
+ */
+ public void backup(File storageDir) throws BackupException
+ {
+ try
+ {
+ File indexDir = new File(getIndexDirectory());
+
+ if (!PrivilegedFileHelper.exists(indexDir))
+ {
+ throw new BackupException("Can't backup index. Directory "
+ + PrivilegedFileHelper.getCanonicalPath(indexDir) + " doesn't exists");
+ }
+ else
+ {
+ File destDir = new File(storageDir, getStorageName());
+ DirectoryHelper.compressDirectory(indexDir, destDir);
+ }
+ }
+ catch (RepositoryConfigurationException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (IOException e)
+ {
+ throw new BackupException(e);
+ }
+ }
+
+ /**
+ * Return index directory.
+ *
+ * @return String
+ * @throws RepositoryConfigurationException
+ */
+ protected String getIndexDirectory() throws RepositoryConfigurationException
+ {
+ return getIndexDir();
+ }
+
+ /**
+ * Returns storage name of index.
+ *
+ * @return String
+ */
+ protected String getStorageName()
+ {
+ return "index";
+ }
+
+ /**
+ * {@inheritDoc}}
+ */
+ public DataRestor getDataRestorer(File storageDir, Connection jdbcConn) throws BackupException
+ {
+ try
+ {
+ File indexDir = new File(getIndexDirectory());
+ File backupDir = new File(storageDir, getStorageName());
+
+ if (!PrivilegedFileHelper.exists(backupDir))
+ {
+ throw new RepositoryConfigurationException("Can't restore index. Directory " + backupDir.getName()
+ + " doesn't exists");
+ }
+ else
+ {
+ return new DirectoryRestor(indexDir, backupDir);
+ }
+ }
+ catch (RepositoryConfigurationException e)
+ {
+ throw new BackupException(e);
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -25,6 +25,7 @@
import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.SuspendException;
import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
import org.exoplatform.services.log.ExoLogger;
@@ -107,8 +108,33 @@
throws RepositoryConfigurationException
{
QueryHandlerContext context =
- new QueryHandlerContext(itemMgr, indexingTree, nodeTypeDataManager, nsReg, parentHandler, getIndexDir() + "_"
- + INDEX_DIR_SUFFIX, extractor, true, virtualTableResolver);
+ new QueryHandlerContext(itemMgr, indexingTree, nodeTypeDataManager, nsReg, parentHandler, getIndexDirectory(),
+ extractor, true, virtualTableResolver);
return context;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getIndexDirectory() throws RepositoryConfigurationException
+ {
+ return getIndexDir() + "_" + INDEX_DIR_SUFFIX;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getStorageName()
+ {
+ return super.getStorageName() + "_" + INDEX_DIR_SUFFIX;
+ }
+
+ @Override
+ protected void suspendLocally() throws SuspendException
+ {
+ super.suspendLocally();
+ isStarted = false;
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexInfos.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexInfos.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexInfos.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -103,8 +103,9 @@
modeHandler.addIndexerIoModeListener(this);
// store parsed FQN to avoid it's parsing each time cache event is generated
namesFqn = Fqn.fromRelativeElements(rootFqn, system ? SYSINDEX_NAMES : INDEX_NAMES);
+
Node<Serializable, Object> cacheRoot = cache.getRoot();
- // prepare cache structures
+
if (!cacheRoot.hasChild(namesFqn))
{
cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
@@ -114,6 +115,7 @@
{
cache.getNode(namesFqn).setResident(true);
}
+
if (modeHandler.getMode() == IndexerIoMode.READ_ONLY)
{
// Currently READ_ONLY is set, so new lists should be fired to multiIndex.
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -87,9 +87,9 @@
// store parsed FQN to avoid it's parsing each time cache event is generated
this.parametersFqn = Fqn.fromRelativeElements(rootFqn, system ? INDEX_PARAMETERS : SYSINDEX_PARAMETERS);
modeHandler.addIndexerIoModeListener(this);
+
Node<Serializable, Object> cacheRoot = cache.getRoot();
- // prepare cache structures
if (!cacheRoot.hasChild(parametersFqn))
{
cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
@@ -112,7 +112,6 @@
Object value = cache.get(parametersFqn, PARAMETER_NAME);
localUpdateInProgress = value != null ? (Boolean)value : false;
}
-
}
/**
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -2576,43 +2576,6 @@
}
/**
- * Suspends multi index: flush volatile index and stop merger.
- *
- * @throws IOException
- */
- protected void suspend() throws IOException
- {
- if (modeHandler.getMode() == IndexerIoMode.READ_WRITE)
- {
- try
- {
- indexUpdateMonitor.setUpdateInProgress(true, true);
- flush();
-
- merger.dispose();
- }
- finally
- {
- indexUpdateMonitor.setUpdateInProgress(false, true);
- }
- }
- }
-
- /**
- * Resume mulit index by starting merger.
- *
- * @throws IOException
- */
- protected void resume() throws IOException
- {
- if (modeHandler.getMode() == IndexerIoMode.READ_WRITE)
- {
- merger = doInitIndexMerger();
- merger.start();
- }
- }
-
- /**
* Refresh list of indexes. Used to be called asynchronously when list changes. New, actual list is read from
* IndexInfos.
* @throws IOException
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -62,9 +62,6 @@
import org.exoplatform.services.jcr.impl.core.query.SearchIndexConfigurationHelper;
import org.exoplatform.services.jcr.impl.core.query.lucene.directory.DirectoryManager;
import org.exoplatform.services.jcr.impl.core.query.lucene.directory.FSDirectoryManager;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.ResumeException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.SuspendException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Suspendable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
@@ -98,7 +95,7 @@
* Implements a {@link org.apache.jackrabbit.core.query.QueryHandler} using
* Lucene.
*/
-public class SearchIndex extends AbstractQueryHandler implements IndexerIoModeListener, Suspendable
+public class SearchIndex extends AbstractQueryHandler implements IndexerIoModeListener
{
private static final DefaultQueryNodeFactory DEFAULT_QUERY_NODE_FACTORY = new DefaultQueryNodeFactory();
@@ -2809,34 +2806,4 @@
log.error("Can not recover error log.", e);
}
}
-
- /**
- * {@inheritDoc}
- */
- public void suspend() throws SuspendException
- {
- try
- {
- index.suspend();
- }
- catch (IOException e)
- {
- throw new SuspendException(e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void resume() throws ResumeException
- {
- try
- {
- index.resume();
- }
- catch (IOException e)
- {
- throw new ResumeException(e);
- }
- }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -31,17 +31,27 @@
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.ResumeException;
+import org.exoplatform.services.jcr.impl.backup.SuspendException;
+import org.exoplatform.services.jcr.impl.backup.Suspendable;
import org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache;
import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
+import org.exoplatform.services.rpc.RPCException;
+import org.exoplatform.services.rpc.RPCService;
+import org.exoplatform.services.rpc.RemoteCommand;
+import org.exoplatform.services.rpc.TopologyChangeEvent;
+import org.exoplatform.services.rpc.TopologyChangeListener;
import org.exoplatform.services.transaction.TransactionService;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.jcr.RepositoryException;
import javax.transaction.TransactionManager;
@@ -55,7 +65,8 @@
*
* @version $Id$
*/
-public class CacheableWorkspaceDataManager extends WorkspacePersistentDataManager
+public class CacheableWorkspaceDataManager extends WorkspacePersistentDataManager implements Suspendable,
+ TopologyChangeListener
{
/**
@@ -71,6 +82,46 @@
private TransactionManager transactionManager;
/**
+ * The service for executing commands on all nodes of cluster.
+ */
+ protected final RPCService rpcService;
+
+ /**
+ * The amount of current working threads.
+ */
+ protected AtomicInteger workingThreads = new AtomicInteger();
+
+ /**
+ * Indicates if component suspended or not.
+ */
+ protected boolean isSuspended = false;
+
+ /**
+ * Allows to make all threads waiting until resume.
+ */
+ protected CountDownLatch latcher = null;
+
+ /**
+ * Indicates that node keep responsible for resuming.
+ */
+ protected Boolean isResponsibleForResuming = false;
+
+ /**
+ * Request to all nodes to check if there is someone who responsible for resuming.
+ */
+ private RemoteCommand requestForResponsibleForResuming;
+
+ /**
+ * Suspend remote command.
+ */
+ private RemoteCommand suspend;
+
+ /**
+ * Resume remote command.
+ */
+ private RemoteCommand resume;
+
+ /**
* ItemData request, used on get operations.
*
*/
@@ -318,18 +369,73 @@
* Items cache
* @param systemDataContainerHolder
* System Workspace data container (persistent level)
+ * @param transactionService
+ * TransactionService
+ * @param rpcService
+ * the service for executing commands on all nodes of cluster
+ */
+ public CacheableWorkspaceDataManager(WorkspaceDataContainer dataContainer, WorkspaceStorageCache cache,
+ SystemDataContainerHolder systemDataContainerHolder, TransactionService transactionService, RPCService rpcService)
+ {
+ super(dataContainer, systemDataContainerHolder);
+ this.cache = cache;
+
+ this.requestCache = new ConcurrentHashMap<Integer, DataRequest>();
+ addItemPersistenceListener(new CacheItemsPersistenceListener());
+
+ transactionManager = transactionService.getTransactionManager();
+
+ this.rpcService = rpcService;
+ doInitRemoteCommands();
+ }
+
+ /**
+ * CacheableWorkspaceDataManager constructor.
+ *
+ * @param dataContainer
+ * Workspace data container (persistent level)
+ * @param cache
+ * Items cache
+ * @param systemDataContainerHolder
+ * System Workspace data container (persistent level)
* @param transactionService TransactionService
*/
public CacheableWorkspaceDataManager(WorkspaceDataContainer dataContainer, WorkspaceStorageCache cache,
SystemDataContainerHolder systemDataContainerHolder, TransactionService transactionService)
{
+ this(dataContainer, cache, systemDataContainerHolder, transactionService, null);
+ }
+
+ /**
+ * CacheableWorkspaceDataManager constructor.
+ *
+ * @param dataContainer
+ * Workspace data container (persistent level)
+ * @param cache
+ * Items cache
+ * @param systemDataContainerHolder
+ * System Workspace data container (persistent level)
+ */
+ public CacheableWorkspaceDataManager(WorkspaceDataContainer dataContainer, WorkspaceStorageCache cache,
+ SystemDataContainerHolder systemDataContainerHolder, RPCService rpcService)
+ {
super(dataContainer, systemDataContainerHolder);
this.cache = cache;
this.requestCache = new ConcurrentHashMap<Integer, DataRequest>();
addItemPersistenceListener(new CacheItemsPersistenceListener());
- transactionManager = transactionService.getTransactionManager();
+ if (cache instanceof JBossCacheWorkspaceStorageCache)
+ {
+ transactionManager = ((JBossCacheWorkspaceStorageCache)cache).getTransactionManager();
+ }
+ else
+ {
+ transactionManager = null;
+ }
+
+ this.rpcService = rpcService;
+ doInitRemoteCommands();
}
/**
@@ -359,6 +465,8 @@
{
transactionManager = null;
}
+
+ this.rpcService = null;
}
/**
@@ -566,19 +674,41 @@
@Override
public void save(final ItemStateChangesLog changesLog) throws RepositoryException
{
- if (isTxAware())
+ if (isSuspended)
{
- // save in dedicated XA transaction
- new SaveInTransaction(changesLog).perform();
+ try
+ {
+ latcher.await();
+ }
+ catch (InterruptedException e)
+ {
+ throw new RepositoryException(e);
+ }
}
- else
+
+ workingThreads.incrementAndGet();
+
+ try
{
- // save normaly
- super.save(changesLog);
+ if (isTxAware())
+ {
+ // save in dedicated XA transaction
+ new SaveInTransaction(changesLog).perform();
+ }
+ else
+ {
- // notify listeners after storage commit
- notifySaveItems(changesLog, false);
+ // save normaly
+ super.save(changesLog);
+
+ // notify listeners after storage commit
+ notifySaveItems(changesLog, false);
+ }
}
+ finally
+ {
+ workingThreads.decrementAndGet();
+ }
}
/**
@@ -961,4 +1091,200 @@
conn.close();
}
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public void suspend() throws SuspendException
+ {
+ isResponsibleForResuming = true;
+
+ if (rpcService != null)
+ {
+ try
+ {
+ rpcService.executeCommandOnAllNodes(suspend, true, null);
+ }
+ catch (SecurityException e)
+ {
+ throw new SuspendException(e);
+ }
+ catch (RPCException e)
+ {
+ throw new SuspendException(e);
+ }
+ }
+ else
+ {
+ suspendLocally();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void resume() throws ResumeException
+ {
+ if (rpcService != null)
+ {
+ try
+ {
+ rpcService.executeCommandOnAllNodes(resume, true, null);
+ }
+ catch (SecurityException e)
+ {
+ throw new ResumeException(e);
+ }
+ catch (RPCException e)
+ {
+ throw new ResumeException(e);
+ }
+ }
+ else
+ {
+ resumeLocally();
+ }
+
+ isResponsibleForResuming = false;
+ }
+
+ private void suspendLocally() throws SuspendException
+ {
+ if (isSuspended)
+ {
+ throw new SuspendException("Component already suspended.");
+ }
+
+ latcher = new CountDownLatch(1);
+ isSuspended = true;
+
+ while (workingThreads.get() != 0)
+ {
+ try
+ {
+ Thread.sleep(50);
+ }
+ catch (InterruptedException e)
+ {
+ throw new SuspendException(e);
+ }
+ }
+ }
+
+ private void resumeLocally() throws ResumeException
+ {
+ if (!isSuspended)
+ {
+ throw new ResumeException("Component is not suspended.");
+ }
+
+ isSuspended = false;
+ latcher.countDown();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void onChange(TopologyChangeEvent event)
+ {
+ if (isSuspended)
+ {
+ new Thread()
+ {
+ @Override
+ public synchronized void run()
+ {
+ try
+ {
+ List<Object> results = rpcService.executeCommandOnAllNodes(requestForResponsibleForResuming, true);
+
+ for (Object result : results)
+ {
+ if ((Boolean)result)
+ {
+ return;
+ }
+ }
+
+ // node which was responsible for resuming leave the cluster, so resume component
+ try
+ {
+ resumeLocally();
+ }
+ catch (ResumeException e)
+ {
+ LOG.error("Can not resume component", e);
+ }
+ }
+ catch (SecurityException e1)
+ {
+ LOG.error("You haven't privileges to execute remote command", e1);
+ }
+ catch (RPCException e1)
+ {
+ LOG.error("Exception during command execution", e1);
+ }
+ }
+ }.start();
+ }
+ }
+
+ /**
+ * Initialization remote commands.
+ */
+ private void doInitRemoteCommands()
+ {
+ if (rpcService != null)
+ {
+ // register commands
+ suspend = rpcService.registerCommand(new RemoteCommand()
+ {
+
+ public String getId()
+ {
+ return "org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager-suspend-"
+ + dataContainer.getUniqueName();
+ }
+
+ public Serializable execute(Serializable[] args) throws Throwable
+ {
+ suspendLocally();
+ return null;
+ }
+ });
+
+ resume = rpcService.registerCommand(new RemoteCommand()
+ {
+
+ public String getId()
+ {
+ return "org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager-resume-"
+ + dataContainer.getUniqueName();
+ }
+
+ public Serializable execute(Serializable[] args) throws Throwable
+ {
+ resumeLocally();
+ return null;
+ }
+ });
+
+ requestForResponsibleForResuming = rpcService.registerCommand(new RemoteCommand()
+ {
+
+ public String getId()
+ {
+ return "org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager-requestForResponsibilityForResuming-"
+ + dataContainer.getUniqueName();
+ }
+
+ public Serializable execute(Serializable[] args) throws Throwable
+ {
+ return isResponsibleForResuming;
+ }
+ });
+
+ rpcService.registerTopologyChangeListener(this);
+ }
+ }
}
\ No newline at end of file
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -42,9 +42,6 @@
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.ResumeException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.SuspendException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Suspendable;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
import org.exoplatform.services.log.ExoLogger;
@@ -58,7 +55,6 @@
import java.util.Iterator;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.jcr.InvalidItemStateException;
import javax.jcr.RepositoryException;
@@ -71,7 +67,7 @@
* @author <a href="mailto:gennady.azarenkov@exoplatform.com">Gennady Azarenkov</a>
* @version $Id$
*/
-public abstract class WorkspacePersistentDataManager implements PersistentDataManager, Suspendable
+public abstract class WorkspacePersistentDataManager implements PersistentDataManager
{
/**
@@ -110,8 +106,6 @@
*/
protected boolean readOnly = false;
- protected ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(true);
-
/**
* WorkspacePersistentDataManager constructor.
*
@@ -136,8 +130,6 @@
*/
public void save(final ItemStateChangesLog changesLog) throws RepositoryException
{
- rwl.readLock().lock();
-
// check if this workspace container is not read-only
if (readOnly && !(changesLog instanceof ReadOnlyThroughChanges))
{
@@ -186,8 +178,6 @@
}
notifySaveItems(persistedLog, true);
-
- rwl.readLock().unlock();
}
class ChangesLogPersister
@@ -841,21 +831,4 @@
{
this.readOnly = status;
}
-
- /**
- * {@inheritDoc}
- */
- public void suspend() throws SuspendException
- {
- rwl.writeLock().lock();
- }
-
- /**
- * {@inheritDoc}
- */
- public void resume() throws ResumeException
- {
- rwl.writeLock().unlock();
- }
-
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -40,6 +40,9 @@
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.backup.Backupable;
+import org.exoplatform.services.jcr.impl.backup.DataRestor;
import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
import org.exoplatform.services.jcr.infinispan.ISPNCacheFactory;
@@ -47,11 +50,11 @@
import org.exoplatform.services.log.Log;
import org.infinispan.Cache;
+import java.io.File;
import java.io.IOException;
import java.io.Serializable;
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -87,7 +90,7 @@
* @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
* @version $Id: ISPNCacheWorkspaceStorageCache.java 3514 2010-11-22 16:14:36Z nzamosenchuk $
*/
-public class ISPNCacheWorkspaceStorageCache implements WorkspaceStorageCache
+public class ISPNCacheWorkspaceStorageCache implements WorkspaceStorageCache, Backupable
{
private static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.ISPNCacheWorkspaceStorageCache");
@@ -1133,4 +1136,65 @@
return null;
}
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public void backup(File storageDir) throws BackupException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clean() throws BackupException
+ {
+ cache.clear();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public DataRestor getDataRestorer(File storageDir, Connection jdbcConn) throws BackupException
+ {
+ return new DataRestor()
+ {
+ /**
+ * {@inheritDoc}
+ */
+ public void clean() throws BackupException
+ {
+ cache.clear();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void restore() throws BackupException
+ {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void commit() throws BackupException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rollback() throws BackupException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws BackupException
+ {
+ }
+ };
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache;
+import org.exoplatform.services.jcr.jbosscache.PrivilegedJBossCacheHelper;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.jboss.cache.Cache;
@@ -988,7 +989,7 @@
public void apply()
{
setCacheLocalMode();
- cache.removeNode(fqn);
+ PrivilegedJBossCacheHelper.removeNode(cache, fqn);
}
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -37,6 +37,9 @@
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.backup.Backupable;
+import org.exoplatform.services.jcr.impl.backup.DataRestor;
import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
import org.exoplatform.services.jcr.jbosscache.ExoJBossCacheFactory;
@@ -47,13 +50,15 @@
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;
+import org.jboss.cache.config.Configuration.CacheMode;
import org.jboss.cache.config.EvictionRegionConfig;
-import org.jboss.cache.config.Configuration.CacheMode;
import org.jboss.cache.eviction.ExpirationAlgorithmConfig;
import org.picocontainer.Startable;
+import java.io.File;
import java.io.IOException;
import java.io.Serializable;
+import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -100,7 +105,7 @@
* @author <a href="mailto:peter.nedonosko@exoplatform.com">Peter Nedonosko</a>
* @version $Id: JBossCacheWorkspaceStorageCache.java 13869 2008-05-05 08:40:10Z pnedonosko $
*/
-public class JBossCacheWorkspaceStorageCache implements WorkspaceStorageCache, Startable
+public class JBossCacheWorkspaceStorageCache implements WorkspaceStorageCache, Startable, Backupable
{
private static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.JBossCacheWorkspaceStorageCache");
@@ -1518,9 +1523,9 @@
}
/**
- * Allows to commit the cache changes in a dedicated XA Tx in order to avoid potential
- * deadlocks
- */
+ * Allows to commit the cache changes in a dedicated XA Tx in order to avoid potential
+ * deadlocks
+ */
private void dedicatedTxCommit()
{
// Ensure that the commit is done in a dedicated tx to avoid deadlock due
@@ -1557,4 +1562,89 @@
}
}
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public void backup(File storageDir) throws BackupException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clean() throws BackupException
+ {
+ cleanCache();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public DataRestor getDataRestorer(File storageDir, Connection jdbcConn) throws BackupException
+ {
+ return new DataRestor()
+ {
+ /**
+ * {@inheritDoc}
+ */
+ public void clean() throws BackupException
+ {
+ cleanCache();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void restore() throws BackupException
+ {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void commit() throws BackupException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rollback() throws BackupException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws BackupException
+ {
+ }
+ };
+ }
+
+ /**
+ * Clean all cache data.
+ */
+ private void cleanCache()
+ {
+ cache.beginTransaction();
+
+ cache.removeNode(itemsRoot);
+ cache.removeNode(refRoot);
+ cache.removeNode(childNodes);
+ cache.removeNode(childProps);
+ cache.removeNode(childNodesList);
+ cache.removeNode(childPropsList);
+
+ cache.commitTransaction();
+
+ createResidentNode(childNodes);
+ createResidentNode(refRoot);
+ createResidentNode(childNodesList);
+ createResidentNode(childProps);
+ createResidentNode(childPropsList);
+ createResidentNode(itemsRoot);
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryContainerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryContainerImpl.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryContainerImpl.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -107,4 +107,12 @@
{
return true;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getUniqueName()
+ {
+ return name;
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -23,26 +23,23 @@
import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.RepositoryEntry;
+import org.exoplatform.services.jcr.config.ValueStorageEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.dataflow.serialization.ObjectReader;
import org.exoplatform.services.jcr.dataflow.serialization.ObjectWriter;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.backup.Backupable;
+import org.exoplatform.services.jcr.impl.backup.ComplexDataRestor;
+import org.exoplatform.services.jcr.impl.backup.DataRestor;
+import org.exoplatform.services.jcr.impl.backup.rdbms.DBBackup;
+import org.exoplatform.services.jcr.impl.backup.rdbms.DBRestor;
+import org.exoplatform.services.jcr.impl.backup.rdbms.DirectoryRestor;
+import org.exoplatform.services.jcr.impl.backup.rdbms.RestoreTableRule;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectReaderImpl;
import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectWriterImpl;
import org.exoplatform.services.jcr.impl.storage.WorkspaceDataContainerBase;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.BackupException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.CleanException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.DataCleaner;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.RestoreException;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.BackupTables;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.RestoreTableRule;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.RestoreTables;
-import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.DBCleanHelper;
-import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.DBCleaner;
-import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.IngresSQLDBCleaner;
-import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.OracleDBCleaner;
-import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.PgSQLDBCleaner;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.GenericConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.HSQLDBConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.MySQLConnectionFactory;
@@ -54,6 +51,8 @@
import org.exoplatform.services.jcr.impl.storage.jdbc.init.StorageDBInitializer;
import org.exoplatform.services.jcr.impl.storage.jdbc.statistics.StatisticsJDBCStorageConnection;
import org.exoplatform.services.jcr.impl.storage.jdbc.update.StorageUpdateManager;
+import org.exoplatform.services.jcr.impl.storage.value.fs.FileValueStorage;
+import org.exoplatform.services.jcr.impl.util.io.DirectoryHelper;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerException;
@@ -136,6 +135,8 @@
protected final String containerName;
+ protected final String uniqueName;
+
protected final String dbSourceName;
protected final boolean multiDb;
@@ -171,6 +172,11 @@
protected boolean useQueryHints;
/**
+ * Workspace configuration.
+ */
+ protected final WorkspaceEntry wsConfig;
+
+ /**
* Shared connection factory.
*
* Issued to share JDBC connection between system and regular workspace in case of same database
@@ -246,7 +252,9 @@
contextInit.recall();
checkIntegrity(wsConfig, repConfig);
+ this.wsConfig = wsConfig;
this.containerName = wsConfig.getName();
+ this.uniqueName = wsConfig.getUniqueName();
this.multiDb = Boolean.parseBoolean(wsConfig.getContainer().getParameterValue(MULTIDB));
this.valueStorageProvider = valueStorageProvider;
@@ -877,6 +885,14 @@
{
return containerName;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getUniqueName()
+ {
+ return uniqueName;
+ }
/**
* {@inheritDoc}
@@ -1014,6 +1030,45 @@
/**
* {@inheritDoc}
*/
+ public void clean() throws BackupException
+ {
+ try
+ {
+ DBCleanService.cleanWorkspaceData(wsConfig);
+
+ if (wsConfig.getContainer().getValueStorages() != null)
+ {
+ for (ValueStorageEntry valueStorage : wsConfig.getContainer().getValueStorages())
+ {
+ File valueStorageDir = new File(valueStorage.getParameterValue(FileValueStorage.PATH));
+ if (PrivilegedFileHelper.exists(valueStorageDir))
+ {
+ DirectoryHelper.removeDirectory(valueStorageDir);
+ }
+ }
+ }
+ }
+ catch (RepositoryConfigurationException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (NamingException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (SQLException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (IOException e)
+ {
+ throw new BackupException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public void backup(File storageDir) throws BackupException
{
ObjectWriter backupInfo = null;
@@ -1051,12 +1106,61 @@
+ containerName + "')");
}
- BackupTables.backup(storageDir, dbSourceName, scripts);
+ final DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
+ if (ds == null)
+ {
+ throw new NameNotFoundException("Data source " + dbSourceName + " not found");
+ }
+
+ Connection jdbcConn =
+ SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+ {
+ public Connection run() throws Exception
+ {
+ return ds.getConnection();
+
+ }
+ });
+
+ DBBackup.backup(storageDir, jdbcConn, scripts);
+
+ // backup value storage
+ if (wsConfig.getContainer().getValueStorages() != null)
+ {
+ for (ValueStorageEntry valueStorage : wsConfig.getContainer().getValueStorages())
+ {
+ File srcDir = new File(valueStorage.getParameterValue(FileValueStorage.PATH));
+ if (!PrivilegedFileHelper.exists(srcDir))
+ {
+ throw new BackupException("Can't backup value storage. Directory " + srcDir.getName()
+ + " doesn't exists");
+ }
+ else
+ {
+ File destValuesDir = new File(storageDir, "values");
+ File destDir = new File(destValuesDir, valueStorage.getId());
+
+ DirectoryHelper.compressDirectory(srcDir, destDir);
+ }
+ }
+ }
}
catch (IOException e)
{
throw new BackupException(e);
}
+ catch (RepositoryConfigurationException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (NamingException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (SQLException e)
+ {
+ throw new BackupException(e);
+ }
finally
{
if (backupInfo != null)
@@ -1076,10 +1180,11 @@
/**
* {@inheritDoc}
*/
- public void restore(File storageDir) throws RestoreException
+ public DataRestor getDataRestorer(File storageDir, Connection jdbcConn) throws BackupException
{
+ List<DataRestor> restorers = new ArrayList<DataRestor>();
+
ObjectReader backupInfo = null;
-
try
{
backupInfo =
@@ -1100,8 +1205,8 @@
restoreTableRule.setSrcMultiDb(srcMultiDb);
restoreTableRule.setDstContainerName(containerName);
restoreTableRule.setDstMultiDb(multiDb);
- restoreTableRule.setContentFile(new File(storageDir, srcTableName + BackupTables.CONTENT_FILE_SUFFIX));
- restoreTableRule.setContentLenFile(new File(storageDir, srcTableName + BackupTables.CONTENT_LEN_FILE_SUFFIX));
+ restoreTableRule.setContentFile(new File(storageDir, srcTableName + DBBackup.CONTENT_FILE_SUFFIX));
+ restoreTableRule.setContentLenFile(new File(storageDir, srcTableName + DBBackup.CONTENT_LEN_FILE_SUFFIX));
if (multiDb)
{
@@ -1153,8 +1258,8 @@
restoreTableRule.setSrcMultiDb(srcMultiDb);
restoreTableRule.setDstContainerName(containerName);
restoreTableRule.setDstMultiDb(multiDb);
- restoreTableRule.setContentFile(new File(storageDir, srcTableName + BackupTables.CONTENT_FILE_SUFFIX));
- restoreTableRule.setContentLenFile(new File(storageDir, srcTableName + BackupTables.CONTENT_LEN_FILE_SUFFIX));
+ restoreTableRule.setContentFile(new File(storageDir, srcTableName + DBBackup.CONTENT_FILE_SUFFIX));
+ restoreTableRule.setContentLenFile(new File(storageDir, srcTableName + DBBackup.CONTENT_LEN_FILE_SUFFIX));
// auto increment ID column
restoreTableRule.setSkipColumnIndex(0);
@@ -1177,8 +1282,8 @@
restoreTableRule.setSrcMultiDb(srcMultiDb);
restoreTableRule.setDstContainerName(containerName);
restoreTableRule.setDstMultiDb(multiDb);
- restoreTableRule.setContentFile(new File(storageDir, srcTableName + BackupTables.CONTENT_FILE_SUFFIX));
- restoreTableRule.setContentLenFile(new File(storageDir, srcTableName + BackupTables.CONTENT_LEN_FILE_SUFFIX));
+ restoreTableRule.setContentFile(new File(storageDir, srcTableName + DBBackup.CONTENT_FILE_SUFFIX));
+ restoreTableRule.setContentLenFile(new File(storageDir, srcTableName + DBBackup.CONTENT_LEN_FILE_SUFFIX));
if (!multiDb || !srcMultiDb)
{
@@ -1189,121 +1294,89 @@
restoreTableRule.setConvertColumnIndex(convertColumnIndex);
}
tables.put(dstTableName, restoreTableRule);
+
+ restorers.add(new DBRestor(storageDir, jdbcConn, tables, wsConfig, swapCleaner));
-
- File tempDir = new File(PrivilegedSystemHelper.getProperty("java.io.tmpdir"));
- RestoreTables restoreTable = new RestoreTables(swapCleaner, tempDir, maxBufferSize);
-
- restoreTable.restore(storageDir, dbSourceName, tables);
- }
- catch (FileNotFoundException e)
- {
- throw new RestoreException(e);
- }
- catch (IOException e)
- {
- throw new RestoreException(e);
- }
- finally
- {
- if (backupInfo != null)
+ // prepare value storage restorer
+ File backupValueStorageDir = new File(storageDir, "values");
+ if (wsConfig.getContainer().getValueStorages() != null)
{
- try
+ List<File> dataDirs = new ArrayList<File>();
+ List<File> backupDirs = new ArrayList<File>();
+
+ List<ValueStorageEntry> valueStorages = wsConfig.getContainer().getValueStorages();
+ String[] valueStoragesFiles = PrivilegedFileHelper.list(backupValueStorageDir);
+
+ if ((valueStoragesFiles == null && valueStorages.size() != 0)
+ || (valueStoragesFiles != null && valueStoragesFiles.length != valueStorages.size()))
{
- backupInfo.close();
+ throw new RepositoryConfigurationException("Workspace configuration [" + wsConfig.getName()
+ + "] has a different amount of value storages than exist in backup");
}
- catch (IOException e)
- {
- throw new RestoreException(e);
- }
- }
- }
- }
- /**
- * {@inheritDoc}
- */
- public DataCleaner getDataCleaner() throws CleanException
- {
- DataCleaner dbCleaner;
-
- try
- {
- final DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds == null)
- {
- throw new NameNotFoundException("Data source " + dbSourceName + " not found");
- }
-
- Connection jdbcConn =
- SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+ for (ValueStorageEntry valueStorage : valueStorages)
{
- public Connection run() throws Exception
+ File backupDir = new File(backupValueStorageDir, valueStorage.getId());
+ if (!PrivilegedFileHelper.exists(backupDir))
{
- return ds.getConnection();
+ throw new RepositoryConfigurationException("Can't restore value storage. Directory "
+ + backupDir.getName() + " doesn't exists");
+ }
+ else
+ {
+ File dataDir = new File(valueStorage.getParameterValue(FileValueStorage.PATH));
+ dataDirs.add(dataDir);
+ backupDirs.add(backupDir);
}
- });
+ }
- String dialect = DialectDetecter.detect(jdbcConn.getMetaData());
-
- List<String> cleanScripts = new ArrayList<String>();
- if (multiDb)
- {
- cleanScripts.add("drop table JCR_MREF");
- cleanScripts.add("drop table JCR_MVALUE");
- cleanScripts.add("drop table JCR_MITEM");
+ restorers.add(new DirectoryRestor(dataDirs, backupDirs));
}
else
{
- cleanScripts
- .add("delete from JCR_SVALUE where exists(select * from JCR_SITEM where JCR_SITEM.ID=JCR_SVALUE.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
- + containerName + "')");
- cleanScripts
- .add("delete from JCR_SREF where exists(select * from JCR_SITEM where JCR_SITEM.ID=JCR_SREF.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
- + containerName + "')");
- }
-
- if (!multiDb && dialect.equals(DBConstants.DB_DIALECT_HSQLDB))
- {
- cleanScripts.add("delete from JCR_SITEM where I_CLASS=2 and CONTAINER_NAME='" + containerName + "'");
-
- dbCleaner = new DBCleaner(jdbcConn, cleanScripts, new DBCleanHelper(containerName, jdbcConn));
- }
- else
- {
- if (!multiDb)
+ if (PrivilegedFileHelper.exists(backupValueStorageDir))
{
- cleanScripts.add("delete from JCR_SITEM where CONTAINER_NAME='" + containerName + "'");
+ throw new RepositoryConfigurationException("Value storage didn't configure in workspace ["
+ + wsConfig.getName() + "] configuration but value storage backup files exist");
}
-
- if (dialect.equals(DBConstants.DB_DIALECT_PGSQL))
- {
- dbCleaner = new PgSQLDBCleaner(jdbcConn, cleanScripts);
- }
- else if (dialect.equals(DBConstants.DB_DIALECT_INGRES))
- {
- dbCleaner = new IngresSQLDBCleaner(jdbcConn, cleanScripts);
- }
- else if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
- {
- dbCleaner = new OracleDBCleaner(jdbcConn, cleanScripts);
- }
- else
- {
- dbCleaner = new DBCleaner(jdbcConn, cleanScripts);
- }
}
- return dbCleaner;
+ return new ComplexDataRestor(restorers);
}
+ catch (FileNotFoundException e)
+ {
+ throw new BackupException(e);
+ }
+ catch (IOException e)
+ {
+ throw new BackupException(e);
+ }
catch (NamingException e)
{
- throw new CleanException(e);
+ throw new BackupException(e);
}
catch (SQLException e)
{
- throw new CleanException(e);
+ throw new BackupException(e);
}
+ catch (RepositoryConfigurationException e)
+ {
+ throw new BackupException(e);
+ }
+ finally
+ {
+ if (backupInfo != null)
+ {
+ try
+ {
+ backupInfo.close();
+ }
+ catch (IOException e)
+ {
+ LOG.error("Can't close object reader", e);
+ }
+ }
+ }
}
}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/DirectoryHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/DirectoryHelper.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/DirectoryHelper.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.util.io;
+
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Helper contains method to perform operations with not empty directory.
+ *
+ * Date: 25 01 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: FSDirectory.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class DirectoryHelper
+{
+
+ /**
+ * Copy directory.
+ *
+ * @param srcPath
+ * source path
+ * @param dstPath
+ * destination path
+ * @throws IOException
+ * if any exception occurred
+ */
+ public static void copyDirectory(File srcPath, File dstPath) throws IOException
+ {
+ if (PrivilegedFileHelper.isDirectory(srcPath))
+ {
+ if (!PrivilegedFileHelper.exists(dstPath))
+ {
+ PrivilegedFileHelper.mkdirs(dstPath);
+ }
+
+ String files[] = PrivilegedFileHelper.list(srcPath);
+ for (int i = 0; i < files.length; i++)
+ {
+ copyDirectory(new File(srcPath, files[i]), new File(dstPath, files[i]));
+ }
+ }
+ else
+ {
+ InputStream in = null;
+ OutputStream out = null;
+
+ try
+ {
+ in = PrivilegedFileHelper.fileInputStream(srcPath);
+ out = PrivilegedFileHelper.fileOutputStream(dstPath);
+
+ // Transfer bytes from in to out
+ byte[] buf = new byte[2048];
+
+ int len;
+
+ while ((len = in.read(buf)) > 0)
+ {
+ out.write(buf, 0, len);
+ }
+ }
+ finally
+ {
+ if (in != null)
+ {
+ in.close();
+ }
+
+ if (out != null)
+ {
+ out.flush();
+ out.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * Remove directory.
+ *
+ * @param dir
+ * directory to remove
+ * @throws IOException
+ * if any exception occurred
+ */
+ public static void removeDirectory(File dir) throws IOException
+ {
+ if (PrivilegedFileHelper.isDirectory(dir))
+ {
+ for (File subFile : PrivilegedFileHelper.listFiles(dir))
+ {
+ removeDirectory(subFile);
+ }
+
+ if (!PrivilegedFileHelper.delete(dir))
+ {
+ throw new IOException("Can't remove folder : " + PrivilegedFileHelper.getCanonicalPath(dir));
+ }
+ }
+ else
+ {
+ if (!PrivilegedFileHelper.delete(dir))
+ {
+ throw new IOException("Can't remove file : " + PrivilegedFileHelper.getCanonicalPath(dir));
+ }
+ }
+ }
+
+ /**
+ * Compress directory.
+ *
+ * @param srcPath
+ * source path
+ * @param dstPath
+ * destination path
+ * @throws IOException
+ * if any exception occurred
+ */
+ public static void compressDirectory(File srcPath, File dstPath) throws IOException
+ {
+ if (PrivilegedFileHelper.isDirectory(srcPath))
+ {
+ if (!PrivilegedFileHelper.exists(dstPath))
+ {
+ PrivilegedFileHelper.mkdirs(dstPath);
+ }
+
+ String files[] = PrivilegedFileHelper.list(srcPath);
+ for (int i = 0; i < files.length; i++)
+ {
+ compressDirectory(new File(srcPath, files[i]), new File(dstPath, files[i]));
+ }
+ }
+ else
+ {
+ InputStream in = null;
+ ZipOutputStream out = null;
+
+ try
+ {
+ in = PrivilegedFileHelper.fileInputStream(srcPath);
+ out = PrivilegedFileHelper.zipOutputStream(dstPath);
+ out.putNextEntry(new ZipEntry(srcPath.getName()));
+
+ // Transfer bytes from in to out
+ byte[] buf = new byte[2048];
+
+ int len;
+
+ while ((len = in.read(buf)) > 0)
+ {
+ out.write(buf, 0, len);
+ }
+ }
+ finally
+ {
+ if (in != null)
+ {
+ in.close();
+ }
+
+ if (out != null)
+ {
+ out.flush();
+ out.closeEntry();
+ out.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * Uncompress directory.
+ *
+ * @param srcPath
+ * source path
+ * @param dstPath
+ * destination path
+ * @throws IOException
+ * if any exception occurred
+ */
+ public static void uncompressDirectory(File srcPath, File dstPath) throws IOException
+ {
+ if (PrivilegedFileHelper.isDirectory(srcPath))
+ {
+ if (!PrivilegedFileHelper.exists(dstPath))
+ {
+ PrivilegedFileHelper.mkdirs(dstPath);
+ }
+
+ String files[] = PrivilegedFileHelper.list(srcPath);
+ for (int i = 0; i < files.length; i++)
+ {
+ uncompressDirectory(new File(srcPath, files[i]), new File(dstPath, files[i]));
+ }
+ }
+ else
+ {
+ ZipInputStream in = null;
+ OutputStream out = null;
+
+ try
+ {
+ in = PrivilegedFileHelper.zipInputStream(srcPath);
+ in.getNextEntry();
+ out = PrivilegedFileHelper.fileOutputStream(dstPath);
+
+ // Transfer bytes from in to out
+ byte[] buf = new byte[2048];
+
+ int len;
+
+ while ((len = in.read(buf)) > 0)
+ {
+ out.write(buf, 0, len);
+ }
+ }
+ finally
+ {
+ if (in != null)
+ {
+ in.close();
+ }
+
+ if (out != null)
+ {
+ out.close();
+ }
+ }
+ }
+ }
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/PrivilegedJBossCacheHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/PrivilegedJBossCacheHelper.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/PrivilegedJBossCacheHelper.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -164,4 +164,39 @@
}
}
+ /**
+ * Remove node in privileged mode.
+ *
+ * @param cache
+ */
+ public static Object removeNode(final Cache<Serializable, Object> cache, final Fqn fqn) throws CacheException
+ {
+ PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ return cache.removeNode(fqn);
+ }
+ };
+ try
+ {
+ return AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof CacheException)
+ {
+ throw (CacheException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/DataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/DataContainer.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/DataContainer.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -41,6 +41,11 @@
String getName();
/**
+ * @return unique name of this container
+ */
+ String getUniqueName();
+
+ /**
* @return current storage version
*/
String getStorageVersion();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceDataContainer.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceDataContainer.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -97,4 +97,5 @@
* @return the value of 'check-sns-new-connection' parameter
*/
boolean isCheckSNSNewConnection();
+
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -586,6 +586,12 @@
return "0";
}
+ @Override
+ public String getUniqueName()
+ {
+ return "MyWorkspaceDataContainer";
+ }
+
};
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java 2011-01-26 16:18:11 UTC (rev 3890)
@@ -20,10 +20,10 @@
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
import org.exoplatform.services.jcr.impl.core.NodeImpl;
import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
-import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
import org.exoplatform.services.jcr.util.IdGenerator;
import org.exoplatform.services.jcr.util.TesterConfigurationHelper;
@@ -31,8 +31,6 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
import javax.jcr.Node;
import javax.jcr.Session;
@@ -174,28 +172,12 @@
assertTrue(res.next());
// remove content
- List<Backupable> backupable = new ArrayList<Backupable>();
- for (String name : repositoryService.getRepository(repositoryName).getWorkspaceNames())
- {
- backupable.addAll(repositoryService.getRepository(repositoryName).getWorkspaceContainer(name)
- .getComponentInstancesOfType(Backupable.class));
- }
+ DBCleanService.cleanRepositoryData(repositoryEntry);
- for (Backupable component : backupable)
- {
- component.getDataCleaner().clean();
- }
-
// check - does JCR_SITEM become empty
- try
- {
- res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
- fail();
- }
- catch (SQLException e)
- {
- //ok
- }
+ res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
+ assertFalse(res.next());
+
statement.close();
service.removeRepository(repositoryName);
@@ -227,18 +209,8 @@
assertTrue(res.next());
// remove content
- List<Backupable> backupable = new ArrayList<Backupable>();
- for (String name : repositoryService.getRepository(repositoryName).getWorkspaceNames())
- {
- backupable.addAll(repositoryService.getRepository(repositoryName).getWorkspaceContainer(name)
- .getComponentInstancesOfType(Backupable.class));
- }
+ DBCleanService.cleanRepositoryData(repositoryEntry);
- for (Backupable component : backupable)
- {
- component.getDataCleaner().clean();
- }
-
// check - does JCR_SITEM become empty
res = statement.executeQuery("select * from JCR_SITEM where ID='" + wsName + id + "'");
assertFalse(res.next());
@@ -273,25 +245,11 @@
assertTrue(res.next());
// remove content
- List<Backupable> backupable =
- repositoryService.getRepository(repositoryName).getWorkspaceContainer(wsName)
- .getComponentInstancesOfType(Backupable.class);
+ DBCleanService.cleanWorkspaceData(repositoryEntry.getWorkspaceEntries().get(0));
- for (Backupable component : backupable)
- {
- component.getDataCleaner().clean();
- }
-
// check - does JCR_SITEM become empty
- try
- {
- res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
- fail();
- }
- catch (SQLException e)
- {
- //ok
- }
+ res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
+ assertFalse(res.next());
statement.close();
service.removeRepository(repositoryName);
@@ -337,15 +295,8 @@
assertTrue(res.next());
// remove content
- List<Backupable> backupable =
- repositoryService.getRepository(repositoryName).getWorkspaceContainer(workspaceEntry.getName())
- .getComponentInstancesOfType(Backupable.class);
+ DBCleanService.cleanWorkspaceData(repositoryEntry.getWorkspaceEntries().get(0));
- for (Backupable component : backupable)
- {
- component.getDataCleaner().clean();
- }
-
// check - does JCR_SITEM become empty
res = statement.executeQuery("select * from JCR_SITEM where ID='" + workspaceEntry.getName() + id + "'");
assertFalse(res.next());
Modified: jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-configuration.xml
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-configuration.xml 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-configuration.xml 2011-01-26 16:18:11 UTC (rev 3890)
@@ -597,6 +597,33 @@
</properties-param>
</init-params>
</component-plugin>
+ <component-plugin>
+ <name>bind.datasource</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+ <init-params>
+ <value-param>
+ <name>bind-name</name>
+ <value>testdbcleaner</value>
+ </value-param>
+ <value-param>
+ <name>class-name</name>
+ <value>javax.sql.DataSource</value>
+ </value-param>
+ <value-param>
+ <name>factory</name>
+ <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+ </value-param>
+ <properties-param>
+ <name>ref-addresses</name>
+ <description>ref-addresses</description>
+ <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
+ <property name="url" value="jdbc:hsqldb:file:target/temp/data/testdbcleaner"/>
+ <property name="username" value="sa"/>
+ <property name="password" value=""/>
+ </properties-param>
+ </init-params>
+ </component-plugin>
<component-plugin>
<name>bind.jcr</name>
<set-method>addPlugin</set-method>
Modified: jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml 2011-01-26 16:18:11 UTC (rev 3890)
@@ -27,6 +27,7 @@
<property name="update-storage" value="false" />
<property name="max-buffer-size" value="200k" />
<property name="swap-directory" value="target/temp/swap/ws" />
+ <property name="dialect" value="auto" />
</properties>
<value-storages>
<value-storage id="ws"
@@ -96,6 +97,7 @@
<property name="update-storage" value="false" />
<property name="max-buffer-size" value="200k" />
<property name="swap-directory" value="target/temp/swap/ws1" />
+ <property name="dialect" value="auto" />
</properties>
<value-storages>
<value-storage id="ws1"
@@ -170,6 +172,7 @@
<property name="update-storage" value="false" />
<property name="max-buffer-size" value="200k" />
<property name="swap-directory" value="target/temp/swap/ws2" />
+ <property name="dialect" value="auto" />
</properties>
<value-storages>
<value-storage id="ws2"
@@ -245,6 +248,7 @@
<property name="update-storage" value="false" />
<property name="max-buffer-size" value="200k" />
<property name="swap-directory" value="target/temp/swap/ws3" />
+ <property name="dialect" value="auto" />
</properties>
<value-storages>
<value-storage id="ws3_big"
@@ -344,6 +348,7 @@
<property name="update-storage" value="false" />
<property name="max-buffer-size" value="200k" />
<property name="swap-directory" value="target/temp/swap/wsdb2" />
+ <property name="dialect" value="auto" />
</properties>
<value-storages>
<value-storage id="ws"
@@ -412,6 +417,7 @@
<property name="update-storage" value="false" />
<property name="max-buffer-size" value="200k" />
<property name="swap-directory" value="target/temp/swap/ws1db2" />
+ <property name="dialect" value="auto" />
</properties>
<value-storages>
<value-storage id="ws1"
@@ -491,6 +497,7 @@
<property name="update-storage" value="false" />
<property name="max-buffer-size" value="200k" />
<property name="swap-directory" value="target/temp/swap/wstck" />
+ <property name="dialect" value="auto" />
</properties>
<value-storages>
<value-storage id="ws"
@@ -572,6 +579,7 @@
<property name="update-storage" value="false" />
<property name="max-buffer-size" value="200k" />
<property name="swap-directory" value="target/temp/swap/ws1tck" />
+ <property name="dialect" value="auto" />
</properties>
<value-storages>
<value-storage id="ws1"
@@ -651,6 +659,7 @@
<property name="update-storage" value="false" />
<property name="max-buffer-size" value="200k" />
<property name="swap-directory" value="target/temp/swap/ws2tck" />
+ <property name="dialect" value="auto" />
</properties>
<value-storages>
<value-storage id="ws2"
Modified: jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration.xml
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration.xml 2011-01-26 15:23:23 UTC (rev 3889)
+++ jcr/trunk/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration.xml 2011-01-26 16:18:11 UTC (rev 3890)
@@ -579,7 +579,7 @@
</properties-param>
</init-params>
</component-plugin>
-<component-plugin>
+ <component-plugin>
<name>bind.datasource</name>
<set-method>addPlugin</set-method>
<type>org.exoplatform.services.naming.BindReferencePlugin</type>
13 years, 3 months
exo-jcr SVN: r3889 - core/branches/2.3.x/patch.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2011-01-26 10:23:23 -0500 (Wed, 26 Jan 2011)
New Revision: 3889
Removed:
core/branches/2.3.x/patch/COR-222/
Log:
COR-222: 2.3.x patch removed
13 years, 3 months
exo-jcr SVN: r3888 - in core/branches/2.3.x/patch: COR-222 and 1 other directory.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2011-01-26 04:18:13 -0500 (Wed, 26 Jan 2011)
New Revision: 3888
Added:
core/branches/2.3.x/patch/COR-222/
core/branches/2.3.x/patch/COR-222/COR-222.patch
Log:
COR-222: 2.3.x patch proposed
Added: core/branches/2.3.x/patch/COR-222/COR-222.patch
===================================================================
--- core/branches/2.3.x/patch/COR-222/COR-222.patch (rev 0)
+++ core/branches/2.3.x/patch/COR-222/COR-222.patch 2011-01-26 09:18:13 UTC (rev 3888)
@@ -0,0 +1,1390 @@
+Index: exo.core.component.document/pom.xml
+===================================================================
+--- exo.core.component.document/pom.xml (revision 3863)
++++ exo.core.component.document/pom.xml (working copy)
+@@ -41,10 +41,6 @@
+ <artifactId>pdfbox</artifactId>
+ </dependency>
+ <dependency>
+- <groupId>com.lowagie</groupId>
+- <artifactId>itext</artifactId>
+- </dependency>
+- <dependency>
+ <groupId>org.htmlparser</groupId>
+ <artifactId>htmlparser</artifactId>
+ </dependency>
+Index: exo.core.component.document/src/main/java/org/exoplatform/services/document/impl/PDFDocumentReader.java
+===================================================================
+--- exo.core.component.document/src/main/java/org/exoplatform/services/document/impl/PDFDocumentReader.java (revision 3863)
++++ exo.core.component.document/src/main/java/org/exoplatform/services/document/impl/PDFDocumentReader.java (working copy)
+@@ -18,37 +18,30 @@
+ */
+ package org.exoplatform.services.document.impl;
+
+-import com.lowagie.text.pdf.PdfDate;
+-import com.lowagie.text.pdf.PdfReader;
+-
++import org.apache.jempbox.xmp.XMPMetadata;
++import org.apache.jempbox.xmp.XMPSchemaBasic;
++import org.apache.jempbox.xmp.XMPSchemaDublinCore;
++import org.apache.jempbox.xmp.XMPSchemaPDF;
++import org.apache.pdfbox.exceptions.InvalidPasswordException;
+ import org.apache.pdfbox.pdmodel.PDDocument;
++import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
++import org.apache.pdfbox.pdmodel.PDDocumentInformation;
++import org.apache.pdfbox.pdmodel.common.PDMetadata;
+ import org.apache.pdfbox.util.PDFTextStripper;
+-import org.exoplatform.commons.utils.ISO8601;
+ import org.exoplatform.services.document.DCMetaData;
+ import org.exoplatform.services.document.DocumentReadException;
+ import org.exoplatform.services.log.ExoLogger;
+ import org.exoplatform.services.log.Log;
+-import org.w3c.dom.Document;
+-import org.w3c.dom.Node;
+-import org.w3c.dom.NodeList;
+-import org.xml.sax.SAXException;
+
+-import java.io.ByteArrayInputStream;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.StringWriter;
+ import java.security.AccessController;
+ import java.security.PrivilegedActionException;
+ import java.security.PrivilegedExceptionAction;
+-import java.text.ParseException;
+ import java.util.Calendar;
+-import java.util.HashMap;
+ import java.util.Properties;
+
+-import javax.xml.parsers.DocumentBuilder;
+-import javax.xml.parsers.DocumentBuilderFactory;
+-import javax.xml.parsers.ParserConfigurationException;
+-
+ /**
+ * Created by The eXo Platform SAS A parser of Adobe PDF files.
+ *
+@@ -168,204 +161,233 @@
+ */
+ public Properties getProperties(InputStream is) throws IOException, DocumentReadException
+ {
+-
+- Properties props = null;
+-
+- PdfReader reader = new PdfReader(is, "".getBytes());
+-
+- // Read the file metadata
+- byte[] metadata = reader.getMetadata();
+-
+- if (metadata != null)
++ PDDocument pdDocument = PDDocument.load(is);
++ Properties props = new Properties();
++ try
+ {
+- // there is XMP metadata try exctract it
+- props = getPropertiesFromMetadata(metadata);
+- }
+-
+- if (props == null)
+- {
+- // it's old pdf document version
+- props = getPropertiesFromInfo(reader.getInfo());
+- }
+- reader.close();
+- if (is != null)
+- try
++ if (pdDocument.isEncrypted())
+ {
+- is.close();
++ try
++ {
++ pdDocument.decrypt("");
++ }
++ catch (InvalidPasswordException e)
++ {
++ throw new DocumentReadException("The pdf document is encrypted.", e);
++ }
++ catch (org.apache.pdfbox.exceptions.CryptographyException e)
++ {
++ throw new DocumentReadException(e.getMessage(), e);
++ }
+ }
+- catch (IOException e)
++
++ PDDocumentCatalog catalog = pdDocument.getDocumentCatalog();
++ PDMetadata meta = catalog.getMetadata();
++ if (meta != null)
+ {
+- }
+- return props;
+- }
++ XMPMetadata metadata = meta.exportXMPMetadata();
+
+- /**
+- * Extract properties from XMP xml.
+- *
+- * @param metadata XML as byte array
+- * @return extracted properties
+- * @throws DocumentReadException
+- * @throws Exception if extracting fails
+- */
+- protected Properties getPropertiesFromMetadata(byte[] metadata) throws IOException, DocumentReadException
+- {
++ XMPSchemaDublinCore dc = metadata.getDublinCoreSchema();
++ if (dc != null)
++ {
++ try
++ {
++ if (dc.getTitle() != null)
++ props.put(DCMetaData.TITLE, dc.getTitle());
++ }
++ catch (Exception e)
++ {
++ log.warn("getTitle failed: " + e);
++ }
++ try
++ {
++ if (dc.getDescription() != null)
++ props.put(DCMetaData.DESCRIPTION, dc.getDescription());
++ }
++ catch (Exception e)
++ {
++ log.warn("getSubject failed: " + e);
++ }
+
+- Properties props = null;
++ try
++ {
++ if (dc.getCreators() != null)
++ {
++ for (String creator : dc.getCreators())
++ {
++ props.put(DCMetaData.CREATOR, creator);
++ }
++ }
++ }
++ catch (Exception e)
++ {
++ log.warn("getCreator failed: " + e);
++ }
+
+- // parse xml
++ try
++ {
++ if (dc.getDates() != null)
++ {
++ for (Calendar date : dc.getDates())
++ {
++ props.put(DCMetaData.DATE, date);
++ }
++ }
++ }
++ catch (Exception e)
++ {
++ log.warn("getDate failed: " + e);
++ }
++ }
+
+- Document doc;
+- try
+- {
+- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+- DocumentBuilder docBuilder = dbf.newDocumentBuilder();
+- doc = docBuilder.parse(new ByteArrayInputStream(metadata));
+- }
+- catch (SAXException e)
+- {
+- throw new DocumentReadException(e.getMessage(), e);
+- }
+- catch (ParserConfigurationException e)
+- {
+- throw new DocumentReadException(e.getMessage(), e);
+- }
+-
+- // Check is there PDF/A-1 XMP
+- String version = "";
+- NodeList list = doc.getElementsByTagName("pdfaid:conformance");
+- if (list != null && list.item(0) != null)
+- {
+- version += list.item(0).getTextContent() + "-";
+- }
+-
+- list = doc.getElementsByTagName("pdfaid:part");
+- if (list != null && list.item(0) != null)
+- {
+- version += list.item(0).getTextContent();
+- }
+-
+- // PDF/A-1a or PDF/A-1b
+- if (version.equalsIgnoreCase("A-1"))
+- {
+- props = getPropsFromPDFAMetadata(doc);
+- }
+-
+- return props;
+- }
+-
+- /**
+- * Extracts properties from PDF Info hash set.
+- *
+- * @param Pdf Info hash set
+- * @return Extracted properties
+- * @throws Exception if extracting fails
+- */
+- @SuppressWarnings("unchecked")
+- protected Properties getPropertiesFromInfo(HashMap info) throws IOException
+- {
+- Properties props = new Properties();
+-
+- String title = (String)info.get("Title");
+- if (title != null)
+- {
+- props.put(DCMetaData.TITLE, title);
+- }
+-
+- String author = (String)info.get("Author");
+- if (author != null)
+- {
+- props.put(DCMetaData.CREATOR, author);
+- }
+-
+- String subject = (String)info.get("Subject");
+- if (subject != null)
+- {
+- props.put(DCMetaData.SUBJECT, subject);
+- }
+-
+- String creationDate = (String)info.get("CreationDate");
+- if (creationDate != null)
+- {
+- props.put(DCMetaData.DATE, PdfDate.decode(creationDate));
+- }
+-
+- String modDate = (String)info.get("ModDate");
+- if (modDate != null)
+- {
+- props.put(DCMetaData.DATE, PdfDate.decode(modDate));
+- }
+-
+- return props;
+- }
+-
+- private Properties getPropsFromPDFAMetadata(Document doc) throws IOException, DocumentReadException
+- {
+- Properties props = new Properties();
+- // get properties
+- NodeList list = doc.getElementsByTagName("rdf:li");
+- if (list != null && list.getLength() > 0)
+- {
+- for (int i = 0; i < list.getLength(); i++)
+- {
+-
+- Node n = list.item(i);
+- // dc:title - TITLE
+- if (n.getParentNode().getParentNode().getNodeName().equals("dc:title"))
++ XMPSchemaPDF pdf = metadata.getPDFSchema();
++ if (pdf != null)
+ {
+- String title = n.getLastChild().getTextContent();
+- props.put(DCMetaData.TITLE, title);
+- }
++ try
++ {
++ if (pdf.getKeywords() != null)
++ props.put(DCMetaData.SUBJECT, pdf.getKeywords());
++ }
++ catch (Exception e)
++ {
++ log.warn("getKeywords failed: " + e);
++ }
+
+- // dc:creator - CREATOR
+- if (n.getParentNode().getParentNode().getNodeName().equals("dc:creator"))
+- {
+- String author = n.getLastChild().getTextContent();
+- props.put(DCMetaData.CREATOR, author);
++ try
++ {
++ if (pdf.getProducer() != null)
++ props.put(DCMetaData.PUBLISHER, pdf.getProducer());
++ }
++ catch (Exception e)
++ {
++ log.warn("getProducer failed: " + e);
++ }
+ }
+
+- // DC:description - SUBJECT
+- if (n.getParentNode().getParentNode().getNodeName().equals("dc:description"))
++ XMPSchemaBasic basic = metadata.getBasicSchema();
++ if (basic != null)
+ {
+- String description = n.getLastChild().getTextContent();
+- props.put(DCMetaData.SUBJECT, description);
+- // props.put(DCMetaData.DESCRIPTION, description);
++ try
++ {
++ if (basic.getCreateDate() != null)
++ props.put(DCMetaData.DATE, basic.getCreateDate());
++ }
++ catch (Exception e)
++ {
++ log.warn("getCreationDate failed: " + e);
++ }
++ try
++ {
++ if (basic.getModifyDate() != null)
++ props.put(DCMetaData.DATE, basic.getModifyDate());
++ }
++ catch (Exception e)
++ {
++ log.warn("getModificationDate failed: " + e);
++ }
++ // try
++ // {
++ // if (basic.getCreatorTool() != null)
++ // props.put(DCMetaData.PUBLISHER, basic.getCreatorTool());
++ // }
++ // catch (Exception e)
++ // {
++ // log.warn("getCreatorTool failed: " + e);
++ // }
+ }
+ }
+- }
++ else
++ {
++ // The pdf doesn't contain any metadata, try to use the document
++ // information instead
++ PDDocumentInformation docInfo = pdDocument.getDocumentInformation();
+
+- try
+- {
+- // xmp:CreateDate - DATE
+- list = doc.getElementsByTagName("xmp:CreateDate");
+- if (list != null && list.item(0) != null)
+- {
+- Node creationDateNode = list.item(0).getLastChild();
+- if (creationDateNode != null)
++ if (docInfo != null)
+ {
+- String creationDate = creationDateNode.getTextContent();
+- Calendar c = ISO8601.parseEx(creationDate);
+- props.put(DCMetaData.DATE, c);
+- }
+- }
++ try
++ {
++ if (docInfo.getAuthor() != null)
++ props.put(DCMetaData.CONTRIBUTOR, docInfo.getAuthor());
++ }
++ catch (Exception e)
++ {
++ log.warn("getAuthor failed: " + e);
++ }
++ try
++ {
++ if (docInfo.getCreationDate() != null)
++ props.put(DCMetaData.DATE, docInfo.getCreationDate());
++ }
++ catch (Exception e)
++ {
++ log.warn("getCreationDate failed: " + e);
++ }
++ try
++ {
++ if (docInfo.getCreator() != null)
++ props.put(DCMetaData.CREATOR, docInfo.getCreator());
++ }
++ catch (Exception e)
++ {
++ log.warn("getCreator failed: " + e);
++ }
++ try
++ {
+
+- // xmp:ModifyDate - DATE
+- list = doc.getElementsByTagName("xmp:ModifyDate");
+- if (list != null && list.item(0) != null)
+- {
+- Node modifyDateNode = list.item(0).getLastChild();
+- if (modifyDateNode != null)
+- {
+- String modifyDate = modifyDateNode.getTextContent();
+- Calendar c = ISO8601.parseEx(modifyDate);
+- props.put(DCMetaData.DATE, c);
++ if (docInfo.getKeywords() != null)
++ props.put(DCMetaData.SUBJECT, docInfo.getKeywords());
++ }
++ catch (Exception e)
++ {
++ log.warn("getKeywords failed: " + e);
++ }
++ try
++ {
++ if (docInfo.getModificationDate() != null)
++ props.put(DCMetaData.DATE, docInfo.getModificationDate());
++ }
++ catch (Exception e)
++ {
++ log.warn("getModificationDate failed: " + e);
++ }
++ try
++ {
++ if (docInfo.getProducer() != null)
++ props.put(DCMetaData.PUBLISHER, docInfo.getProducer());
++ }
++ catch (Exception e)
++ {
++ log.warn("getProducer failed: " + e);
++ }
++ try
++ {
++ if (docInfo.getSubject() != null)
++ props.put(DCMetaData.DESCRIPTION, docInfo.getSubject());
++ }
++ catch (Exception e)
++ {
++ log.warn("getSubject failed: " + e);
++ }
++ try
++ {
++ if (docInfo.getTitle() != null)
++ props.put(DCMetaData.TITLE, docInfo.getTitle());
++ }
++ catch (Exception e)
++ {
++ log.warn("getTitle failed: " + e);
++ }
+ }
+ }
+ }
+- catch (ParseException e)
++ finally
+ {
+- throw new DocumentReadException(e.getMessage(), e);
++ if (pdDocument != null)
++ {
++ pdDocument.close();
++ }
+ }
++
+ return props;
+ }
+-
+ }
+Index: exo.core.component.document/src/test/java/org/exoplatform/services/document/test/TestPropertiesExtracting.java
+===================================================================
+--- exo.core.component.document/src/test/java/org/exoplatform/services/document/test/TestPropertiesExtracting.java (revision 3863)
++++ exo.core.component.document/src/test/java/org/exoplatform/services/document/test/TestPropertiesExtracting.java (working copy)
+@@ -18,7 +18,6 @@
+ */
+ package org.exoplatform.services.document.test;
+
+-import org.exoplatform.commons.utils.ISO8601;
+ import org.exoplatform.services.document.DCMetaData;
+ import org.exoplatform.services.document.DocumentReader;
+ import org.exoplatform.services.document.DocumentReaderService;
+@@ -51,10 +50,10 @@
+ Properties etalon = new Properties();
+ etalon.put(DCMetaData.TITLE, "Test de convertion de fichier tif");
+ etalon.put(DCMetaData.CREATOR, "Christian Klaus");
+- etalon.put(DCMetaData.SUBJECT, "20080901 TEST Christian Etat OK");
+- Calendar c = ISO8601.parseEx("2008-09-01T08:01:10+00:00");
+- etalon.put(DCMetaData.DATE, c);
+- evalProps(etalon, testprops);
++ etalon.put(DCMetaData.DESCRIPTION, "20080901 TEST Christian Etat OK");
++ // Calendar c = ISO8601.parseEx("2008-09-01T08:01:10+00:00");
++ // etalon.put(DCMetaData.DATE, c);
++ evalProps(etalon, testprops, false);
+ }
+ finally
+ {
+@@ -62,6 +61,26 @@
+ }
+ }
+
++ public void testPDFDocumentReaderServiceBrokenFile() throws Exception
++ {
++ InputStream is = TestPropertiesExtracting.class.getResourceAsStream("/pfs_accapp.pdf");
++ try
++ {
++
++ DocumentReader rdr = service.getDocumentReader("application/pdf");
++ Properties testprops = rdr.getProperties(is);
++ Properties etalon = new Properties();
++ etalon.put(DCMetaData.TITLE, "Personal Account Opening Form VN");
++ etalon.put(DCMetaData.CREATOR, "mr");
++ etalon.put(DCMetaData.PUBLISHER, "Adobe LiveCycle Designer ES 8.2");
++ evalProps(etalon, testprops, false);
++ }
++ finally
++ {
++ is.close();
++ }
++ }
++
+ public void testWordDocumentReaderService() throws Exception
+ {
+ InputStream is = TestPropertiesExtracting.class.getResourceAsStream("/test.doc");
+@@ -75,7 +94,7 @@
+ etalon.put(DCMetaData.CREATOR, "Max Yakimenko");
+ etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
+ etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
+- evalProps(etalon, props);
++ evalProps(etalon, props, true);
+ }
+ finally
+ {
+@@ -96,7 +115,7 @@
+ etalon.put(DCMetaData.CREATOR, "Max Yakimenko");
+ etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
+ etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
+- evalProps(etalon, props);
++ evalProps(etalon, props, true);
+ }
+ finally
+ {
+@@ -118,7 +137,7 @@
+ etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
+ etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
+
+- evalProps(etalon, props);
++ evalProps(etalon, props, true);
+ }
+ finally
+ {
+@@ -146,7 +165,7 @@
+ etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
+ etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
+
+- evalProps(etalon, props);
++ evalProps(etalon, props, true);
+ }
+ finally
+ {
+@@ -174,7 +193,7 @@
+ etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
+ etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
+
+- evalProps(etalon, props);
++ evalProps(etalon, props, true);
+ }
+ finally
+ {
+@@ -202,7 +221,7 @@
+ etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
+ etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
+
+- evalProps(etalon, props);
++ evalProps(etalon, props, true);
+ }
+ finally
+ {
+@@ -228,7 +247,7 @@
+ etalon.put(DCMetaData.CREATOR, "nikolaz ");
+ etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
+
+- evalProps(etalon, props);
++ evalProps(etalon, props, true);
+ }
+ finally
+ {
+@@ -236,7 +255,7 @@
+ }
+ }
+
+- private void evalProps(Properties etalon, Properties testedProps)
++ private void evalProps(Properties etalon, Properties testedProps, boolean testSize)
+ {
+ Iterator it = etalon.entrySet().iterator();
+ while (it.hasNext())
+@@ -244,13 +263,12 @@
+ Map.Entry prop = (Map.Entry)it.next();
+ Object tval = testedProps.get(prop.getKey());
+ assertNotNull(prop.getKey() + " property not founded. ", tval);
+- if (tval instanceof Date)
+- {
+- System.out.println("was:" + ((Date)tval).getTime() + " expected: " + ((Date)prop.getValue()).getTime());
+- }
+ assertEquals(prop.getKey() + " property value is incorrect", prop.getValue(), tval);
+ }
+- assertEquals("size is incorrect", etalon.size(), testedProps.size());
++ if (testSize)
++ {
++ assertEquals("size is incorrect", etalon.size(), testedProps.size());
++ }
+ }
+
+ }
+Index: exo.core.component.document/src/test/resources/pfs_accapp.pdf
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+
+Property changes on: exo.core.component.document\src\test\resources\pfs_accapp.pdf
+___________________________________________________________________
+Added: svn:mime-type
+ + application/octet-stream
+
+Index: pom.xml
+===================================================================
+--- pom.xml (revision 3863)
++++ pom.xml (working copy)
+@@ -1,382 +1,375 @@
+-<!--
+-
+- Copyright (C) 2009 eXo Platform SAS.
+-
+- This is free software; you can redistribute it and/or modify it
+- under the terms of the GNU Lesser General Public License as
+- published by the Free Software Foundation; either version 2.1 of
+- the License, or (at your option) any later version.
+-
+- This software is distributed in the hope that it will be useful,
+- but WITHOUT ANY WARRANTY; without even the implied warranty of
+- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+- Lesser General Public License for more details.
+-
+- You should have received a copy of the GNU Lesser General Public
+- License along with this software; if not, write to the Free
+- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+- 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+-
+--->
+-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+- <modelVersion>4.0.0</modelVersion>
+-
+- <parent>
+- <groupId>org.exoplatform</groupId>
+- <artifactId>foundation-parent</artifactId>
+- <version>7</version>
+- </parent>
+-
+- <groupId>org.exoplatform.core</groupId>
+- <artifactId>core-parent</artifactId>
+- <version>2.3.7-GA-SNAPSHOT</version>
+- <packaging>pom</packaging>
+-
+- <name>eXo Core</name>
+-
+- <properties>
+- <exo.product.name>exo-core</exo.product.name>
+- <exo.product.specification>2.3</exo.product.specification>
+-
+- <org.exoplatform.framework.junit.version>1.2.1-GA</org.exoplatform.framework.junit.version>
+- <org.exoplatform.kernel.version>2.2.7-GA-SNAPSHOT</org.exoplatform.kernel.version>
+- </properties>
+-
+- <scm>
+- <connection>scm:svn:http://anonsvn.jboss.org/repos/exo-jcr/core/branches/2.3.x/</connection>
+- <developerConnection>scm:svn:https://svn.jboss.org/repos/exo-jcr/core/branches/2.3.x/</developerConnection>
+- <url>http://fisheye.jboss.org/browse/exo-jcr/core/branches/2.3.x</url>
+- </scm>
+-
+- <modules>
+- <module>exo.core.component.security.core</module>
+- <module>exo.core.component.database</module>
+- <module>exo.core.component.document</module>
+- <module>exo.core.component.ldap</module>
+- <module>exo.core.component.organization.api</module>
+- <module>exo.core.component.organization.jdbc</module>
+- <module>exo.core.component.organization.ldap</module>
+- <module>exo.core.component.xml-processing</module>
+- <module>exo.core.component.script.groovy</module>
+- <module>exo.core.component.web.css</module>
+- <module>packaging/module</module>
+- </modules>
+-
+- <dependencyManagement>
+- <dependencies>
+-
+- <dependency>
+- <groupId>org.exoplatform.tool</groupId>
+- <artifactId>exo.tool.framework.junit</artifactId>
+- <version>${org.exoplatform.framework.junit.version}</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.exoplatform.kernel</groupId>
+- <artifactId>exo.kernel.commons</artifactId>
+- <version>${org.exoplatform.kernel.version}</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.exoplatform.kernel</groupId>
+- <artifactId>exo.kernel.component.common</artifactId>
+- <version>${org.exoplatform.kernel.version}</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.exoplatform.kernel</groupId>
+- <artifactId>exo.kernel.container</artifactId>
+- <version>${org.exoplatform.kernel.version}</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.exoplatform.kernel</groupId>
+- <artifactId>exo.kernel.component.cache</artifactId>
+- <version>${org.exoplatform.kernel.version}</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.exoplatform.core</groupId>
+- <artifactId>exo.core.component.database</artifactId>
+- <version>${project.version}</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.exoplatform.core</groupId>
+- <artifactId>exo.core.component.ldap</artifactId>
+- <version>${project.version}</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.exoplatform.core</groupId>
+- <artifactId>exo.core.component.organization.api</artifactId>
+- <version>${project.version}</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.exoplatform.core</groupId>
+- <artifactId>exo.core.component.organization.jdbc</artifactId>
+- <version>${project.version}</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.exoplatform.core</groupId>
+- <artifactId>exo.core.component.security.core</artifactId>
+- <version>${project.version}</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>javax.resource</groupId>
+- <artifactId>connector-api</artifactId>
+- <version>1.5</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>javax.servlet</groupId>
+- <artifactId>servlet-api</artifactId>
+- <version>2.4</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>javax.transaction</groupId>
+- <artifactId>jta</artifactId>
+- <version>1.0.1B</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.slf4j</groupId>
+- <artifactId>slf4j-api</artifactId>
+- <version>1.5.8</version>
+- <scope>test</scope>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.slf4j</groupId>
+- <artifactId>slf4j-log4j12</artifactId>
+- <version>1.5.8</version>
+- <scope>test</scope>
+- </dependency>
+-
+-
+- <dependency>
+- <groupId>pull-parser</groupId>
+- <artifactId>pull-parser</artifactId>
+- <version>2</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>commons-lang</groupId>
+- <artifactId>commons-lang</artifactId>
+- <version>2.4</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>hsqldb</groupId>
+- <artifactId>hsqldb</artifactId>
+- <version>1.8.0.7</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>com.experlog</groupId>
+- <artifactId>xapool</artifactId>
+- <version>1.5.0</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.hibernate</groupId>
+- <artifactId>hibernate-core</artifactId>
+- <version>3.3.2.GA</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>xstream</groupId>
+- <artifactId>xstream</artifactId>
+- <version>1.0.2</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>picocontainer</groupId>
+- <artifactId>picocontainer</artifactId>
+- <version>1.1</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>xdoclet</groupId>
+- <artifactId>xdoclet-hibernate-module</artifactId>
+- <version>1.2.3</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>xdoclet</groupId>
+- <artifactId>xdoclet-xdoclet-module</artifactId>
+- <version>1.2.3</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>xdoclet</groupId>
+- <artifactId>xjavadoc</artifactId>
+- <version>1.2.3</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>com.microsoft</groupId>
+- <artifactId>sqljdbc</artifactId>
+- <version>1.1.1501</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>com.ibm.db2</groupId>
+- <artifactId>db2jcc</artifactId>
+- <version>9.1</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>com.ibm.db2</groupId>
+- <artifactId>db2jcc_license_cu</artifactId>
+- <version>9.1</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>oracle</groupId>
+- <artifactId>ojdbc</artifactId>
+- <version>1.4</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>postgresql</groupId>
+- <artifactId>postgresql</artifactId>
+- <version>8.3-603.jdbc3</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>mysql</groupId>
+- <artifactId>mysql-connector-java</artifactId>
+- <version>5.0.8</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.codehaus.groovy</groupId>
+- <artifactId>groovy-all</artifactId>
+- <version>1.6.5</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.hibernate</groupId>
+- <artifactId>hibernate-annotations</artifactId>
+- <version>3.4.0.GA</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.apache.pdfbox</groupId>
+- <artifactId>pdfbox</artifactId>
+- <version>1.1.0</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>com.lowagie</groupId>
+- <artifactId>itext</artifactId>
+- <version>2.1.0</version>
+- <scope>compile</scope>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.htmlparser</groupId>
+- <artifactId>htmlparser</artifactId>
+- <version>1.6</version>
+- <scope>compile</scope>
+- <exclusions>
+- <exclusion>
+- <groupId>com.sun</groupId>
+- <artifactId>tools</artifactId>
+- </exclusion>
+- </exclusions>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.apache.poi</groupId>
+- <artifactId>poi</artifactId>
+- <version>3.6</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.apache.poi</groupId>
+- <artifactId>poi-scratchpad</artifactId>
+- <version>3.6</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.apache.poi</groupId>
+- <artifactId>poi-ooxml</artifactId>
+- <version>3.6</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>com.novell.ldap</groupId>
+- <artifactId>jldap</artifactId>
+- <version>4.3</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>jtidy</groupId>
+- <artifactId>jtidy</artifactId>
+- <version>4aug2000r7-dev</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>org.w3c</groupId>
+- <artifactId>sac</artifactId>
+- <version>1.3</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>batik</groupId>
+- <artifactId>batik-util</artifactId>
+- <version>1.7</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>batik</groupId>
+- <artifactId>batik-css</artifactId>
+- <version>1.7</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>commons-dbcp</groupId>
+- <artifactId>commons-dbcp</artifactId>
+- <version>1.2.2</version>
+- <exclusions>
+- <exclusion>
+- <groupId>commons-pool</groupId>
+- <artifactId>commons-pool</artifactId>
+- </exclusion>
+- </exclusions>
+- </dependency>
+-
+- <dependency>
+- <groupId>commons-pool</groupId>
+- <artifactId>commons-pool</artifactId>
+- <version>1.5.4</version>
+- </dependency>
+-
+- <dependency>
+- <groupId>javassist</groupId>
+- <artifactId>javassist</artifactId>
+- <version>3.4.GA</version>
+- </dependency>
+-
+- </dependencies>
+- </dependencyManagement>
+-
+- <dependencies>
+- <dependency>
+- <groupId>junit</groupId>
+- <artifactId>junit</artifactId>
+- <scope>test</scope>
+- </dependency>
+- <dependency>
+- <groupId>org.slf4j</groupId>
+- <artifactId>slf4j-log4j12</artifactId>
+- <scope>test</scope>
+- </dependency>
+- </dependencies>
+-</project>
++<!--
++
++ Copyright (C) 2009 eXo Platform SAS.
++
++ This is free software; you can redistribute it and/or modify it
++ under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation; either version 2.1 of
++ the License, or (at your option) any later version.
++
++ This software is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with this software; if not, write to the Free
++ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
++
++-->
++<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
++ <modelVersion>4.0.0</modelVersion>
++
++ <parent>
++ <groupId>org.exoplatform</groupId>
++ <artifactId>foundation-parent</artifactId>
++ <version>7</version>
++ </parent>
++
++ <groupId>org.exoplatform.core</groupId>
++ <artifactId>core-parent</artifactId>
++ <version>2.3.7-GA-SNAPSHOT</version>
++ <packaging>pom</packaging>
++
++ <name>eXo Core</name>
++
++ <properties>
++ <exo.product.name>exo-core</exo.product.name>
++ <exo.product.specification>2.3</exo.product.specification>
++
++ <org.exoplatform.framework.junit.version>1.2.1-GA</org.exoplatform.framework.junit.version>
++ <org.exoplatform.kernel.version>2.2.7-GA-SNAPSHOT</org.exoplatform.kernel.version>
++ </properties>
++
++ <scm>
++ <connection>scm:svn:http://anonsvn.jboss.org/repos/exo-jcr/core/branches/2.3.x/</connection>
++ <developerConnection>scm:svn:https://svn.jboss.org/repos/exo-jcr/core/branches/2.3.x/</developerConnection>
++ <url>http://fisheye.jboss.org/browse/exo-jcr/core/branches/2.3.x</url>
++ </scm>
++
++ <modules>
++ <module>exo.core.component.security.core</module>
++ <module>exo.core.component.database</module>
++ <module>exo.core.component.document</module>
++ <module>exo.core.component.ldap</module>
++ <module>exo.core.component.organization.api</module>
++ <module>exo.core.component.organization.jdbc</module>
++ <module>exo.core.component.organization.ldap</module>
++ <module>exo.core.component.xml-processing</module>
++ <module>exo.core.component.script.groovy</module>
++ <module>exo.core.component.web.css</module>
++ <module>packaging/module</module>
++ </modules>
++
++ <dependencyManagement>
++ <dependencies>
++
++ <dependency>
++ <groupId>org.exoplatform.tool</groupId>
++ <artifactId>exo.tool.framework.junit</artifactId>
++ <version>${org.exoplatform.framework.junit.version}</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.exoplatform.kernel</groupId>
++ <artifactId>exo.kernel.commons</artifactId>
++ <version>${org.exoplatform.kernel.version}</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.exoplatform.kernel</groupId>
++ <artifactId>exo.kernel.component.common</artifactId>
++ <version>${org.exoplatform.kernel.version}</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.exoplatform.kernel</groupId>
++ <artifactId>exo.kernel.container</artifactId>
++ <version>${org.exoplatform.kernel.version}</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.exoplatform.kernel</groupId>
++ <artifactId>exo.kernel.component.cache</artifactId>
++ <version>${org.exoplatform.kernel.version}</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.exoplatform.core</groupId>
++ <artifactId>exo.core.component.database</artifactId>
++ <version>${project.version}</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.exoplatform.core</groupId>
++ <artifactId>exo.core.component.ldap</artifactId>
++ <version>${project.version}</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.exoplatform.core</groupId>
++ <artifactId>exo.core.component.organization.api</artifactId>
++ <version>${project.version}</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.exoplatform.core</groupId>
++ <artifactId>exo.core.component.organization.jdbc</artifactId>
++ <version>${project.version}</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.exoplatform.core</groupId>
++ <artifactId>exo.core.component.security.core</artifactId>
++ <version>${project.version}</version>
++ </dependency>
++
++ <dependency>
++ <groupId>javax.resource</groupId>
++ <artifactId>connector-api</artifactId>
++ <version>1.5</version>
++ </dependency>
++
++ <dependency>
++ <groupId>javax.servlet</groupId>
++ <artifactId>servlet-api</artifactId>
++ <version>2.4</version>
++ </dependency>
++
++ <dependency>
++ <groupId>javax.transaction</groupId>
++ <artifactId>jta</artifactId>
++ <version>1.0.1B</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.slf4j</groupId>
++ <artifactId>slf4j-api</artifactId>
++ <version>1.5.8</version>
++ <scope>test</scope>
++ </dependency>
++
++ <dependency>
++ <groupId>org.slf4j</groupId>
++ <artifactId>slf4j-log4j12</artifactId>
++ <version>1.5.8</version>
++ <scope>test</scope>
++ </dependency>
++
++
++ <dependency>
++ <groupId>pull-parser</groupId>
++ <artifactId>pull-parser</artifactId>
++ <version>2</version>
++ </dependency>
++
++ <dependency>
++ <groupId>commons-lang</groupId>
++ <artifactId>commons-lang</artifactId>
++ <version>2.4</version>
++ </dependency>
++
++ <dependency>
++ <groupId>hsqldb</groupId>
++ <artifactId>hsqldb</artifactId>
++ <version>1.8.0.7</version>
++ </dependency>
++
++ <dependency>
++ <groupId>com.experlog</groupId>
++ <artifactId>xapool</artifactId>
++ <version>1.5.0</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.hibernate</groupId>
++ <artifactId>hibernate-core</artifactId>
++ <version>3.3.2.GA</version>
++ </dependency>
++
++ <dependency>
++ <groupId>xstream</groupId>
++ <artifactId>xstream</artifactId>
++ <version>1.0.2</version>
++ </dependency>
++
++ <dependency>
++ <groupId>picocontainer</groupId>
++ <artifactId>picocontainer</artifactId>
++ <version>1.1</version>
++ </dependency>
++
++ <dependency>
++ <groupId>xdoclet</groupId>
++ <artifactId>xdoclet-hibernate-module</artifactId>
++ <version>1.2.3</version>
++ </dependency>
++
++ <dependency>
++ <groupId>xdoclet</groupId>
++ <artifactId>xdoclet-xdoclet-module</artifactId>
++ <version>1.2.3</version>
++ </dependency>
++
++ <dependency>
++ <groupId>xdoclet</groupId>
++ <artifactId>xjavadoc</artifactId>
++ <version>1.2.3</version>
++ </dependency>
++
++ <dependency>
++ <groupId>com.microsoft</groupId>
++ <artifactId>sqljdbc</artifactId>
++ <version>1.1.1501</version>
++ </dependency>
++
++ <dependency>
++ <groupId>com.ibm.db2</groupId>
++ <artifactId>db2jcc</artifactId>
++ <version>9.1</version>
++ </dependency>
++
++ <dependency>
++ <groupId>com.ibm.db2</groupId>
++ <artifactId>db2jcc_license_cu</artifactId>
++ <version>9.1</version>
++ </dependency>
++
++ <dependency>
++ <groupId>oracle</groupId>
++ <artifactId>ojdbc</artifactId>
++ <version>1.4</version>
++ </dependency>
++
++ <dependency>
++ <groupId>postgresql</groupId>
++ <artifactId>postgresql</artifactId>
++ <version>8.3-603.jdbc3</version>
++ </dependency>
++
++ <dependency>
++ <groupId>mysql</groupId>
++ <artifactId>mysql-connector-java</artifactId>
++ <version>5.0.8</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.codehaus.groovy</groupId>
++ <artifactId>groovy-all</artifactId>
++ <version>1.6.5</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.hibernate</groupId>
++ <artifactId>hibernate-annotations</artifactId>
++ <version>3.4.0.GA</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.apache.pdfbox</groupId>
++ <artifactId>pdfbox</artifactId>
++ <version>1.1.0</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.htmlparser</groupId>
++ <artifactId>htmlparser</artifactId>
++ <version>1.6</version>
++ <scope>compile</scope>
++ <exclusions>
++ <exclusion>
++ <groupId>com.sun</groupId>
++ <artifactId>tools</artifactId>
++ </exclusion>
++ </exclusions>
++ </dependency>
++
++ <dependency>
++ <groupId>org.apache.poi</groupId>
++ <artifactId>poi</artifactId>
++ <version>3.6</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.apache.poi</groupId>
++ <artifactId>poi-scratchpad</artifactId>
++ <version>3.6</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.apache.poi</groupId>
++ <artifactId>poi-ooxml</artifactId>
++ <version>3.6</version>
++ </dependency>
++
++ <dependency>
++ <groupId>com.novell.ldap</groupId>
++ <artifactId>jldap</artifactId>
++ <version>4.3</version>
++ </dependency>
++
++ <dependency>
++ <groupId>jtidy</groupId>
++ <artifactId>jtidy</artifactId>
++ <version>4aug2000r7-dev</version>
++ </dependency>
++
++ <dependency>
++ <groupId>org.w3c</groupId>
++ <artifactId>sac</artifactId>
++ <version>1.3</version>
++ </dependency>
++
++ <dependency>
++ <groupId>batik</groupId>
++ <artifactId>batik-util</artifactId>
++ <version>1.7</version>
++ </dependency>
++
++ <dependency>
++ <groupId>batik</groupId>
++ <artifactId>batik-css</artifactId>
++ <version>1.7</version>
++ </dependency>
++
++ <dependency>
++ <groupId>commons-dbcp</groupId>
++ <artifactId>commons-dbcp</artifactId>
++ <version>1.2.2</version>
++ <exclusions>
++ <exclusion>
++ <groupId>commons-pool</groupId>
++ <artifactId>commons-pool</artifactId>
++ </exclusion>
++ </exclusions>
++ </dependency>
++
++ <dependency>
++ <groupId>commons-pool</groupId>
++ <artifactId>commons-pool</artifactId>
++ <version>1.5.4</version>
++ </dependency>
++
++ <dependency>
++ <groupId>javassist</groupId>
++ <artifactId>javassist</artifactId>
++ <version>3.4.GA</version>
++ </dependency>
++
++ </dependencies>
++ </dependencyManagement>
++
++ <dependencies>
++ <dependency>
++ <groupId>junit</groupId>
++ <artifactId>junit</artifactId>
++ <scope>test</scope>
++ </dependency>
++ <dependency>
++ <groupId>org.slf4j</groupId>
++ <artifactId>slf4j-log4j12</artifactId>
++ <scope>test</scope>
++ </dependency>
++ </dependencies>
++</project>
13 years, 3 months
exo-jcr SVN: r3887 - in core/trunk: exo.core.component.document and 3 other directories.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2011-01-26 03:54:27 -0500 (Wed, 26 Jan 2011)
New Revision: 3887
Added:
core/trunk/exo.core.component.document/src/test/resources/pfs_accapp.pdf
Modified:
core/trunk/exo.core.component.document/pom.xml
core/trunk/exo.core.component.document/src/main/java/org/exoplatform/services/document/impl/PDFDocumentReader.java
core/trunk/exo.core.component.document/src/test/java/org/exoplatform/services/document/test/TestPropertiesExtracting.java
core/trunk/pom.xml
Log:
EXOJCR-1175: Implement PDFDocumentReader.getProperties using PDFBox
Modified: core/trunk/exo.core.component.document/pom.xml
===================================================================
--- core/trunk/exo.core.component.document/pom.xml 2011-01-26 08:25:40 UTC (rev 3886)
+++ core/trunk/exo.core.component.document/pom.xml 2011-01-26 08:54:27 UTC (rev 3887)
@@ -55,10 +55,6 @@
<artifactId>pdfbox</artifactId>
</dependency>
<dependency>
- <groupId>com.lowagie</groupId>
- <artifactId>itext</artifactId>
- </dependency>
- <dependency>
<groupId>org.htmlparser</groupId>
<artifactId>htmlparser</artifactId>
</dependency>
Modified: core/trunk/exo.core.component.document/src/main/java/org/exoplatform/services/document/impl/PDFDocumentReader.java
===================================================================
--- core/trunk/exo.core.component.document/src/main/java/org/exoplatform/services/document/impl/PDFDocumentReader.java 2011-01-26 08:25:40 UTC (rev 3886)
+++ core/trunk/exo.core.component.document/src/main/java/org/exoplatform/services/document/impl/PDFDocumentReader.java 2011-01-26 08:54:27 UTC (rev 3887)
@@ -18,38 +18,30 @@
*/
package org.exoplatform.services.document.impl;
-import com.lowagie.text.pdf.PdfDate;
-import com.lowagie.text.pdf.PdfReader;
-
+import org.apache.jempbox.xmp.XMPMetadata;
+import org.apache.jempbox.xmp.XMPSchemaBasic;
+import org.apache.jempbox.xmp.XMPSchemaDublinCore;
+import org.apache.jempbox.xmp.XMPSchemaPDF;
+import org.apache.pdfbox.exceptions.InvalidPasswordException;
import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
+import org.apache.pdfbox.pdmodel.PDDocumentInformation;
+import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.pdfbox.util.PDFTextStripper;
-import org.exoplatform.commons.utils.ISO8601;
-import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.services.document.DCMetaData;
import org.exoplatform.services.document.DocumentReadException;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import java.text.ParseException;
import java.util.Calendar;
-import java.util.HashMap;
import java.util.Properties;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
/**
* Created by The eXo Platform SAS A parser of Adobe PDF files.
*
@@ -167,227 +159,279 @@
* @see org.exoplatform.services.document.DocumentReader#getProperties(java.io.
* InputStream)
*/
- public Properties getProperties(InputStream is) throws IOException, DocumentReadException
+ public Properties getProperties(final InputStream is) throws IOException, DocumentReadException
{
+ try
+ {
+ return (Properties)AccessController.doPrivileged(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ if (is == null)
+ {
+ throw new NullPointerException("InputStream is null.");
+ }
- Properties props = null;
+ PDDocument pdDocument = PDDocument.load(is);
+ Properties props = new Properties();
+ try
+ {
+ if (pdDocument.isEncrypted())
+ {
+ try
+ {
+ pdDocument.decrypt("");
+ }
+ catch (InvalidPasswordException e)
+ {
+ throw new DocumentReadException("The pdf document is encrypted.", e);
+ }
+ catch (org.apache.pdfbox.exceptions.CryptographyException e)
+ {
+ throw new DocumentReadException(e.getMessage(), e);
+ }
+ }
- PdfReader reader = new PdfReader(is, "".getBytes());
+ PDDocumentCatalog catalog = pdDocument.getDocumentCatalog();
+ PDMetadata meta = catalog.getMetadata();
+ if (meta != null)
+ {
+ XMPMetadata metadata = meta.exportXMPMetadata();
- // Read the file metadata
- byte[] metadata = reader.getMetadata();
+ XMPSchemaDublinCore dc = metadata.getDublinCoreSchema();
+ if (dc != null)
+ {
+ try
+ {
+ if (dc.getTitle() != null)
+ props.put(DCMetaData.TITLE, dc.getTitle());
+ }
+ catch (Exception e)
+ {
+ log.warn("getTitle failed: " + e);
+ }
+ try
+ {
+ if (dc.getDescription() != null)
+ props.put(DCMetaData.DESCRIPTION, dc.getDescription());
+ }
+ catch (Exception e)
+ {
+ log.warn("getSubject failed: " + e);
+ }
- if (metadata != null)
- {
- // there is XMP metadata try exctract it
- props = getPropertiesFromMetadata(metadata);
- }
+ try
+ {
+ if (dc.getCreators() != null)
+ {
+ for (String creator : dc.getCreators())
+ {
+ props.put(DCMetaData.CREATOR, creator);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ log.warn("getCreator failed: " + e);
+ }
- if (props == null)
- {
- // it's old pdf document version
- props = getPropertiesFromInfo(reader.getInfo());
- }
- reader.close();
- if (is != null)
- try
- {
- is.close();
- }
- catch (IOException e)
- {
- }
- return props;
- }
+ try
+ {
+ if (dc.getDates() != null)
+ {
+ for (Calendar date : dc.getDates())
+ {
+ props.put(DCMetaData.DATE, date);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ log.warn("getDate failed: " + e);
+ }
+ }
- /**
- * Extract properties from XMP xml.
- *
- * @param metadata XML as byte array
- * @return extracted properties
- * @throws DocumentReadException
- * @throws Exception if extracting fails
- */
- protected Properties getPropertiesFromMetadata(final byte[] metadata) throws IOException, DocumentReadException
- {
+ XMPSchemaPDF pdf = metadata.getPDFSchema();
+ if (pdf != null)
+ {
+ try
+ {
+ if (pdf.getKeywords() != null)
+ props.put(DCMetaData.SUBJECT, pdf.getKeywords());
+ }
+ catch (Exception e)
+ {
+ log.warn("getKeywords failed: " + e);
+ }
- Properties props = null;
+ try
+ {
+ if (pdf.getProducer() != null)
+ props.put(DCMetaData.PUBLISHER, pdf.getProducer());
+ }
+ catch (Exception e)
+ {
+ log.warn("getProducer failed: " + e);
+ }
+ }
- // parse xml
- Document doc;
- try
- {
- final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- doc = SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Document>()
- {
- public Document run() throws Exception
- {
- DocumentBuilder docBuilder = dbf.newDocumentBuilder();
- return docBuilder.parse(new ByteArrayInputStream(metadata));
+ XMPSchemaBasic basic = metadata.getBasicSchema();
+ if (basic != null)
+ {
+ try
+ {
+ if (basic.getCreateDate() != null)
+ props.put(DCMetaData.DATE, basic.getCreateDate());
+ }
+ catch (Exception e)
+ {
+ log.warn("getCreationDate failed: " + e);
+ }
+ try
+ {
+ if (basic.getModifyDate() != null)
+ props.put(DCMetaData.DATE, basic.getModifyDate());
+ }
+ catch (Exception e)
+ {
+ log.warn("getModificationDate failed: " + e);
+ }
+ // try
+ // {
+ // if (basic.getCreatorTool() != null)
+ // props.put(DCMetaData.PUBLISHER, basic.getCreatorTool());
+ // }
+ // catch (Exception e)
+ // {
+ // log.warn("getCreatorTool failed: " + e);
+ // }
+ }
+ }
+ else
+ {
+ // The pdf doesn't contain any metadata, try to use the document
+ // information instead
+ PDDocumentInformation docInfo = pdDocument.getDocumentInformation();
+
+ if (docInfo != null)
+ {
+ try
+ {
+ if (docInfo.getAuthor() != null)
+ props.put(DCMetaData.CONTRIBUTOR, docInfo.getAuthor());
+ }
+ catch (Exception e)
+ {
+ log.warn("getAuthor failed: " + e);
+ }
+ try
+ {
+ if (docInfo.getCreationDate() != null)
+ props.put(DCMetaData.DATE, docInfo.getCreationDate());
+ }
+ catch (Exception e)
+ {
+ log.warn("getCreationDate failed: " + e);
+ }
+ try
+ {
+ if (docInfo.getCreator() != null)
+ props.put(DCMetaData.CREATOR, docInfo.getCreator());
+ }
+ catch (Exception e)
+ {
+ log.warn("getCreator failed: " + e);
+ }
+ try
+ {
+
+ if (docInfo.getKeywords() != null)
+ props.put(DCMetaData.SUBJECT, docInfo.getKeywords());
+ }
+ catch (Exception e)
+ {
+ log.warn("getKeywords failed: " + e);
+ }
+ try
+ {
+ if (docInfo.getModificationDate() != null)
+ props.put(DCMetaData.DATE, docInfo.getModificationDate());
+ }
+ catch (Exception e)
+ {
+ log.warn("getModificationDate failed: " + e);
+ }
+ try
+ {
+ if (docInfo.getProducer() != null)
+ props.put(DCMetaData.PUBLISHER, docInfo.getProducer());
+ }
+ catch (Exception e)
+ {
+ log.warn("getProducer failed: " + e);
+ }
+ try
+ {
+ if (docInfo.getSubject() != null)
+ props.put(DCMetaData.DESCRIPTION, docInfo.getSubject());
+ }
+ catch (Exception e)
+ {
+ log.warn("getSubject failed: " + e);
+ }
+ try
+ {
+ if (docInfo.getTitle() != null)
+ props.put(DCMetaData.TITLE, docInfo.getTitle());
+ }
+ catch (Exception e)
+ {
+ log.warn("getTitle failed: " + e);
+ }
+
+ // docInfo.getTrapped();
+ }
+ }
+ }
+ finally
+ {
+ if (pdDocument != null)
+ {
+ pdDocument.close();
+ }
+
+ if (is != null)
+ {
+ try
+ {
+ is.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+ return props;
}
});
+
}
catch (PrivilegedActionException pae)
{
Throwable cause = pae.getCause();
- if (cause instanceof SAXException)
+ if (cause instanceof IOException)
{
- throw new DocumentReadException(cause.getMessage(), cause);
- }
- else if (cause instanceof ParserConfigurationException)
- {
- throw (RuntimeException)cause;
- }
- else if (cause instanceof IOException)
- {
throw (IOException)cause;
}
else if (cause instanceof RuntimeException)
{
- throw new DocumentReadException(cause.getMessage(), cause);
+ throw (RuntimeException)cause;
}
else
{
throw new RuntimeException(cause);
}
}
-
- // Check is there PDF/A-1 XMP
- String version = "";
- NodeList list = doc.getElementsByTagName("pdfaid:conformance");
- if (list != null && list.item(0) != null)
- {
- version += list.item(0).getTextContent() + "-";
- }
-
- list = doc.getElementsByTagName("pdfaid:part");
- if (list != null && list.item(0) != null)
- {
- version += list.item(0).getTextContent();
- }
-
- // PDF/A-1a or PDF/A-1b
- if (version.equalsIgnoreCase("A-1"))
- {
- props = getPropsFromPDFAMetadata(doc);
- }
-
- return props;
}
- /**
- * Extracts properties from PDF Info hash set.
- *
- * @param Pdf Info hash set
- * @return Extracted properties
- * @throws Exception if extracting fails
- */
- @SuppressWarnings("unchecked")
- protected Properties getPropertiesFromInfo(HashMap info) throws IOException
- {
- Properties props = new Properties();
-
- String title = (String)info.get("Title");
- if (title != null)
- {
- props.put(DCMetaData.TITLE, title);
- }
-
- String author = (String)info.get("Author");
- if (author != null)
- {
- props.put(DCMetaData.CREATOR, author);
- }
-
- String subject = (String)info.get("Subject");
- if (subject != null)
- {
- props.put(DCMetaData.SUBJECT, subject);
- }
-
- String creationDate = (String)info.get("CreationDate");
- if (creationDate != null)
- {
- props.put(DCMetaData.DATE, PdfDate.decode(creationDate));
- }
-
- String modDate = (String)info.get("ModDate");
- if (modDate != null)
- {
- props.put(DCMetaData.DATE, PdfDate.decode(modDate));
- }
-
- return props;
- }
-
- private Properties getPropsFromPDFAMetadata(Document doc) throws IOException, DocumentReadException
- {
- Properties props = new Properties();
- // get properties
- NodeList list = doc.getElementsByTagName("rdf:li");
- if (list != null && list.getLength() > 0)
- {
- for (int i = 0; i < list.getLength(); i++)
- {
-
- Node n = list.item(i);
- // dc:title - TITLE
- if (n.getParentNode().getParentNode().getNodeName().equals("dc:title"))
- {
- String title = n.getLastChild().getTextContent();
- props.put(DCMetaData.TITLE, title);
- }
-
- // dc:creator - CREATOR
- if (n.getParentNode().getParentNode().getNodeName().equals("dc:creator"))
- {
- String author = n.getLastChild().getTextContent();
- props.put(DCMetaData.CREATOR, author);
- }
-
- // DC:description - SUBJECT
- if (n.getParentNode().getParentNode().getNodeName().equals("dc:description"))
- {
- String description = n.getLastChild().getTextContent();
- props.put(DCMetaData.SUBJECT, description);
- // props.put(DCMetaData.DESCRIPTION, description);
- }
- }
- }
-
- try
- {
- // xmp:CreateDate - DATE
- list = doc.getElementsByTagName("xmp:CreateDate");
- if (list != null && list.item(0) != null)
- {
- Node creationDateNode = list.item(0).getLastChild();
- if (creationDateNode != null)
- {
- String creationDate = creationDateNode.getTextContent();
- Calendar c = ISO8601.parseEx(creationDate);
- props.put(DCMetaData.DATE, c);
- }
- }
-
- // xmp:ModifyDate - DATE
- list = doc.getElementsByTagName("xmp:ModifyDate");
- if (list != null && list.item(0) != null)
- {
- Node modifyDateNode = list.item(0).getLastChild();
- if (modifyDateNode != null)
- {
- String modifyDate = modifyDateNode.getTextContent();
- Calendar c = ISO8601.parseEx(modifyDate);
- props.put(DCMetaData.DATE, c);
- }
- }
- }
- catch (ParseException e)
- {
- throw new DocumentReadException(e.getMessage(), e);
- }
- return props;
- }
-
}
Modified: core/trunk/exo.core.component.document/src/test/java/org/exoplatform/services/document/test/TestPropertiesExtracting.java
===================================================================
--- core/trunk/exo.core.component.document/src/test/java/org/exoplatform/services/document/test/TestPropertiesExtracting.java 2011-01-26 08:25:40 UTC (rev 3886)
+++ core/trunk/exo.core.component.document/src/test/java/org/exoplatform/services/document/test/TestPropertiesExtracting.java 2011-01-26 08:54:27 UTC (rev 3887)
@@ -18,7 +18,6 @@
*/
package org.exoplatform.services.document.test;
-import org.exoplatform.commons.utils.ISO8601;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.services.document.DCMetaData;
import org.exoplatform.services.document.DocumentReader;
@@ -77,10 +76,10 @@
Properties etalon = new Properties();
etalon.put(DCMetaData.TITLE, "Test de convertion de fichier tif");
etalon.put(DCMetaData.CREATOR, "Christian Klaus");
- etalon.put(DCMetaData.SUBJECT, "20080901 TEST Christian Etat OK");
- Calendar c = ISO8601.parseEx("2008-09-01T08:01:10+00:00");
- etalon.put(DCMetaData.DATE, c);
- evalProps(etalon, testprops);
+ etalon.put(DCMetaData.DESCRIPTION, "20080901 TEST Christian Etat OK");
+ // Calendar c = ISO8601.parseEx("2008-09-01T08:01:10+00:00");
+ // etalon.put(DCMetaData.DATE, c);
+ evalProps(etalon, testprops, false);
}
finally
{
@@ -88,6 +87,26 @@
}
}
+ public void testPDFDocumentReaderServiceBrokenFile() throws Exception
+ {
+ InputStream is = TestPropertiesExtracting.class.getResourceAsStream("/pfs_accapp.pdf");
+ try
+ {
+
+ DocumentReader rdr = service.getDocumentReader("application/pdf");
+ Properties testprops = rdr.getProperties(is);
+ Properties etalon = new Properties();
+ etalon.put(DCMetaData.TITLE, "Personal Account Opening Form VN");
+ etalon.put(DCMetaData.CREATOR, "mr");
+ etalon.put(DCMetaData.PUBLISHER, "Adobe LiveCycle Designer ES 8.2");
+ evalProps(etalon, testprops, false);
+ }
+ finally
+ {
+ is.close();
+ }
+ }
+
public void testWordDocumentReaderService() throws Exception
{
InputStream is = TestPropertiesExtracting.class.getResourceAsStream("/test.doc");
@@ -101,7 +120,7 @@
etalon.put(DCMetaData.CREATOR, "Max Yakimenko");
etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
- evalProps(etalon, props);
+ evalProps(etalon, props, true);
}
finally
{
@@ -122,7 +141,7 @@
etalon.put(DCMetaData.CREATOR, "Max Yakimenko");
etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
- evalProps(etalon, props);
+ evalProps(etalon, props, true);
}
finally
{
@@ -144,7 +163,7 @@
etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
- evalProps(etalon, props);
+ evalProps(etalon, props, true);
}
finally
{
@@ -172,7 +191,7 @@
etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
- evalProps(etalon, props);
+ evalProps(etalon, props, true);
}
finally
{
@@ -200,7 +219,7 @@
etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
- evalProps(etalon, props);
+ evalProps(etalon, props, true);
}
finally
{
@@ -228,7 +247,7 @@
etalon.put(DCMetaData.CONTRIBUTOR, "Max Yakimenko");
etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
- evalProps(etalon, props);
+ evalProps(etalon, props, true);
}
finally
{
@@ -254,7 +273,7 @@
etalon.put(DCMetaData.CREATOR, "Sergiy Karpenko");
etalon.put(DCMetaData.DESCRIPTION, "test-Comments");
- evalProps(etalon, props);
+ evalProps(etalon, props, true);
}
finally
{
@@ -262,7 +281,7 @@
}
}
- private void evalProps(Properties etalon, Properties testedProps)
+ private void evalProps(Properties etalon, Properties testedProps, boolean testSize)
{
Iterator it = etalon.entrySet().iterator();
while (it.hasNext())
@@ -272,7 +291,10 @@
assertNotNull(prop.getKey() + " property not founded. ", tval);
assertEquals(prop.getKey() + " property value is incorrect", prop.getValue(), tval);
}
- assertEquals("size is incorrect", etalon.size(), testedProps.size());
+ if (testSize)
+ {
+ assertEquals("size is incorrect", etalon.size(), testedProps.size());
+ }
}
}
Added: core/trunk/exo.core.component.document/src/test/resources/pfs_accapp.pdf
===================================================================
(Binary files differ)
Property changes on: core/trunk/exo.core.component.document/src/test/resources/pfs_accapp.pdf
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: core/trunk/pom.xml
===================================================================
--- core/trunk/pom.xml 2011-01-26 08:25:40 UTC (rev 3886)
+++ core/trunk/pom.xml 2011-01-26 08:54:27 UTC (rev 3887)
@@ -272,15 +272,7 @@
<artifactId>pdfbox</artifactId>
<version>1.1.0</version>
</dependency>
-
<dependency>
- <groupId>com.lowagie</groupId>
- <artifactId>itext</artifactId>
- <version>2.1.0</version>
- <scope>compile</scope>
- </dependency>
-
- <dependency>
<groupId>org.htmlparser</groupId>
<artifactId>htmlparser</artifactId>
<version>1.6</version>
13 years, 3 months