exo-jcr SVN: r4230 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr: impl/backup and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-04-13 06:47:04 -0400 (Wed, 13 Apr 2011)
New Revision: 4230
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ManageableRepository.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/RepositorySuspendController.java
Log:
EXOJCR-1301: Allow to use external backup tools in a secure manner
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ManageableRepository.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ManageableRepository.java 2011-04-13 09:55:03 UTC (rev 4229)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ManageableRepository.java 2011-04-13 10:47:04 UTC (rev 4230)
@@ -60,6 +60,16 @@
final int READONLY = 2;
/**
+ * Repository SUSPENDED state.
+ */
+ public final int SUSPENDED = 3;
+
+ /**
+ * Undefined state.
+ */
+ public final int UNDEFINED = 4;
+
+ /**
* Add the items persistence listener to the named workspace.
*
* @param workspaceName - name of workspace
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/RepositorySuspendController.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/RepositorySuspendController.java 2011-04-13 09:55:03 UTC (rev 4229)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/RepositorySuspendController.java 2011-04-13 10:47:04 UTC (rev 4230)
@@ -41,21 +41,6 @@
@NameTemplate(@Property(key = "service", value = "RepositorySuspendController"))
public class RepositorySuspendController implements Startable
{
- /**
- * Repository ONLINE state.
- */
- private final int ONLINE = 1;
-
- /**
- * Repository SUSPENDED state.
- */
- private final int SUSPENDED = 3;
-
- /**
- * Undefined state.
- */
- private final int UNDEFINED = 4;
-
private final ManageableRepository repository;
/**
@@ -72,11 +57,13 @@
}
/**
- * {@inheritDoc}
+ * Suspend repository which means that allow only read operations. All writing threads will wait until resume operations invoked.
+ *
+ * @return repository state
*/
@Managed
@ManagedDescription("Suspend repository which means that allow only read operations. All writing threads will wait until resume operations invoked.")
- public void suspend()
+ public int suspend()
{
for (Suspendable component : getSuspendableComponents())
{
@@ -89,14 +76,18 @@
log.error("Can't suspend component", e);
}
}
+
+ return getState();
}
/**
- * {@inheritDoc}
+ * Resume repository. All previously suspended threads continue working.
+ *
+ * @return repository state
*/
@Managed
@ManagedDescription("Resume repository. All previously suspended threads continue working.")
- public void resume()
+ public int resume()
{
List<Suspendable> components = getSuspendableComponents();
Collections.reverse(components);
@@ -115,16 +106,18 @@
log.error("Can't resume component", e);
}
}
+
+ return getState();
}
/**
- * {@inheritDoc}
+ * Returns repository state.
*/
@Managed
@ManagedDescription("Returns repository state.")
public int getState()
{
- int state = ONLINE;
+ int state = ManageableRepository.ONLINE;
boolean hasSuspendedComponents = false;
boolean hasOnlineComponents = false;
@@ -137,17 +130,17 @@
if (hasOnlineComponents)
{
- return UNDEFINED;
+ return ManageableRepository.UNDEFINED;
}
- state = SUSPENDED;
+ state = ManageableRepository.SUSPENDED;
}
else
{
hasOnlineComponents = true;
if (hasSuspendedComponents)
{
- return UNDEFINED;
+ return ManageableRepository.UNDEFINED;
}
}
}
15 years
exo-jcr SVN: r4229 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl: backup and 3 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-04-13 05:55:03 -0400 (Wed, 13 Apr 2011)
New Revision: 4229
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/RepositorySuspendController.java
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/backup/Suspendable.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/lucene/SearchIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
Log:
EXOJCR-1301: Allow to use external backup tools in a secure manner
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-04-12 13:53:48 UTC (rev 4228)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2011-04-13 09:55:03 UTC (rev 4229)
@@ -34,6 +34,7 @@
import org.exoplatform.services.jcr.core.nodetype.ExtendedNodeTypeManager;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
+import org.exoplatform.services.jcr.impl.backup.RepositorySuspendController;
import org.exoplatform.services.jcr.impl.core.AddNamespacePluginHolder;
import org.exoplatform.services.jcr.impl.core.LocationFactory;
import org.exoplatform.services.jcr.impl.core.NamespaceDataPersister;
@@ -638,6 +639,8 @@
{
public Void run()
{
+
+ registerComponentImplementation(RepositorySuspendController.class);
registerComponentImplementation(IdGenerator.class);
registerComponentImplementation(RepositoryIndexSearcherHolder.class);
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/RepositorySuspendController.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/RepositorySuspendController.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/RepositorySuspendController.java 2011-04-13 09:55:03 UTC (rev 4229)
@@ -0,0 +1,183 @@
+/*
+ * 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.management.annotations.Managed;
+import org.exoplatform.management.annotations.ManagedDescription;
+import org.exoplatform.management.jmx.annotations.NameTemplate;
+import org.exoplatform.management.jmx.annotations.Property;
+import org.exoplatform.services.jcr.core.ManageableRepository;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.picocontainer.Startable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Allows via JMX suspend and resume repository's components.
+ *
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy Bazko</a>
+ * @version $Id: RepositorySuspendController.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+@Managed
+@NameTemplate(@Property(key = "service", value = "RepositorySuspendController"))
+public class RepositorySuspendController implements Startable
+{
+ /**
+ * Repository ONLINE state.
+ */
+ private final int ONLINE = 1;
+
+ /**
+ * Repository SUSPENDED state.
+ */
+ private final int SUSPENDED = 3;
+
+ /**
+ * Undefined state.
+ */
+ private final int UNDEFINED = 4;
+
+ private final ManageableRepository repository;
+
+ /**
+ * Logger.
+ */
+ protected static Log log = ExoLogger.getLogger("exo.jcr.component.core.RepositorySuspendController");
+
+ /**
+ * RepositoryController constructor.
+ */
+ public RepositorySuspendController(ManageableRepository repository)
+ {
+ this.repository = repository;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Managed
+ @ManagedDescription("Suspend repository which means that allow only read operations. All writing threads will wait until resume operations invoked.")
+ public void suspend()
+ {
+ for (Suspendable component : getSuspendableComponents())
+ {
+ try
+ {
+ component.suspend();
+ }
+ catch (SuspendException e)
+ {
+ log.error("Can't suspend component", e);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Managed
+ @ManagedDescription("Resume repository. All previously suspended threads continue working.")
+ public void resume()
+ {
+ List<Suspendable> components = getSuspendableComponents();
+ Collections.reverse(components);
+
+ for (Suspendable component : components)
+ {
+ try
+ {
+ if (component.isSuspended())
+ {
+ component.resume();
+ }
+ }
+ catch (ResumeException e)
+ {
+ log.error("Can't resume component", e);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Managed
+ @ManagedDescription("Returns repository state.")
+ public int getState()
+ {
+ int state = ONLINE;
+
+ boolean hasSuspendedComponents = false;
+ boolean hasOnlineComponents = false;
+
+ for (Suspendable component : getSuspendableComponents())
+ {
+ if (component.isSuspended())
+ {
+ hasSuspendedComponents = true;
+
+ if (hasOnlineComponents)
+ {
+ return UNDEFINED;
+ }
+
+ state = SUSPENDED;
+ }
+ else
+ {
+ hasOnlineComponents = true;
+ if (hasSuspendedComponents)
+ {
+ return UNDEFINED;
+ }
+ }
+ }
+
+ return state;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void start()
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop()
+ {
+ }
+
+ private List<Suspendable> getSuspendableComponents()
+ {
+ List<Suspendable> components = new ArrayList<Suspendable>();
+ for (String workspaceName : repository.getWorkspaceNames())
+ {
+ components.addAll(repository.getWorkspaceContainer(workspaceName).getComponentInstancesOfType(
+ Suspendable.class));
+ }
+
+ return components;
+ }
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/Suspendable.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/Suspendable.java 2011-04-12 13:53:48 UTC (rev 4228)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/Suspendable.java 2011-04-13 09:55:03 UTC (rev 4229)
@@ -25,17 +25,24 @@
public interface Suspendable
{
/**
- * Suspend component.
+ * Suspend component.
*
- * @throws SuspendException of error occurred
+ * @throws SuspendException of error occurred
*/
void suspend() throws SuspendException;
/**
- * Resume component.
+ * Resume component.
*
- * @throws ResumeException of error occurred
+ * @throws ResumeException of error occurred
*/
void resume() throws ResumeException;
+ /**
+ * Indicates if component is suspended or not.
+ *
+ * @return
+ */
+ boolean isSuspended();
+
}
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-04-12 13:53:48 UTC (rev 4228)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2011-04-13 09:55:03 UTC (rev 4229)
@@ -1056,6 +1056,14 @@
}
/**
+ * {@inheritDoc}
+ */
+ public boolean isSuspended()
+ {
+ return isSuspended;
+ }
+
+ /**
* Switches index into online or offline modes.
*
* @param isOnline
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-04-12 13:53:48 UTC (rev 4228)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2011-04-13 09:55:03 UTC (rev 4229)
@@ -515,6 +515,11 @@
protected CountDownLatch latcher = null;
/**
+ * Indicates if component suspended or not.
+ */
+ protected boolean isSuspended = false;
+
+ /**
* Working constructor.
*
* @throws RepositoryConfigurationException
@@ -3090,6 +3095,8 @@
{
latcher = new CountDownLatch(1);
close();
+
+ isSuspended = true;
}
/**
@@ -3103,6 +3110,8 @@
doInit();
latcher.countDown();
+
+ isSuspended = false;
}
catch (IOException e)
{
@@ -3115,6 +3124,14 @@
}
/**
+ * {@inheritDoc}
+ */
+ public boolean isSuspended()
+ {
+ return isSuspended;
+ }
+
+ /**
* If component is suspended need to wait resuming and not allow
* execute query on closed index.
*
@@ -3122,7 +3139,7 @@
*/
private void waitForResuming() throws IOException
{
- if (latcher != null && latcher.getCount() != 0)
+ if (isSuspended)
{
try
{
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-04-12 13:53:48 UTC (rev 4228)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-04-13 09:55:03 UTC (rev 4229)
@@ -1148,6 +1148,14 @@
isResponsibleForResuming = false;
}
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isSuspended()
+ {
+ return isSuspended;
+ }
+
private void suspendLocally() throws SuspendException
{
if (isSuspended)
15 years
exo-jcr SVN: r4228 - in jcr/trunk: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock and 10 other directories.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-04-12 09:53:48 -0400 (Tue, 12 Apr 2011)
New Revision: 4228
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionRegistry.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.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/lucene/DynamicPooledExecutor.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexMerger.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/LinkedWorkspaceStorageCacheImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/proccess/WorkerService.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/AbstractBackupJob.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupChainImpl.java
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/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/initializer/RemoteWorkspaceInitializationService.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/replication/recovery/ConnectionFailDetector.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/replication/recovery/WaitConfirmation.java
jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServerImpl.java
jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/data/FtpDataTransiverImpl.java
Log:
EXOJCR-1241 : The patch was applied for "Give a more understandable name to all the existing Threads"
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionRegistry.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionRegistry.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionRegistry.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -212,7 +212,7 @@
{
super(workTime);
this.sessionTimeOut = sessionTimeOut;
- setName("SessionCleaner " + (id == null ? getId() : id));
+ setName("Session Cleaner " + (id == null ? getId() : id));
setPriority(Thread.MIN_PRIORITY);
setDaemon(true);
start();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.jcr.impl.core.lock;
+import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.impl.proccess.WorkerService;
@@ -39,21 +40,30 @@
*/
private final WorkerService workerService;
+
/**
* Constructor.
* @param entry - RepositoryEntry that may contain lock-remover-max-threads parameter.
*/
public LockRemoverHolder(RepositoryEntry entry)
{
+ this(null, entry);
+ }
+
+ /**
+ * Constructor.
+ * @param ctx - The {@link ExoContainerContext} in which the {@link LockRemoverHolder}
+ * is registered
+ * @param entry - RepositoryEntry that may contain lock-remover-max-threads parameter.
+ */
+ public LockRemoverHolder(ExoContainerContext ctx, RepositoryEntry entry)
+ {
int threadCount = DEFAULT_THREAD_COUNT;
- if (entry != null)
+ if (entry != null && entry.getLockRemoverThreadsCount() > 0)
{
- if (entry.getLockRemoverThreadsCount() > 0)
- {
- threadCount = entry.getLockRemoverThreadsCount();
- }
+ threadCount = entry.getLockRemoverThreadsCount();
}
- workerService = new WorkerService(threadCount, "lock-remover-" + entry.getName());
+ workerService = new WorkerService(threadCount, "Lock Remover " + (ctx != null ? ctx.getName() : (entry == null ? "" : entry.getName())));
}
/**
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-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -22,6 +22,7 @@
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.WildcardQuery;
import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.services.document.DocumentReaderService;
import org.exoplatform.services.jcr.RepositoryService;
@@ -180,6 +181,11 @@
protected final String wsId;
/**
+ * The unique name of the workspace container
+ */
+ protected final String wsContainerId;
+
+ /**
* Component responsible for executing commands in cluster nodes.
*/
protected final RPCService rpcService;
@@ -214,19 +220,21 @@
*/
private RemoteCommand requestForResponsibleForResuming;
- public SearchManager(WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
+ public SearchManager(ExoContainerContext ctx, WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
DocumentReaderService extractor, ConfigurationManager cfm, final RepositoryIndexSearcherHolder indexSearcherHolder)
throws RepositoryException, RepositoryConfigurationException
{
- this(wEntry, rEntry, rService, config, nsReg, ntReg, itemMgr, parentSearchManager, extractor, cfm,
+ this(ctx, wEntry, rEntry, rService, config, nsReg, ntReg, itemMgr, parentSearchManager, extractor, cfm,
indexSearcherHolder, null);
}
/**
* Creates a new <code>SearchManager</code>.
*
+ * @param ctx
+ * The eXo Container context in which the SearchManager is registered
* @param rEntry
* repository configuration
* @param rService
@@ -253,13 +261,14 @@
* if the search manager cannot be initialized
* @throws RepositoryConfigurationException
*/
- public SearchManager(WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
+ public SearchManager(ExoContainerContext ctx, WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
DocumentReaderService extractor, ConfigurationManager cfm,
final RepositoryIndexSearcherHolder indexSearcherHolder, RPCService rpcService) throws RepositoryException,
RepositoryConfigurationException
{
+ this.wsContainerId = ctx.getName();
this.rpcService = rpcService;
this.repositoryName = rEntry.getName();
this.workspaceName = wEntry.getName();
@@ -863,8 +872,18 @@
try
{
Class qHandlerClass = Class.forName(className, true, this.getClass().getClassLoader());
- Constructor constuctor = qHandlerClass.getConstructor(QueryHandlerEntry.class, ConfigurationManager.class);
- handler = (QueryHandler)constuctor.newInstance(config, cfm);
+ try
+ {
+ // We first try a constructor with the workspace id
+ Constructor constuctor = qHandlerClass.getConstructor(String.class, QueryHandlerEntry.class, ConfigurationManager.class);
+ handler = (QueryHandler)constuctor.newInstance(wsContainerId, config, cfm);
+ }
+ catch (NoSuchMethodException e)
+ {
+ // No constructor with the workspace id can be found so we use the default constructor
+ Constructor constuctor = qHandlerClass.getConstructor(QueryHandlerEntry.class, ConfigurationManager.class);
+ handler = (QueryHandler)constuctor.newInstance(config, cfm);
+ }
QueryHandler parentHandler = (this.parentSearchManager != null) ? parentSearchManager.getHandler() : null;
QueryHandlerContext context = createQueryHandlerContext(parentHandler);
handler.setContext(context);
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-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -16,6 +16,7 @@
*/
package org.exoplatform.services.jcr.impl.core.query;
+import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.services.document.DocumentReaderService;
import org.exoplatform.services.jcr.RepositoryService;
@@ -61,22 +62,22 @@
public static final String INDEX_DIR_SUFFIX = "system";
- public SystemSearchManager(WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
+ public SystemSearchManager(ExoContainerContext ctx, WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
WorkspacePersistentDataManager itemMgr, DocumentReaderService service, ConfigurationManager cfm,
RepositoryIndexSearcherHolder indexSearcherHolder, RPCService rpcService) throws RepositoryException,
RepositoryConfigurationException
{
- super(wEntry, rEntry, rService, config, nsReg, ntReg, itemMgr, null, service, cfm, indexSearcherHolder,
+ super(ctx, wEntry, rEntry, rService, config, nsReg, ntReg, itemMgr, null, service, cfm, indexSearcherHolder,
rpcService);
}
- public SystemSearchManager(WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
+ public SystemSearchManager(ExoContainerContext ctx, WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
WorkspacePersistentDataManager itemMgr, DocumentReaderService service, ConfigurationManager cfm,
RepositoryIndexSearcherHolder indexSearcherHolder) throws RepositoryException, RepositoryConfigurationException
{
- this(wEntry, rEntry, rService, config, nsReg, ntReg, itemMgr, service, cfm, indexSearcherHolder, null);
+ this(ctx, wEntry, rEntry, rService, config, nsReg, ntReg, itemMgr, service, cfm, indexSearcherHolder, null);
}
@Override
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DynamicPooledExecutor.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DynamicPooledExecutor.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DynamicPooledExecutor.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -16,12 +16,14 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.lang.reflect.InvocationTargetException;
-
import EDU.oswego.cs.dl.util.concurrent.Callable;
import EDU.oswego.cs.dl.util.concurrent.FutureResult;
import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
+import EDU.oswego.cs.dl.util.concurrent.ThreadFactory;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.atomic.AtomicInteger;
+
/**
* <code>DynamicPooledExecutor</code> implements an executor, which dynamically
* adjusts its maximum number of threads according to the number of available
@@ -50,6 +52,12 @@
public DynamicPooledExecutor() {
executor = new PooledExecutor();
executor.setKeepAliveTime(500);
+ executor.setThreadFactory(new ThreadFactory() {
+ AtomicInteger count = new AtomicInteger();
+ public Thread newThread(Runnable command) {
+ return new Thread(command, "DynamicPooledExecutor-thread-" + count.incrementAndGet());
+ }
+ });
adjustPoolSize();
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexMerger.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexMerger.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexMerger.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -108,7 +108,7 @@
IndexMerger(MultiIndex multiIndex)
{
this.multiIndex = multiIndex;
- setName("IndexMerger");
+ setName("Index Merger" + (multiIndex.workspaceId == null ? "" : " " + multiIndex.workspaceId));
setDaemon(true);
try
{
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-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -197,7 +197,7 @@
/**
* Timer to schedule flushes of this index after some idle time.
*/
- private static final Timer FLUSH_TIMER = new Timer(true);
+ private static final Timer FLUSH_TIMER = new Timer("MultiIndex Flush Timer", true);
/**
* Task that is periodically called by {@link #FLUSH_TIMER} and checks if
@@ -253,6 +253,11 @@
private final IndexerIoModeHandler modeHandler;
/**
+ * The unique id of the workspace corresponding to this multi index
+ */
+ final String workspaceId;
+
+ /**
* Creates a new MultiIndex.
*
* @param handler
@@ -272,6 +277,7 @@
// this method is run in privileged mode internally
this.indexDir = directoryManager.getDirectory(".");
this.handler = handler;
+ this.workspaceId = handler.getWsId();
this.cache = new DocNumberCache(handler.getCacheSize());
this.indexingTree = indexingTree;
this.nsMappings = handler.getNamespaceMappings();
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-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -482,6 +482,11 @@
*/
private ErrorLog errorLog;
+ /**
+ * The unique id of the workspace corresponding to current instance of {@link SearchIndex}
+ */
+ private final String wsId;
+
private final ConfigurationManager cfm;
/**
@@ -515,25 +520,36 @@
* @throws RepositoryConfigurationException
* @throws IOException
*/
- public SearchIndex(QueryHandlerEntry queryHandlerConfig, ConfigurationManager cfm) throws IOException,
+ public SearchIndex(String wsId, QueryHandlerEntry queryHandlerConfig, ConfigurationManager cfm) throws IOException,
RepositoryConfigurationException
{
+ this.wsId = wsId;
this.analyzer = new JcrStandartAnalyzer();
- // this.queryHandlerConfig = new QueryHandlerEntryWrapper(
- // queryHandlerConfig);
this.cfm = cfm;
SearchIndexConfigurationHelper searchIndexConfigurationHelper = new SearchIndexConfigurationHelper(this);
searchIndexConfigurationHelper.init(queryHandlerConfig);
}
/**
+ * Working constructor.
+ *
+ * @throws RepositoryConfigurationException
+ * @throws IOException
+ */
+ public SearchIndex(QueryHandlerEntry queryHandlerConfig, ConfigurationManager cfm) throws IOException,
+ RepositoryConfigurationException
+ {
+ this(null, queryHandlerConfig, cfm);
+ }
+
+ /**
* For test constructor.
*/
public SearchIndex()
{
this.analyzer = new JcrStandartAnalyzer();
- // this.queryHandlerConfig = null;
this.cfm = null;
+ this.wsId = null;
}
/**
@@ -700,6 +716,14 @@
}
modeHandler.addIndexerIoModeListener(this);
+ }
+
+ /**
+ * @return the wsId
+ */
+ public String getWsId()
+ {
+ return wsId;
}
private void reindex(boolean doReindexing, boolean doCheck, ItemDataConsumer itemStateManager) throws IOException
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -45,10 +45,10 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Timer;
import java.util.TimerTask;
import java.util.WeakHashMap;
+import java.util.Map.Entry;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.ReentrantLock;
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/proccess/WorkerService.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/proccess/WorkerService.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/proccess/WorkerService.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -59,7 +59,7 @@
this.isDaemon = isDaemon;
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
- this.namePrefix = namePrefix + "-" + poolNumber.getAndIncrement() + "-thread-";
+ this.namePrefix = (namePrefix == null || namePrefix.isEmpty()) ? "pool-" + poolNumber.getAndIncrement() + "-thread-" : namePrefix + " ";
}
public Thread newThread(Runnable r)
@@ -79,7 +79,7 @@
*/
public WorkerService(int threadCount)
{
- this(threadCount, "pool");
+ this(threadCount, null);
}
/**
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -19,6 +19,7 @@
package org.exoplatform.services.jcr.impl.util.io;
import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.services.jcr.impl.proccess.WorkerThread;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -50,11 +51,21 @@
this(DEFAULT_TIMEOUT);
}
+ public FileCleaner(ExoContainerContext ctx)
+ {
+ this(null, ctx, DEFAULT_TIMEOUT);
+ }
+
public FileCleaner(long timeout)
{
this(timeout, true);
}
+ public FileCleaner(String prefix, ExoContainerContext ctx, long timeout)
+ {
+ this(ctx == null ? prefix : (prefix == null ? "" : prefix + " ") + ctx.getName(), timeout, true);
+ }
+
public FileCleaner(boolean start)
{
this(DEFAULT_TIMEOUT, start);
@@ -62,8 +73,13 @@
public FileCleaner(long timeout, boolean start)
{
+ this(null, timeout, start);
+ }
+
+ public FileCleaner(String id, long timeout, boolean start)
+ {
super(timeout);
- setName("FileCleaner " + getId());
+ setName("File Cleaner " + (id == null ? getId() : id));
setDaemon(true);
setPriority(Thread.MIN_PRIORITY);
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -18,6 +18,8 @@
*/
package org.exoplatform.services.jcr.impl.util.io;
+import org.exoplatform.container.ExoContainerContext;
+
/**
* Created by The eXo Platform SAS. <br/> per workspace container file cleaner holder object
*
@@ -31,9 +33,14 @@
public FileCleanerHolder()
{
- this.fileCleaner = new FileCleaner();
+ this(null);
}
+ public FileCleanerHolder(ExoContainerContext ctx)
+ {
+ this.fileCleaner = new FileCleaner(ctx);
+ }
+
public FileCleaner getFileCleaner()
{
return fileCleaner;
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/AbstractBackupJob.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/AbstractBackupJob.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/AbstractBackupJob.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -66,6 +66,7 @@
NotifyThread(BackupJobListener[] listeners, BackupJob job)
{
+ super("NotifyThread");
super.setDaemon(true); // The Java Virtual Machine exits when the only threads running are all
// daemon threads.
this.listeners = listeners;
@@ -92,6 +93,7 @@
ErrorNotifyThread(BackupJobListener[] listeners, BackupJob job, String message, Throwable error)
{
super(listeners, job);
+ setName("ErrorNotifyThread");
this.error = error;
this.message = message;
}
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupChainImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupChainImpl.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupChainImpl.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -311,7 +311,7 @@
}
else
{
- Thread starter = new Thread()
+ Thread starter = new Thread("IncrementalBackup Starter")
{
@Override
public void run()
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-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -22,6 +22,7 @@
import org.exoplatform.commons.utils.PrivilegedFileHelper;
import org.exoplatform.commons.utils.PrivilegedSystemHelper;
import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.container.xml.PropertiesParam;
import org.exoplatform.services.jcr.RepositoryService;
@@ -208,7 +209,7 @@
private final WorkspaceBackupAutoStopper workspaceBackupStopper;
private final RepositoryBackupAutoStopper repositoryBackupStopper;
-
+
/**
* Temporary directory;
*/
@@ -309,6 +310,11 @@
class WorkspaceBackupAutoStopper extends Thread
{
+ WorkspaceBackupAutoStopper(ExoContainerContext ctx)
+ {
+ super("WorkspaceBackupAutoStopper" + (ctx == null ? "" : " " + ctx.getName()));
+ }
+
/**
* {@inheritDoc}
*/
@@ -359,6 +365,11 @@
class RepositoryBackupAutoStopper extends Thread
{
+ RepositoryBackupAutoStopper(ExoContainerContext ctx)
+ {
+ super("RepositoryBackupAutoStopper" + (ctx == null ? "" : " " + ctx.getName()));
+ }
+
/**
* {@inheritDoc}
*/
@@ -410,21 +421,47 @@
*/
public BackupManagerImpl(InitParams initParams, RepositoryService repoService)
{
- this(initParams, repoService, null);
+ this(null, initParams, repoService, null);
}
/**
* BackupManagerImpl constructor.
*
+ * @param initParams
* InitParams, the init parameters
* @param repoService
* RepositoryService, the repository service
+ */
+ public BackupManagerImpl(ExoContainerContext ctx, InitParams initParams, RepositoryService repoService)
+ {
+ this(ctx, initParams, repoService, null);
+ }
+
+ /**
+ * BackupManagerImpl constructor.
+ *
+ * InitParams, the init parameters
+ * @param repoService
+ * RepositoryService, the repository service
* @param registryService
* RegistryService, the registry service
*/
public BackupManagerImpl(InitParams initParams, RepositoryService repoService, RegistryService registryService)
{
-
+ this(null, initParams, repoService, registryService);
+ }
+
+ /**
+ * BackupManagerImpl constructor.
+ *
+ * InitParams, the init parameters
+ * @param repoService
+ * RepositoryService, the repository service
+ * @param registryService
+ * RegistryService, the registry service
+ */
+ public BackupManagerImpl(ExoContainerContext ctx, InitParams initParams, RepositoryService repoService, RegistryService registryService)
+ {
this.messagesListener = new MessagesListener();
this.repoService = repoService;
this.registryService = registryService;
@@ -457,13 +494,13 @@
this.restoreJobs = new ArrayList<JobWorkspaceRestore>();
this.restoreRepositoryJobs = new ArrayList<JobRepositoryRestore>();
- this.workspaceBackupStopper = new WorkspaceBackupAutoStopper();
+ this.workspaceBackupStopper = new WorkspaceBackupAutoStopper(ctx);
this.workspaceBackupStopper.start();
- this.repositoryBackupStopper = new RepositoryBackupAutoStopper();
+ this.repositoryBackupStopper = new RepositoryBackupAutoStopper(ctx);
this.repositoryBackupStopper.start();
}
-
+
/**
* {@inheritDoc}
*/
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-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -117,6 +117,7 @@
RepositoryEntry repositoryEntry, Map<String, BackupChainLog> workspacesMapping,
RepositoryBackupChainLog backupChainLog)
{
+ super("JobRepositoryRestore " + repositoryEntry.getName());
this.repositoryService = repoService;
this.backupManager = backupManagerImpl;
this.repositoryEntry = repositoryEntry;
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-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobWorkspaceRestore.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -134,6 +134,7 @@
public JobWorkspaceRestore(RepositoryService repositoryService, BackupManager backupManager, String repositoryName,
BackupChainLog log, WorkspaceEntry wEntry)
{
+ super("JobWorkspaceRestore " + wEntry.getUniqueName());
this.repositoryService = repositoryService;
this.backupManager = backupManager;
this.repositoryName = repositoryName;
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/initializer/RemoteWorkspaceInitializationService.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/initializer/RemoteWorkspaceInitializationService.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/initializer/RemoteWorkspaceInitializationService.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -392,6 +392,7 @@
*/
public WorkspaceDataPublisher(BackupChain chain, RemoteTransport transport)
{
+ super("WorkspaceDataPublisher");
this.backupChain = chain;
this.transport = transport;
}
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/replication/recovery/ConnectionFailDetector.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/replication/recovery/ConnectionFailDetector.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/replication/recovery/ConnectionFailDetector.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -310,6 +310,11 @@
*/
private final ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>();
+ public ViewChecker()
+ {
+ super("ViewChecker");
+ }
+
/**
* putView.
*
@@ -368,6 +373,7 @@
*/
public ReconectTtread(boolean isStop)
{
+ super("ReconectTtread");
log.info("Thread '" + getName() + "' is init ...");
this.isStop = isStop;
}
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/replication/recovery/WaitConfirmation.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/replication/recovery/WaitConfirmation.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/replication/recovery/WaitConfirmation.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -68,7 +68,7 @@
*/
WaitConfirmation(long timeOut, RecoveryManager recoveryManager, String identifier)
{
- super();
+ super("WaitConfirmation " + identifier);
this.timeOut = timeOut;
this.recoveryManager = recoveryManager;
this.identifier = identifier;
Modified: jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServerImpl.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServerImpl.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -219,6 +219,7 @@
{
this.ftpServer = ftpServer;
this.serverSocket = serverSocket;
+ setName("Ftp Server" + (configuration.getPortalContainer() == null ? "" : " " + configuration.getPortalContainer().getName()));
setDaemon(true);
}
Modified: jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/data/FtpDataTransiverImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/data/FtpDataTransiverImpl.java 2011-04-11 17:42:26 UTC (rev 4227)
+++ jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/data/FtpDataTransiverImpl.java 2011-04-12 13:53:48 UTC (rev 4228)
@@ -209,6 +209,11 @@
protected class AcceptDataConnect extends Thread
{
+ public AcceptDataConnect()
+ {
+ super("AcceptDataConnect" + (configuration.getPortalContainer() == null ? "" : " " + configuration.getPortalContainer().getName()));
+ }
+
protected Log acceptLog = ExoLogger.getLogger("jcr.AcceptDataConnect");
@Override
@@ -237,6 +242,11 @@
protected class ConnectDataPort extends Thread
{
+ public ConnectDataPort()
+ {
+ super("ConnectDataPort" + (configuration.getPortalContainer() == null ? "" : " " + configuration.getPortalContainer().getName()));
+ }
+
protected Log connectLog = ExoLogger.getLogger("jcr.ConnectDataPort");
@Override
15 years
exo-jcr SVN: r4227 - in jcr/trunk/exo.jcr.component.ext/src: main/java/org/exoplatform/services/jcr/ext/hierarchy/impl and 2 other directories.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2011-04-11 13:42:26 -0400 (Mon, 11 Apr 2011)
New Revision: 4227
Added:
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/hierarchy/
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/hierarchy/TestNodeHierarchyCreator.java
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/NodeHierarchyCreator.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/HierarchyConfig.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NewGroupListener.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NewUserListener.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NodeHierarchyCreatorImpl.java
Log:
EXOJCR-1136: Improve the NodeHierarchyCreator to better scale in term of users
New NodeHierarchyCreator based on the data distribution service
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/NodeHierarchyCreator.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/NodeHierarchyCreator.java 2011-04-11 17:40:26 UTC (rev 4226)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/NodeHierarchyCreator.java 2011-04-11 17:42:26 UTC (rev 4227)
@@ -24,21 +24,73 @@
import javax.jcr.Node;
/**
+ * This service is used as an helper to initialize the JCR
+ *
* Created by The eXo Platform SAS Author : Dang Van Minh minh.dang(a)exoplatform.com Nov 15, 2007
* 10:10:10 AM
*/
public interface NodeHierarchyCreator
{
- public String getJcrPath(String alias);
+ /**
+ * Gets the JCR path corresponding to the given alias
+ * @param alias the alias of the path to retrieve
+ * @return the corresponding JCR path
+ */
+ String getJcrPath(String alias);
- public void init(String repository) throws Exception;
+ /**
+ * Initialize the given repository thanks to all the registered plugins
+ * @param repository the repository to initialize
+ * @throws Exception if an exception occurs
+ * @deprecated use init() instead
+ */
+ void init(String repository) throws Exception;
- public Node getUserNode(SessionProvider sessionProvider, String userName) throws Exception;
+ /**
+ * Initialize the current repository thanks to all the registered plugins
+ * @param repository the repository to initialize
+ * @throws Exception if an exception occurs
+ */
+ void init() throws Exception;
- public Node getUserApplicationNode(SessionProvider sessionProvider, String userName) throws Exception;
+ /**
+ * Remove the JCR node corresponding to the root node of the user workspace
+ * @param sessionProvider the session provider to use to remove the root node
+ * @param userName the user name for which we want to remove the root node of his workspace
+ * @throws Exception if an exception occurs
+ */
+ void removeUserNode(SessionProvider sessionProvider, String userName) throws Exception;
- public Node getPublicApplicationNode(SessionProvider sessionProvider) throws Exception;
+ /**
+ * Gets the JCR node corresponding to the root node of the user workspace
+ * @param sessionProvider the session provider to use to get the root node
+ * @param userName the user name for which we want to find the root node of his workspace
+ * @return the root node of the workspace of the given user
+ * @throws Exception if an exception occurs
+ */
+ Node getUserNode(SessionProvider sessionProvider, String userName) throws Exception;
- public void addPlugin(ComponentPlugin plugin);
+ /**
+ * Gets the JCR node corresponding to the root node of the user's applications
+ * @param sessionProvider the session provider to use to get the root node
+ * @param userName the user name for which we want to find the root node of his applications
+ * @return the root node of the user's applications of the given user
+ * @throws Exception if an exception occurs
+ */
+ Node getUserApplicationNode(SessionProvider sessionProvider, String userName) throws Exception;
+
+ /**
+ * Gets the JCR node corresponding to the root node of the public applications
+ * @param sessionProvider the session provider to use to get the root node
+ * @return the root node of the public applications
+ * @throws Exception if an exception occurs
+ */
+ Node getPublicApplicationNode(SessionProvider sessionProvider) throws Exception;
+
+ /**
+ * Registers a new plugins
+ * @param plugin the plugin to register
+ */
+ void addPlugin(ComponentPlugin plugin);
}
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/HierarchyConfig.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/HierarchyConfig.java 2011-04-11 17:40:26 UTC (rev 4226)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/HierarchyConfig.java 2011-04-11 17:42:26 UTC (rev 4227)
@@ -18,8 +18,12 @@
*/
package org.exoplatform.services.jcr.ext.hierarchy.impl;
+import org.exoplatform.services.jcr.access.PermissionType;
+
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* Created by The eXo Platform SAS Author : Dang Van Minh minh.dang(a)exoplatform.com Nov 15, 2007
@@ -101,6 +105,30 @@
return this.permissions;
}
+ public Map<String, String[]> getPermissions(String identityToAdd)
+ {
+ Map<String, String[]> permissionsMap = new HashMap<String, String[]>();
+ if (identityToAdd != null && !identityToAdd.isEmpty())
+ {
+ permissionsMap.put(identityToAdd, PermissionType.ALL);
+ }
+ for (Permission permission : permissions)
+ {
+ List<String> lPermissions = new ArrayList<String>(4);
+ if ("true".equalsIgnoreCase(permission.getRead()))
+ lPermissions.add(PermissionType.READ);
+ if ("true".equalsIgnoreCase(permission.getAddNode()))
+ lPermissions.add(PermissionType.ADD_NODE);
+ if ("true".equalsIgnoreCase(permission.getSetProperty()))
+ lPermissions.add(PermissionType.SET_PROPERTY);
+ if ("true".equalsIgnoreCase(permission.getRemove()))
+ lPermissions.add(PermissionType.REMOVE);
+ permissionsMap.put(permission.getIdentity(),
+ (String[])lPermissions.toArray(new String[lPermissions.size()]));
+ }
+ return permissionsMap;
+ }
+
public void setPermissions(List<Permission> list)
{
this.permissions = list;
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NewGroupListener.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NewGroupListener.java 2011-04-11 17:40:26 UTC (rev 4226)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NewGroupListener.java 2011-04-11 17:42:26 UTC (rev 4227)
@@ -20,22 +20,21 @@
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.services.jcr.RepositoryService;
-import org.exoplatform.services.jcr.access.PermissionType;
-import org.exoplatform.services.jcr.config.RepositoryEntry;
-import org.exoplatform.services.jcr.core.ExtendedNode;
import org.exoplatform.services.jcr.core.ManageableRepository;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionManager;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionMode;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionType;
import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
import org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig.JcrPath;
-import org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig.Permission;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
import org.exoplatform.services.organization.Group;
import org.exoplatform.services.organization.GroupEventListener;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
-import javax.jcr.PathNotFoundException;
import javax.jcr.Session;
/**
@@ -44,22 +43,24 @@
*/
public class NewGroupListener extends GroupEventListener
{
+ private static final Log log = ExoLogger.getLogger("exo.jcr.component.ext.NewGroupListener");
- private HierarchyConfig config_;
+ private static final String GROUPS_PATH = "groupsPath";
- private RepositoryService jcrService_;
+ private final HierarchyConfig config_;
- private String groupsPath_;
+ private final RepositoryService jcrService_;
+
+ private final DataDistributionType dataDistributionType_;
+
+ private final String groupsPath_;
- final static private String NT_UNSTRUCTURED = "nt:unstructured".intern();
-
- final static private String GROUPS_PATH = "groupsPath";
-
public NewGroupListener(RepositoryService jcrService, NodeHierarchyCreator nodeHierarchyCreatorService,
- InitParams params) throws Exception
+ DataDistributionManager dataDistributionManager, InitParams params) throws Exception
{
jcrService_ = jcrService;
config_ = (HierarchyConfig)params.getObjectParamValues(HierarchyConfig.class).get(0);
+ dataDistributionType_ = dataDistributionManager.getDataDistributionType(DataDistributionMode.NONE);
groupsPath_ = nodeHierarchyCreatorService.getJcrPath(GROUPS_PATH);
}
@@ -81,13 +82,9 @@
else
groupId = parentId + "/" + group.getGroupName();
}
- List<RepositoryEntry> repositories = jcrService_.getConfig().getRepositoryConfigurations();
if (isNew)
{
- for (RepositoryEntry repo : repositories)
- {
- buildGroupStructure(repo.getName(), groupId);
- }
+ buildGroupStructure(jcrService_.getCurrentRepository(), groupId);
}
}
@@ -109,103 +106,66 @@
else
groupId = parentId + "/" + group.getGroupName();
}
- List<RepositoryEntry> repositories = jcrService_.getConfig().getRepositoryConfigurations();
- for (RepositoryEntry repo : repositories)
- {
- try
- {
- removeGroup(repo.getName(), groupId);
- }
- catch (Exception e)
- {
- continue;
- }
- }
+ removeGroup(jcrService_.getCurrentRepository(), groupId);
}
- private void removeGroup(String repoName, String groupId) throws Exception
+ private void removeGroup(ManageableRepository manageableRepository, String groupId) throws Exception
{
- ManageableRepository manageableRepository = jcrService_.getRepository(repoName);
- String systemWorkspace = manageableRepository.getConfiguration().getDefaultWorkspaceName();
- Session session = manageableRepository.getSystemSession(systemWorkspace);
- Node groupNode = (Node)session.getItem(groupsPath_ + groupId);
- groupNode.remove();
- session.save();
- session.logout();
- }
-
- @SuppressWarnings("unchecked")
- private void buildGroupStructure(String repository, String groupId) throws Exception
- {
- ManageableRepository manageableRepository = jcrService_.getRepository(repository);
- String systemWorkspace = manageableRepository.getConfiguration().getDefaultWorkspaceName();
- Session session = manageableRepository.getSystemSession(systemWorkspace);
- Node groupsHome = (Node)session.getItem(groupsPath_);
- List jcrPaths = config_.getJcrPaths();
- Node groupNode = null;
+ Session session = null;
try
{
- groupNode = groupsHome.getNode(groupId.substring(1, groupId.length()));
+ String systemWorkspace = manageableRepository.getConfiguration().getDefaultWorkspaceName();
+ session = manageableRepository.getSystemSession(systemWorkspace);
+ Node groupsHome = (Node)session.getItem(groupsPath_);
+ dataDistributionType_.removeDataNode(groupsHome, groupId);
}
- catch (PathNotFoundException e)
+ catch (Exception e)
{
- groupNode = groupsHome.addNode(groupId.substring(1, groupId.length()));
+ log.error("An error occurs while removing the group directory of '" + groupId + "'", e);
}
- for (JcrPath jcrPath : (List<JcrPath>)jcrPaths)
+ finally
{
- createNode(groupNode, jcrPath.getPath(), jcrPath.getNodeType(), jcrPath.getMixinTypes(), getPermissions(
- jcrPath.getPermissions(), groupId));
+ if (session != null)
+ {
+ session.logout();
+ }
}
- session.save();
- session.logout();
}
@SuppressWarnings("unchecked")
- private void createNode(Node groupNode, String path, String nodeType, List<String> mixinTypes, Map permissions)
- throws Exception
+ private void buildGroupStructure(ManageableRepository manageableRepository, String groupId) throws Exception
{
- if (nodeType == null || nodeType.length() == 0)
- nodeType = NT_UNSTRUCTURED;
+ Session session = null;
try
{
- groupNode = groupNode.getNode(path);
+ String systemWorkspace = manageableRepository.getConfiguration().getDefaultWorkspaceName();
+ session = manageableRepository.getSystemSession(systemWorkspace);
+ Node groupsHome = (Node)session.getItem(groupsPath_);
+ Node groupNode = dataDistributionType_.getOrCreateDataNode(groupsHome, groupId);
+ @SuppressWarnings("rawtypes")
+ List jcrPaths = config_.getJcrPaths();
+ for (JcrPath jcrPath : (List<JcrPath>)jcrPaths)
+ {
+ createNode(groupNode, jcrPath.getPath(), jcrPath.getNodeType(), jcrPath.getMixinTypes(),
+ jcrPath.getPermissions("*:".concat(groupId)));
+ }
}
- catch (PathNotFoundException e)
+ catch (Exception e)
{
- groupNode = groupNode.addNode(path, nodeType);
+ log.error("An error occurs while initializing the group directory of '" + groupId + "'", e);
}
- if (groupNode.canAddMixin("exo:privilegeable"))
- groupNode.addMixin("exo:privilegeable");
- if (permissions != null && !permissions.isEmpty())
- ((ExtendedNode)groupNode).setPermissions(permissions);
- if (mixinTypes.size() > 0)
+ finally
{
- for (String mixin : mixinTypes)
+ if (session != null)
{
- if (groupNode.canAddMixin(mixin))
- groupNode.addMixin(mixin);
+ session.logout();
}
}
}
- private Map getPermissions(List<Permission> permissions, String groupId)
+ private void createNode(Node groupNode, String path, String nodeType, List<String> mixinTypes, Map<String, String[]> permissions)
+ throws Exception
{
- Map<String, String[]> permissionsMap = new HashMap<String, String[]>();
- String groupIdentity = "*:".concat(groupId);
- permissionsMap.put(groupIdentity, PermissionType.ALL);
- for (Permission permission : permissions)
- {
- StringBuilder strPer = new StringBuilder();
- if ("true".equals(permission.getRead()))
- strPer.append(PermissionType.READ);
- if ("true".equals(permission.getAddNode()))
- strPer.append(",").append(PermissionType.ADD_NODE);
- if ("true".equals(permission.getSetProperty()))
- strPer.append(",").append(PermissionType.SET_PROPERTY);
- if ("true".equals(permission.getRemove()))
- strPer.append(",").append(PermissionType.REMOVE);
- permissionsMap.put(permission.getIdentity(), strPer.toString().split(","));
- }
- return permissionsMap;
+ dataDistributionType_.getOrCreateDataNode(groupNode, path, nodeType, mixinTypes, permissions);
}
}
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NewUserListener.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NewUserListener.java 2011-04-11 17:40:26 UTC (rev 4226)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NewUserListener.java 2011-04-11 17:42:26 UTC (rev 4227)
@@ -20,23 +20,22 @@
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.services.jcr.RepositoryService;
-import org.exoplatform.services.jcr.access.PermissionType;
-import org.exoplatform.services.jcr.config.RepositoryEntry;
-import org.exoplatform.services.jcr.core.ExtendedNode;
import org.exoplatform.services.jcr.core.ManageableRepository;
+import org.exoplatform.services.jcr.ext.common.SessionProvider;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionManager;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionMode;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionType;
import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
import org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig.JcrPath;
-import org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig.Permission;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
import org.exoplatform.services.organization.User;
import org.exoplatform.services.organization.UserEventListener;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
-import javax.jcr.PathNotFoundException;
-import javax.jcr.Session;
/**
* Created by The eXo Platform SAS Author : Dang Van Minh minh.dang(a)exoplatform.com Nov 15, 2007
@@ -44,137 +43,81 @@
*/
public class NewUserListener extends UserEventListener
{
+ private static final Log log = ExoLogger.getLogger("exo.jcr.component.ext.NewUserListener");
- private HierarchyConfig config_;
+ private final HierarchyConfig config_;
- private RepositoryService jcrService_;
+ private final RepositoryService jcrService_;
- private NodeHierarchyCreator nodeHierarchyCreatorService_;
+ private final NodeHierarchyCreator nodeHierarchyCreatorService_;
+
+ private final DataDistributionType dataDistributionType_;
- private String userPath_;
-
- final static private String USERS_PATH = "usersPath";
-
- final static private String NT_UNSTRUCTURED = "nt:unstructured".intern();
-
public NewUserListener(RepositoryService jcrService, NodeHierarchyCreator nodeHierarchyCreatorService,
- InitParams params) throws Exception
+ DataDistributionManager dataDistributionManager, InitParams params) throws Exception
{
jcrService_ = jcrService;
- nodeHierarchyCreatorService_ = nodeHierarchyCreatorService;
+ dataDistributionType_ = dataDistributionManager.getDataDistributionType(DataDistributionMode.NONE);
config_ = (HierarchyConfig)params.getObjectParamValues(HierarchyConfig.class).get(0);
- nodeHierarchyCreatorService_.addPlugin(new AddPathPlugin(params));
- userPath_ = nodeHierarchyCreatorService.getJcrPath(USERS_PATH);
+ nodeHierarchyCreatorService.addPlugin(new AddPathPlugin(params));
+ nodeHierarchyCreatorService_ = nodeHierarchyCreatorService;
}
public void preSave(User user, boolean isNew) throws Exception
{
- String userName = user.getUserName();
- List<RepositoryEntry> repositories = jcrService_.getConfig().getRepositoryConfigurations();
- // TODO [PN, 12.02.08] only default repository should contains user structure
if (isNew)
{
- for (RepositoryEntry repo : repositories)
- {
- processUserStructure(repo.getName(), userName);
- }
+ processUserStructure(jcrService_.getCurrentRepository(), user.getUserName());
}
}
- @SuppressWarnings("unchecked")
- private void processUserStructure(String repository, String userName) throws Exception
+ private void processUserStructure(ManageableRepository manageableRepository, String userName) throws Exception
{
- ManageableRepository manageableRepository = jcrService_.getRepository(repository);
- String systemWorkspace = manageableRepository.getConfiguration().getDefaultWorkspaceName();
- Session session = manageableRepository.getSystemSession(systemWorkspace);
- Node usersHome = (Node)session.getItem(userPath_);
- List<JcrPath> jcrPaths = config_.getJcrPaths();
- Node userNode = null;
- try
+ SessionProvider sessionProvider = SessionProvider.createSystemProvider();
+ try
{
- userNode = usersHome.getNode(userName);
+ Node userNode = nodeHierarchyCreatorService_.getUserNode(sessionProvider, userName);
+ List<JcrPath> jcrPaths = config_.getJcrPaths();
+ for (JcrPath jcrPath : jcrPaths)
+ {
+ createNode(userNode, jcrPath.getPath(), jcrPath.getNodeType(), jcrPath.getMixinTypes(),
+ jcrPath.getPermissions(userName));
+ }
}
- catch (PathNotFoundException e)
+ catch (Exception e)
{
- userNode = usersHome.addNode(userName);
+ log.error("An error occurs while initializing the user directory of '" + userName + "'", e);
}
- for (JcrPath jcrPath : jcrPaths)
+ finally
{
- createNode(userNode, jcrPath.getPath(), jcrPath.getNodeType(), jcrPath.getMixinTypes(), getPermissions(jcrPath
- .getPermissions(), userName));
+ sessionProvider.close();
+ sessionProvider = null;
}
- session.save();
- session.logout();
}
public void preDelete(User user)
{
// use a anonymous connection for the configuration as the user is not
// authentified at that time
- List<RepositoryEntry> repositories = jcrService_.getConfig().getRepositoryConfigurations();
- for (RepositoryEntry repo : repositories)
- {
- try
- {
- ManageableRepository manaRepo = jcrService_.getRepository(repo.getName());
- Session session = manaRepo.getSystemSession(manaRepo.getConfiguration().getDefaultWorkspaceName());
- Node usersHome = (Node)session.getItem(nodeHierarchyCreatorService_.getJcrPath(USERS_PATH));
- usersHome.getNode(user.getUserName()).remove();
- session.save();
- session.logout();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private void createNode(Node userNode, String path, String nodeType, List<String> mixinTypes, Map permissions)
- throws Exception
- {
- if (nodeType == null || nodeType.length() == 0)
- nodeType = NT_UNSTRUCTURED;
+ SessionProvider sessionProvider = SessionProvider.createSystemProvider();
try
{
- userNode = userNode.getNode(path);
+ nodeHierarchyCreatorService_.removeUserNode(sessionProvider, user.getUserName());
}
- catch (PathNotFoundException e)
+ catch (Exception e)
{
- userNode = userNode.addNode(path, nodeType);
+ log.error("An error occurs while removing the user directory of '" + user.getUserName() + "'", e);
}
- if (userNode.canAddMixin("exo:privilegeable"))
- userNode.addMixin("exo:privilegeable");
- if (permissions != null && !permissions.isEmpty())
- ((ExtendedNode)userNode).setPermissions(permissions);
- if (mixinTypes.size() > 0)
+ finally
{
- for (String mixin : mixinTypes)
- {
- if (userNode.canAddMixin(mixin))
- userNode.addMixin(mixin);
- }
+ sessionProvider.close();
+ sessionProvider = null;
}
}
- private Map getPermissions(List<Permission> permissions, String userId)
+ private void createNode(Node userNode, String path, String nodeType, List<String> mixinTypes, Map<String, String[]> permissions)
+ throws Exception
{
- Map<String, String[]> permissionsMap = new HashMap<String, String[]>();
- permissionsMap.put(userId, PermissionType.ALL);
- for (Permission permission : permissions)
- {
- StringBuilder strPer = new StringBuilder();
- if ("true".equals(permission.getRead()))
- strPer.append(PermissionType.READ);
- if ("true".equals(permission.getAddNode()))
- strPer.append(",").append(PermissionType.ADD_NODE);
- if ("true".equals(permission.getSetProperty()))
- strPer.append(",").append(PermissionType.SET_PROPERTY);
- if ("true".equals(permission.getRemove()))
- strPer.append(",").append(PermissionType.REMOVE);
- permissionsMap.put(permission.getIdentity(), strPer.toString().split(","));
- }
- return permissionsMap;
+ dataDistributionType_.getOrCreateDataNode(userNode, path, nodeType, mixinTypes, permissions);
}
}
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NodeHierarchyCreatorImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NodeHierarchyCreatorImpl.java 2011-04-11 17:40:26 UTC (rev 4226)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/hierarchy/impl/NodeHierarchyCreatorImpl.java 2011-04-11 17:42:26 UTC (rev 4227)
@@ -18,23 +18,27 @@
*/
package org.exoplatform.services.jcr.ext.hierarchy.impl;
+import org.exoplatform.commons.utils.PropertyManager;
import org.exoplatform.container.component.ComponentPlugin;
+import org.exoplatform.container.xml.InitParams;
import org.exoplatform.services.jcr.RepositoryService;
-import org.exoplatform.services.jcr.access.PermissionType;
-import org.exoplatform.services.jcr.core.ExtendedNode;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionManager;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionMode;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionType;
import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
import org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig.JcrPath;
-import org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig.Permission;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
import org.picocontainer.Startable;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
-import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
@@ -42,33 +46,65 @@
import javax.jcr.Session;
/**
+ *
* Created by The eXo Platform SAS Author : Dang Van Minh minh.dang(a)exoplatform.com Nov 15, 2007
* 2:21:57 PM
*/
public class NodeHierarchyCreatorImpl implements NodeHierarchyCreator, Startable
{
- final static private String NT_UNSTRUCTURED = "nt:unstructured".intern();
+ private static final Log log = ExoLogger.getLogger("exo.jcr.component.ext.NodeHierarchyCreatorImpl");
- final static private String USERS_PATH = "usersPath";
+ private static final String USERS_PATH = "usersPath";
- final static private String USER_APPLICATION = "userApplicationData";
+ private static final String USER_APPLICATION = "userApplicationData";
- final static private String PUBLIC_APPLICATION = "eXoApplications";
+ private static final String PUBLIC_APPLICATION = "eXoApplications";
- final static private String USER_PRIVATE = "userPrivate";
+ private static final String USER_PRIVATE = "userPrivate";
- final static private String USER_PUBLIC = "userPublic";
+ private static final String USER_PUBLIC = "userPublic";
- private RepositoryService jcrService_;
+ private final RepositoryService jcrService_;
- List<AddPathPlugin> pathPlugins_ = new ArrayList<AddPathPlugin>();
+ private final DataDistributionManager dataDistributionManager_;
- public NodeHierarchyCreatorImpl(RepositoryService jcrService) throws Exception
+ private final List<AddPathPlugin> pathPlugins_ = new ArrayList<AddPathPlugin>();
+
+ private final Map<String, String> paths_ = new HashMap<String, String>();
+
+ private final boolean oldDistribution;
+
+ public NodeHierarchyCreatorImpl(RepositoryService jcrService, InitParams params)
{
+ this(jcrService, null, params);
+ }
+
+ public NodeHierarchyCreatorImpl(RepositoryService jcrService, DataDistributionManager dataDistributionManager,
+ InitParams params)
+ {
+ if (dataDistributionManager == null)
+ {
+ throw new IllegalArgumentException("The DataDistributionManager is now mandatory if you use the "
+ + "NodeHierarchyCreator, so please define it in your configuration "
+ + "as described in the JCR documentation");
+ }
jcrService_ = jcrService;
+ dataDistributionManager_ = dataDistributionManager;
+ oldDistribution =
+ params != null && params.getValueParam("old-user-distribution") != null
+ && Boolean.valueOf(params.getValueParam("old-user-distribution").getValue());
+ if (PropertyManager.isDevelopping() && !oldDistribution)
+ {
+ log.info("The NodeHierarchyCreator is configured to use the new distribution mechanism for the"
+ + " users directories, if you prefer to use the old mechanism set the value parameter "
+ + "'old-user-distribution' to 'true'.");
+ }
}
+ /**
+ * {@inheritDoc}
+ */
public void start()
{
try
@@ -77,112 +113,102 @@
}
catch (Exception e)
{
- e.printStackTrace();
+ log.error("An error occurs while processing the plugins", e);
}
}
+ /**
+ * {@inheritDoc}
+ */
public void stop()
{
}
+ /**
+ * {@inheritDoc}
+ */
public void init(String repository) throws Exception
{
- initBasePath(repository);
+ init();
}
- @SuppressWarnings("unchecked")
- private void createNode(Node rootNode, String path, String nodeType, List<String> mixinTypes, Map permissions)
- throws Exception
+ /**
+ * {@inheritDoc}
+ */
+ public void init() throws Exception
{
- Node node = rootNode;
- for (String token : path.split("/"))
- {
- if (token.length() > 0)
- {
- try
- {
- node = node.getNode(token);
- }
- catch (PathNotFoundException e)
- {
- if (nodeType == null || nodeType.length() == 0)
- nodeType = NT_UNSTRUCTURED;
- node = node.addNode(token, nodeType);
- if (node.canAddMixin("exo:privilegeable"))
- node.addMixin("exo:privilegeable");
- if (permissions != null && !permissions.isEmpty())
- ((ExtendedNode)node).setPermissions(permissions);
- if (mixinTypes.size() > 0)
- {
- for (String mixin : mixinTypes)
- {
- if (node.canAddMixin(mixin))
- node.addMixin(mixin);
- }
- }
- }
- }
- }
+ initBasePath();
}
- public Map getPermissions(List<Permission> permissions)
+ private void createNode(Node rootNode, String path, String nodeType, List<String> mixinTypes,
+ Map<String, String[]> permissions) throws Exception
{
- Map<String, String[]> permissionsMap = new HashMap<String, String[]>();
- for (Permission permission : permissions)
- {
- StringBuilder strPer = new StringBuilder();
- if ("true".equals(permission.getRead()))
- strPer.append(PermissionType.READ);
- if ("true".equals(permission.getAddNode()))
- strPer.append(",").append(PermissionType.ADD_NODE);
- if ("true".equals(permission.getSetProperty()))
- strPer.append(",").append(PermissionType.SET_PROPERTY);
- if ("true".equals(permission.getRemove()))
- strPer.append(",").append(PermissionType.REMOVE);
- permissionsMap.put(permission.getIdentity(), strPer.toString().split(","));
- }
- return permissionsMap;
+ dataDistributionManager_.getDataDistributionType(DataDistributionMode.NONE).getOrCreateDataNode(rootNode, path,
+ nodeType, mixinTypes, permissions);
}
- @SuppressWarnings("unchecked")
private void processAddPathPlugin() throws Exception
{
Session session = null;
+ ManageableRepository currentRepo = jcrService_.getCurrentRepository();
for (AddPathPlugin pathPlugin : pathPlugins_)
{
HierarchyConfig hierarchyConfig = pathPlugin.getPaths();
- String repository = hierarchyConfig.getRepository();
+ if (hierarchyConfig == null)
+ {
+ continue;
+ }
List<JcrPath> jcrPaths = hierarchyConfig.getJcrPaths();
- for (String workspaceName : hierarchyConfig.getWorkspaces())
+ if (jcrPaths == null)
{
- session = jcrService_.getRepository(repository).getSystemSession(workspaceName);
- Node rootNode = session.getRootNode();
- for (JcrPath jcrPath : jcrPaths)
+ continue;
+ }
+ Set<String> workspaceNames = new LinkedHashSet<String>();
+ if (hierarchyConfig.getWorkspaces() != null)
+ {
+ workspaceNames.addAll(hierarchyConfig.getWorkspaces());
+ }
+ workspaceNames.add(currentRepo.getConfiguration().getDefaultWorkspaceName());
+ for (String workspaceName : workspaceNames)
+ {
+ JcrPath currentjcrPath = null;
+ try
{
- String nodeType = jcrPath.getNodeType();
- if (nodeType == null || nodeType.length() == 0)
- nodeType = NT_UNSTRUCTURED;
- List<String> mixinTypes = jcrPath.getMixinTypes();
- if (mixinTypes == null)
- mixinTypes = new ArrayList<String>();
- if (!jcrPath.getAlias().equals(USER_APPLICATION) && !jcrPath.getAlias().startsWith(USER_PRIVATE)
- && !jcrPath.getAlias().startsWith(USER_PUBLIC))
+ session = currentRepo.getSystemSession(workspaceName);
+ Node rootNode = session.getRootNode();
+ for (JcrPath jcrPath : jcrPaths)
{
- createNode(rootNode, jcrPath.getPath(), nodeType, mixinTypes,
- getPermissions(jcrPath.getPermissions()));
+ currentjcrPath = jcrPath;
+ if (!jcrPath.getAlias().equals(USER_APPLICATION) && !jcrPath.getAlias().startsWith(USER_PRIVATE)
+ && !jcrPath.getAlias().startsWith(USER_PUBLIC))
+ {
+ createNode(rootNode, jcrPath.getPath(), jcrPath.getNodeType(), jcrPath.getMixinTypes(),
+ jcrPath.getPermissions(null));
+ }
}
}
- session.save();
- session.logout();
+ catch (Exception e)
+ {
+ log.error("An error occurs while processing the JCR path which alias is "
+ + (currentjcrPath == null ? null : currentjcrPath.getAlias()) + " with the workspace "
+ + workspaceName, e);
+ }
+ finally
+ {
+ if (session != null)
+ {
+ session.logout();
+ session = null;
+ }
+ }
}
}
}
- @SuppressWarnings("unchecked")
- private void initBasePath(String repository) throws Exception
+ private void initBasePath() throws Exception
{
Session session = null;
- ManageableRepository manageableRepository = jcrService_.getRepository(repository);
+ ManageableRepository manageableRepository = jcrService_.getCurrentRepository();
String defaultWorkspace = manageableRepository.getConfiguration().getDefaultWorkspaceName();
String systemWorkspace = manageableRepository.getConfiguration().getSystemWorkspaceName();
boolean isSameWorksapce = defaultWorkspace.equalsIgnoreCase(systemWorkspace);
@@ -190,123 +216,142 @@
for (AddPathPlugin pathPlugin : pathPlugins_)
{
HierarchyConfig hierarchyConfig = pathPlugin.getPaths();
+ if (hierarchyConfig == null)
+ {
+ continue;
+ }
List<JcrPath> jcrPaths = hierarchyConfig.getJcrPaths();
+ if (jcrPaths == null)
+ {
+ continue;
+ }
for (String workspaceName : workspaceNames)
{
if (!isSameWorksapce && workspaceName.equalsIgnoreCase(systemWorkspace))
continue;
- session = manageableRepository.getSystemSession(workspaceName);
- Node rootNode = session.getRootNode();
- for (JcrPath jcrPath : jcrPaths)
+ JcrPath currentjcrPath = null;
+ try
{
- String nodeType = jcrPath.getNodeType();
- if (nodeType == null || nodeType.length() == 0)
- nodeType = NT_UNSTRUCTURED;
- List<String> mixinTypes = jcrPath.getMixinTypes();
- if (mixinTypes == null)
- mixinTypes = new ArrayList<String>();
- if (!jcrPath.getAlias().equals(USER_APPLICATION) && !jcrPath.getAlias().startsWith(USER_PRIVATE)
- && !jcrPath.getAlias().startsWith(USER_PUBLIC))
+ session = manageableRepository.getSystemSession(workspaceName);
+ Node rootNode = session.getRootNode();
+ for (JcrPath jcrPath : jcrPaths)
{
- createNode(rootNode, jcrPath.getPath(), nodeType, mixinTypes,
- getPermissions(jcrPath.getPermissions()));
+ currentjcrPath = jcrPath;
+ if (!jcrPath.getAlias().equals(USER_APPLICATION) && !jcrPath.getAlias().startsWith(USER_PRIVATE)
+ && !jcrPath.getAlias().startsWith(USER_PUBLIC))
+ {
+ createNode(rootNode, jcrPath.getPath(), jcrPath.getNodeType(), jcrPath.getMixinTypes(),
+ jcrPath.getPermissions(null));
+ }
}
}
- session.save();
- session.logout();
+ catch (Exception e)
+ {
+ log.error("An error occurs while processing the JCR path which alias is "
+ + (currentjcrPath == null ? null : currentjcrPath.getAlias()) + " with the workspace "
+ + workspaceName, e);
+ }
+ finally
+ {
+ if (session != null)
+ {
+ session.logout();
+ session = null;
+ }
+ }
}
}
}
+ /**
+ * {@inheritDoc}
+ */
public Node getUserApplicationNode(SessionProvider sessionProvider, String userName) throws Exception
{
Node userNode = getUserNode(sessionProvider, userName);
- Node userAppNode = null;
- try
- {
- userAppNode = userNode.getNode(getJcrPath(USER_APPLICATION));
- }
- catch (PathNotFoundException e)
- {
- userAppNode = userNode.addNode(getJcrPath(USER_APPLICATION));
- userNode.save();
- }
- return userAppNode;
+ return dataDistributionManager_.getDataDistributionType(DataDistributionMode.NONE).getOrCreateDataNode(userNode,
+ getJcrPath(USER_APPLICATION));
}
+ /**
+ * {@inheritDoc}
+ */
public Node getPublicApplicationNode(SessionProvider sessionProvider) throws Exception
{
- ManageableRepository currentRepo = jcrService_.getCurrentRepository();
- Session session =
- getSession(sessionProvider, currentRepo, currentRepo.getConfiguration().getDefaultWorkspaceName());
+ Session session = getSession(sessionProvider);
Node rootNode = session.getRootNode();
- String publicApplication = getJcrPath(PUBLIC_APPLICATION);
- session.logout();
- return rootNode.getNode(publicApplication.substring(1, publicApplication.length()));
+ return dataDistributionManager_.getDataDistributionType(DataDistributionMode.NONE).getDataNode(rootNode,
+ getJcrPath(PUBLIC_APPLICATION));
}
+ /**
+ * {@inheritDoc}
+ */
public Node getUserNode(SessionProvider sessionProvider, String userName) throws Exception
{
String userPath = getJcrPath(USERS_PATH);
- ManageableRepository currentRepo = jcrService_.getCurrentRepository();
- Session session =
- getSession(sessionProvider, currentRepo, currentRepo.getConfiguration().getDefaultWorkspaceName());
+ Session session = getSession(sessionProvider);
Node usersNode = (Node)session.getItem(userPath);
- Node userNode = null;
+ DataDistributionType type =
+ dataDistributionManager_.getDataDistributionType(oldDistribution ? DataDistributionMode.NONE
+ : DataDistributionMode.READABLE);
+ return type.getOrCreateDataNode(usersNode, userName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeUserNode(SessionProvider sessionProvider, String userName) throws Exception
+ {
+ String userPath = getJcrPath(USERS_PATH);
+ Session session = getSession(sessionProvider);
try
{
- userNode = usersNode.getNode(userName);
+ Node usersNode = (Node)session.getItem(userPath);
+ DataDistributionType type =
+ dataDistributionManager_.getDataDistributionType(oldDistribution ? DataDistributionMode.NONE
+ : DataDistributionMode.READABLE);
+ type.removeDataNode(usersNode, userName);
}
catch (PathNotFoundException e)
{
- userNode = usersNode.addNode(userName);
- usersNode.save();
+ // ignore me
}
- finally
- {
- session.logout();
- }
- return userNode;
}
- private Session getSession(SessionProvider sessionProvider, ManageableRepository repo, String defaultWorkspace)
- throws RepositoryException
+ private Session getSession(SessionProvider sessionProvider) throws RepositoryException
{
- return sessionProvider.getSession(defaultWorkspace, repo);
+ ManageableRepository repo = jcrService_.getCurrentRepository();
+ return sessionProvider.getSession(repo.getConfiguration().getDefaultWorkspaceName(), repo);
}
+ /**
+ * {@inheritDoc}
+ */
public String getJcrPath(String alias)
{
- for (int j = 0; j < pathPlugins_.size(); j++)
+ return paths_.get(alias);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPlugin(ComponentPlugin plugin)
+ {
+ if (plugin instanceof AddPathPlugin)
{
- HierarchyConfig config = pathPlugins_.get(j).getPaths();
- List jcrPaths = config.getJcrPaths();
- for (Iterator iter = jcrPaths.iterator(); iter.hasNext();)
+ AddPathPlugin app = (AddPathPlugin)plugin;
+ pathPlugins_.add(app);
+ if (app.getPaths() != null && app.getPaths().getJcrPaths() != null)
{
- HierarchyConfig.JcrPath jcrPath = (HierarchyConfig.JcrPath)iter.next();
- if (jcrPath.getAlias().equals(alias))
+ for (JcrPath jcrPath : app.getPaths().getJcrPaths())
{
- return jcrPath.getPath();
+ if (jcrPath.getAlias() != null && jcrPath.getPath() != null)
+ {
+ paths_.put(jcrPath.getAlias(), jcrPath.getPath());
+ }
}
}
}
- return null;
}
-
- public void addPlugin(ComponentPlugin plugin)
- {
- if (plugin instanceof AddPathPlugin)
- pathPlugins_.add((AddPathPlugin)plugin);
- }
-
- @SuppressWarnings("unused")
- public ComponentPlugin removePlugin(String name)
- {
- return null;
- }
-
- public Collection getPlugins()
- {
- return null;
- }
}
Added: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/hierarchy/TestNodeHierarchyCreator.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/hierarchy/TestNodeHierarchyCreator.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/hierarchy/TestNodeHierarchyCreator.java 2011-04-11 17:42:26 UTC (rev 4227)
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2011 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.ext.hierarchy;
+
+import org.exoplatform.services.jcr.core.ExtendedNode;
+import org.exoplatform.services.jcr.ext.BaseStandaloneTest;
+import org.exoplatform.services.jcr.ext.common.SessionProvider;
+import org.exoplatform.services.jcr.ext.hierarchy.impl.NewGroupListener;
+import org.exoplatform.services.jcr.ext.hierarchy.impl.NewUserListener;
+import org.exoplatform.services.organization.User;
+import org.exoplatform.services.organization.impl.GroupImpl;
+import org.exoplatform.services.organization.impl.UserImpl;
+import org.exoplatform.services.security.ConversationState;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Session;
+
+/**
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class TestNodeHierarchyCreator extends BaseStandaloneTest
+{
+ private NodeHierarchyCreator creator;
+ private SessionProvider sessionProvider;
+ private NewUserListener userListener;
+ private NewGroupListener groupListener;
+ private Session session;
+
+ /**
+ * @see org.exoplatform.services.jcr.ext.BaseStandaloneTest#setUp()
+ */
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ creator = (NodeHierarchyCreator)container.getComponentInstanceOfType(NodeHierarchyCreator.class);
+ userListener = (NewUserListener)container.getComponentInstanceOfType(NewUserListener.class);
+ groupListener = (NewGroupListener)container.getComponentInstanceOfType(NewGroupListener.class);
+ sessionProvider = new SessionProvider(ConversationState.getCurrent());
+ session = sessionProvider.getSession("ws1", repository);
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.ext.BaseStandaloneTest#tearDown()
+ */
+ @Override
+ protected void tearDown() throws Exception
+ {
+ creator = null;
+ userListener = null;
+ groupListener = null;
+ if (session != null)
+ {
+ session.logout();
+ session = null;
+ }
+ if (sessionProvider != null)
+ {
+ sessionProvider.close();
+ sessionProvider = null;
+ }
+ super.tearDown();
+ }
+
+ public void testGetJcrPath() throws Exception
+ {
+ assertEquals("/exo:applications", creator.getJcrPath("eXoApplications"));
+ assertEquals("/exo:services", creator.getJcrPath("eXoServices"));
+ assertEquals("/Users", creator.getJcrPath("usersPath"));
+ assertEquals("/Groups/Path/Home", creator.getJcrPath("groupsPath"));
+ }
+
+ public void testInit() throws Exception
+ {
+ Node node = (Node)session.getItem("/exo:services");
+ assertNotNull(node);
+ assertTrue(node.isNodeType("nt:folder"));
+ assertTrue(node.canAddMixin("mix:referenceable"));
+ assertTrue(node.canAddMixin("exo:privilegeable"));
+
+ node = (Node)session.getItem("/exo:applications");
+ assertNotNull(node);
+ assertFalse(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertTrue(node.canAddMixin("exo:privilegeable"));
+
+ node = (Node)session.getItem("/Users");
+ assertNotNull(node);
+ assertFalse(node.isNodeType("nt:folder"));
+ assertTrue(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("*:/platform/administrators"));
+
+ node = (Node)session.getItem("/Groups/Path/Home");
+ assertNotNull(node);
+ assertTrue(node.isNodeType("nt:unstructured"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("*:/platform/administrators"));
+ assertTrue(node.getParent().isNodeType("nt:unstructured"));
+ assertFalse(node.getParent().canAddMixin("mix:referenceable"));
+ assertFalse(node.getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node.getParent()).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node.getParent()).getACL().getPermissions("*:/platform/administrators"));
+ assertTrue(node.getParent().getParent().isNodeType("nt:unstructured"));
+ assertFalse(node.getParent().getParent().canAddMixin("mix:referenceable"));
+ assertFalse(node.getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node.getParent().getParent()).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node.getParent().getParent()).getACL().getPermissions("*:/platform/administrators"));
+ }
+
+ public void testGetUserNode() throws Exception
+ {
+ Node node = creator.getUserNode(sessionProvider, "foo");
+ assertNotNull(node);
+ assertTrue(node.getPath().startsWith("/Users"));
+ }
+
+ public void testGetUserApplicationNode() throws Exception
+ {
+ User user = new UserImpl("foo");
+ userListener.preSave(user, true);
+ Node node = creator.getUserApplicationNode(sessionProvider, "foo");
+ assertNotNull(node);
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("*:/platform/administrators"));
+ Node parentNode = creator.getUserNode(sessionProvider, "foo");
+ assertNotNull(parentNode);
+ assertTrue(node.getPath().startsWith(parentNode.getPath()));
+ assertNotNull(session.getItem(node.getPath()));
+ userListener.preDelete(user);
+ try
+ {
+ session.getItem(node.getPath());
+ fail("A PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // ignore me
+ }
+ }
+
+ public void testGroupsNode() throws Exception
+ {
+ GroupImpl group1 = new GroupImpl("platform");
+ GroupImpl group2 = new GroupImpl();
+ group2.setId("/platform/users");
+ GroupImpl group3 = new GroupImpl("my-group-name2");
+ group3.setParentId("/platform");
+
+ groupListener.preSave(group1, true);
+ Node node = (Node)session.getItem("/Groups/Path/Home/" + group1.getGroupName());
+ assertNotNull(node);
+ node = node.getNode("ApplicationData");
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("*:/platform/administrators"));
+
+ groupListener.preSave(group2, true);
+ node = (Node)session.getItem("/Groups/Path/Home" + group2.getId());
+ assertNotNull(node);
+ node = node.getNode("ApplicationData");
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("*:/platform/administrators"));
+ groupListener.preDelete(group2);
+ try
+ {
+ session.getItem("/Groups/Path/Home" + group2.getId());
+ fail("A PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // ignore me
+ }
+ groupListener.preSave(group3, true);
+ node = (Node)session.getItem("/Groups/Path/Home" + group3.getParentId() + "/" + group3.getGroupName());
+ assertNotNull(node);
+ node = node.getNode("ApplicationData");
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("*:/platform/administrators"));
+ groupListener.preDelete(group3);
+ try
+ {
+ session.getItem("/Groups/Path/Home" + group3.getParentId() + "/" + group3.getGroupName());
+ fail("A PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // ignore me
+ }
+ groupListener.preDelete(group1);
+ try
+ {
+ session.getItem("/Groups/Path/Home/" + group1.getGroupName());
+ fail("A PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // ignore me
+ }
+ }
+}
15 years
exo-jcr SVN: r4226 - in jcr/trunk/exo.jcr.component.ext/src: main/java/org/exoplatform/services/jcr/ext/distribution and 4 other directories.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2011-04-11 13:40:26 -0400 (Mon, 11 Apr 2011)
New Revision: 4226
Added:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionManager.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionMode.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionType.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/AbstractDataDistributionType.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByHash.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByName.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByPath.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionManagerImpl.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/distribution/
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/distribution/TestDataDistributionManager.java
Modified:
jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml
jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-jcr-ext-config.xml
Log:
EXOJCR-1206: Create a data distribution service to help the applications to better distribute their child nodes
First Implementation
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionManager.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionManager.java 2011-04-11 17:40:26 UTC (rev 4226)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2011 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.ext.distribution;
+
+
+/**
+ * This service is used to distribute smartly the data over the JCR. It can help you to have the best
+ * possible performances in read and write accesses, especially if you have a lot of nodes of the
+ * same type to store, instead of storing them yourself under the same parent node (which can
+ * affect the performances if you have a lot of nodes to store), we simply delegate data access and
+ * storage to the {@link DataDistributionType} corresponding to the expected mode that will store the
+ * data for you in an optimized and reliable way.
+ *
+ * See below an example of how it can be used
+ * <pre>
+ * // Get the data distribution corresponding to the readable mode
+ * DataDistributionType type = manager.getDataDistributionType(DataDistributionMode.READABLE);
+ * // Get or create the node corresponding to "john.smith"
+ * Node node = type.getOrCreateDataNode(parentNode, "john.smith");
+ * </pre>
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public interface DataDistributionManager
+{
+ /**
+ * Retrieves the data distribution type corresponding to given mode.
+ * @param mode the mode of distribution to use
+ * @return the expected mode if it exists <code>null</code> otherwise.
+ */
+ DataDistributionType getDataDistributionType(DataDistributionMode mode);
+}
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionMode.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionMode.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionMode.java 2011-04-11 17:40:26 UTC (rev 4226)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 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.ext.distribution;
+
+/**
+ * The existing data distribution modes are the following:
+ * <ul>
+ * <li>Readable mode that is used to store the data in an understandable way for a human
+ * being, corresponding to <code>DataDistributionMode.READABLE</code>.</li>
+ * <li>Optimized mode that is used when we don't need to be able to understand
+ * how it is stored, we only want to have the best possible performances,
+ * corresponding to <code>DataDistributionMode.OPTIMIZED</code>.</li>
+ * <li>None mode that is used when we just want to store the node
+ * as it is without using any distribution algorithm. This is mostly
+ * interesting as helper to create a hierarchy of nodes in a reliable way
+ * when we already know that we have only few nodes to store,
+ * corresponding to <code>DataDistributionMode.NONE</code>.</li>
+ * </ul>
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public enum DataDistributionMode
+{
+ READABLE, OPTIMIZED, NONE
+}
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionType.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionType.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/DataDistributionType.java 2011-04-11 17:40:26 UTC (rev 4226)
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2011 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.ext.distribution;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+
+/**
+ * This interface describes a type of distribution.
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public interface DataDistributionType
+{
+ /**
+ * Retrieves the node from the JCR under the given root node and corresponding to the given
+ * data id.
+ * @param rootNode the root node under which the data to find is stored
+ * @param dataId the id of the data to find
+ * @return the Node corresponding to the data to find
+ * @throws PathNotFoundException if the data cannot be find
+ * @throws RepositoryException if an error occurred while trying to get the expected data
+ */
+ Node getDataNode(Node rootNode, String dataId) throws PathNotFoundException, RepositoryException;
+
+ /**
+ * Tries to get the node from the JCR and if it cannot be found, it will create it automatically.
+ * @param rootNode the root node under which the data to find is stored
+ * @param dataId the id of the data to find/create
+ * @return the Node corresponding to the data to find
+ * @throws RepositoryException if an error occurred while trying to get or create the expected data
+ */
+ Node getOrCreateDataNode(Node rootNode, String dataId) throws RepositoryException;
+
+ /**
+ * Tries to get the node from the JCR and if it cannot be found, it will create it automatically.
+ * If the node has to be created, the node will be created with the given node type.
+ * @param rootNode the root node under which the data to find is stored
+ * @param dataId the id of the data to find/create
+ * @param nodeType the node type to use in case we need to create the node
+ * @return the Node corresponding to the data to find
+ * @throws RepositoryException if an error occurred while trying to get or create the expected data
+ */
+ Node getOrCreateDataNode(Node rootNode, String dataId, String nodeType) throws RepositoryException;
+
+ /**
+ * Tries to get the node from the JCR and if it cannot be found, it will create it automatically.
+ * If the node has to be created, the node will be created with the given node type and given
+ * mixin types.
+ * @param rootNode the root node under which the data to find is stored
+ * @param dataId the id of the data to find/create
+ * @param nodeType the node type to use in case we need to create the node
+ * @param mixinTypes the mixin types to use in case we need to create the node
+ * @return the Node corresponding to the data to find
+ * @throws RepositoryException if an error occurred while trying to get or create the expected data
+ */
+ Node getOrCreateDataNode(Node rootNode, String dataId, String nodeType, List<String> mixinTypes) throws RepositoryException;
+
+ /**
+ * Tries to get the node from the JCR and if it cannot be found, it will create it automatically.
+ * If the node has to be created, the node will be created with the given node type, given
+ * mixin types and given permissions.
+ * @param rootNode the root node under which the data to find is stored
+ * @param dataId the id of the data to find/create
+ * @param nodeType the node type to use in case we need to create the node
+ * @param mixinTypes the mixin types to use in case we need to create the node
+ * @param permissions the permissions to use in case we need to create the node
+ * @return the Node corresponding to the data to find
+ * @throws RepositoryException if an error occurred while trying to get or create the expected data
+ */
+ Node getOrCreateDataNode(Node rootNode, String dataId, String nodeType, List<String> mixinTypes, Map<String, String[]> permissions) throws RepositoryException;
+
+ /**
+ * Remove the node from the JCR if it exists
+ * @param rootNode the root node under which the data to remove is stored
+ * @param dataId the id of the data to remove
+ * @throws RepositoryException if an error occurred while trying to remove the expected data
+ */
+ void removeDataNode(Node rootNode, String dataId) throws RepositoryException;
+}
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/AbstractDataDistributionType.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/AbstractDataDistributionType.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/AbstractDataDistributionType.java 2011-04-11 17:40:26 UTC (rev 4226)
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2011 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.ext.distribution.impl;
+
+import org.exoplatform.services.jcr.core.ExtendedNode;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionType;
+import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+
+/**
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public abstract class AbstractDataDistributionType implements DataDistributionType
+{
+ /**
+ * The default node type to use when we create a new node
+ */
+ private static final String DEFAULT_NODE_TYPE = "nt:unstructured".intern();
+
+ /**
+ * The map defining all the locks available
+ */
+ private final ConcurrentMap<String, Lock> locks = new ConcurrentHashMap<String, Lock>(64, 0.75f, 64);
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node getDataNode(Node rootNode, String dataId) throws PathNotFoundException, RepositoryException
+ {
+ return rootNode.getNode(getRelativePath(dataId));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node getOrCreateDataNode(Node rootNode, String dataId) throws RepositoryException
+ {
+ return getOrCreateDataNode(rootNode, dataId, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node getOrCreateDataNode(Node rootNode, String dataId, String nodeType) throws RepositoryException
+ {
+ return getOrCreateDataNode(rootNode, dataId, nodeType, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node getOrCreateDataNode(Node rootNode, String dataId, String nodeType, List<String> mixinTypes)
+ throws RepositoryException
+ {
+ return getOrCreateDataNode(rootNode, dataId, nodeType, mixinTypes, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node getOrCreateDataNode(Node rootNode, String dataId, String nodeType, List<String> mixinTypes,
+ Map<String, String[]> permissions) throws RepositoryException
+ {
+ try
+ {
+ return getDataNode(rootNode, dataId);
+ }
+ catch (PathNotFoundException e)
+ {
+ // ignore me
+ }
+ // The node could not be found so we need to create it
+ Node node = rootNode;
+ List<String> ancestors = getAncestors(dataId);
+ for (int i = 0, length = ancestors.size(); i < length; i++)
+ {
+ String nodeName = ancestors.get(i);
+ try
+ {
+ node = node.getNode(nodeName);
+ continue;
+ }
+ catch (PathNotFoundException e)
+ {
+ // ignore me
+ }
+ // The node doesn't exist we need to create it
+ node = createNode(node, nodeName, nodeType, mixinTypes, permissions, i == length - 1);
+ }
+ return node;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeDataNode(Node rootNode, String dataId) throws RepositoryException
+ {
+ Lock lock = getLock(rootNode, getRelativePath(dataId));
+ lock.lock();
+ try
+ {
+ Node node = getDataNode(rootNode, dataId);
+ Node parentNode = node.getParent();
+ node.remove();
+ parentNode.save();
+ }
+ catch (PathNotFoundException e)
+ {
+ // ignore me
+ }
+ finally
+ {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Creates the node of the given node type with the given node name directly under
+ * the given parent node, using the given mixin types and permissions
+ * @param parentNode the parent node
+ * @param nodeName the name of the node to create
+ * @param nodeType the node type to use
+ * @param mixinTypes the list of mixin types to use
+ * @param permissions the map of permissions to use
+ * @param isLeaf indicates whether or not the current node to create is the leaf node
+ * @return the created node
+ * @throws RepositoryException if any exception occurs while creating the node
+ */
+ private Node createNode(final Node parentNode, final String nodeName, final String nodeType,
+ final List<String> mixinTypes, final Map<String, String[]> permissions, final boolean isLeaf)
+ throws RepositoryException
+ {
+ Lock lock = getLock(parentNode, nodeName);
+ lock.lock();
+ try
+ {
+ try
+ {
+ // We ensure that the node has not been created since the last time we checked
+ return parentNode.getNode(nodeName);
+ }
+ catch (PathNotFoundException e)
+ {
+ // ignore me
+ }
+
+ boolean useParameters = !useParametersOnLeafOnly() || (useParametersOnLeafOnly() && isLeaf);
+ Node node;
+ if (nodeType == null || nodeType.isEmpty() || !useParameters)
+ {
+ node = parentNode.addNode(nodeName, DEFAULT_NODE_TYPE);
+ }
+ else
+ {
+ node = parentNode.addNode(nodeName, nodeType);
+ }
+ if (useParameters)
+ {
+ if (permissions != null && !permissions.isEmpty())
+ {
+ if (node.canAddMixin("exo:privilegeable"))
+ {
+ node.addMixin("exo:privilegeable");
+ }
+ ((ExtendedNode)node).setPermissions(permissions);
+ }
+ if (mixinTypes != null)
+ {
+ for (int i = 0, length = mixinTypes.size(); i < length; i++)
+ {
+ String mixin = mixinTypes.get(i);
+ if (node.canAddMixin(mixin))
+ {
+ node.addMixin(mixin);
+ }
+ }
+ }
+ }
+ parentNode.save();
+ return node;
+ }
+ finally
+ {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Creates the full path of the given node name
+ * @param parentNode the parent node from which we extract the absolute path
+ * @param relativePath the relative path of the node for which we want the full path
+ * @return the full path of the node for which we want the path
+ * @throws RepositoryException if any exception occurs while creating the path
+ */
+ private String createFullPath(Node parentNode, String relativePath) throws RepositoryException
+ {
+ StringBuilder buffer = new StringBuilder(256);
+ buffer.append(((RepositoryImpl)parentNode.getSession().getRepository()).getName());
+ buffer.append('/');
+ buffer.append(parentNode.getSession().getWorkspace().getName());
+ String rootPath = parentNode.getPath();
+ buffer.append(rootPath);
+ if (!rootPath.endsWith("/"))
+ {
+ buffer.append('/');
+ }
+ buffer.append(relativePath);
+ return buffer.toString();
+ }
+
+ /**
+ * Get the lock corresponding to the given node name
+ * @param parentNode the parent node of the node to lock
+ * @param relativePath the relative path of the node to lock
+ * @return the lock corresponding to the given node name
+ * @throws RepositoryException if any exception occurs while getting the lock
+ */
+ private Lock getLock(Node parentNode, String relativePath) throws RepositoryException
+ {
+ String fullPath = createFullPath(parentNode, relativePath);
+ Lock lock = locks.get(fullPath);
+ if (lock != null)
+ {
+ return lock;
+ }
+ lock = new InternalLock(fullPath);
+ Lock prevLock = locks.putIfAbsent(fullPath, lock);
+ if (prevLock != null)
+ {
+ lock = prevLock;
+ }
+ return lock;
+
+ }
+
+ /**
+ * Gives the relative path corresponding to the given id of the data to find/create
+ * @param dataId the id of the data to find/create
+ * @return the relative path of the data to find/create
+ */
+ protected String getRelativePath(String dataId)
+ {
+ StringBuilder buffer = new StringBuilder(256);
+ List<String> ancestors = getAncestors(dataId);
+ for (int i = 0, length = ancestors.size(); i < length; i++)
+ {
+ buffer.append(ancestors.get(i));
+ if (i != length - 1)
+ {
+ buffer.append('/');
+ }
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Gives the list of all the name of the ancestors
+ * @param dataId the id of the data to find/create
+ * @return the list of the ancestor names
+ */
+ protected abstract List<String> getAncestors(String dataId);
+
+ /**
+ * Indicates whether or not the node type, the mixin types and the permissions have to
+ * be used on leaf node only.
+ * @return <code>true</code> if only the leaf node has to be created with the parameters
+ * <code>false</code> otherwise.
+ */
+ protected abstract boolean useParametersOnLeafOnly();
+
+
+ /**
+ * This kind of locks can self unregister from the map of locks
+ */
+ private class InternalLock extends ReentrantLock {
+
+ /**
+ * Serial Version UID
+ */
+ private static final long serialVersionUID = -3362387346368015145L;
+
+ /**
+ * The id corresponding to the lock in the map
+ */
+ private final String fullPath;
+
+ /**
+ * The default constructor
+ * @param fullId the id corresponding to the lock in the map
+ */
+ public InternalLock(String fullPath) {
+ super();
+ this.fullPath = fullPath;
+ }
+
+ @Override
+ public void unlock() {
+ if (!hasQueuedThreads()) {
+ // No thread is currently waiting for this lock
+ // The lock will then be removed
+ locks.remove(fullPath, this);
+ }
+ super.unlock();
+ }
+ }
+}
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByHash.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByHash.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByHash.java 2011-04-11 17:40:26 UTC (rev 4226)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 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.ext.distribution.impl;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * It will generate from the data id an hash code thanks to an hashing function
+ * then with this hash code it will be able to generate a hierarchy of sub-nodes
+ * with <code>n</code> levels of depth for example with <code>n = 4</code> and
+ * MD5 as hashing function:
+ * For "john.smith" with MD5, the hash code in base 32 is 12spjkm4fhsrl151pva3f7mf1r,
+ * so the path would be "1/2/s/john.smith"
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class DataDistributionByHash extends AbstractDataDistributionType
+{
+ /**
+ * The level of depth used by the algorithm
+ */
+ private int depth = 4;
+
+ /**
+ * The name of the hash algorithm to use
+ */
+ private String hashAlgorithm = "MD5";
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected List<String> getAncestors(String dataId)
+ {
+ List<String> result = new ArrayList<String>(depth);
+ String hash = hash(dataId);
+ int length = hash.length();
+ for (int i = 0; i < depth - 1 && i < length; i++)
+ {
+ result.add(hash.substring(i, i + 1));
+ }
+ result.add(dataId);
+ return result;
+ }
+
+ /**
+ * Gives the hash code of the given data id
+ * @param dataId The id of the data to hash
+ * @return The hash code of the value of the given data id in base 32
+ */
+ private String hash(String dataId)
+ {
+ try
+ {
+ MessageDigest digest = MessageDigest.getInstance(hashAlgorithm);
+ digest.update(dataId.getBytes("UTF-8"));
+ return new BigInteger(1, digest.digest()).toString(32);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Could not generate the hash code of '" + dataId + "' with the algorithm '"
+ + hashAlgorithm + "'", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean useParametersOnLeafOnly()
+ {
+ return true;
+ }
+}
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByName.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByName.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByName.java 2011-04-11 17:40:26 UTC (rev 4226)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 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.ext.distribution.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * This data distribution will distribute the data in a understandable way for a human being.
+ * The expected data id is for example a login of a user.
+ * It will generate a hierarchy of sub-nodes with <code>n</code> levels of depth for example
+ * with <code>n = 4</code>:
+ * <ul>
+ * <li>Usename: john.smith (size >= 4) it will generate a path of type "j___/jo___/joh___/john.smith"</li>
+ * <li>Usename: bob (size < 4) it will generate a path of type "b___/bo___/bob"</li>
+ * </ul>
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class DataDistributionByName extends AbstractDataDistributionType
+{
+
+ /**
+ * The level of depth used by the algorithm
+ */
+ private int depth = 4;
+
+ /**
+ * The suffix used by the algorithm to indicate that they are sub nodes inside
+ */
+ private String suffix = "___";
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected List<String> getAncestors(String dataId)
+ {
+ List<String> result = new ArrayList<String>(depth);
+ int length = dataId.length();
+ for (int i = 0; i < depth - 1 && i < length - 1; i++)
+ {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append(dataId, 0, i + 1);
+ buffer.append(suffix);
+ result.add(buffer.toString());
+ }
+ result.add(dataId);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean useParametersOnLeafOnly()
+ {
+ return true;
+ }
+}
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByPath.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByPath.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionByPath.java 2011-04-11 17:40:26 UTC (rev 4226)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 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.ext.distribution.impl;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This distribution doesn't do anything specific, it only stores the content as
+ * requested, which means that the data id expected is simply a relative path. It will
+ * mainly help to create a tree of nodes in a reliable way.
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class DataDistributionByPath extends AbstractDataDistributionType
+{
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected List<String> getAncestors(String relativePath)
+ {
+ if (relativePath.startsWith("/"))
+ relativePath = relativePath.substring(1);
+ return Arrays.asList(relativePath.split("/"));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean useParametersOnLeafOnly()
+ {
+ return false;
+ }
+}
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionManagerImpl.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/distribution/impl/DataDistributionManagerImpl.java 2011-04-11 17:40:26 UTC (rev 4226)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2011 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.ext.distribution.impl;
+
+import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.container.xml.ObjectParameter;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionManager;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionMode;
+import org.exoplatform.services.jcr.ext.distribution.DataDistributionType;
+
+/**
+ * The default implementation of a {@link DataDistributionManager}.
+ * It will use a {@link DataDistributionByName} when the readable mode is expected
+ * and a {@link DataDistributionByHash} when the non readable mode is expected
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class DataDistributionManagerImpl implements DataDistributionManager
+{
+
+ /**
+ * The {@link DataDistributionType} used in case of "readable" mode
+ */
+ private DataDistributionType readable = new DataDistributionByName();
+
+ /**
+ * The {@link DataDistributionType} used in case of "optimized" mode
+ */
+ private DataDistributionType optimized = new DataDistributionByHash();
+
+ /**
+ * The {@link DataDistributionType} used in case of "none" mode
+ */
+ private DataDistributionType none = new DataDistributionByPath();
+
+ public DataDistributionManagerImpl()
+ {
+ this(null);
+ }
+
+ public DataDistributionManagerImpl(InitParams params)
+ {
+ if (params != null)
+ {
+ ObjectParameter op = params.getObjectParam("readable");
+ if (op != null && op.getObject() instanceof DataDistributionType)
+ {
+ this.readable = (DataDistributionType)op.getObject();
+ }
+ op = params.getObjectParam("optimized");
+ if (op != null && op.getObject() instanceof DataDistributionType)
+ {
+ this.optimized = (DataDistributionType)op.getObject();
+ }
+ op = params.getObjectParam("none");
+ if (op != null && op.getObject() instanceof DataDistributionType)
+ {
+ this.none = (DataDistributionType)op.getObject();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public DataDistributionType getDataDistributionType(DataDistributionMode mode)
+ {
+ if (mode == DataDistributionMode.READABLE)
+ {
+ return readable;
+ }
+ else if (mode == DataDistributionMode.OPTIMIZED)
+ {
+ return optimized;
+ }
+ else if (mode == DataDistributionMode.NONE)
+ {
+ return none;
+ }
+ return null;
+ }
+}
Added: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/distribution/TestDataDistributionManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/distribution/TestDataDistributionManager.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/distribution/TestDataDistributionManager.java 2011-04-11 17:40:26 UTC (rev 4226)
@@ -0,0 +1,624 @@
+/*
+ * Copyright (C) 2011 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.ext.distribution;
+
+import org.exoplatform.services.jcr.access.PermissionType;
+import org.exoplatform.services.jcr.core.ExtendedNode;
+import org.exoplatform.services.jcr.ext.BaseStandaloneTest;
+import org.exoplatform.services.jcr.impl.core.SessionImpl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Session;
+
+/**
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class TestDataDistributionManager extends BaseStandaloneTest
+{
+ private DataDistributionManager manager;
+
+ private Node parentNode;
+
+ /**
+ * @see org.exoplatform.services.jcr.ext.BaseStandaloneTest#setUp()
+ */
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ manager = (DataDistributionManager)container.getComponentInstanceOfType(DataDistributionManager.class);
+ parentNode = root.addNode("TestDataDistributionManager");
+ session.save();
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.ext.BaseStandaloneTest#tearDown()
+ */
+ @Override
+ protected void tearDown() throws Exception
+ {
+ manager = null;
+ if (parentNode != null)
+ {
+ parentNode.remove();
+ session.save();
+ parentNode = null;
+ }
+ super.tearDown();
+ }
+
+ public void testDataDistributionModeNone() throws Exception
+ {
+ DataDistributionType type = manager.getDataDistributionType(DataDistributionMode.NONE);
+ String dataId = "/a/a/a/a/";
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ Node node = type.getOrCreateDataNode(parentNode, dataId);
+ assertTrue(node.isSame(type.getOrCreateDataNode(parentNode, dataId)));
+ assertEquals(1, node.getParent().getNodes().getSize());
+ Node node2 = type.getDataNode(parentNode, dataId);
+ assertTrue(node.isSame(node2));
+ Node node3 = parentNode.getNode("a/a/a/a");
+ assertTrue(node.isSame(node3));
+ Node node4 = type.getOrCreateDataNode(parentNode, "a/a/a/b", "nt:folder");
+ assertFalse(node.isSame(node4));
+ assertTrue(node.getParent().isSame(node4.getParent()));
+ assertTrue(node4.isNodeType("nt:folder"));
+ assertTrue(node4.canAddMixin("mix:referenceable"));
+ assertTrue(node4.canAddMixin("exo:privilegeable"));
+
+ dataId = "b/a/a/a";
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+
+ Node node5 =
+ type.getOrCreateDataNode(parentNode, dataId, "nt:folder", Collections.singletonList("mix:referenceable"));
+ assertFalse(node.isSame(node5));
+ assertFalse(node.getParent().isSame(node5.getParent()));
+ assertTrue(node5.isNodeType("nt:folder"));
+ assertFalse(node5.canAddMixin("mix:referenceable"));
+ assertTrue(node5.canAddMixin("exo:privilegeable"));
+ assertTrue(node5.getParent().isNodeType("nt:folder"));
+ assertFalse(node5.getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node5.getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(node5.getParent().getParent().isNodeType("nt:folder"));
+ assertFalse(node5.getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node5.getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(node5.getParent().getParent().getParent().isNodeType("nt:folder"));
+ assertFalse(node5.getParent().getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node5.getParent().getParent().getParent().canAddMixin("exo:privilegeable"));
+ Map<String, String[]> permissions = Collections.singletonMap("root", PermissionType.ALL);
+ type.removeDataNode(parentNode, dataId);
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+
+ dataId = "c/a/a/a";
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ Node node6 =
+ type.getOrCreateDataNode(parentNode, dataId, "nt:folder", Collections.singletonList("mix:referenceable"),
+ permissions);
+ assertFalse(node.isSame(node6));
+ assertFalse(node.getParent().isSame(node6.getParent()));
+ assertTrue(node6.isNodeType("nt:folder"));
+ assertFalse(node6.canAddMixin("mix:referenceable"));
+ assertFalse(node6.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node6).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node6).getACL().getPermissions("root"));
+ assertTrue(node6.getParent().isNodeType("nt:folder"));
+ assertFalse(node6.getParent().canAddMixin("mix:referenceable"));
+ assertFalse(node6.getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node6.getParent()).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node6.getParent()).getACL().getPermissions("root"));
+ assertTrue(node6.getParent().getParent().isNodeType("nt:folder"));
+ assertFalse(node6.getParent().getParent().canAddMixin("mix:referenceable"));
+ assertFalse(node6.getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node6.getParent().getParent()).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node6.getParent().getParent()).getACL().getPermissions("root"));
+ assertTrue(node6.getParent().getParent().getParent().isNodeType("nt:folder"));
+ assertFalse(node6.getParent().getParent().getParent().canAddMixin("mix:referenceable"));
+ assertFalse(node6.getParent().getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node6.getParent().getParent().getParent()).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node6.getParent().getParent().getParent()).getACL().getPermissions("root"));
+ type.removeDataNode(parentNode, dataId);
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ }
+
+ public void testDataDistributionModeReadable() throws Exception
+ {
+ DataDistributionType type = manager.getDataDistributionType(DataDistributionMode.READABLE);
+ String dataId = "john.smith";
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ Map<String, String[]> permissions = Collections.singletonMap("root", PermissionType.ALL);
+ Node node =
+ type.getOrCreateDataNode(parentNode, dataId, "nt:folder", Collections.singletonList("mix:referenceable"),
+ permissions);
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("root"));
+ assertFalse(node.getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(node.getPath().endsWith("j___/jo___/joh___/john.smith"));
+
+ dataId = "bob";
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ node =
+ type.getOrCreateDataNode(parentNode, dataId, "nt:folder", Collections.singletonList("mix:referenceable"),
+ permissions);
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("root"));
+ assertFalse(node.getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(node.getPath().endsWith("b___/bo___/bob"));
+
+ dataId = "john___";
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ node =
+ type.getOrCreateDataNode(parentNode, dataId, "nt:folder", Collections.singletonList("mix:referenceable"),
+ permissions);
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("root"));
+ assertFalse(node.getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(node.getPath().endsWith("j___/jo___/joh___/john___"));
+
+ dataId = "joh___";
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ node =
+ type.getOrCreateDataNode(parentNode, dataId, "nt:folder", Collections.singletonList("mix:referenceable"),
+ permissions);
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("root"));
+ assertFalse(node.getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(node.getPath().endsWith("j___/jo___/joh___/joh___"));
+
+ dataId = "jo___";
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ node =
+ type.getOrCreateDataNode(parentNode, dataId, "nt:folder", Collections.singletonList("mix:referenceable"),
+ permissions);
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("root"));
+ assertFalse(node.getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(node.getPath().endsWith("j___/jo___/jo____/jo___"));
+
+ dataId = "j___";
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ node =
+ type.getOrCreateDataNode(parentNode, dataId, "nt:folder", Collections.singletonList("mix:referenceable"),
+ permissions);
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("root"));
+ assertFalse(node.getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(node.getPath().endsWith("j___/j____/j_____/j___"));
+ type.removeDataNode(parentNode, dataId);
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ }
+
+ public void testDataDistributionModeOptimized() throws Exception
+ {
+ DataDistributionType type = manager.getDataDistributionType(DataDistributionMode.OPTIMIZED);
+ String dataId = "john.smith";
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ Map<String, String[]> permissions = Collections.singletonMap("root", PermissionType.ALL);
+ Node node =
+ type.getOrCreateDataNode(parentNode, dataId, "nt:folder", Collections.singletonList("mix:referenceable"),
+ permissions);
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("root"));
+ assertFalse(node.getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(node.getPath().endsWith("1/2/s/john.smith"));
+
+ dataId = "mary";
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ node =
+ type.getOrCreateDataNode(parentNode, dataId, "nt:folder", Collections.singletonList("mix:referenceable"),
+ permissions);
+ assertTrue(node.isNodeType("nt:folder"));
+ assertFalse(node.canAddMixin("mix:referenceable"));
+ assertFalse(node.canAddMixin("exo:privilegeable"));
+ assertTrue(((ExtendedNode)node).getACL().hasPermissions());
+ assertNotNull(((ExtendedNode)node).getACL().getPermissions("root"));
+ assertFalse(node.getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertFalse(node.getParent().getParent().getParent().isNodeType("nt:folder"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("mix:referenceable"));
+ assertTrue(node.getParent().getParent().getParent().canAddMixin("exo:privilegeable"));
+ assertTrue(node.getPath().endsWith("5/o/s/mary"));
+ type.removeDataNode(parentNode, dataId);
+ try
+ {
+ type.getDataNode(parentNode, dataId);
+ fail("a PathNotFoundException is expected");
+ }
+ catch (PathNotFoundException e)
+ {
+ // expected behavior
+ }
+ }
+
+// public void testMultiThreadingNone() throws Exception
+// {
+// testMultiThreading(manager.getDataDistributionType(DataDistributionMode.NONE), "key/");
+// }
+//
+// public void testMultiThreadingReadable() throws Exception
+// {
+// testMultiThreading(manager.getDataDistributionType(DataDistributionMode.READABLE), "key-");
+// }
+//
+// public void testMultiThreadingOptimized() throws Exception
+// {
+// testMultiThreading(manager.getDataDistributionType(DataDistributionMode.OPTIMIZED), "");
+// }
+
+ public void testMultiThreading(final DataDistributionType type, final String dataIdPrefix) throws Exception
+ {
+ long time = System.currentTimeMillis();
+ final int totalElement = 50;
+ final int totalTimes = 3;
+ int reader = 20;
+ int writer = 10;
+ int remover = 5;
+ final CountDownLatch startSignalWriter = new CountDownLatch(1);
+ final CountDownLatch startSignalOthers = new CountDownLatch(1);
+ final CountDownLatch doneSignal = new CountDownLatch(reader + writer + remover);
+ final List<Exception> errors = Collections.synchronizedList(new ArrayList<Exception>());
+ for (int i = 0; i < writer; i++)
+ {
+ final int index = i;
+ Thread thread = new Thread()
+ {
+ public void run()
+ {
+ Session session = null;
+ try
+ {
+ startSignalWriter.await();
+ for (int j = 0; j < totalTimes; j++)
+ {
+ session = (SessionImpl)repository.login(credentials, WS_NAME);
+ Node node = (Node)session.getItem(parentNode.getPath());
+ for (int i = 0; i < totalElement; i++)
+ {
+ type.getOrCreateDataNode(node, dataIdPrefix + i);
+ }
+ if (index == 0 && j == 0)
+ {
+ // The cache is full, we can launch the others
+ startSignalOthers.countDown();
+ }
+ session.logout();
+ sleep(50);
+ }
+ }
+ catch (Exception e)
+ {
+ errors.add(e);
+ startSignalOthers.countDown();
+ }
+ finally
+ {
+ doneSignal.countDown();
+ if (session != null)
+ {
+ session.logout();
+ session = null;
+ }
+ }
+ }
+ };
+ thread.start();
+ }
+ startSignalWriter.countDown();
+ for (int i = 0; i < reader; i++)
+ {
+ Thread thread = new Thread()
+ {
+ public void run()
+ {
+ Session session = null;
+ try
+ {
+ startSignalOthers.await();
+ for (int j = 0; j < totalTimes; j++)
+ {
+ session = (SessionImpl)repository.login(credentials, WS_NAME);
+ Node node = (Node)session.getItem(parentNode.getPath());
+ for (int i = 0; i < totalElement; i++)
+ {
+ try
+ {
+ type.getDataNode(node, dataIdPrefix + i);
+ }
+ catch (PathNotFoundException e)
+ {
+ // ignore me
+ }
+ }
+ session.logout();
+ sleep(50);
+ }
+ }
+ catch (Exception e)
+ {
+ errors.add(e);
+ }
+ finally
+ {
+ doneSignal.countDown();
+ if (session != null)
+ {
+ session.logout();
+ session = null;
+ }
+ }
+ }
+ };
+ thread.start();
+ }
+ for (int i = 0; i < remover; i++)
+ {
+ Thread thread = new Thread()
+ {
+ public void run()
+ {
+ Session session = null;
+ try
+ {
+ startSignalOthers.await();
+ for (int j = 0; j < totalTimes; j++)
+ {
+ session = (SessionImpl)repository.login(credentials, WS_NAME);
+ Node node = (Node)session.getItem(parentNode.getPath());
+ for (int i = 0; i < totalElement; i++)
+ {
+ type.removeDataNode(node, dataIdPrefix + i);
+ }
+ session.logout();
+ sleep(50);
+ }
+ }
+ catch (Exception e)
+ {
+ errors.add(e);
+ }
+ finally
+ {
+ doneSignal.countDown();
+ if (session != null)
+ {
+ session.logout();
+ session = null;
+ }
+ }
+ }
+ };
+ thread.start();
+ }
+ doneSignal.await();
+ for (int i = 0; i < totalElement; i++)
+ {
+ type.removeDataNode(parentNode, dataIdPrefix + i);
+ }
+ if (!errors.isEmpty())
+ {
+ for (Exception e : errors)
+ {
+ e.printStackTrace();
+ }
+ throw errors.get(0);
+ }
+ System.out.println("Total Time for '" + type.getClass().getSimpleName() + "' = " + (System.currentTimeMillis() - time));
+ }
+}
Modified: jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml 2011-04-11 10:54:50 UTC (rev 4225)
+++ jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml 2011-04-11 17:40:26 UTC (rev 4226)
@@ -423,6 +423,11 @@
<type>org.exoplatform.services.jcr.ext.repository.creation.RepositoryCreationServiceImpl</type>
</component>
+ <component>
+ <key>org.exoplatform.services.jcr.ext.distribution.DataDistributionManager</key>
+ <type>org.exoplatform.services.jcr.ext.distribution.impl.DataDistributionManagerImpl</type>
+ </component>
+
<!-- component>
<key>org.exoplatform.services.organization.OrganizationService</key>
<type>org.exoplatform.services.organization.hibernate.OrganizationServiceImpl</type>
@@ -992,7 +997,146 @@
</component-plugin>
</component-plugins>
</component>
-
+ <component>
+ <key>org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator</key>
+ <type>org.exoplatform.services.jcr.ext.hierarchy.impl.NodeHierarchyCreatorImpl</type>
+ </component>
+ <component>
+ <type>org.exoplatform.services.jcr.ext.hierarchy.impl.NewUserListener</type>
+ <init-params>
+ <object-param>
+ <name>configuration</name>
+ <description>description</description>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig">
+ <field name="repository">
+ <string>db1</string>
+ </field>
+ <field name="workspaces">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>ws1</string>
+ </value>
+ </collection>
+ </field>
+ <field name="jcrPaths">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig$JcrPath">
+ <field name="alias">
+ <string>userApplicationData</string>
+ </field>
+ <field name="path">
+ <string>ApplicationData</string>
+ </field>
+ <field name="nodeType">
+ <string>nt:folder</string>
+ </field>
+ <field name="mixinTypes">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>mix:referenceable</string>
+ </value>
+ </collection>
+ </field>
+ <field name="permissions">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig$Permission">
+ <field name="identity">
+ <string>*:/platform/administrators</string>
+ </field>
+ <field name="read">
+ <string>true</string>
+ </field>
+ <field name="addNode">
+ <string>true</string>
+ </field>
+ <field name="setProperty">
+ <string>true</string>
+ </field>
+ <field name="remove">
+ <string>true</string>
+ </field>
+ </object>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component>
+ <component>
+ <type>org.exoplatform.services.jcr.ext.hierarchy.impl.NewGroupListener</type>
+ <init-params>
+ <object-param>
+ <name>configuration></name>
+ <description>description</description>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig">
+ <field name="repository">
+ <string>db1</string>
+ </field>
+ <field name="workspaces">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>ws1</string>
+ </value>
+ </collection>
+ </field>
+ <field name="jcrPaths">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig$JcrPath">
+ <field name="alias">
+ <string>groupApplicationData</string>
+ </field>
+ <field name="path">
+ <string>ApplicationData</string>
+ </field>
+ <field name="nodeType">
+ <string>nt:folder</string>
+ </field>
+ <field name="mixinTypes">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>mix:referenceable</string>
+ </value>
+ </collection>
+ </field>
+ <field name="permissions">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig$Permission">
+ <field name="identity">
+ <string>*:/platform/administrators</string>
+ </field>
+ <field name="read">
+ <string>true</string>
+ </field>
+ <field name="addNode">
+ <string>true</string>
+ </field>
+ <field name="setProperty">
+ <string>true</string>
+ </field>
+ <field name="remove">
+ <string>true</string>
+ </field>
+ </object>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component>
<external-component-plugins>
<target-component>org.exoplatform.services.jcr.ext.script.groovy.GroovyScript2RestLoader</target-component>
<component-plugin>
@@ -2095,5 +2239,140 @@
</init-params>
</component-plugin>
</external-component-plugins>
-
+ <external-component-plugins>
+ <target-component>org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator</target-component>
+ <component-plugin>
+ <name>addPaths</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.jcr.ext.hierarchy.impl.AddPathPlugin</type>
+ <init-params>
+ <object-param>
+ <name>cms.configuration</name>
+ <description>configuration for the cms path</description>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig">
+ <field name="repository">
+ <string>db1</string>
+ </field>
+ <field name="workspaces">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>ws1</string>
+ </value>
+ </collection>
+ </field>
+ <field name="jcrPaths">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig$JcrPath">
+ <field name="alias">
+ <string>eXoApplications</string>
+ </field>
+ <field name="path">
+ <string>/exo:applications</string>
+ </field>
+ <field name="mixinTypes">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>mix:referenceable</string>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </value>
+ <value>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig$JcrPath">
+ <field name="alias">
+ <string>eXoServices</string>
+ </field>
+ <field name="path">
+ <string>/exo:services</string>
+ </field>
+ <field name="nodeType">
+ <string>nt:folder</string>
+ </field>
+ </object>
+ </value>
+ <value>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig$JcrPath">
+ <field name="alias">
+ <string>usersPath</string>
+ </field>
+ <field name="path">
+ <string>/Users</string>
+ </field>
+ <field name="permissions">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig$Permission">
+ <field name="identity">
+ <string>*:/platform/administrators</string>
+ </field>
+ <field name="read">
+ <string>true</string>
+ </field>
+ <field name="addNode">
+ <string>true</string>
+ </field>
+ <field name="setProperty">
+ <string>true</string>
+ </field>
+ <field name="remove">
+ <string>true</string>
+ </field>
+ </object>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </value>
+ <value>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig$JcrPath">
+ <field name="alias">
+ <string>groupsPath</string>
+ </field>
+ <field name="path">
+ <string>/Groups/Path/Home</string>
+ </field>
+ <field name="nodeType">
+ <string>nt:unstructured</string>
+ </field>
+ <field name="mixinTypes">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>mix:referenceable</string>
+ </value>
+ </collection>
+ </field>
+ <field name="permissions">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.jcr.ext.hierarchy.impl.HierarchyConfig$Permission">
+ <field name="identity">
+ <string>*:/platform/administrators</string>
+ </field>
+ <field name="read">
+ <string>true</string>
+ </field>
+ <field name="addNode">
+ <string>true</string>
+ </field>
+ <field name="setProperty">
+ <string>true</string>
+ </field>
+ <field name="remove">
+ <string>true</string>
+ </field>
+ </object>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins>
</configuration>
Modified: jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-jcr-ext-config.xml
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-jcr-ext-config.xml 2011-04-11 10:54:50 UTC (rev 4225)
+++ jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-jcr-ext-config.xml 2011-04-11 17:40:26 UTC (rev 4226)
@@ -20,7 +20,7 @@
-->
<repository-service default-repository="db1">
<repositories>
- <repository name="db1" system-workspace="ws" default-workspace="ws">
+ <repository name="db1" system-workspace="ws" default-workspace="ws1">
<security-domain>exo-domain</security-domain>
<access-control>optional</access-control>
<authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
15 years
exo-jcr SVN: r4225 - jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/configuration.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-04-11 06:54:50 -0400 (Mon, 11 Apr 2011)
New Revision: 4225
Modified:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
Log:
EXOJCR-1296: [DOC] Allow to ignore events for descendents on rename by adding "trigger-events-for-descendents-on-rename" property with "false" value
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2011-04-11 10:54:23 UTC (rev 4224)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2011-04-11 10:54:50 UTC (rev 4225)
@@ -251,6 +251,21 @@
<para><emphasis role="bold">properties</emphasis>: The list of properties
(name-value pairs) for the concrete Workspace data container.</para>
+ <table>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>trigger_events_for_descendents_on_rename</entry>
+
+ <entry>indicates if need to trigger events for descendents on
+ rename or not. It allows to increase performance on rename
+ operation but in same time Observation'll not notified, has
+ default value true</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
<para><emphasis role="bold">value-storages</emphasis>: The list of value
storage plugins.</para>
</section>
15 years
exo-jcr SVN: r4224 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr: impl/core and 8 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-04-11 06:54:23 -0400 (Mon, 11 Apr 2011)
New Revision: 4224
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataTraversingVisitor.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemState.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataMoveVisitor.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.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/JBossCacheWorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/serialization/ItemStateReader.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/serialization/ItemStateWriter.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLog.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/importing/BaseXmlImporter.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceDataContainer.java
Log:
EXOJCR-1296: Allow to ignore events for descendents on rename by adding "trigger-events-for-descendents-on-rename" property with "false" value
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataTraversingVisitor.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataTraversingVisitor.java 2011-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataTraversingVisitor.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -37,6 +37,8 @@
*/
protected final int maxLevel;
+ public static final int INFINITE_DEPTH = -1;
+
/**
* Current level.
*/
@@ -62,7 +64,7 @@
*/
public ItemDataTraversingVisitor(ItemDataConsumer dataManager)
{
- this.maxLevel = -1;
+ this.maxLevel = INFINITE_DEPTH;
this.dataManager = dataManager;
}
@@ -83,7 +85,7 @@
try
{
entering(node, currentLevel);
- if (maxLevel == -1 || currentLevel < maxLevel)
+ if (maxLevel == INFINITE_DEPTH || currentLevel < maxLevel)
{
currentLevel++;
for (PropertyData data : dataManager.getChildPropertiesData(node))
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemState.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemState.java 2011-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemState.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -19,8 +19,10 @@
package org.exoplatform.services.jcr.dataflow;
import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
+import org.exoplatform.services.jcr.datamodel.IllegalPathException;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.QPath;
+import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -54,6 +56,8 @@
public static final int RENAMED = 32;
+ public static final int PATH_CHANGED = 64;
+
/**
* underlying item data
*/
@@ -78,6 +82,11 @@
*/
private transient QPath ancestorToSave;
+ /**
+ * Storing old node path during Session.move() operation
+ */
+ private QPath oldPath;
+
/**
* The constructor
*
@@ -110,7 +119,27 @@
this(data, state, eventFire, ancestorToSave, isInternalCreated, true);
}
+ /**
+ * @param data
+ * underlying data
+ * @param state
+ * @param eventFire
+ * - if the state cause some event firing
+ * @param ancestorToSave
+ * - path of item which should be called in save (usually for session.move())
+ * @param isInternalCreated
+ * - indicates that item is created internally by system
+ * @param oldPath
+ * - store to old node path during Session.move() operation
+ */
public ItemState(ItemData data, int state, boolean eventFire, QPath ancestorToSave, boolean isInternalCreated,
+ boolean isPersisted, QPath oldPath)
+ {
+ this(data, state, eventFire, ancestorToSave, isInternalCreated, isPersisted);
+ this.oldPath = oldPath;
+ }
+
+ public ItemState(ItemData data, int state, boolean eventFire, QPath ancestorToSave, boolean isInternalCreated,
boolean isPersisted)
{
if (isInternalCreated)
@@ -194,6 +223,11 @@
return (state == RENAMED);
}
+ public boolean isPathChanged()
+ {
+ return (state == PATH_CHANGED);
+ }
+
public boolean isEventFire()
{
return eventFire;
@@ -219,6 +253,11 @@
return ancestorToSave;
}
+ public QPath getOldPath()
+ {
+ return oldPath;
+ }
+
@Override
public boolean equals(Object obj)
{
@@ -360,6 +399,8 @@
return "MIXIN_CHANGED";
case RENAMED :
return "RENAMED";
+ case PATH_CHANGED :
+ return "PATH_CHANGED";
default :
return "UNDEFINED STATE";
}
@@ -380,6 +421,18 @@
out.writeInt(state);
out.writeBoolean(isPersisted);
out.writeBoolean(eventFire);
+
+ if (oldPath == null)
+ {
+ out.writeInt(-1);
+ }
+ else
+ {
+ byte[] buf = oldPath.getAsString().getBytes(Constants.DEFAULT_ENCODING);
+ out.writeInt(buf.length);
+ out.write(buf);
+ }
+
out.writeObject(data);
}
@@ -388,6 +441,27 @@
state = in.readInt();
isPersisted = in.readBoolean();
eventFire = in.readBoolean();
+
+ int len = in.readInt();
+ if (len == -1)
+ {
+ oldPath = null;
+ }
+ else
+ {
+ byte[] buf = new byte[len];
+ in.readFully(buf);
+
+ try
+ {
+ oldPath = QPath.parse(new String(buf, Constants.DEFAULT_ENCODING));
+ }
+ catch (IllegalPathException e)
+ {
+ throw new IOException("Data currupted.", e);
+ }
+ }
+
data = (ItemData)in.readObject();
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -1851,7 +1851,7 @@
continue;
}
- if (rstate.getState() == ItemState.RENAMED)
+ if (rstate.isRenamed())
{
// find DELETED
rstate = changes.findItemState(rstate.getData().getIdentifier(), false, new int[]{ItemState.DELETED});
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2011-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -50,6 +50,7 @@
import org.exoplatform.services.jcr.impl.xml.exporting.BaseXmlExporter;
import org.exoplatform.services.jcr.impl.xml.importing.ContentImporter;
import org.exoplatform.services.jcr.impl.xml.importing.StreamImporter;
+import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
import org.exoplatform.services.jcr.util.IdGenerator;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -159,6 +160,8 @@
private long lastAccessTime;
+ private boolean triggerEventsForDescendentsOnRename;
+
private final int lazyReadThreshold;
private final SessionRegistry sessionRegistry;
@@ -224,7 +227,9 @@
sessionRegistry.registerSession(this);
this.lastAccessTime = System.currentTimeMillis();
-
+ this.triggerEventsForDescendentsOnRename =
+ wsConfig.getContainer().getParameterBoolean(WorkspaceDataContainer.TRIGGER_EVENTS_FOR_DESCENDENTS_ON_RENAME,
+ WorkspaceDataContainer.TRIGGER_EVENTS_FOR_DESCENDENTS_ON_RENAME_DEFAULT);
}
/**
@@ -996,7 +1001,8 @@
ItemDataMoveVisitor initializer =
new ItemDataMoveVisitor((NodeData)destParentNode.getData(), destNodePath.getName().getInternalName(),
- nodeTypeManager, getTransientNodesManager(), true);
+ nodeTypeManager, getTransientNodesManager(), true, triggerEventsForDescendentsOnRename
+ || !srcNodePath.makeParentPath().equals(destNodePath.makeParentPath()));
getTransientNodesManager().rename((NodeData)srcNode.getData(), initializer);
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataMoveVisitor.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataMoveVisitor.java 2011-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataMoveVisitor.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -82,6 +82,11 @@
protected QPath ancestorToSave = null;
+ /**
+ * Trigger events for descendents.
+ */
+ protected boolean triggerEventsForDescendents;
+
/**
* Creates an instance of this class.
*
@@ -95,20 +100,39 @@
* - Source data manager
* @param keepIdentifiers
* - Is it necessity to keep <code>Identifiers</code>
+ * @param triggerEventsForDescendents
+ * - Trigger events for descendents.
*/
-
public ItemDataMoveVisitor(NodeData parent, InternalQName dstNodeName, NodeTypeDataManager nodeTypeManager,
- SessionDataManager srcDataManager, boolean keepIdentifiers)
+ SessionDataManager srcDataManager, boolean keepIdentifiers, boolean triggerEventsForDescendents)
{
- super(srcDataManager);
+ super(srcDataManager, triggerEventsForDescendents ? INFINITE_DEPTH : 0);
this.keepIdentifiers = keepIdentifiers;
this.ntManager = nodeTypeManager;
this.destNodeName = dstNodeName;
this.parents = new Stack<NodeData>();
this.parents.add(parent);
+ this.triggerEventsForDescendents = triggerEventsForDescendents;
}
+ /**
+ * Creates an instance of this class.
+ *
+ * @param parent - The parent node
+ * @param dstNodeName Destination node name
+ * @param nodeTypeManager - The NodeTypeManager
+ * @param srcDataManager - Source data manager
+ * @param keepIdentifiers - Is it necessity to keep <code>Identifiers</code>
+ * @param skipEventsForDescendents - Don't generate events for the
+ * descendants.
+ */
+ public ItemDataMoveVisitor(NodeData parent, InternalQName dstNodeName, NodeTypeDataManager nodeTypeManager,
+ SessionDataManager srcDataManager, boolean keepIdentifiers)
+ {
+ this(parent, dstNodeName, nodeTypeManager, srcDataManager, keepIdentifiers, false);
+ }
+
@Override
protected void entering(NodeData node, int level) throws RepositoryException
{
@@ -230,6 +254,12 @@
// if level == 0 set internal createt as false for validating on save
addStates.add(new ItemState(newNode, ItemState.RENAMED, level == 0, ancestorToSave, false, level == 0));
deleteStates.add(new ItemState(node, ItemState.DELETED, level == 0, ancestorToSave, false, false));
+
+ if (!triggerEventsForDescendents)
+ {
+ addStates.add(new ItemState(newNode, ItemState.PATH_CHANGED, false, ancestorToSave, false, false, node
+ .getQPath()));
+ }
}
@Override
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java 2011-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -32,6 +32,8 @@
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
+import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -43,10 +45,10 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Timer;
import java.util.TimerTask;
import java.util.WeakHashMap;
-import java.util.Map.Entry;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.ReentrantLock;
@@ -1886,6 +1888,68 @@
// RENAME goes before DELETE
put(item);
}
+ else if (state.isPathChanged())
+ {
+ writeLock.lock();
+ try
+ {
+ for (Entry<CacheKey, CacheValue> cacheEntry : cache.entrySet())
+ {
+ CacheKey cacheKey = cacheEntry.getKey();
+ CacheValue cacheValue = cacheEntry.getValue();
+
+ ItemData oldItemData = cacheValue.getItem();
+ if (oldItemData.getQPath().isDescendantOf(state.getOldPath()))
+ {
+ int relativeDegree = oldItemData.getQPath().getDepth() - state.getOldPath().getDepth();
+ QPath newQPath =
+ QPath.makeChildPath(state.getData().getQPath(),
+ oldItemData.getQPath().getRelPath(relativeDegree));
+
+ if (oldItemData.isNode())
+ {
+ NodeData nodeData = (NodeData)oldItemData;
+ TransientNodeData newItemData =
+ new TransientNodeData(newQPath, nodeData.getIdentifier(), nodeData.getPersistedVersion(),
+ nodeData.getPrimaryTypeName(), nodeData.getMixinTypeNames(),
+ nodeData.getOrderNumber(), nodeData.getParentIdentifier(), nodeData.getACL());
+ cache.put(cacheKey, new CacheValue(newItemData, cacheValue.getExpiredTime()));
+
+ // update in children nodes
+ List<NodeData> cachedChildNodes = nodesCache.get(nodeData.getParentIdentifier());
+ if (cachedChildNodes != null)
+ {
+ int index = cachedChildNodes.indexOf(oldItemData);
+ cachedChildNodes.set(index, newItemData);
+ }
+ }
+ else
+ {
+ PropertyData oldPropertyData = (PropertyData)oldItemData;
+ TransientPropertyData newPropertyData =
+ new TransientPropertyData(newQPath, oldPropertyData.getIdentifier(),
+ oldPropertyData.getPersistedVersion(), oldPropertyData.getType(),
+ oldPropertyData.getParentIdentifier(), oldPropertyData.isMultiValued(),
+ oldPropertyData.getValues());
+ cache.put(cacheKey, new CacheValue(newPropertyData, cacheValue.getExpiredTime()));
+
+ // update in children properties
+ List<PropertyData> cachedChildProps =
+ propertiesCache.get(oldPropertyData.getParentIdentifier());
+ if (cachedChildProps != null)
+ {
+ int index = cachedChildProps.indexOf(oldItemData);
+ cachedChildProps.set(index, newPropertyData);
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ writeLock.unlock();
+ }
+ }
else if (state.isUpdated())
{
// UPDATE occurs on reordered (no subtree!) and merged nodes (for each
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-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -355,7 +355,7 @@
ItemState itemState =
new ItemState(newData, prevState.getState(), prevState.isEventFire(), prevState.getAncestorToSave(),
- prevState.isInternallyCreated(), prevState.isPersisted());
+ prevState.isInternallyCreated(), prevState.isPersisted(), prevState.getOldPath());
newLog.add(itemState);
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-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -329,6 +329,10 @@
{
putItem(state.getData());
}
+ else if (state.isPathChanged())
+ {
+ updateTreePath(state.getOldPath(), state.getData().getQPath(), null);
+ }
else if (state.isMixinChanged())
{
if (state.isPersisted())
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-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -554,6 +554,10 @@
{
putItem(state.getData());
}
+ else if (state.isPathChanged())
+ {
+ updateTreePath(state.getOldPath(), state.getData().getQPath(), null);
+ }
else if (state.isMixinChanged())
{
if (state.isPersisted())
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/serialization/ItemStateReader.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/serialization/ItemStateReader.java 2011-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/serialization/ItemStateReader.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -22,6 +22,9 @@
import org.exoplatform.services.jcr.dataflow.serialization.ObjectReader;
import org.exoplatform.services.jcr.dataflow.serialization.SerializationConstants;
import org.exoplatform.services.jcr.dataflow.serialization.UnknownClassIdException;
+import org.exoplatform.services.jcr.datamodel.IllegalPathException;
+import org.exoplatform.services.jcr.datamodel.QPath;
+import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import java.io.EOFException;
@@ -94,17 +97,26 @@
boolean isPersisted = in.readBoolean();
boolean eventFire = in.readBoolean();
+ QPath oldPath = null;
+ int len = in.readInt();
+ if (len != -1)
+ {
+ byte[] buf = new byte[len];
+ in.readFully(buf);
+ oldPath = QPath.parse(new String(buf, Constants.DEFAULT_ENCODING));
+ }
+
boolean isNodeData = in.readBoolean();
if (isNodeData)
{
PresistedNodeDataReader rdr = new PresistedNodeDataReader();
- is = new ItemState(rdr.read(in), state, eventFire, null, false, isPersisted);
+ is = new ItemState(rdr.read(in), state, eventFire, null, false, isPersisted, oldPath);
}
else
{
PersistedPropertyDataReader rdr = new PersistedPropertyDataReader(fileCleaner, maxBufferSize, holder);
- is = new ItemState(rdr.read(in), state, eventFire, null, false, isPersisted);
+ is = new ItemState(rdr.read(in), state, eventFire, null, false, isPersisted, oldPath);
}
return is;
}
@@ -112,5 +124,9 @@
{
throw new StreamCorruptedException("Unexpected EOF in middle of data block.");
}
+ catch (IllegalPathException e)
+ {
+ throw new IOException("Data corrupted", e);
+ }
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/serialization/ItemStateWriter.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/serialization/ItemStateWriter.java 2011-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/serialization/ItemStateWriter.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -24,6 +24,7 @@
import org.exoplatform.services.jcr.dataflow.serialization.ObjectWriter;
import org.exoplatform.services.jcr.dataflow.serialization.SerializationConstants;
import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.impl.Constants;
import java.io.IOException;
@@ -58,6 +59,17 @@
out.writeBoolean(itemState.isPersisted());
out.writeBoolean(itemState.isEventFire());
+ if (itemState.getOldPath() == null)
+ {
+ out.writeInt(-1);
+ }
+ else
+ {
+ byte[] buf = itemState.getOldPath().getAsString().getBytes(Constants.DEFAULT_ENCODING);
+ out.writeInt(buf.length);
+ out.write(buf);
+ }
+
// write flag isNodeData and ItemData
ItemData data = itemState.getData();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java 2011-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -91,7 +91,7 @@
for (ItemState change : changes.getAllStates())
{
states.add(new ItemState(copyItemData(change.getData()), change.getState(), change.isEventFire(), change
- .getAncestorToSave(), change.isInternallyCreated(), change.isPersisted()));
+ .getAncestorToSave(), change.isInternallyCreated(), change.isPersisted(), change.getOldPath()));
}
newLog.addLog(new PlainChangesLogImpl(states, changes.getSessionId(), changes.getEventType()));
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLog.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLog.java 2011-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLog.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -487,6 +487,7 @@
* if renaming is not detected.
* @throws IllegalPathException
*/
+ @Deprecated
public ItemState[] findRenamed(QPath deletedPath) throws IllegalPathException
{
List<ItemState> allStates = getAllStates();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/importing/BaseXmlImporter.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/importing/BaseXmlImporter.java 2011-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/importing/BaseXmlImporter.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -175,7 +175,7 @@
for (ItemState itemState : changesLog.getAllStates())
{
newChangesLog.add(new ItemState(itemState.getData(), itemState.getState(), itemState.isEventFire(),
- ancestorToSave, itemState.isInternallyCreated(), itemState.isPersisted()));
+ ancestorToSave, itemState.isInternallyCreated(), itemState.isPersisted(), itemState.getOldPath()));
}
changesLog.clear();
changesLog.addAll(newChangesLog.getAllStates());
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-04-11 09:54:46 UTC (rev 4223)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceDataContainer.java 2011-04-11 10:54:23 UTC (rev 4224)
@@ -38,7 +38,10 @@
{
// configuration params
+ public static final String TRIGGER_EVENTS_FOR_DESCENDENTS_ON_RENAME = "trigger-events-for-descendents-on-rename";
+ public static final boolean TRIGGER_EVENTS_FOR_DESCENDENTS_ON_RENAME_DEFAULT = true;
+
public final static String CONTAINER_NAME = "containerName";
public final static String MAXBUFFERSIZE_PROP = "max-buffer-size";
15 years
exo-jcr SVN: r4223 - in jcr/trunk: exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/server and 1 other directories.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-04-11 05:54:46 -0400 (Mon, 11 Apr 2011)
New Revision: 4223
Modified:
jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupClientImpl.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgent.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgentTest.java
Log:
EXOJCR-1300 : Changes for QueryParam was commited.
Modified: jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupClientImpl.java
===================================================================
--- jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupClientImpl.java 2011-04-11 09:51:54 UTC (rev 4222)
+++ jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupClientImpl.java 2011-04-11 09:54:46 UTC (rev 4223)
@@ -52,6 +52,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
import javax.ws.rs.core.Response;
@@ -469,6 +470,13 @@
BackupAgentResponse response = null;
String sURL = null;
+ String backupSetPathEncoded = null;
+
+ if (backupSetPath != null)
+ {
+ backupSetPathEncoded = URLEncoder.encode(backupSetPath, "UTF-8");
+ }
+
if (workspaceName != null)
{
if (config != null)
@@ -484,7 +492,8 @@
sURL =
path + HTTPBackupAgent.Constants.BASE_URL
+ HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/"
- + repositoryName + "/" + backupSetPath + "/" + removeExists;
+ + repositoryName
+ + "/" + removeExists + "?backup-set-path=" + backupSetPathEncoded;
}
WorkspaceEntry wEntry = null;
@@ -529,8 +538,7 @@
sURL =
path + HTTPBackupAgent.Constants.BASE_URL
+ HTTPBackupAgent.Constants.OperationType.RESTORE_REPOSITORY_BACKUP_SET + "/"
- + backupSetPath + "/"
- + removeExists;
+ + removeExists + "?backup-set-path=" + backupSetPathEncoded;
}
RepositoryEntry wEntry = null;
@@ -613,8 +621,8 @@
{
sURL =
path + HTTPBackupAgent.Constants.BASE_URL
- + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + backupSetPath + "/"
- + removeExists;
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + removeExists
+ + "?backup-set-path=" + backupSetPathEncoded;
}
response = transport.executeGET(sURL);
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgent.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgent.java 2011-04-11 09:51:54 UTC (rev 4222)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgent.java 2011-04-11 09:54:46 UTC (rev 4223)
@@ -56,6 +56,8 @@
import java.io.File;
import java.io.FilenameFilter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
@@ -70,6 +72,7 @@
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@@ -837,16 +840,33 @@
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed("administrators")
- @Path("/restore/backup-set/{repo}/{backup-set-path:.*}/{remove-Existing}")
+ @Path("/restore/backup-set/{repo}/{remove-Existing}")
public Response restoreBackupSet(WorkspaceEntry wEntry, @PathParam("repo") String repository,
- @PathParam("backup-set-path") String backupSetPath, @PathParam("remove-Existing") Boolean removeExisting)
+ @QueryParam("backup-set-path") String backupSetPathEncoded, @PathParam("remove-Existing") Boolean removeExisting)
{
String failMessage;
Response.Status status;
Throwable exception;
+ String backupSetPath = null;
+
try
{
+ backupSetPath = URLDecoder.decode(backupSetPathEncoded, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ log.error("Can not start restore the workspace '" + "/" + repository + "/" + wEntry.getName()
+ + "' from backup set '" + backupSetPath + "'", e);
+
+ return Response.status(Response.Status.BAD_REQUEST).entity(
+ "Can not start restore the workspace '" + "/" + repository + "/" + wEntry.getName()
+ + "' from backup set '" + backupSetPath + "' : " + e.getMessage())
+ .type(MediaType.TEXT_PLAIN).cacheControl(noCache).build();
+ }
+
+ try
+ {
validateOneRestoreInstants(repository, wEntry.getName());
File backupSetDir = (new File(backupSetPath));
@@ -1135,14 +1155,29 @@
@GET
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed("administrators")
- @Path("/restore/backup-set/{backup-set-path:.*}/{remove-Existing}")
- public Response restoreFromBackupSet(@PathParam("backup-set-path") String backupSetPath,
+ @Path("/restore/backup-set/{remove-Existing}")
+ public Response restoreFromBackupSet(@QueryParam("backup-set-path") String backupSetPathEncoded,
@PathParam("remove-Existing") Boolean removeExisting)
{
String failMessage = null;
Response.Status status = null;
Throwable exception = null;
+
+ String backupSetPath = null;
+ try
+ {
+ backupSetPath = URLDecoder.decode(backupSetPathEncoded, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ log.error("Can not start restore from backup set '" + backupSetPathEncoded + "'", e);
+
+ return Response.status(Response.Status.BAD_REQUEST).entity(
+ "Can not start restore from backup set '" + backupSetPathEncoded + "' : " + e.getMessage()).type(
+ MediaType.TEXT_PLAIN).cacheControl(noCache).build();
+ }
+
File backupSetDir = (new File(backupSetPath));
File backuplog = null;
@@ -1611,17 +1646,34 @@
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed("administrators")
- @Path("/restore-repository/backup-set/{backup-set-path:.*}/{remove-Existing}")
+ @Path("/restore-repository/backup-set/{remove-Existing}")
public Response restoreRepositoryBackupSet(RepositoryEntry rEntry,
- @PathParam("backup-set-path") String backupSetPath,
+ @QueryParam("backup-set-path") String backupSetPathEncoded,
@PathParam("remove-Existing") Boolean removeExisting)
{
String failMessage;
Response.Status status;
Throwable exception;
+ String backupSetPath = null;
+
try
{
+ backupSetPath = URLDecoder.decode(backupSetPathEncoded, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ log.error("Can not start restore the repository '" + "/" + rEntry.getName() + "' from backup set '"
+ + backupSetPath + "'", e);
+
+ return Response.status(Response.Status.BAD_REQUEST).entity(
+ "Can not start restore the repository '" + "/" + rEntry.getName() + "' from backup set '"
+ + backupSetPath + "' : " + e.getMessage()).type(MediaType.TEXT_PLAIN).cacheControl(noCache)
+ .build();
+ }
+
+ try
+ {
validateOneRepositoryRestoreInstants(rEntry.getName());
File backupSetDir = (new File(backupSetPath));
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-04-11 09:51:54 UTC (rev 4222)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgentTest.java 2011-04-11 09:54:46 UTC (rev 4223)
@@ -68,6 +68,7 @@
import java.io.File;
import java.io.InputStream;
import java.net.URI;
+import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -1425,7 +1426,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
+ backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
break;
}
}
@@ -1472,8 +1473,9 @@
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")),
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "db6" + "/" + "true"
+ + "?backup-set-path=" + backupSetPath), new URI(""), new ByteArrayInputStream(json
+ .toString().getBytes("UTF-8")),
new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
@@ -1552,7 +1554,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
+ backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
break;
}
}
@@ -1575,8 +1577,8 @@
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
ContainerRequestUserRole creq =
new ContainerRequestUserRole("GET", new URI(HTTP_BACKUP_AGENT_PATH
- + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + backupSetPath + "/"
- + "true"), new URI(""), null, new InputHeadersMap(headers));
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "true"
+ + "?backup-set-path=" + backupSetPath), new URI(""), null, new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
ContainerResponse cres = new ContainerResponse(responseWriter);
@@ -1654,7 +1656,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
+ backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
break;
}
}
@@ -1678,8 +1680,8 @@
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
ContainerRequestUserRole creq =
new ContainerRequestUserRole("GET", new URI(HTTP_BACKUP_AGENT_PATH
- + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + backupSetPath + "/"
- + "false"), new URI(""), null, new InputHeadersMap(headers));
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "false"
+ + "?backup-set-path=" + backupSetPath), new URI(""), null, new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
ContainerResponse cres = new ContainerResponse(responseWriter);
@@ -1757,7 +1759,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
+ backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
break;
}
}
@@ -1807,7 +1809,7 @@
ContainerRequestUserRole creq =
new ContainerRequestUserRole("POST", new URI(HTTP_BACKUP_AGENT_PATH
+ HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "db6" + "/"
- + backupSetPath + "/" + "false"), new URI(""), new ByteArrayInputStream(json.toString()
+ + "false" + "?backup-set-path=" + backupSetPath), new URI(""), new ByteArrayInputStream(json.toString()
.getBytes("UTF-8")), new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
@@ -2511,7 +2513,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
+ backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
break;
}
}
@@ -2579,8 +2581,7 @@
ContainerRequestUserRole creq =
new ContainerRequestUserRole("POST", new URI(HTTP_BACKUP_AGENT_PATH
+ HTTPBackupAgent.Constants.OperationType.RESTORE_REPOSITORY_BACKUP_SET + "/"
- + backupSetPath + "/"
- + "true"),
+ + "true" + "?backup-set-path=" + backupSetPath),
new URI(""), new ByteArrayInputStream(json.toString().getBytes("UTF-8")),
new InputHeadersMap(headers));
@@ -2659,7 +2660,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
+ backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
break;
}
}
@@ -2728,7 +2729,7 @@
ContainerRequestUserRole creq =
new ContainerRequestUserRole("POST", new URI(HTTP_BACKUP_AGENT_PATH
+ HTTPBackupAgent.Constants.OperationType.RESTORE_REPOSITORY_BACKUP_SET + "/"
- + backupSetPath + "/" + "false"), new URI(""), new ByteArrayInputStream(json.toString()
+ + "false" + "?backup-set-path=" + backupSetPath), new URI(""), new ByteArrayInputStream(json.toString()
.getBytes("UTF-8")), new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
@@ -2806,7 +2807,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
+ backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
break;
}
}
@@ -2829,8 +2830,8 @@
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
ContainerRequestUserRole creq =
new ContainerRequestUserRole("GET", new URI(HTTP_BACKUP_AGENT_PATH
- + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + backupSetPath + "/"
- + "true"), new URI(""), null, new InputHeadersMap(headers));
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "true"
+ + "?backup-set-path=" + backupSetPath), new URI(""), null, new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
ContainerResponse cres = new ContainerResponse(responseWriter);
@@ -2907,7 +2908,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
+ backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
break;
}
}
@@ -2931,8 +2932,8 @@
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
ContainerRequestUserRole creq =
new ContainerRequestUserRole("GET", new URI(HTTP_BACKUP_AGENT_PATH
- + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + backupSetPath + "/"
- + "false"), new URI(""), null, new InputHeadersMap(headers));
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "false"
+ + "?backup-set-path=" + backupSetPath), new URI(""), null, new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
ContainerResponse cres = new ContainerResponse(responseWriter);
15 years
exo-jcr SVN: r4222 - in jcr/trunk: exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/server and 1 other directories.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-04-11 05:51:54 -0400 (Mon, 11 Apr 2011)
New Revision: 4222
Modified:
jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupClientImpl.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgent.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgentTest.java
Log:
JCR-1563 : Changes was reverted.
Modified: jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupClientImpl.java
===================================================================
--- jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupClientImpl.java 2011-04-11 09:31:32 UTC (rev 4221)
+++ jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupClientImpl.java 2011-04-11 09:51:54 UTC (rev 4222)
@@ -52,7 +52,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
import javax.ws.rs.core.Response;
@@ -470,13 +469,6 @@
BackupAgentResponse response = null;
String sURL = null;
- String backupSetPathEncoded = null;
-
- if (backupSetPath != null)
- {
- backupSetPathEncoded = URLEncoder.encode(backupSetPath, "UTF-8");
- }
-
if (workspaceName != null)
{
if (config != null)
@@ -492,8 +484,7 @@
sURL =
path + HTTPBackupAgent.Constants.BASE_URL
+ HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/"
- + repositoryName
- + "/" + removeExists + "?backup-set-path=" + backupSetPathEncoded;
+ + repositoryName + "/" + backupSetPath + "/" + removeExists;
}
WorkspaceEntry wEntry = null;
@@ -538,7 +529,8 @@
sURL =
path + HTTPBackupAgent.Constants.BASE_URL
+ HTTPBackupAgent.Constants.OperationType.RESTORE_REPOSITORY_BACKUP_SET + "/"
- + removeExists + "?backup-set-path=" + backupSetPathEncoded;
+ + backupSetPath + "/"
+ + removeExists;
}
RepositoryEntry wEntry = null;
@@ -621,8 +613,8 @@
{
sURL =
path + HTTPBackupAgent.Constants.BASE_URL
- + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + removeExists
- + "?backup-set-path=" + backupSetPathEncoded;
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + backupSetPath + "/"
+ + removeExists;
}
response = transport.executeGET(sURL);
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgent.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgent.java 2011-04-11 09:31:32 UTC (rev 4221)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgent.java 2011-04-11 09:51:54 UTC (rev 4222)
@@ -56,8 +56,6 @@
import java.io.File;
import java.io.FilenameFilter;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
@@ -72,7 +70,6 @@
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@@ -840,33 +837,16 @@
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed("administrators")
- @Path("/restore/backup-set/{repo}/{remove-Existing}")
+ @Path("/restore/backup-set/{repo}/{backup-set-path:.*}/{remove-Existing}")
public Response restoreBackupSet(WorkspaceEntry wEntry, @PathParam("repo") String repository,
- @QueryParam("backup-set-path") String backupSetPathEncoded, @PathParam("remove-Existing") Boolean removeExisting)
+ @PathParam("backup-set-path") String backupSetPath, @PathParam("remove-Existing") Boolean removeExisting)
{
String failMessage;
Response.Status status;
Throwable exception;
- String backupSetPath = null;
-
try
{
- backupSetPath = URLDecoder.decode(backupSetPathEncoded, "UTF-8");
- }
- catch (UnsupportedEncodingException e)
- {
- log.error("Can not start restore the workspace '" + "/" + repository + "/" + wEntry.getName()
- + "' from backup set '" + backupSetPath + "'", e);
-
- return Response.status(Response.Status.BAD_REQUEST).entity(
- "Can not start restore the workspace '" + "/" + repository + "/" + wEntry.getName()
- + "' from backup set '" + backupSetPath + "' : " + e.getMessage())
- .type(MediaType.TEXT_PLAIN).cacheControl(noCache).build();
- }
-
- try
- {
validateOneRestoreInstants(repository, wEntry.getName());
File backupSetDir = (new File(backupSetPath));
@@ -1155,29 +1135,14 @@
@GET
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed("administrators")
- @Path("/restore/backup-set/{remove-Existing}")
- public Response restoreFromBackupSet(@QueryParam("backup-set-path") String backupSetPathEncoded,
+ @Path("/restore/backup-set/{backup-set-path:.*}/{remove-Existing}")
+ public Response restoreFromBackupSet(@PathParam("backup-set-path") String backupSetPath,
@PathParam("remove-Existing") Boolean removeExisting)
{
String failMessage = null;
Response.Status status = null;
Throwable exception = null;
-
- String backupSetPath = null;
- try
- {
- backupSetPath = URLDecoder.decode(backupSetPathEncoded, "UTF-8");
- }
- catch (UnsupportedEncodingException e)
- {
- log.error("Can not start restore from backup set '" + backupSetPathEncoded + "'", e);
-
- return Response.status(Response.Status.BAD_REQUEST).entity(
- "Can not start restore from backup set '" + backupSetPathEncoded + "' : " + e.getMessage()).type(
- MediaType.TEXT_PLAIN).cacheControl(noCache).build();
- }
-
File backupSetDir = (new File(backupSetPath));
File backuplog = null;
@@ -1646,34 +1611,17 @@
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed("administrators")
- @Path("/restore-repository/backup-set/{remove-Existing}")
+ @Path("/restore-repository/backup-set/{backup-set-path:.*}/{remove-Existing}")
public Response restoreRepositoryBackupSet(RepositoryEntry rEntry,
- @QueryParam("backup-set-path") String backupSetPathEncoded,
+ @PathParam("backup-set-path") String backupSetPath,
@PathParam("remove-Existing") Boolean removeExisting)
{
String failMessage;
Response.Status status;
Throwable exception;
- String backupSetPath = null;
-
try
{
- backupSetPath = URLDecoder.decode(backupSetPathEncoded, "UTF-8");
- }
- catch (UnsupportedEncodingException e)
- {
- log.error("Can not start restore the repository '" + "/" + rEntry.getName() + "' from backup set '"
- + backupSetPath + "'", e);
-
- return Response.status(Response.Status.BAD_REQUEST).entity(
- "Can not start restore the repository '" + "/" + rEntry.getName() + "' from backup set '"
- + backupSetPath + "' : " + e.getMessage()).type(MediaType.TEXT_PLAIN).cacheControl(noCache)
- .build();
- }
-
- try
- {
validateOneRepositoryRestoreInstants(rEntry.getName());
File backupSetDir = (new File(backupSetPath));
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-04-11 09:31:32 UTC (rev 4221)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgentTest.java 2011-04-11 09:51:54 UTC (rev 4222)
@@ -68,7 +68,6 @@
import java.io.File;
import java.io.InputStream;
import java.net.URI;
-import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -1426,7 +1425,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
+ backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
break;
}
}
@@ -1473,9 +1472,8 @@
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" + "/" + "true"
- + "?backup-set-path=" + backupSetPath), new URI(""), new ByteArrayInputStream(json
- .toString().getBytes("UTF-8")),
+ + 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();
@@ -1554,7 +1552,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
+ backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
break;
}
}
@@ -1577,8 +1575,8 @@
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
ContainerRequestUserRole creq =
new ContainerRequestUserRole("GET", new URI(HTTP_BACKUP_AGENT_PATH
- + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "true"
- + "?backup-set-path=" + backupSetPath), new URI(""), null, new InputHeadersMap(headers));
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + backupSetPath + "/"
+ + "true"), new URI(""), null, new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
ContainerResponse cres = new ContainerResponse(responseWriter);
@@ -1656,7 +1654,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
+ backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
break;
}
}
@@ -1680,8 +1678,8 @@
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
ContainerRequestUserRole creq =
new ContainerRequestUserRole("GET", new URI(HTTP_BACKUP_AGENT_PATH
- + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "false"
- + "?backup-set-path=" + backupSetPath), new URI(""), null, new InputHeadersMap(headers));
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + backupSetPath + "/"
+ + "false"), new URI(""), null, new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
ContainerResponse cres = new ContainerResponse(responseWriter);
@@ -1759,7 +1757,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
+ backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
break;
}
}
@@ -1809,7 +1807,7 @@
ContainerRequestUserRole creq =
new ContainerRequestUserRole("POST", new URI(HTTP_BACKUP_AGENT_PATH
+ HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "db6" + "/"
- + "false" + "?backup-set-path=" + backupSetPath), new URI(""), new ByteArrayInputStream(json.toString()
+ + backupSetPath + "/" + "false"), new URI(""), new ByteArrayInputStream(json.toString()
.getBytes("UTF-8")), new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
@@ -2513,7 +2511,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
+ backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
break;
}
}
@@ -2581,7 +2579,8 @@
ContainerRequestUserRole creq =
new ContainerRequestUserRole("POST", new URI(HTTP_BACKUP_AGENT_PATH
+ HTTPBackupAgent.Constants.OperationType.RESTORE_REPOSITORY_BACKUP_SET + "/"
- + "true" + "?backup-set-path=" + backupSetPath),
+ + backupSetPath + "/"
+ + "true"),
new URI(""), new ByteArrayInputStream(json.toString().getBytes("UTF-8")),
new InputHeadersMap(headers));
@@ -2660,7 +2659,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
+ backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
break;
}
}
@@ -2729,7 +2728,7 @@
ContainerRequestUserRole creq =
new ContainerRequestUserRole("POST", new URI(HTTP_BACKUP_AGENT_PATH
+ HTTPBackupAgent.Constants.OperationType.RESTORE_REPOSITORY_BACKUP_SET + "/"
- + "false" + "?backup-set-path=" + backupSetPath), new URI(""), new ByteArrayInputStream(json.toString()
+ + backupSetPath + "/" + "false"), new URI(""), new ByteArrayInputStream(json.toString()
.getBytes("UTF-8")), new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
@@ -2807,7 +2806,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
+ backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
break;
}
}
@@ -2830,8 +2829,8 @@
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
ContainerRequestUserRole creq =
new ContainerRequestUserRole("GET", new URI(HTTP_BACKUP_AGENT_PATH
- + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "true"
- + "?backup-set-path=" + backupSetPath), new URI(""), null, new InputHeadersMap(headers));
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + backupSetPath + "/"
+ + "true"), new URI(""), null, new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
ContainerResponse cres = new ContainerResponse(responseWriter);
@@ -2908,7 +2907,7 @@
{
if (bcl.getBackupId().equals(id))
{
- backupSetPath = URLEncoder.encode(bcl.getBackupConfig().getBackupDir().getCanonicalPath(), "UTF-8");
+ backupSetPath = bcl.getBackupConfig().getBackupDir().getCanonicalPath();
break;
}
}
@@ -2932,8 +2931,8 @@
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
ContainerRequestUserRole creq =
new ContainerRequestUserRole("GET", new URI(HTTP_BACKUP_AGENT_PATH
- + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + "false"
- + "?backup-set-path=" + backupSetPath), new URI(""), null, new InputHeadersMap(headers));
+ + HTTPBackupAgent.Constants.OperationType.RESTORE_BACKUP_SET + "/" + backupSetPath + "/"
+ + "false"), new URI(""), null, new InputHeadersMap(headers));
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
ContainerResponse cres = new ContainerResponse(responseWriter);
15 years
exo-jcr SVN: r4221 - jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/server.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-04-11 05:31:32 -0400 (Mon, 11 Apr 2011)
New Revision: 4221
Modified:
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgentTest.java
Log:
JCR-1563: The test HTTPBackupAgent was fixed.
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-04-11 08:35:21 UTC (rev 4220)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/server/HTTPBackupAgentTest.java 2011-04-11 09:31:32 UTC (rev 4221)
@@ -3161,35 +3161,4 @@
}
}
}
-
- public void testStartBackupRepository_OnWin() throws Exception
- {
- Session session_db6_ws2 = repositoryService.getRepository("db6").login(credentials, "ws2");
- assertNotNull(session_db6_ws2);
-
- session_db6_ws2.getRootNode().addNode("NODE_NAME_TO_TEST");
- session_db6_ws2.save();
-
- File f = new File("E:\\data\\exo-working\\temp\\backup");
-
- BackupConfigBean configBean = new BackupConfigBean(BackupManager.FULL_AND_INCREMENTAL, f.getPath(), 10000l);
-
- JsonGeneratorImpl generatorImpl = new JsonGeneratorImpl();
- JsonValue json = generatorImpl.createJsonObject(configBean);
-
- 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.START_BACKUP_REPOSITORY + "/db6"), new URI(""),
- new ByteArrayInputStream(json.toString().getBytes("UTF-8")), new InputHeadersMap(headers));
-
- ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
- ContainerResponse cres = new ContainerResponse(responseWriter);
- handler.handleRequest(creq, cres);
-
- assertEquals(200, cres.getStatus());
-
- Thread.sleep(10000);
- }
}
15 years