exo-jcr SVN: r3350 - 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: sergiykarpenko
Date: 2010-10-27 03:52:37 -0400 (Wed, 27 Oct 2010)
New Revision: 3350
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-999: lock-remover-max-threads parameter description added
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 2010-10-26 15:33:02 UTC (rev 3349)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2010-10-27 07:52:37 UTC (rev 3350)
@@ -197,6 +197,16 @@
<para><emphasis role="bold">session-max-age</emphasis>: The time after
which an idle session will be removed (called logout). If session-max-age
is not set up, idle session will never be removed.</para>
+
+ <para id="JCR.eXoJCRconfiguration.LockRemoverMaxThreads"><emphasis
+ role="bold">lock-remover-max-threads</emphasis>: Number of threads that
+ can serve LockRemover tasks. Default value is 1. Repository may have many
+ workspaces, each workspace have own LockManager. JCR supports Locks with
+ defined lifetime. Such a lock must be removed is it become expired. That
+ is what LockRemovers does. But LockRemovers is not an independent
+ timer-threads, its a task that executed each 30 seconds. Such a task is
+ served by ThreadPoolExecutor which may use different number of
+ threads.</para>
</section>
<section>
@@ -376,6 +386,13 @@
<para><emphasis role="bold">path</emphasis>: A lock folder. Each workspace
has its own one.</para>
+ <note>
+ <para>Also see <link
+ linkend="JCR.eXoJCRconfiguration.LockRemoverMaxThreads"><emphasis
+ role="bold">lock-remover-max-threads</emphasis></link> repository
+ configuration parameter.</para>
+ </note>
+
<programlisting><!ELEMENT repository-service (repositories)>
<!ATTLIST repository-service default-repository NMTOKEN #REQUIRED>
<!ELEMENT repositories (repository)>
13 years, 6 months
exo-jcr SVN: r3349 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/core/lock and 7 other directories.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-10-26 11:33:02 -0400 (Tue, 26 Oct 2010)
New Revision: 3349
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.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/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.core/src/main/resources/binding.xml
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCleanableFileStreamValueData.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestPersistedValueData.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestTransientValueData.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestValueImpl.java
Log:
EXOJCR-999: FileCleaner reverted to rev.3344
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java 2010-10-26 15:33:02 UTC (rev 3349)
@@ -48,8 +48,6 @@
protected int lockRemoverMaxThreadCount;
- protected int fileCleanerMaxThreadsCount;
-
public RepositoryInfo()
{
@@ -203,15 +201,6 @@
}
/**
- * Returns FileCleaner per-repository max threads count.
- * @return LockRemovers per-repository max threads count
- */
- public int getFileCleanerThreadsCount()
- {
- return fileCleanerMaxThreadsCount;
- }
-
- /**
* Sets LockRemovers per-repository max threads count.
* @param lockRemoverMaxThreadCount
*/
@@ -221,15 +210,6 @@
}
/**
- * Sets FileCleaner per-repository max threads count.
- * @param fileCleanerMaxThreadsCount
- */
- public void setFileCleanerThreadsCount(int fileCleanerMaxThreadsCount)
- {
- this.fileCleanerMaxThreadsCount = fileCleanerMaxThreadsCount;
- }
-
- /**
* Merges the current {@link RepositoryInfo} with the given one. The current {@link RepositoryInfo}
* has the highest priority thus only absent data will be overrode
* @param entry the entry to merge with the current {@link RepositoryInfo}
@@ -250,7 +230,5 @@
setSessionTimeOut(entry.sessionTimeOut);
if (lockRemoverMaxThreadCount == 0)
setLockRemoverThreadsCount(entry.lockRemoverMaxThreadCount);
- if (fileCleanerMaxThreadsCount == 0)
- setFileCleanerThreadsCount(entry.fileCleanerMaxThreadsCount);
}
}
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 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.java 2010-10-26 15:33:02 UTC (rev 3349)
@@ -1,3 +1,21 @@
+/*
+ * 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.core.lock;
import org.exoplatform.services.jcr.config.RepositoryEntry;
@@ -5,13 +23,12 @@
/**
* LockRemoverHolder holds is a single per-repository LockRemover container.
- * @author <a href="mailto:foo@bar.org">Foo Bar</a>
+ *
+ * @author <a href="mailto:karpenko.sergiy@gmail.com">Karpenko Sergiy</a>
* @version $Id: exo-jboss-codetemplates.xml 34360 2009-07-22 23:58:59Z aheritier $
- *
*/
public class LockRemoverHolder
{
-
/**
* Default amount of thread that may be used by WorkerService to serve LockRemovers.
*/
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 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/proccess/WorkerService.java 2010-10-26 15:33:02 UTC (rev 3349)
@@ -1,3 +1,21 @@
+/*
+ * 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.proccess;
import java.util.concurrent.ScheduledFuture;
@@ -6,6 +24,12 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+/**
+ * WorkerService.
+ *
+ * @author <a href="mailto:karpenko.sergiy@gmail.com">Karpenko Sergiy</a>
+ * @version $Id: WorkerService.java 34361 2010-08-24 23:58:59Z aheritier $
+ */
public class WorkerService
{
/**
@@ -95,22 +119,10 @@
}
/**
- * Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks
- * will be accepted.
+ * Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
*/
public void stop()
{
executor.shutdown();
}
-
- /**
- * Creates and executes a one-shot action that becomes enabled after the given delay.
- *
- * @param command
- * @param delay
- */
- public void executeDelay(Runnable command, long delay)
- {
- executor.schedule(command, delay, TimeUnit.MILLISECONDS);
- }
}
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 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java 2010-10-26 15:33:02 UTC (rev 3349)
@@ -18,11 +18,16 @@
*/
package org.exoplatform.services.jcr.impl.util.io;
-import org.exoplatform.services.jcr.impl.proccess.WorkerService;
+import org.exoplatform.services.jcr.impl.proccess.WorkerThread;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import java.io.File;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
/**
* Created by The eXo Platform SAS.
@@ -30,43 +35,103 @@
* @author Gennady Azarenkov
* @version $Id: FileCleaner.java 11907 2008-03-13 15:36:21Z ksm $
*/
-public class FileCleaner
+public class FileCleaner extends WorkerThread
{
protected static final long DEFAULT_TIMEOUT = 30000;
protected static Log log = ExoLogger.getLogger("exo.jcr.component.core.FileCleaner");
+ protected final ConcurrentLinkedQueue<File> files = new ConcurrentLinkedQueue<File>();
+
+ public FileCleaner()
+ {
+ this(DEFAULT_TIMEOUT);
+ }
+
+ public FileCleaner(long timeout)
+ {
+ this(timeout, true);
+ }
+
+ public FileCleaner(boolean start)
+ {
+ this(DEFAULT_TIMEOUT, start);
+ }
+
+ public FileCleaner(long timeout, boolean start)
+ {
+ super(timeout);
+ setName("FileCleaner " + getId());
+ setDaemon(true);
+ setPriority(Thread.MIN_PRIORITY);
+
+ if (start)
+ start();
+
+ PrivilegedAction<Object> action = new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ registerShutdownHook();
+ return null;
+ }
+ };
+ AccessController.doPrivileged(action);
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("FileCleaner instantiated name= " + getName() + " timeout= " + timeout);
+ }
+ }
+
/**
- * FileCleanerTask is a task that might be executed with WorkerService. This task
- * tries to remove single file. If remove is failed it register itself to execute again.
+ * @param file
*/
- class FileCleanerTask implements Runnable
+ public void addFile(File file)
{
- protected final File file;
+ if (PrivilegedFileHelper.exists(file))
+ {
+ files.offer(file);
+ }
+ }
- private final WorkerService executor;
-
- FileCleanerTask(WorkerService workerService, File file)
+ @Override
+ public void halt()
+ {
+ try
{
- this.file = file;
- this.executor = workerService;
+ callPeriodically();
}
+ catch (Exception e)
+ {
+ }
- /**
- * {@inheritDoc}
- */
- public void run()
+ if (files != null && files.size() > 0)
+ log.warn("There are uncleared files: " + files.size());
+
+ super.halt();
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.proccess.WorkerThread#callPeriodically()
+ */
+ @Override
+ protected void callPeriodically() throws Exception
+ {
+ File file = null;
+ Set<File> notRemovedFiles = new HashSet<File>();
+ while ((file = files.poll()) != null)
{
if (PrivilegedFileHelper.exists(file))
{
if (!PrivilegedFileHelper.delete(file))
{
+ notRemovedFiles.add(file);
+
if (log.isDebugEnabled())
log.debug("Could not delete " + (file.isDirectory() ? "directory" : "file")
+ ". Will try next time: " + PrivilegedFileHelper.getAbsolutePath(file));
- // delete is failed, so execute this task again
- executor.executeDelay(this, timeout);
}
else if (log.isDebugEnabled())
{
@@ -75,44 +140,37 @@
}
}
}
- }
- final long timeout;
-
- final WorkerService workerService;
-
- /**
- * TODO this constructor used only in ext project. Clean it.
- *
- * @param timeout
- */
- public FileCleaner(long timeout)
- {
- this(new WorkerService(1), DEFAULT_TIMEOUT);
+ //add do lists tail all not removed files
+ if (!notRemovedFiles.isEmpty())
+ {
+ files.addAll(notRemovedFiles);
+ }
}
- public FileCleaner(WorkerService workerService)
+ private void registerShutdownHook()
{
- this(workerService, DEFAULT_TIMEOUT);
- }
-
- public FileCleaner(WorkerService workerService, long timeout)
- {
- this.timeout = timeout;
- this.workerService = workerService;
- }
-
- /**
- * Add file to special removing queue.
- *
- * @param file - file that must be removed
- */
- public void addFile(File file)
- {
- if (PrivilegedFileHelper.exists(file))
+ // register shutdown hook for final cleaning up
+ try
{
- workerService.executeDelay(new FileCleanerTask(workerService, file), timeout);
+ Runtime.getRuntime().addShutdownHook(new Thread()
+ {
+ @Override
+ public void run()
+ {
+ File file = null;
+ while ((file = files.poll()) != null)
+ {
+ PrivilegedFileHelper.delete(file);
+ }
+ }
+ });
}
+ catch (IllegalStateException e)
+ {
+ // can't register shutdownhook because
+ // jvm shutdown sequence has already begun,
+ // silently ignore...
+ }
}
-
}
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 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java 2010-10-26 15:33:02 UTC (rev 3349)
@@ -18,9 +18,6 @@
*/
package org.exoplatform.services.jcr.impl.util.io;
-import org.exoplatform.services.jcr.config.RepositoryEntry;
-import org.exoplatform.services.jcr.impl.proccess.WorkerService;
-
/**
* Created by The eXo Platform SAS. <br/> per workspace container file cleaner holder object
*
@@ -29,56 +26,17 @@
*/
public class FileCleanerHolder
{
- /**
- * Default amount of thread that may be used by WorkerService to serve LockRemovers.
- */
- public final int DEFAULT_THREAD_COUNT = 1;
- /**
- * WorkerService that executed LockRemover.
- */
- private final WorkerService workerService;
+ private final FileCleaner fileCleaner;
- /**
- * Constructor. Used in tests.
- *
- * @param threadCount - how mane threads can serve FileCleaner tasks
- */
- public FileCleanerHolder(int threadCount)
+ public FileCleanerHolder()
{
- workerService = new WorkerService(threadCount, "file-cleaner-");
+ this.fileCleaner = new FileCleaner();
}
- /**
- * Constructor.
- * @param entry - RepositoryEntry that may contain lock-remover-max-threads parameter.
- */
- public FileCleanerHolder(RepositoryEntry entry)
- {
- int threadCount = DEFAULT_THREAD_COUNT;
- if (entry != null)
- {
- if (entry.getLockRemoverThreadsCount() > 0)
- {
- threadCount = entry.getLockRemoverThreadsCount();
- }
- }
- workerService = new WorkerService(threadCount, "file-cleaner-" + entry.getName());
- }
-
public FileCleaner getFileCleaner()
{
- return new FileCleaner(workerService);
+ return fileCleaner;
}
- public FileCleaner getFileCleaner(long timeout)
- {
- return new FileCleaner(workerService, timeout);
- }
-
- public void stop()
- {
- this.workerService.stop();
- }
-
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/resources/binding.xml
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/resources/binding.xml 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/main/resources/binding.xml 2010-10-26 15:33:02 UTC (rev 3349)
@@ -19,9 +19,6 @@
deserializer="org.exoplatform.services.jcr.util.ConfigurationFormat.parseTime" usage="optional" />
<value name="lock-remover-max-threads" field="lockRemoverMaxThreadCount"
deserializer="org.exoplatform.services.jcr.util.ConfigurationFormat.parseInt" usage="optional" />
- <value name="file-cleaner-max-threads" field="fileCleanerMaxThreadsCount"
- deserializer="org.exoplatform.services.jcr.util.ConfigurationFormat.parseInt" usage="optional" />
-
<value name="authentication-policy" field="authenticationPolicy" />
<collection name="workspaces" field="workspaces" item-type="org.exoplatform.services.jcr.config.WorkspaceEntry" />
</mapping>
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCleanableFileStreamValueData.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCleanableFileStreamValueData.java 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCleanableFileStreamValueData.java 2010-10-26 15:33:02 UTC (rev 3349)
@@ -20,7 +20,6 @@
import org.exoplatform.services.jcr.JcrImplBaseTest;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
-import org.exoplatform.services.jcr.impl.proccess.WorkerService;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import org.exoplatform.services.jcr.impl.util.io.SwapFile;
@@ -50,7 +49,6 @@
private File testFile = new File(parentDir, FILE_NAME);
- private WorkerService workerService;
private FileCleaner testCleaner;
private CleanableFilePersistedValueData cleanableValueData;
@@ -84,9 +82,9 @@
public void setUp() throws Exception
{
super.setUp();
- WorkerService workerService = new WorkerService(1);
- testCleaner = new FileCleaner(workerService, CLEANER_TIMEOUT);
+ testCleaner = new FileCleaner(CLEANER_TIMEOUT);
+
SwapFile sf = SwapFile.get(parentDir, FILE_NAME);
FileOutputStream fout = new FileOutputStream(sf);
fout.write("testFileCleaned".getBytes());
@@ -101,9 +99,9 @@
{
cleanableValueData = null;
+ testCleaner.halt();
testCleaner = null;
- workerService.stop();
-
+
if (testFile.exists())
{
testFile.delete();
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java 2010-10-26 15:33:02 UTC (rev 3349)
@@ -104,7 +104,7 @@
// ref.add(new StringRefAddr("database", "jdbc:hsqldb:file:data/test"));
// SimpleJNDIContextInitializer.initialize(sourceName, ref);
- FileCleanerHolder holder = new FileCleanerHolder(1);
+ FileCleanerHolder holder = new FileCleanerHolder();
container =
new JDBCWorkspaceDataContainer(config, repositoryEntry, null, new StandaloneStoragePluginProvider(config,
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java 2010-10-26 15:33:02 UTC (rev 3349)
@@ -22,7 +22,6 @@
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.dataflow.TesterTransientValueData;
-import org.exoplatform.services.jcr.impl.proccess.WorkerService;
import org.exoplatform.services.jcr.impl.storage.value.ValueDataResourceHolder;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
@@ -44,8 +43,6 @@
private File rootDir;
- WorkerService workerService;
-
private FileCleaner cleaner;
private ValueDataResourceHolder resources = new ValueDataResourceHolder();
@@ -59,9 +56,9 @@
protected void setUp() throws Exception
{
super.setUp();
- workerService = new WorkerService(1, "TestFileIOChannel-file-cleaner");
- cleaner = new FileCleaner(workerService, 2000);
+ cleaner = new FileCleaner(2000);
+
rootDir = new File(new File("target"), "vs1");
rootDir.mkdirs();
@@ -78,7 +75,7 @@
@Override
protected void tearDown() throws Exception
{
- cleaner = null;
+ cleaner.halt();
}
public void testRead() throws Exception
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestPersistedValueData.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestPersistedValueData.java 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestPersistedValueData.java 2010-10-26 15:33:02 UTC (rev 3349)
@@ -23,7 +23,6 @@
import org.exoplatform.services.jcr.impl.dataflow.persistent.ByteArrayPersistedValueData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.CleanableFilePersistedValueData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.FilePersistedValueData;
-import org.exoplatform.services.jcr.impl.proccess.WorkerService;
import org.exoplatform.services.jcr.impl.storage.value.fs.Probe;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import org.exoplatform.services.jcr.impl.util.io.SwapFile;
@@ -82,8 +81,7 @@
public void testIfFinalizeRemovesTempFileStreamValueData() throws Exception
{
- WorkerService workerService = new WorkerService(1, "TestPersistedValueData-file-cleaner");
- FileCleaner testFileCleaner = new FileCleaner(workerService, 1000);
+ FileCleaner testFileCleaner = new FileCleaner(1000, true);
try
{
byte[] buf = "0123456789".getBytes();
@@ -109,7 +107,7 @@
}
finally
{
- testFileCleaner = null;
+ testFileCleaner.halt();
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestTransientValueData.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestTransientValueData.java 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestTransientValueData.java 2010-10-26 15:33:02 UTC (rev 3349)
@@ -24,7 +24,6 @@
import org.exoplatform.services.jcr.datamodel.InternalQName;
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
-import org.exoplatform.services.jcr.impl.proccess.WorkerService;
import org.exoplatform.services.jcr.impl.util.JCRDateFormat;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
@@ -67,8 +66,7 @@
public void testCreateFileStreamTransientValueData() throws Exception
{
- WorkerService workerService = new WorkerService(1, "TestTransientValueData-file-cleaner");
- FileCleaner testFileCleaner = new FileCleaner(workerService);
+ FileCleaner testFileCleaner = new FileCleaner();
try
{
byte[] buf = "0123456789".getBytes();
@@ -106,7 +104,7 @@
}
finally
{
- testFileCleaner = null;
+ testFileCleaner.halt();
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestValueImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestValueImpl.java 2010-10-26 15:08:22 UTC (rev 3348)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestValueImpl.java 2010-10-26 15:33:02 UTC (rev 3349)
@@ -27,7 +27,6 @@
import org.exoplatform.services.jcr.impl.core.value.LongValue;
import org.exoplatform.services.jcr.impl.core.value.StringValue;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
-import org.exoplatform.services.jcr.impl.proccess.WorkerService;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import java.io.File;
@@ -51,8 +50,7 @@
public void testNewBinaryValue() throws Exception
{
- WorkerService workerService = new WorkerService(1, "TestValueImpl-file-cleaner");
- FileCleaner testFileCleaner = new FileCleaner(workerService);
+ FileCleaner testFileCleaner = new FileCleaner();
try
{
@@ -95,7 +93,7 @@
}
finally
{
- testFileCleaner = null;
+ testFileCleaner.halt();
}
}
13 years, 6 months
exo-jcr SVN: r3348 - in jcr/trunk/exo.jcr.component.ext/src: test/java/org/exoplatform/services/jcr/ext/script/groovy and 1 other directory.
by do-not-reply@jboss.org
Author: aparfonov
Date: 2010-10-26 11:08:22 -0400 (Tue, 26 Oct 2010)
New Revision: 3348
Added:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyResourceLoader.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyCompilerTest.java
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java
Log:
EXOJCR-1020
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java 2010-10-26 13:38:12 UTC (rev 3347)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java 2010-10-26 15:08:22 UTC (rev 3348)
@@ -32,10 +32,8 @@
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.jcr.ext.registry.RegistryEntry;
import org.exoplatform.services.jcr.ext.registry.RegistryService;
-import org.exoplatform.services.jcr.ext.resource.JcrURLConnection;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import org.exoplatform.services.rest.ext.groovy.DefaultGroovyResourceLoader;
import org.exoplatform.services.rest.ext.groovy.GroovyJaxrsPublisher;
import org.exoplatform.services.rest.ext.groovy.ResourceId;
import org.exoplatform.services.rest.impl.ResourceBinder;
@@ -53,7 +51,6 @@
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
-import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
@@ -98,7 +95,7 @@
{
/** Logger. */
- private static final Log LOG = ExoLogger.getLogger("exo.jcr.component.ext.GroovyScript2RestLoader");
+ static final Log LOG = ExoLogger.getLogger("exo.jcr.component.ext.GroovyScript2RestLoader");
/** Default node types for Groovy scripts. */
private static final String DEFAULT_NODETYPE = "exo:groovyResourceContainer";
@@ -1275,7 +1272,6 @@
public Response list(@PathParam("repository") String repository, @PathParam("workspace") String workspace,
@QueryParam("name") String name)
{
-
Session ses = null;
try
{
@@ -1335,7 +1331,6 @@
Collections.sort(scriptList);
return Response.status(Response.Status.OK).entity(new ScriptList(scriptList)).type(MediaType.APPLICATION_JSON)
.build();
-
}
catch (Exception e)
{
@@ -1377,131 +1372,21 @@
}
/**
- * JCR groovy resource resolver.
- */
- protected class JcrGroovyResourceLoader extends DefaultGroovyResourceLoader
- {
-
- public JcrGroovyResourceLoader(URL[] roots) throws MalformedURLException
- {
- super(normalizeJcrURL(roots));
- }
-
- @Override
- protected URL getResource(String filename) throws MalformedURLException
- {
- filename = filename.intern();
- URL resource = null;
- synchronized (filename)
- {
- resource = resources.get(filename);
- boolean inCache = resource != null;
- for (URL root : roots)
- {
- if (resource == null)
- {
- if ("jcr".equals(root.getProtocol()))
- {
- // In JCR URL path represented by fragment
- // jcr://repository/workspace#/path
- String ref = root.getRef();
- resource = new URL(root, "#" + ref + filename);
- }
- else
- {
- resource = new URL(root, filename);
- }
- }
- URLConnection connection = null;
- try
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Try to load resource from URL : " + resource);
-
- connection = resource.openConnection();
- connection.getInputStream().close();
-
- break;
- }
- catch (IOException e)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Can't open URL : " + resource);
-
- resource = null;
- }
- finally
- {
- if (connection != null && resource != null && "jcr".equals(resource.getProtocol()))
- {
- ((JcrURLConnection)connection).disconnect();
- }
- }
- }
- if (resource != null)
- {
- resources.put(filename, resource);
- }
- else if (inCache)
- {
- // Remove from map if resource is unreachable
- resources.remove(filename);
- }
- }
- return resource;
- }
- }
-
- private static URL[] normalizeJcrURL(URL[] src) throws MalformedURLException
- {
- URL[] res = new URL[src.length];
- for (int i = 0; i < src.length; i++)
- {
- if ("jcr".equals(src[i].getProtocol()))
- {
- String ref = src[i].getRef();
- if (ref == null)
- {
- ref = "/";
- }
- else if (ref.charAt(ref.length() - 1) != '/')
- {
- ref = ref + "/";
- }
- res[i] = new URL(src[i], "#" + ref);
- }
- else
- {
- res[i] = src[i];
- }
- }
- return res;
- }
-
- /**
* Script meta-data, used for pass script meta-data as JSON.
*/
public static class ScriptMetadata
{
- /**
- * Is script autoload.
- */
+ /** Is script autoload. */
private final boolean autoload;
- /**
- * Is script loaded.
- */
+ /** Is script loaded. */
private final boolean load;
- /**
- * Script media type (script/groovy).
- */
+ /** Script media type (script/groovy). */
private final String mediaType;
- /**
- * Last modified date.
- */
+ /** Last modified date. */
private final long lastModified;
public ScriptMetadata(boolean autoload, boolean load, String mediaType, long lastModified)
@@ -1551,9 +1436,7 @@
public static class ScriptList
{
- /**
- * The list of scripts.
- */
+ /** The list of scripts. */
private List<String> list;
/**
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java 2010-10-26 15:08:22 UTC (rev 3348)
@@ -0,0 +1,111 @@
+/**
+ * Copyright (C) 2010 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.script.groovy;
+
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyCodeSource;
+
+import org.exoplatform.services.jcr.ext.resource.JcrURLConnection;
+import org.exoplatform.services.jcr.ext.resource.UnifiedNodeReference;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * JcrGroovyCompiler can load source code of groovy script from JCR and parse it
+ * via GroovyClassLoader.
+ *
+ * @author <a href="mailto:andrew00x@gmail.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public class JcrGroovyCompiler
+{
+ protected GroovyClassLoader gcl;
+
+ public JcrGroovyCompiler()
+ {
+ ClassLoader cl = getClass().getClassLoader();
+ this.gcl = new GroovyClassLoader(cl);
+ }
+
+ /**
+ * @return get underling groovy class loader
+ */
+ public GroovyClassLoader getGroovyClassLoader()
+ {
+ return gcl;
+ }
+
+ /**
+ * Set groovy class loader.
+ *
+ * @param gcl groovy class loader
+ * @throws NullPointerException if <code>gcl == null</code>
+ */
+ public void setGroovyClassLoader(GroovyClassLoader gcl)
+ {
+ if (gcl == null)
+ throw new NullPointerException("GroovyClassLoader may not be null.");
+ this.gcl = gcl;
+ }
+
+ public Class<?>[] compile(UnifiedNodeReference... sourceReferences) throws IOException
+ {
+ GroovyClassLoader cl = gcl;
+ Class<?>[] classes = new Class<?>[sourceReferences.length];
+ for (int i = 0; i < sourceReferences.length; i++)
+ {
+ JcrURLConnection conn = null;
+ try
+ {
+ URL url = sourceReferences[i].getURL();
+ conn = (JcrURLConnection)url.openConnection();
+ Class<?> clazz = cl.parseClass(createCodeSource(conn.getInputStream(), url.toString()));
+ classes[i] = clazz;
+ }
+ finally
+ {
+ if (conn != null)
+ {
+ conn.disconnect();
+ }
+ }
+ }
+ return classes;
+ }
+
+ /**
+ * Create {@link GroovyCodeSource} from given stream and name. Code base
+ * 'file:/groovy/script' (default code base used for all Groovy classes) will
+ * be used.
+ *
+ * @param in groovy source code stream
+ * @param name code source name
+ * @return GroovyCodeSource
+ */
+ // Override this method if need other behavior.
+ protected GroovyCodeSource createCodeSource(InputStream in, String name)
+ {
+ GroovyCodeSource gcs = new GroovyCodeSource(in, name, "/groovy/script");
+ gcs.setCachable(false);
+ return gcs;
+ }
+}
Property changes on: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyResourceLoader.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyResourceLoader.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyResourceLoader.java 2010-10-26 15:08:22 UTC (rev 3348)
@@ -0,0 +1,129 @@
+/*
+ * 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.ext.script.groovy;
+
+import org.exoplatform.services.jcr.ext.resource.JcrURLConnection;
+import org.exoplatform.services.rest.ext.groovy.DefaultGroovyResourceLoader;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+/**
+ * JCR groovy resource resolver.
+ */
+public class JcrGroovyResourceLoader extends DefaultGroovyResourceLoader
+{
+
+ private static URL[] normalizeJcrURL(URL[] src) throws MalformedURLException
+ {
+ URL[] res = new URL[src.length];
+ for (int i = 0; i < src.length; i++)
+ {
+ if ("jcr".equals(src[i].getProtocol()))
+ {
+ String ref = src[i].getRef();
+ if (ref == null)
+ {
+ ref = "/";
+ }
+ else if (ref.charAt(ref.length() - 1) != '/')
+ {
+ ref = ref + "/";
+ }
+ res[i] = new URL(src[i], "#" + ref);
+ }
+ else
+ {
+ res[i] = src[i];
+ }
+ }
+ return res;
+ }
+
+ public JcrGroovyResourceLoader(URL[] roots) throws MalformedURLException
+ {
+ super(normalizeJcrURL(roots));
+ }
+
+ @Override
+ protected URL getResource(String filename) throws MalformedURLException
+ {
+ filename = filename.intern();
+ URL resource = null;
+ synchronized (filename)
+ {
+ resource = resources.get(filename);
+ boolean inCache = resource != null;
+ for (URL root : roots)
+ {
+ if (resource == null)
+ {
+ if ("jcr".equals(root.getProtocol()))
+ {
+ // In JCR URL path represented by fragment
+ // jcr://repository/workspace#/path
+ String ref = root.getRef();
+ resource = new URL(root, "#" + ref + filename);
+ }
+ else
+ {
+ resource = new URL(root, filename);
+ }
+ }
+ URLConnection connection = null;
+ try
+ {
+ if (GroovyScript2RestLoader.LOG.isDebugEnabled())
+ GroovyScript2RestLoader.LOG.debug("Try to load resource from URL : " + resource);
+
+ connection = resource.openConnection();
+ connection.getInputStream().close();
+
+ break;
+ }
+ catch (IOException e)
+ {
+ if (GroovyScript2RestLoader.LOG.isDebugEnabled())
+ GroovyScript2RestLoader.LOG.debug("Can't open URL : " + resource);
+
+ resource = null;
+ }
+ finally
+ {
+ if (connection != null && resource != null && "jcr".equals(resource.getProtocol()))
+ {
+ ((JcrURLConnection)connection).disconnect();
+ }
+ }
+ }
+ if (resource != null)
+ {
+ resources.put(filename, resource);
+ }
+ else if (inCache)
+ {
+ // Remove from map if resource is unreachable
+ resources.remove(filename);
+ }
+ }
+ return resource;
+ }
+}
\ No newline at end of file
Property changes on: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyResourceLoader.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyCompilerTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyCompilerTest.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyCompilerTest.java 2010-10-26 15:08:22 UTC (rev 3348)
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2010 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.script.groovy;
+
+import groovy.lang.GroovyObject;
+
+import org.exoplatform.services.jcr.ext.BaseStandaloneTest;
+import org.exoplatform.services.jcr.ext.resource.UnifiedNodeReference;
+
+import java.util.Calendar;
+
+import javax.jcr.Node;
+
+/**
+ * @author <a href="mailto:andrew00x@gmail.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public class GroovyCompilerTest extends BaseStandaloneTest
+{
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ Node groovyRepo = root.addNode("groovyRepo", "nt:folder");
+ Node org = groovyRepo.addNode("org", "nt:folder");
+ Node exo = org.addNode("exoplatform", "nt:folder");
+ Node a = exo.addNode("A.groovy", "nt:file");
+ a = a.addNode("jcr:content", "nt:resource");
+ a.setProperty("jcr:mimeType", "script/groovy");
+ a.setProperty("jcr:lastModified", Calendar.getInstance());
+ a.setProperty("jcr:data", //
+ "package org.exoplatform\n" + //
+ " class A { String message = 'groovy compiler test' }");
+
+ Node test = exo.addNode("test", "nt:folder");
+ Node b = test.addNode("B.groovy", "nt:file");
+ b = b.addNode("jcr:content", "nt:resource");
+ b.setProperty("jcr:mimeType", "script/groovy");
+ b.setProperty("jcr:lastModified", Calendar.getInstance());
+ b.setProperty("jcr:data", //
+ "package org.exoplatform.test\n" + //
+ " import org.exoplatform.A\n" + //
+ " class B extends A {}");
+ session.save();
+ }
+
+ public void testGroovyDependency() throws Exception
+ {
+ JcrGroovyCompiler compiler = new JcrGroovyCompiler();
+ compiler.getGroovyClassLoader().setResourceLoader(
+ new JcrGroovyResourceLoader(new java.net.URL[]{new java.net.URL("jcr://db1/ws#/groovyRepo")}));
+ Class<?>[] classes =
+ compiler.compile(new UnifiedNodeReference("db1", "ws", "/groovyRepo/org/exoplatform/test/B.groovy"));
+ assertEquals(1, classes.length);
+ GroovyObject go = (GroovyObject)classes[0].newInstance();
+ assertEquals("groovy compiler test", go.invokeMethod("getMessage", new Object[0]));
+ }
+
+}
Property changes on: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyCompilerTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
13 years, 6 months
exo-jcr SVN: r3347 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-10-26 09:38:12 -0400 (Tue, 26 Oct 2010)
New Revision: 3347
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java
Log:
EXOJCR-999: FileCleaner fixed
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 2010-10-26 12:14:01 UTC (rev 3346)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java 2010-10-26 13:38:12 UTC (rev 3347)
@@ -111,7 +111,7 @@
{
if (PrivilegedFileHelper.exists(file))
{
- workerService.executePeriodically(new FileCleanerTask(workerService, file), timeout);
+ workerService.executeDelay(new FileCleanerTask(workerService, file), timeout);
}
}
13 years, 6 months
exo-jcr SVN: r3346 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/proccess and 6 other directories.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-10-26 08:14:01 -0400 (Tue, 26 Oct 2010)
New Revision: 3346
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.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.core/src/main/resources/binding.xml
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCleanableFileStreamValueData.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestPersistedValueData.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestTransientValueData.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestValueImpl.java
Log:
EXOJCR-999: FileCleaner based on WorkerService implemented
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java 2010-10-26 08:39:49 UTC (rev 3345)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java 2010-10-26 12:14:01 UTC (rev 3346)
@@ -48,6 +48,8 @@
protected int lockRemoverMaxThreadCount;
+ protected int fileCleanerMaxThreadsCount;
+
public RepositoryInfo()
{
@@ -201,6 +203,15 @@
}
/**
+ * Returns FileCleaner per-repository max threads count.
+ * @return LockRemovers per-repository max threads count
+ */
+ public int getFileCleanerThreadsCount()
+ {
+ return fileCleanerMaxThreadsCount;
+ }
+
+ /**
* Sets LockRemovers per-repository max threads count.
* @param lockRemoverMaxThreadCount
*/
@@ -210,6 +221,15 @@
}
/**
+ * Sets FileCleaner per-repository max threads count.
+ * @param fileCleanerMaxThreadsCount
+ */
+ public void setFileCleanerThreadsCount(int fileCleanerMaxThreadsCount)
+ {
+ this.fileCleanerMaxThreadsCount = fileCleanerMaxThreadsCount;
+ }
+
+ /**
* Merges the current {@link RepositoryInfo} with the given one. The current {@link RepositoryInfo}
* has the highest priority thus only absent data will be overrode
* @param entry the entry to merge with the current {@link RepositoryInfo}
@@ -230,5 +250,7 @@
setSessionTimeOut(entry.sessionTimeOut);
if (lockRemoverMaxThreadCount == 0)
setLockRemoverThreadsCount(entry.lockRemoverMaxThreadCount);
+ if (fileCleanerMaxThreadsCount == 0)
+ setFileCleanerThreadsCount(entry.fileCleanerMaxThreadsCount);
}
}
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 2010-10-26 08:39:49 UTC (rev 3345)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/proccess/WorkerService.java 2010-10-26 12:14:01 UTC (rev 3346)
@@ -95,10 +95,22 @@
}
/**
- * Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
+ * Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks
+ * will be accepted.
*/
public void stop()
{
executor.shutdown();
}
+
+ /**
+ * Creates and executes a one-shot action that becomes enabled after the given delay.
+ *
+ * @param command
+ * @param delay
+ */
+ public void executeDelay(Runnable command, long delay)
+ {
+ executor.schedule(command, delay, TimeUnit.MILLISECONDS);
+ }
}
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 2010-10-26 08:39:49 UTC (rev 3345)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java 2010-10-26 12:14:01 UTC (rev 3346)
@@ -18,16 +18,11 @@
*/
package org.exoplatform.services.jcr.impl.util.io;
-import org.exoplatform.services.jcr.impl.proccess.WorkerThread;
+import org.exoplatform.services.jcr.impl.proccess.WorkerService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import java.io.File;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
/**
* Created by The eXo Platform SAS.
@@ -35,104 +30,43 @@
* @author Gennady Azarenkov
* @version $Id: FileCleaner.java 11907 2008-03-13 15:36:21Z ksm $
*/
-
-public class FileCleaner extends WorkerThread
+public class FileCleaner
{
protected static final long DEFAULT_TIMEOUT = 30000;
protected static Log log = ExoLogger.getLogger("exo.jcr.component.core.FileCleaner");
- protected final ConcurrentLinkedQueue<File> files = new ConcurrentLinkedQueue<File>();
-
- public FileCleaner()
- {
- this(DEFAULT_TIMEOUT);
- }
-
- public FileCleaner(long timeout)
- {
- this(timeout, true);
- }
-
- public FileCleaner(boolean start)
- {
- this(DEFAULT_TIMEOUT, start);
- }
-
- public FileCleaner(long timeout, boolean start)
- {
- super(timeout);
- setName("FileCleaner " + getId());
- setDaemon(true);
- setPriority(Thread.MIN_PRIORITY);
-
- if (start)
- start();
-
- PrivilegedAction<Object> action = new PrivilegedAction<Object>()
- {
- public Object run()
- {
- registerShutdownHook();
- return null;
- }
- };
- AccessController.doPrivileged(action);
-
- if (log.isDebugEnabled())
- {
- log.debug("FileCleaner instantiated name= " + getName() + " timeout= " + timeout);
- }
- }
-
/**
- * @param file
+ * FileCleanerTask is a task that might be executed with WorkerService. This task
+ * tries to remove single file. If remove is failed it register itself to execute again.
*/
- public void addFile(File file)
+ class FileCleanerTask implements Runnable
{
- if (PrivilegedFileHelper.exists(file))
- {
- files.offer(file);
- }
- }
+ protected final File file;
- @Override
- public void halt()
- {
- try
+ private final WorkerService executor;
+
+ FileCleanerTask(WorkerService workerService, File file)
{
- callPeriodically();
+ this.file = file;
+ this.executor = workerService;
}
- catch (Exception e)
- {
- }
- if (files != null && files.size() > 0)
- log.warn("There are uncleared files: " + files.size());
-
- super.halt();
- }
-
- /**
- * @see org.exoplatform.services.jcr.impl.proccess.WorkerThread#callPeriodically()
- */
- @Override
- protected void callPeriodically() throws Exception
- {
- File file = null;
- Set<File> notRemovedFiles = new HashSet<File>();
- while ((file = files.poll()) != null)
+ /**
+ * {@inheritDoc}
+ */
+ public void run()
{
if (PrivilegedFileHelper.exists(file))
{
if (!PrivilegedFileHelper.delete(file))
{
- notRemovedFiles.add(file);
-
if (log.isDebugEnabled())
log.debug("Could not delete " + (file.isDirectory() ? "directory" : "file")
+ ". Will try next time: " + PrivilegedFileHelper.getAbsolutePath(file));
+ // delete is failed, so execute this task again
+ executor.executeDelay(this, timeout);
}
else if (log.isDebugEnabled())
{
@@ -141,37 +75,44 @@
}
}
}
+ }
- //add do lists tail all not removed files
- if (!notRemovedFiles.isEmpty())
- {
- files.addAll(notRemovedFiles);
- }
+ final long timeout;
+
+ final WorkerService workerService;
+
+ /**
+ * TODO this constructor used only in ext project. Clean it.
+ *
+ * @param timeout
+ */
+ public FileCleaner(long timeout)
+ {
+ this(new WorkerService(1), DEFAULT_TIMEOUT);
}
- private void registerShutdownHook()
+ public FileCleaner(WorkerService workerService)
{
- // register shutdown hook for final cleaning up
- try
+ this(workerService, DEFAULT_TIMEOUT);
+ }
+
+ public FileCleaner(WorkerService workerService, long timeout)
+ {
+ this.timeout = timeout;
+ this.workerService = workerService;
+ }
+
+ /**
+ * Add file to special removing queue.
+ *
+ * @param file - file that must be removed
+ */
+ public void addFile(File file)
+ {
+ if (PrivilegedFileHelper.exists(file))
{
- Runtime.getRuntime().addShutdownHook(new Thread()
- {
- @Override
- public void run()
- {
- File file = null;
- while ((file = files.poll()) != null)
- {
- PrivilegedFileHelper.delete(file);
- }
- }
- });
+ workerService.executePeriodically(new FileCleanerTask(workerService, file), timeout);
}
- catch (IllegalStateException e)
- {
- // can't register shutdownhook because
- // jvm shutdown sequence has already begun,
- // silently ignore...
- }
}
+
}
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 2010-10-26 08:39:49 UTC (rev 3345)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java 2010-10-26 12:14:01 UTC (rev 3346)
@@ -18,26 +18,67 @@
*/
package org.exoplatform.services.jcr.impl.util.io;
+import org.exoplatform.services.jcr.config.RepositoryEntry;
+import org.exoplatform.services.jcr.impl.proccess.WorkerService;
+
/**
* Created by The eXo Platform SAS. <br/> per workspace container file cleaner holder object
*
* @author Gennady Azarenkov
* @version $Id: WorkspaceFileCleanerHolder.java 11907 2008-03-13 15:36:21Z ksm $
*/
-
public class FileCleanerHolder
{
+ /**
+ * Default amount of thread that may be used by WorkerService to serve LockRemovers.
+ */
+ public final int DEFAULT_THREAD_COUNT = 1;
- private final FileCleaner fileCleaner;
+ /**
+ * WorkerService that executed LockRemover.
+ */
+ private final WorkerService workerService;
- public FileCleanerHolder()
+ /**
+ * Constructor. Used in tests.
+ *
+ * @param threadCount - how mane threads can serve FileCleaner tasks
+ */
+ public FileCleanerHolder(int threadCount)
{
- this.fileCleaner = new FileCleaner();
+ workerService = new WorkerService(threadCount, "file-cleaner-");
}
+ /**
+ * Constructor.
+ * @param entry - RepositoryEntry that may contain lock-remover-max-threads parameter.
+ */
+ public FileCleanerHolder(RepositoryEntry entry)
+ {
+ int threadCount = DEFAULT_THREAD_COUNT;
+ if (entry != null)
+ {
+ if (entry.getLockRemoverThreadsCount() > 0)
+ {
+ threadCount = entry.getLockRemoverThreadsCount();
+ }
+ }
+ workerService = new WorkerService(threadCount, "file-cleaner-" + entry.getName());
+ }
+
public FileCleaner getFileCleaner()
{
- return fileCleaner;
+ return new FileCleaner(workerService);
}
+ public FileCleaner getFileCleaner(long timeout)
+ {
+ return new FileCleaner(workerService, timeout);
+ }
+
+ public void stop()
+ {
+ this.workerService.stop();
+ }
+
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/resources/binding.xml
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/resources/binding.xml 2010-10-26 08:39:49 UTC (rev 3345)
+++ jcr/trunk/exo.jcr.component.core/src/main/resources/binding.xml 2010-10-26 12:14:01 UTC (rev 3346)
@@ -19,6 +19,9 @@
deserializer="org.exoplatform.services.jcr.util.ConfigurationFormat.parseTime" usage="optional" />
<value name="lock-remover-max-threads" field="lockRemoverMaxThreadCount"
deserializer="org.exoplatform.services.jcr.util.ConfigurationFormat.parseInt" usage="optional" />
+ <value name="file-cleaner-max-threads" field="fileCleanerMaxThreadsCount"
+ deserializer="org.exoplatform.services.jcr.util.ConfigurationFormat.parseInt" usage="optional" />
+
<value name="authentication-policy" field="authenticationPolicy" />
<collection name="workspaces" field="workspaces" item-type="org.exoplatform.services.jcr.config.WorkspaceEntry" />
</mapping>
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCleanableFileStreamValueData.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCleanableFileStreamValueData.java 2010-10-26 08:39:49 UTC (rev 3345)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCleanableFileStreamValueData.java 2010-10-26 12:14:01 UTC (rev 3346)
@@ -20,6 +20,7 @@
import org.exoplatform.services.jcr.JcrImplBaseTest;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
+import org.exoplatform.services.jcr.impl.proccess.WorkerService;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import org.exoplatform.services.jcr.impl.util.io.SwapFile;
@@ -49,6 +50,7 @@
private File testFile = new File(parentDir, FILE_NAME);
+ private WorkerService workerService;
private FileCleaner testCleaner;
private CleanableFilePersistedValueData cleanableValueData;
@@ -82,9 +84,9 @@
public void setUp() throws Exception
{
super.setUp();
+ WorkerService workerService = new WorkerService(1);
+ testCleaner = new FileCleaner(workerService, CLEANER_TIMEOUT);
- testCleaner = new FileCleaner(CLEANER_TIMEOUT);
-
SwapFile sf = SwapFile.get(parentDir, FILE_NAME);
FileOutputStream fout = new FileOutputStream(sf);
fout.write("testFileCleaned".getBytes());
@@ -99,9 +101,9 @@
{
cleanableValueData = null;
- testCleaner.halt();
testCleaner = null;
-
+ workerService.stop();
+
if (testFile.exists())
{
testFile.delete();
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java 2010-10-26 08:39:49 UTC (rev 3345)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java 2010-10-26 12:14:01 UTC (rev 3346)
@@ -104,7 +104,7 @@
// ref.add(new StringRefAddr("database", "jdbc:hsqldb:file:data/test"));
// SimpleJNDIContextInitializer.initialize(sourceName, ref);
- FileCleanerHolder holder = new FileCleanerHolder();
+ FileCleanerHolder holder = new FileCleanerHolder(1);
container =
new JDBCWorkspaceDataContainer(config, repositoryEntry, null, new StandaloneStoragePluginProvider(config,
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java 2010-10-26 08:39:49 UTC (rev 3345)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java 2010-10-26 12:14:01 UTC (rev 3346)
@@ -22,6 +22,7 @@
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.dataflow.TesterTransientValueData;
+import org.exoplatform.services.jcr.impl.proccess.WorkerService;
import org.exoplatform.services.jcr.impl.storage.value.ValueDataResourceHolder;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
@@ -43,6 +44,8 @@
private File rootDir;
+ WorkerService workerService;
+
private FileCleaner cleaner;
private ValueDataResourceHolder resources = new ValueDataResourceHolder();
@@ -56,9 +59,9 @@
protected void setUp() throws Exception
{
super.setUp();
+ workerService = new WorkerService(1, "TestFileIOChannel-file-cleaner");
+ cleaner = new FileCleaner(workerService, 2000);
- cleaner = new FileCleaner(2000);
-
rootDir = new File(new File("target"), "vs1");
rootDir.mkdirs();
@@ -75,7 +78,7 @@
@Override
protected void tearDown() throws Exception
{
- cleaner.halt();
+ cleaner = null;
}
public void testRead() throws Exception
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestPersistedValueData.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestPersistedValueData.java 2010-10-26 08:39:49 UTC (rev 3345)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestPersistedValueData.java 2010-10-26 12:14:01 UTC (rev 3346)
@@ -23,6 +23,7 @@
import org.exoplatform.services.jcr.impl.dataflow.persistent.ByteArrayPersistedValueData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.CleanableFilePersistedValueData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.FilePersistedValueData;
+import org.exoplatform.services.jcr.impl.proccess.WorkerService;
import org.exoplatform.services.jcr.impl.storage.value.fs.Probe;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import org.exoplatform.services.jcr.impl.util.io.SwapFile;
@@ -81,7 +82,8 @@
public void testIfFinalizeRemovesTempFileStreamValueData() throws Exception
{
- FileCleaner testFileCleaner = new FileCleaner(1000, true);
+ WorkerService workerService = new WorkerService(1, "TestPersistedValueData-file-cleaner");
+ FileCleaner testFileCleaner = new FileCleaner(workerService, 1000);
try
{
byte[] buf = "0123456789".getBytes();
@@ -107,7 +109,7 @@
}
finally
{
- testFileCleaner.halt();
+ testFileCleaner = null;
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestTransientValueData.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestTransientValueData.java 2010-10-26 08:39:49 UTC (rev 3345)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestTransientValueData.java 2010-10-26 12:14:01 UTC (rev 3346)
@@ -24,6 +24,7 @@
import org.exoplatform.services.jcr.datamodel.InternalQName;
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
+import org.exoplatform.services.jcr.impl.proccess.WorkerService;
import org.exoplatform.services.jcr.impl.util.JCRDateFormat;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
@@ -66,7 +67,8 @@
public void testCreateFileStreamTransientValueData() throws Exception
{
- FileCleaner testFileCleaner = new FileCleaner();
+ WorkerService workerService = new WorkerService(1, "TestTransientValueData-file-cleaner");
+ FileCleaner testFileCleaner = new FileCleaner(workerService);
try
{
byte[] buf = "0123456789".getBytes();
@@ -104,7 +106,7 @@
}
finally
{
- testFileCleaner.halt();
+ testFileCleaner = null;
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestValueImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestValueImpl.java 2010-10-26 08:39:49 UTC (rev 3345)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestValueImpl.java 2010-10-26 12:14:01 UTC (rev 3346)
@@ -27,6 +27,7 @@
import org.exoplatform.services.jcr.impl.core.value.LongValue;
import org.exoplatform.services.jcr.impl.core.value.StringValue;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
+import org.exoplatform.services.jcr.impl.proccess.WorkerService;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import java.io.File;
@@ -50,7 +51,8 @@
public void testNewBinaryValue() throws Exception
{
- FileCleaner testFileCleaner = new FileCleaner();
+ WorkerService workerService = new WorkerService(1, "TestValueImpl-file-cleaner");
+ FileCleaner testFileCleaner = new FileCleaner(workerService);
try
{
@@ -93,7 +95,7 @@
}
finally
{
- testFileCleaner.halt();
+ testFileCleaner = null;
}
}
13 years, 6 months
exo-jcr SVN: r3345 - jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav.
by do-not-reply@jboss.org
Author: dkuleshov
Date: 2010-10-26 04:39:49 -0400 (Tue, 26 Oct 2010)
New Revision: 3345
Modified:
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
Log:
EXOJCR-1010: created two more constructors for WebDavServiceImpl
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java 2010-10-25 14:13:33 UTC (rev 3344)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java 2010-10-26 08:39:49 UTC (rev 3345)
@@ -75,6 +75,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.PathNotFoundException;
@@ -286,6 +287,94 @@
}
/**
+ * Constructor.
+ *
+ * @param params Initialization params
+ * @param repositoryService repository service
+ * @param sessionProviderService session provider service
+ */
+ protected WebDavServiceImpl(Map<String, String> params, RepositoryService repositoryService,
+ ThreadLocalSessionProviderService sessionProviderService) throws Exception
+ {
+ this.sessionProviderService = sessionProviderService;
+ this.repositoryService = repositoryService;
+ this.nullResourceLocks = new NullResourceLocksHolder();
+
+ String paramValue = params.get(INIT_PARAM_DEF_FOLDER_NODE_TYPE);
+ if (paramValue != null)
+ {
+ defaultFolderNodeType = paramValue;
+ log.info(INIT_PARAM_DEF_FOLDER_NODE_TYPE + " = " + defaultFolderNodeType);
+ }
+
+ paramValue = params.get(INIT_PARAM_DEF_FILE_NODE_TYPE);
+ if (paramValue != null)
+ {
+ defaultFileNodeType = paramValue;
+ log.info(INIT_PARAM_DEF_FILE_NODE_TYPE + " = " + defaultFileNodeType);
+ }
+
+ paramValue = params.get(INIT_PARAM_DEF_FILE_MIME_TYPE);
+ if (paramValue != null)
+ {
+ defaultFileMimeType = paramValue;
+ log.info(INIT_PARAM_DEF_FILE_MIME_TYPE + " = " + defaultFileMimeType);
+ }
+
+ paramValue = params.get(INIT_PARAM_UPDATE_POLICY);
+ if (paramValue != null)
+ {
+ updatePolicyType = paramValue;
+ log.info(INIT_PARAM_UPDATE_POLICY + " = " + updatePolicyType);
+ }
+
+ paramValue = params.get(INIT_PARAM_AUTO_VERSION);
+ if (paramValue != null)
+ {
+ autoVersionType = paramValue;
+ log.info(INIT_PARAM_AUTO_VERSION + " = " + autoVersionType);
+ }
+
+ paramValue = params.get(INIT_PARAM_CACHE_CONTROL);
+ if (paramValue != null)
+ {
+ try
+ {
+ String[] elements = paramValue.split(";");
+ for (String element : elements)
+ {
+ String cacheValue = element.split(":")[1];
+ String keys = element.split(":")[0];
+ for (String key : keys.split(","))
+ {
+ MediaType mediaType = new MediaType(key.split("/")[0], key.split("/")[1]);
+ cacheControlMap.put(mediaType, cacheValue);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ log.warn("Invalid " + INIT_PARAM_CACHE_CONTROL + " parameter");
+ }
+
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param repositoryService repository service
+ * @param sessionProviderService session provider service
+ */
+ protected WebDavServiceImpl(RepositoryService repositoryService,
+ ThreadLocalSessionProviderService sessionProviderService)
+ {
+ this.sessionProviderService = sessionProviderService;
+ this.repositoryService = repositoryService;
+ this.nullResourceLocks = new NullResourceLocksHolder();
+ }
+
+ /**
* {@inheritDoc}
*/
@CHECKIN
13 years, 6 months
exo-jcr SVN: r3344 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl: proccess and 1 other directory.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-10-25 10:13:33 -0400 (Mon, 25 Oct 2010)
New Revision: 3344
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.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/proccess/WorkerService.java
Log:
EXOJCR-999: WorkerThreadFactory updated
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java 2010-10-25 12:35:03 UTC (rev 3343)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java 2010-10-25 14:13:33 UTC (rev 3344)
@@ -38,7 +38,7 @@
private final long timeout;
- private ScheduledFuture lockRemoverTask = null;
+ private ScheduledFuture<?> lockRemoverTask = null;
class LockRemoverTask implements Runnable
{
@@ -69,11 +69,10 @@
public void start()
{
- if (lockRemoverTask != null)
+ if (lockRemoverTask == null)
{
- stop();
+ lockRemoverTask = workerService.executePeriodically(new LockRemoverTask(lockManager), timeout);
}
- lockRemoverTask = workerService.executePeriodically(new LockRemoverTask(lockManager), timeout);
}
public void stop()
@@ -81,5 +80,4 @@
lockRemoverTask.cancel(false);
lockRemoverTask = null;
}
-
}
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 2010-10-25 12:35:03 UTC (rev 3343)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.java 2010-10-25 14:13:33 UTC (rev 3344)
@@ -36,7 +36,7 @@
threadCount = entry.getLockRemoverThreadsCount();
}
}
- workerService = new WorkerService(threadCount, "lock-remover");
+ workerService = new WorkerService(threadCount, "lock-remover-" + entry.getName());
}
/**
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 2010-10-25 12:35:03 UTC (rev 3343)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/proccess/WorkerService.java 2010-10-25 14:13:33 UTC (rev 3344)
@@ -13,9 +13,9 @@
*/
private final ScheduledThreadPoolExecutor executor;
- class WorkerThreadFactory implements ThreadFactory
+ static class WorkerThreadFactory implements ThreadFactory
{
- final AtomicInteger poolNumber = new AtomicInteger(1);
+ static final AtomicInteger poolNumber = new AtomicInteger(1);
final ThreadGroup group;
@@ -23,18 +23,25 @@
final String namePrefix;
+ final boolean isDaemon;
+
WorkerThreadFactory(String namePrefix)
{
+ this(namePrefix, false);
+ }
+
+ WorkerThreadFactory(String namePrefix, boolean isDaemon)
+ {
+ this.isDaemon = isDaemon;
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
- this.namePrefix = namePrefix + poolNumber.getAndIncrement() + "-thread-";
+ this.namePrefix = namePrefix + "-" + poolNumber.getAndIncrement() + "-thread-";
}
public Thread newThread(Runnable r)
{
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
- if (t.isDaemon())
- t.setDaemon(false);
+ t.setDaemon(isDaemon);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
@@ -63,13 +70,26 @@
}
/**
+ * Constructor.
+ *
+ * @param threadCount - max thread count that executor may use
+ * @param threadNamePrefix - thread name prefix
+ * @param makeThreadsDaemon - does thread created by Service must be daemon
+ */
+ public WorkerService(int threadCount, String threadNamePrefix, boolean makeThreadsDaemon)
+ {
+ executor =
+ new ScheduledThreadPoolExecutor(threadCount, new WorkerThreadFactory(threadNamePrefix, makeThreadsDaemon));
+ }
+
+ /**
* Execute specified <code>command</code> periodically with <code>delay</code>.
*
* @param command - command that must be executed
* @param delay - delay between each command execution
* @return
*/
- public ScheduledFuture executePeriodically(Runnable command, long delay)
+ public ScheduledFuture<?> executePeriodically(Runnable command, long delay)
{
return executor.scheduleWithFixedDelay(command, 0, delay, TimeUnit.MILLISECONDS);
}
13 years, 6 months
exo-jcr SVN: r3343 - jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command.
by do-not-reply@jboss.org
Author: dkuleshov
Date: 2010-10-25 08:35:03 -0400 (Mon, 25 Oct 2010)
New Revision: 3343
Modified:
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java
Log:
EXOJCR-1012: added checking for PROPFIND 'propname' correct properties' names output
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java 2010-10-25 06:31:29 UTC (rev 3342)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java 2010-10-25 12:35:03 UTC (rev 3343)
@@ -138,6 +138,8 @@
String find = outputStream.toString();
assertTrue(find.contains(authorProp));
assertTrue(find.contains("D:getlastmodified"));
+ assertFalse(find.contains("jcr:lockOwner"));
+ assertFalse(find.contains("D:lockdiscovery"));
}
public void testAllProps() throws Exception
@@ -214,11 +216,10 @@
ByteArrayOutputStream bas = new ByteArrayOutputStream();
((PropFindResponseEntity)resp.getEntity()).write(bas);
String find = new String(bas.toByteArray());
- assertTrue(!find.contains("jcr:lockOnwer"));
- assertTrue(!find.contains("D:lockdiscovery"));
+ assertFalse(find.contains("jcr:lockOnwer"));
+ assertFalse(find.contains("D:lockdiscovery"));
}
-
public void testPropWithPercent() throws Exception
{
String content = TestUtils.getFileContent();
13 years, 6 months
exo-jcr SVN: r3342 - jcr/tags/1.12.5-GA.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-10-25 02:31:29 -0400 (Mon, 25 Oct 2010)
New Revision: 3342
Added:
jcr/tags/1.12.5-GA/readme.txt
Log:
EXOJCR-1016: release notes
Added: jcr/tags/1.12.5-GA/readme.txt
===================================================================
--- jcr/tags/1.12.5-GA/readme.txt (rev 0)
+++ jcr/tags/1.12.5-GA/readme.txt 2010-10-25 06:31:29 UTC (rev 3342)
@@ -0,0 +1,388 @@
+JCR 1.12.5-GA release notes
+===========================
+
+eXoPlatform Java Content Repository (JSR-170) implementation and Extension services with clustering support.
+
+Features of this version:
+- JobSchedulerServiceImpl support multi portal containers
+- Performance improvements
+
+Changes of 1.12.5-GA
+=====================
+
+Bug
+ * [KER-162] - Simple skin from examples folder doesn't appear at list
+ * [KER-163] - CachingContainer returns unregistered components
+ * [COR-213] - User logged-out and cannot login after some inactivity
+ * [WS-254] - Add org.exoplatform.services.rest.ext.method.filter.MethodAccessFilter in container configuration by default
+ * [JCR-1438] - Problem with JCR versionning
+ * [JCR-1449] - Can't get property of a node if it has a child node with the same name with the property
+ * [JCR-1450] - JCROrganizationService contains nodetype with same name as in CS
+ * [JCR-1453] - Missed nodetypes in cluster testing configuration
+ * [JCR-1462] - Problems during testing of backup on jcr 1.12.5-GA-SNAPSHOT
+ * [JCR-1466] - RepositoryException: URI is not hierarchical on remove workspace via backup console
+ * [JCR-1474] - NPE when try to import data via WorkspaceContentImporter
+
+Improvement
+ * [KER-160] - Prevent the JobSchedulerServiceImpl to launch jobs that rely on non started services in JBoss AS
+ * [KER-161] - Make the JobSchedulerServiceImpl support multi portal containers
+
+Task
+ * [JCR-1455] - Doc's title should be rename from eXoJCR Reference Manual to eXo JCR Developer Guide
+ * [JCR-1461] - Remove timestamp from names of jar-files in application bundles
+ * [JCR-1467] - Cannot use webdav service with a version of jcr:content
+ * [JCR-1471] - Updating eXo JCR version in ra.xml automatically
+ * [JCR-1472] - Adopt Backup client article
+ * [JCR-1473] - merge performance improvements
+
+Changes of 1.12.4-GA
+=====================
+
+Bug
+ * [EXOJCR-688] - Some entries in the eXo JCR cache are not evicted properly
+ * [EXOJCR-843] - Exceptions after importing file with version history
+ * [EXOJCR-849] - "Permission denied" on client side, when trying to move file(s) to another workspace through FTP
+ * [EXOJCR-856] - Problems while recopying same files via webdav
+ * [EXOJCR-865] - Data corrupt after restore a node which has been imported with version history
+ * [EXOJCR-878] - WebDAV doesn't work with nt:file
+ * [EXOJCR-879] - TestCaching.testNotModifiedSince failed in same cases
+ * [EXOJCR-888] - The problems with restore version node
+ * [EXOJCR-890] - JSON framework don't work with beans created in groovy
+ * [EXOJCR-891] - Snaphosts IDs make the applications build improperly
+ * [EXOJCR-908] - Used wrong delimiter during parsing permission value
+ * [EXOJCR-909] - In LDAPService, InitialContext is not safely closed in authenticate method
+ * [EXOJCR-912] - Unable to convert the JCR documentation to pdf
+ * [EXOJCR-916] - Duplicate instantiation of some services
+ * [EXOJCR-921] - Workspace.copy(srcWS, srcAbsPath, destAbsPath) can not copy root child to another workspace root child
+ * [EXOJCR-924] - Unable to coerce 'Event' into a LONG: java.lang.NumberFormatException: For input string: "Event"
+ * [EXOJCR-933] - Determine property type from nodetype definition in DocumentViewImport for version history.
+ * [EXOJCR-936] - Avoid converting binary value to String in tests
+
+Feature Request
+ * [EXOJCR-842] - Allow to disable a given PortalContainer
+ * [EXOJCR-880] - Determine property is multi or single value from nodetype definition in import.
+ * [EXOJCR-886] - Update the document handler to manage MS Office 2007 meta data extraction (docx, ...)
+ * [EXOJCR-934] - Decouple event name from listener name in ListenerService.
+ * [EXOJCR-935] - Add "dav:isreadonly" property management
+
+Task
+ * [EXOJCR-896] - Port Manageability article into docbook
+ * [EXOJCR-905] - Merge the reference guide and the user guide in one single guide
+ * [EXOJCR-913] - Abuse of INFO level logging for DocNumberCache.get()
+ * [EXOJCR-914] - excessive INFO logging by IndexMerger.run()
+ * [EXOJCR-915] - excessive INFO logging by IndexMerger.run()
+ * [EXOJCR-917] - core.packaging.module.js error when in deploy phase
+ * [EXOJCR-919] - maxVolatileTime should be checked on checkFlush()
+ * [EXOJCR-927] - Add "application/x-groovy+html" to HTMLDocumentReader and "application/x-jaxrs+groovy" to TextPlainDocumentReader
+ * [EXOJCR-892] - Remove Fake Chapters
+
+Changes of 1.12.3-GA
+=====================
+
+Bug
+ * [EXOJCR-754] - JDBC Statements left open : Use of Datasources instead of DBCP and C3P0 pools
+ * [EXOJCR-763] - Reordering samename sibling nodes does not update path of child nodes
+ * [EXOJCR-766] - QPath isDescendantOf returns wrong result on samename siblings
+ * [EXOJCR-774] - If-Modified-Since doesn't seem to be well managed in the Wevdav
+ * [EXOJCR-781] - LockManagerImpl should call InitialContextInitializer.recall
+ * [EXOJCR-784] - DOC : wrong examples in profiles section
+ * [EXOJCR-785] - Parameter maxVolatileTime is not working correctly
+ * [EXOJCR-788] - Inconsistency issue cans occur on default portal container parameters
+ * [EXOJCR-795] - Unexpected behavior of the method PortalContainer.isScopeValid()
+ * [EXOJCR-796] - Data corruption
+ * [EXOJCR-804] - "No such file or directory" exception for value storage when using MySQL or Postgres DB in WCM demo 2.0
+ * [EXOJCR-806] - Problems while copying "ftp-ftp"
+ * [EXOJCR-810] - TestRemoveFromValueStorage failed in configuration without ValueStorage
+ * [EXOJCR-813] - ItemImpl.getParent method must return session pooled parent
+ * [EXOJCR-817] - max-buffer-size from configuration should be use to TransientValueData in import (docview and sysview)
+ * [EXOJCR-835] - TestMultiDbJDBCConnection and TestSingleDbJDBCConnection must drop also JCR_xCONTAINER table on tearDown
+ * [EXOJCR-857] - Exception during PROPFIND request if some property content "%" and after not hex chracters
+ * [EXOJCR-865] - Data corrupt after restore a node which has been imported with version history
+ * [EXOJCR-882] - TestCaching fails on Windows XP SP 2 with Russian locale
+
+Feature Request
+ * [EXOJCR-230] - Refactore and move in main part of exo.ws.rest.core project class AbstractResourceTest
+ * [EXOJCR-782] - No longer force extension developers to redefine the whole dependencies list
+ * [EXOJCR-783] - Use cached table for HSLQLDB tables
+ * [EXOJCR-797] - Unable see error message from ProxyService if remote server does not provide Content-Type header.
+
+Task
+ * [EXOJCR-392] - Siblings reordering may update not all the child-items in cache
+ * [EXOJCR-751] - Prepare maintenance branch for jcr 1.12
+ * [EXOJCR-808] - For Sybase DB "check-sns-new-connection" should be set to false by default
+ * [EXOJCR-809] - OrganizationService's tests should not be excluded
+ * [EXOJCR-815] - Document how to use AS Managed DataSource
+ * [EXOJCR-867] - Port documentation for Kernel from wiki to docbook
+ * [EXOJCR-868] - Port documentation for Core from wiki to docbook
+ * [EXOJCR-869] - Port documentation for JCR from wiki to docbook
+ * [EXOJCR-870] - Cleanup WS documentation
+ * [EXOJCR-871] - Document RestServicesList service
+ * [EXOJCR-881] - Port functionality of EXOJCR-482 in jcr-1.12.x
+ * [EXOJCR-884] - Rename JCR documentation artifacts to exo.jcr.* form
+
+Changes of 1.12.2-GA
+====================
+
+Bug
+ * [EXOJCR-497] - JCR serialization test wrong logic with CASable storage
+ * [EXOJCR-730] - Restored repository not accessible after restart Tomcat
+ * [EXOJCR-731] - Deploy error (500 - Unexpected error. null) of REST Service with annotation inheritance.
+ * [EXOJCR-735] - JCR repositories created in runtime is not available after eXo Social restart
+ * [EXOJCR-736] - Problems with anonymous entrance on FTP and NPE
+ * [EXOJCR-743] - InitialContextBinder bind twice same datasource in some case
+ * [EXOJCR-762] - Check whether the repository with the given name doesn't exists before starting restore from backup
+
+Feature Request
+ * [EXOJCR-640] - Migrate to newer version of Apache PDFBox ( and FontBox ) if possible;
+
+Task
+ * [EXOJCR-596] - Upload eXoJCR documentation on jboss.org
+ * [EXOJCR-668] - Validate format of the default values of the property definition during the nodetype registration
+ * [EXOJCR-738] - Search does not work with source in CDATA tag in XML document
+ * [EXOJCR-740] - Constrains ranges are not used in NodeTypeImpl.canSetProperty() validation
+ * [EXOJCR-741] - Backupconsole build improvements
+ * [EXOJCR-765] - Use StringBuilder instead of String concatenation in MSExcelDocumentReader.getContentAsText
+ * [EXOJCR-681] - Decreasing perfomance while running WebdavReadWriteTest tests several times in row
+
+
+
+Changes of 1.12.2-CR1
+=====================
+
+Bug
+ * [EXOJCR-175] - Problems with HTTPBackupAgent - Cyrillic symbols aren't showing after restore
+ * [EXOJCR-683] - java.io.IOException: Socket read failed on heavy loaded WebdavAddBLOBTest benchmark test
+ * [EXOJCR-697] - SQL search by date doesn't work
+ * [EXOJCR-698] - URL encoding in SEARCH and PROPFIND responces differs.
+ * [EXOJCR-700] - Problem in user search with MySql and PostgresDB
+ * [EXOJCR-704] - JCR testuite hangs on sybase
+ * [EXOJCR-708] - Problem with full text searching in text files with non-latin content.
+ * [EXOJCR-712] - Concurrent service creation leads to duplicate service instantiation
+ * [EXOJCR-724] - Bad URL in the error message when a component cannot be instantiated
+ * [EXOJCR-726] - Improper conversion of jboss.server.config.url system property value into File (spaces in filename problem)
+ * [EXOJCR-729] - The FileNotFoundException in restore workspace over BackupWorkspaceinitializer
+ * [EXOJCR-734] - The binary values was not stored in incremental backup.
+
+Feature Request
+ * [EXOJCR-705] - Expose listeners in OrganizationService
+ * [EXOJCR-707] - Check repository management operations on thread safety
+ * [EXOJCR-718] - Allow to get the complete configuration at runtime
+ * [EXOJCR-719] - Better debugging of components loaded
+ * [EXOJCR-721] - Add possibility to use customized GroovyClassLoader in org.exoplatform.services.script.groovy.GroovyScriptInstantiator
+ * [EXOJCR-722] - Make it possible to use other then org.exoplatform.services.rest.impl.method.DefaultMethodInvoker
+
+Task
+ * [EXOJCR-354] - Invoke post read after permissions check
+ * [EXOJCR-663] - Make possibility extends classes RequestDispatcher and ResourceBinder.
+ * [EXOJCR-691] - Fix your missing dependencies
+ * [EXOJCR-692] - Find the reason why the method of type Node.hasNodes is much slower since beta5
+ * [EXOJCR-694] - Change JBC dependencies to use 3.2.4.GA
+ * [EXOJCR-696] - Reduce the concurrency Level in the JBoss Cache Config
+ * [EXOJCR-711] - Misleading error message appears when the external settings cannot be found
+ * [EXOJCR-714] - Improve the usability of the ContainerLifecyclePlugin
+ * [EXOJCR-715] - Ensure that the ExoContainer is fully ThreadSafe
+ * [EXOJCR-716] - Prevent the JobSchedulerServiceImpl to launch jobs that rely on non started services
+ * [EXOJCR-717] - Add to RestRegistryService method without repositoryName in PathParam, insted use current repository. Methods with repositoryName in PathParam marks as Deprecated.
+ * [EXOJCR-720] - Make possibility extends classe GroovyScript2RestLoader
+ * [EXOJCR-723] - JCR Statistics: Describe the arguments of the methods exposed through JMX
+ * [EXOJCR-728] - implementing RequestLifecycle for REST services
+
+
+Changes of 1.12.1-GA
+=====================
+
+Bug
+ * [EXOJCR-612] - JBoss Cache Implementation for the Cache Service test TestAbstractExoCache fails
+ * [EXOJCR-638] - get mixin types through the NodeTypeUtil class
+ * [EXOJCR-661] - Cannot access to the MBeans through the JConsole in Standalone mode
+ * [EXOJCR-662] - Processing SQLException may cause infinite loop.
+ * [EXOJCR-664] - org.exoplatform.services.jcr.impl.storage.value.fs.TestFileIOChannel.testConcurrentRead fail with MSSQL and DB2
+ * [EXOJCR-667] - Temporary spooled file can be not found on save
+ * [EXOJCR-671] - ConcurrentModificationException in FileCleaner with heavy load
+ * [EXOJCR-672] - An eXoCache clear should be local
+ * [EXOJCR-687] - Some JCR parameters that are time parameter are retrieved as number instead of time
+
+Feature Request
+ * [EXOJCR-498] - Provide more details when a JCR query is invalid
+ * [EXOJCR-634] - Upload of a file with special characters like " ' " in filename is not supported by the FTPservice
+ * [EXOJCR-645] - Add ExtHttpHeaders.JAXRS_BODY_PROVIDED header for unhandled exception in REST services and set error message to body responce
+
+Task
+ * [EXOJCR-578] - Use Fisheye in SCM urls used in maven
+ * [EXOJCR-611] - Provide a way to collect statistics around the JCR API accesses
+ * [EXOJCR-639] - Find the reason why the methods of type Property.setValue are much slower since beta5
+ * [EXOJCR-685] - Change JBC dependencies to use 3.2.3.GA
+ * [EXOJCR-689] - Standartize eXo JCR docnmentation projects description.
+ * [EXOJCR-690] - Apply changes in the eXo JCR project in order to be able to publish artifacts in the nexus of JBoss
+ * [EXOJCR-545] - Checking performance on SearchNodesByPropertyTest
+ * [EXOJCR-643] - Improve the performances of the lucene indexing in a cluster by removing contention for read operations
+
+
+Changes of 1.12.1-CR1
+=====================
+
+Bug
+ * [EXOJCR-256] - There are server errors "500 Internal Server Error:" during creation repository or workspace by RestRepositoryService
+ * [EXOJCR-348] - Test problem: TestCleanableFileStreamValueData failed
+ * [EXOJCR-519] - DAILY TESTS are going too long (avg time=5hours)
+ * [EXOJCR-531] - Problems with Lock operations
+ * [EXOJCR-546] - TESTING: Performance testing problems. LockUnlockOwnNodeTest - TPS fell down
+ * [EXOJCR-548] - problem with import & export node
+ * [EXOJCR-555] - NPE with cache eviction at startup
+ * [EXOJCR-557] - Problem while uploading *.pdf to WebDAV server using Mac OS Finder
+ * [EXOJCR-558] - Files uploaded by Mac OS finder are displayed with size "0"
+ * [EXOJCR-559] - Problems with daily performance testing - on PostgreSQL 8.2.9
+ * [EXOJCR-567] - The REST servlet dump errors when the client cut the socket too early should be only a debug log
+ * [EXOJCR-572] - Can not create workspace with default configuration of lock manager
+ * [EXOJCR-581] - Listing the directory in TreeFile may return null during race condition, causing NPE.
+ * [EXOJCR-584] - User's research is case sensitive
+ * [EXOJCR-586] - Missed slf4j dependency for jcr applications on tomcat AS
+ * [EXOJCR-587] - session.save() throws NPE after node reordering
+ * [EXOJCR-588] - Tests errors in eXo XML Processing Services on MACOS
+ * [EXOJCR-591] - Problem with ObservationManager
+ * [EXOJCR-599] - deadlock during dashboard editing
+ * [EXOJCR-600] - Concurrency problem (java.util.HashMap.put called from CacheableLockManagerImpl.getSessionLockManager(CacheableLockManagerImpl.java:473))
+ * [EXOJCR-601] - gatein sample extension should not be required
+ * [EXOJCR-602] - StackOverflow on JsonGeneratorImpl
+ * [EXOJCR-603] - impossible to change user password
+ * [EXOJCR-607] - Sybase Issue with GateIn
+ * [EXOJCR-608] - XaSessionImpl as XA resource should be unique per user, workspace and repository
+ * [EXOJCR-614] - Node.getReferences fail in some cases
+ * [EXOJCR-615] - Need check nodedata to avoid exception in method NodeImpl.isNodeType(String).
+ * [EXOJCR-619] - Log record forging (Security Issue)
+ * [EXOJCR-621] - Conflict between symlink feature and Jbosscache
+ * [EXOJCR-623] - Unable to get a version of document using WebDAV (HTTP Response 404 returned).
+ * [EXOJCR-633] - Problems with manual testing - tomcat-server on ftp -.IndexOutOfBoundsException
+
+Feature Request
+ * [EXOJCR-549] - Backup and Restore of a whole Repository
+ * [EXOJCR-571] - Change PersitedValueDataReader/Writer
+ * [EXOJCR-573] - Create database and bind DataSource in runtime
+ * [EXOJCR-582] - DB script modification for oracle11 compatibility
+ * [EXOJCR-585] - Allow to get statistics on Database Access without using a Profiler
+ * [EXOJCR-616] - Remove repository container from repositoryContainers map when repository container start fail.
+ * [EXOJCR-617] - Map environment parameters for all String fields in Repository configuration
+
+Task
+ * [EXOJCR-150] - Ftp client tests failute
+ * [EXOJCR-250] - Add human readable message in case Workspace creation error via HTTPBackupAgent
+ * [EXOJCR-393] - Create indexer load test
+ * [EXOJCR-523] - Upgrade to JBoss Cache 3.2.3.GA
+ * [EXOJCR-550] - Bind slf4j-log4j and log4j dependencies onto the test phase of the various modules of JCR
+ * [EXOJCR-552] - Allow to Test eXo JCR 1.12 on EC2
+ * [EXOJCR-575] - Remove unused PairChangesLog class
+ * [EXOJCR-589] - Limit network traffic and thread blocking for the Lucene Indexer in a cluster
+ * [EXOJCR-590] - DO NOT exclude tests from a parent pom
+ * [EXOJCR-598] - Allow to disable the hints used for the Complex Queries on oracle
+ * [EXOJCR-605] - Normalize logging categories
+ * [EXOJCR-631] - Find a reason, why functional tests fails under Tornado.MySQL with "Cannot create PoolableConnectionFactory (Too many connections)" message.
+ * [EXOJCR-632] - svn: File 'jcr.packaging.module/1.12.0-CP01/jcr.packaging.module-1.12.0-CP01.js' has inconsistent newlines
+
+
+Features of eXoJCR 1.12 comparing to 1.11
+=========================================
+
+- Repository clustering based on JBossCache and JBoss Transactions.
+- Lazy-load option for child nodes and properties read, improved items dataflow for read/write operations
+- Alternative data container optimized for read operations (consuming less database queries)
+- Database dialect can be autodetected (if not pointed in the configuration)
+- Support for Values large of 2GiB
+- Portal container configuration improvements (default definitions, link and externaly loaded parameters)
+- Concurrency improvements for Session registry and Values stroage
+- Concurrency improvements for XA transactions support (Repository login and logout faster now)
+- Improved serach based on Lucene 2.4
+- Support of MySQL/InnoDB database for multi-language content
+- Standalone container can use configuration stored in JBossAS server configuration directory by default
+- WebDAV server update-policy can be configured to different versioning behaviour
+- Lot of WebDAV server bugfixes
+- HTTP (RESTful) Backup agent with concole client
+- HTTP (RESTful) Repository management service
+- Support of Java6 and Java5 runtime and development environment
+
+Since version of 1.12 eXoJCR available under LGPL license (version 2.1).
+
+eXoJCR 1.12 tested in on the databases:
+ MySQL 5.1 MYSQL Connector/J 5.1.8
+ Oracle DB 10g (10.2.0.1) Oracle 10g (10.2.0.1)
+ PostgresSQL 8.3.7 JDBC4 Driver, Version 8.3-605
+ DB2 9,7 IBM Data Server Driver for JDBC and SQLJ (JCC Driver) Version: 9.1 (fixpack 3a)
+ MS SQL Server 2005 SP3 JDBC Driver 2.0
+ MS SQL Server 2008 SP1 JDBC Driver 2.0
+ Sybase 15.0.2 JConnect v6.0.5 (Build 26564 / 11 Jun 2009)
+
+
+Release includes:
+* eXo Kernel 2.2.5-GA
+* eXo Core 2.3.5-GA
+* eXo WS 2.1.5-GA
+* eXo JCR 1.12.5-GA
+
+1.12.5-GA tasks:
+* http://jira.exoplatform.org/browse/KER/fixforversion/12103
+* http://jira.exoplatform.org/browse/COR/fixforversion/12102
+* http://jira.exoplatform.org/browse/WS/fixforversion/12104
+* http://jira.exoplatform.org/browse/JCR/fixforversion/12052
+
+JCR Samples
+===========
+
+1. Start Up (Tomcat)
+ Tomcat 6 bundled can be started by executing the following commands:
+
+ $CATALINA_HOME\bin\eXo.bat run (Windows)
+
+ $CATALINA_HOME/bin/eXo.sh run (Unix)
+
+2. After startup, the sample applications will be available by visiting:
+
+ http://localhost:8080/browser - Simple JCR browser
+ Browse the JCR repository that was started with Tomcat
+ http://localhost:8080/fckeditor - FCK editor sample
+ Edits the sample node using FCKEditor and browse it JCR browser
+ http://localhost:8080/rest/jcr/repository/production - WebDAV service,
+ Open in Microsoft Explorer, File-Open-OpenAsWebFolder with url http://localhost:8080/rest/jcr/repository/production
+ Add/read/remove files there and browse it in the JCR browser or FTP.
+ User name/password: root/exo
+ ftp://localhost:2121 - FTP server
+ Open the repository in FTP client and browse the JCR repository started with Tomcat as FTP content,
+ add/read/remove files there and browse it in the JCR browser or WebDAV.
+
+EAR deploy
+==========
+
+eXo JCR was tested under JBoss-5.1.0.GA application server
+
+JBoss-5.1.0.GA
+
+ 1. Configuration
+
+ * Copy jcr.ear into $jboss_home/server/default/deploy
+ * Create $jboss_home/server/default/conf/exo-conf folder if it doesn't exist.
+ * Put exo-configuration.xml into $jboss_home/server/default/conf/exo-conf/exo-configuration.xml
+ * Configure JAAS by inserting XML fragment shown below into $jboss_home/server/default/conf/login-config.xml
+
+---------
+<application-policy name="exo-domain">
+ <authentication>
+ <login-module code="org.exoplatform.services.security.j2ee.JbossLoginModule" flag="required"></login-module>
+ </authentication>
+ </application-policy>
+---------
+
+ 2. Start Up
+
+ Execute
+ * bin/run.bat on Windows
+ or
+ * bin/run.sh on Unix
+
+Resources
+=========
+
+ Company site http://www.exoplatform.com
+ Documentation wiki http://wiki.exoplatform.org
+ Community JIRA https://jira.jboss.org/jira/browse/EXOJCR, http://jira.exoplatform.org
+ Comminity site http://www.exoplatform.org
+ Community forum http://www.exoplatform.com/portal/public/en/forum
+ JavaDoc site http://docs.exoplatform.org
+
\ No newline at end of file
13 years, 6 months
exo-jcr SVN: r3341 - in jcr/branches/1.12.x/patch: EXOJCR-999 and 1 other directory.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-10-22 11:59:33 -0400 (Fri, 22 Oct 2010)
New Revision: 3341
Added:
jcr/branches/1.12.x/patch/EXOJCR-999/
jcr/branches/1.12.x/patch/EXOJCR-999/EXOJCR-999.patch
Log:
EXOJCR-999: patch for 1.12.x commited
Added: jcr/branches/1.12.x/patch/EXOJCR-999/EXOJCR-999.patch
===================================================================
--- jcr/branches/1.12.x/patch/EXOJCR-999/EXOJCR-999.patch (rev 0)
+++ jcr/branches/1.12.x/patch/EXOJCR-999/EXOJCR-999.patch 2010-10-22 15:59:33 UTC (rev 3341)
@@ -0,0 +1,2451 @@
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java (working copy)
+@@ -46,6 +46,8 @@
+
+ protected long sessionTimeOut;
+
++ protected int lockRemoverMaxThreadCount;
++
+ public RepositoryInfo()
+ {
+
+@@ -190,17 +192,43 @@
+ }
+
+ /**
++ * Returns LockRemovers per-repository max threads count.
++ * @return LockRemovers per-repository max threads count
++ */
++ public int getLockRemoverThreadsCount()
++ {
++ return lockRemoverMaxThreadCount;
++ }
++
++ /**
++ * Sets LockRemovers per-repository max threads count.
++ * @param lockRemoverMaxThreadCount
++ */
++ public void setLockRemoverThreadsCount(int lockRemoverMaxThreadCount)
++ {
++ this.lockRemoverMaxThreadCount = lockRemoverMaxThreadCount;
++ }
++
++ /**
+ * Merges the current {@link RepositoryInfo} with the given one. The current {@link RepositoryInfo}
+ * has the highest priority thus only absent data will be overrode
+ * @param entry the entry to merge with the current {@link RepositoryInfo}
+ */
+ void merge(RepositoryInfo entry)
+ {
+- if (systemWorkspaceName == null) setSystemWorkspaceName(entry.systemWorkspaceName);
+- if (defaultWorkspaceName == null) setDefaultWorkspaceName(entry.defaultWorkspaceName);
+- if (accessControl == null) setAccessControl(entry.accessControl);
+- if (securityDomain == null) setSecurityDomain(entry.securityDomain);
+- if (authenticationPolicy == null) setAuthenticationPolicy(entry.authenticationPolicy);
+- if (sessionTimeOut == 0) setSessionTimeOut(entry.sessionTimeOut);
+- }
++ if (systemWorkspaceName == null)
++ setSystemWorkspaceName(entry.systemWorkspaceName);
++ if (defaultWorkspaceName == null)
++ setDefaultWorkspaceName(entry.defaultWorkspaceName);
++ if (accessControl == null)
++ setAccessControl(entry.accessControl);
++ if (securityDomain == null)
++ setSecurityDomain(entry.securityDomain);
++ if (authenticationPolicy == null)
++ setAuthenticationPolicy(entry.authenticationPolicy);
++ if (sessionTimeOut == 0)
++ setSessionTimeOut(entry.sessionTimeOut);
++ if (lockRemoverMaxThreadCount == 0)
++ setLockRemoverThreadsCount(entry.lockRemoverMaxThreadCount);
++ }
+ }
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java (working copy)
+@@ -91,7 +91,7 @@
+ super(config, repConfig, dataManager, namespaceRegistry, locationFactory, nodeTypeManager, valueFactory,
+ accessManager);
+
+- this.fileCleaner = new FileCleaner();
++ this.fileCleaner = valueFactory.getFileCleaner();
+
+ restoreDir = restorePath;
+
+@@ -366,8 +366,6 @@
+
+ restoreChangesLog.restore();
+
+- TransactionChangesLog log = restoreChangesLog.getItemDataChangesLog();
+-
+ }
+ else if (changesLogType == RestoreChangesLog.Type.ItemDataChangesLog_without_Streams)
+ {
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java (working copy)
+@@ -43,6 +43,7 @@
+ import org.exoplatform.services.jcr.impl.Constants;
+ import org.exoplatform.services.jcr.impl.core.SessionDataManager;
+ import org.exoplatform.services.jcr.impl.core.lock.LockRemover;
++import org.exoplatform.services.jcr.impl.core.lock.LockRemoverHolder;
+ import org.exoplatform.services.jcr.impl.core.lock.SessionLockManager;
+ import org.exoplatform.services.jcr.impl.dataflow.TransientItemData;
+ import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
+@@ -178,10 +179,10 @@
+ * @throws RepositoryConfigurationException
+ */
+ public CacheableLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
+- InitialContextInitializer context, TransactionService transactionService, ConfigurationManager cfm)
+- throws RepositoryConfigurationException, RepositoryException
++ InitialContextInitializer context, TransactionService transactionService, ConfigurationManager cfm,
++ LockRemoverHolder lockRemoverHolder) throws RepositoryConfigurationException, RepositoryException
+ {
+- this(dataManager, config, context, transactionService.getTransactionManager(), cfm);
++ this(dataManager, config, context, transactionService.getTransactionManager(), cfm, lockRemoverHolder);
+ }
+
+ /**
+@@ -193,10 +194,10 @@
+ * @throws RepositoryConfigurationException
+ */
+ public CacheableLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
+- InitialContextInitializer context, ConfigurationManager cfm) throws RepositoryConfigurationException,
+- RepositoryException
++ InitialContextInitializer context, ConfigurationManager cfm, LockRemoverHolder lockRemoverHolder)
++ throws RepositoryConfigurationException, RepositoryException
+ {
+- this(dataManager, config, context, (TransactionManager)null, cfm);
++ this(dataManager, config, context, (TransactionManager)null, cfm, lockRemoverHolder);
+
+ }
+
+@@ -211,8 +212,8 @@
+ * @throws RepositoryConfigurationException
+ */
+ public CacheableLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
+- InitialContextInitializer context, TransactionManager transactionManager, ConfigurationManager cfm)
+- throws RepositoryConfigurationException, RepositoryException
++ InitialContextInitializer context, TransactionManager transactionManager, ConfigurationManager cfm,
++ LockRemoverHolder lockRemoverHolder) throws RepositoryConfigurationException, RepositoryException
+ {
+ lockRoot = Fqn.fromElements(LOCKS);
+
+@@ -269,6 +270,9 @@
+ {
+ throw new RepositoryConfigurationException("Cache configuration not found");
+ }
++
++ lockRemover = lockRemoverHolder.getLockRemover(this);
++
+ }
+
+ /**
+@@ -490,7 +494,7 @@
+ }
+ return true;
+ }
+-
++
+ /**
+ * Return new instance of session lock manager.
+ */
+@@ -769,7 +773,7 @@
+ */
+ public void start()
+ {
+- lockRemover = new LockRemover(this);
++ lockRemover.start();
+ }
+
+ /*
+@@ -778,8 +782,8 @@
+ */
+ public void stop()
+ {
+- lockRemover.halt();
+- lockRemover.interrupt();
++ lockRemover.stop();
++
+ sessionLockManagers.clear();
+ cache.stop();
+ }
+@@ -913,7 +917,7 @@
+ {
+ return getExactNodeOrCloseParentLock(node, true);
+ }
+-
++
+ private LockData getExactNodeOrCloseParentLock(NodeData node, boolean checkHasLocks) throws RepositoryException
+ {
+
+@@ -954,7 +958,7 @@
+ {
+ return getClosedChild(node, true);
+ }
+-
++
+ private LockData getClosedChild(NodeData node, boolean checkHasLocks) throws RepositoryException
+ {
+
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/jdbc/CacheableJDBCLockManagerImpl.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/jdbc/CacheableJDBCLockManagerImpl.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/jdbc/CacheableJDBCLockManagerImpl.java (working copy)
+@@ -42,6 +42,7 @@
+ import org.exoplatform.services.jcr.impl.Constants;
+ import org.exoplatform.services.jcr.impl.core.SessionDataManager;
+ import org.exoplatform.services.jcr.impl.core.lock.LockRemover;
++import org.exoplatform.services.jcr.impl.core.lock.LockRemoverHolder;
+ import org.exoplatform.services.jcr.impl.core.lock.SessionLockManager;
+ import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManager;
+ import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableSessionLockManager;
+@@ -161,10 +162,10 @@
+ * @throws RepositoryConfigurationException
+ */
+ public CacheableJDBCLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
+- InitialContextInitializer context, TransactionService transactionService, ConfigurationManager cfm)
+- throws RepositoryConfigurationException, RepositoryException
++ InitialContextInitializer context, TransactionService transactionService, ConfigurationManager cfm,
++ LockRemoverHolder lockRemoverHolder) throws RepositoryConfigurationException, RepositoryException
+ {
+- this(dataManager, config, context, transactionService.getTransactionManager(), cfm);
++ this(dataManager, config, context, transactionService.getTransactionManager(), cfm, lockRemoverHolder);
+ }
+
+ /**
+@@ -176,10 +177,10 @@
+ * @throws RepositoryConfigurationException
+ */
+ public CacheableJDBCLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
+- InitialContextInitializer context, ConfigurationManager cfm) throws RepositoryConfigurationException,
+- RepositoryException
++ InitialContextInitializer context, ConfigurationManager cfm, LockRemoverHolder lockRemoverHolder)
++ throws RepositoryConfigurationException, RepositoryException
+ {
+- this(dataManager, config, context, (TransactionManager)null, cfm);
++ this(dataManager, config, context, (TransactionManager)null, cfm, lockRemoverHolder);
+ }
+
+ /**
+@@ -194,8 +195,8 @@
+ * @throws RepositoryException
+ */
+ public CacheableJDBCLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
+- InitialContextInitializer context, TransactionManager transactionManager, ConfigurationManager cfm)
+- throws RepositoryConfigurationException, RepositoryException
++ InitialContextInitializer context, TransactionManager transactionManager, ConfigurationManager cfm,
++ LockRemoverHolder lockRemoverHolder) throws RepositoryConfigurationException, RepositoryException
+ {
+ lockRoot = Fqn.fromElements(LOCKS);
+
+@@ -250,6 +251,8 @@
+ {
+ throw new RepositoryConfigurationException("Cache configuration not found");
+ }
++
++ lockRemover = lockRemoverHolder.getLockRemover(this);
+ }
+
+ @Managed
+@@ -598,7 +601,7 @@
+ */
+ public void start()
+ {
+- lockRemover = new LockRemover(this);
++ lockRemover.start();
+ }
+
+ /**
+@@ -606,8 +609,8 @@
+ */
+ public void stop()
+ {
+- lockRemover.halt();
+- lockRemover.interrupt();
++ lockRemover.stop();
++
+ sessionLockManagers.clear();
+ cache.stop();
+ }
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java (working copy)
+@@ -146,12 +146,14 @@
+ * @param dataManager
+ * @param config
+ */
+- public LockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config)
++ public LockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
++ LockRemoverHolder lockRemoverHolder)
+ {
+- this(dataManager, config, null);
++ this(dataManager, config, null, lockRemoverHolder);
+ }
+
+- public LockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config, LockPersister persister)
++ public LockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config, LockPersister persister,
++ LockRemoverHolder lockRemoverHolder)
+ {
+
+ this.dataManager = dataManager;
+@@ -169,6 +171,7 @@
+ tokensMap = new HashMap<String, LockData>();
+
+ dataManager.addItemPersistenceListener(this);
++ lockRemover = lockRemoverHolder.getLockRemover(this);
+ }
+
+ public synchronized void addLockToken(String sessionId, String lt)
+@@ -468,7 +471,7 @@
+ */
+ public void start()
+ {
+- lockRemover = new LockRemover(this);
++ lockRemover.start();
+ }
+
+ // Quick method. We need to reconstruct
+@@ -503,8 +506,8 @@
+ */
+ public void stop()
+ {
+- lockRemover.halt();
+- lockRemover.interrupt();
++ lockRemover.stop();
++
+ locks.clear();
+ pendingLocks.clear();
+ tokensMap.clear();
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java (working copy)
+@@ -18,47 +18,68 @@
+ */
+ package org.exoplatform.services.jcr.impl.core.lock;
+
+-import org.exoplatform.services.jcr.impl.proccess.WorkerThread;
+-import org.exoplatform.services.log.ExoLogger;
+-import org.exoplatform.services.log.Log;
++import org.exoplatform.services.jcr.impl.proccess.WorkerService;
+
++import java.util.concurrent.ScheduledFuture;
++
+ /**
+ * Created by The eXo Platform SAS.
+ *
+ * @author <a href="mailto:Sergey.Kabashnyuk@gmail.com">Sergey Kabashnyuk</a>
+ * @version $Id: LockRemover.java 11987 2008-03-17 09:06:06Z ksm $
+ */
+-public class LockRemover extends WorkerThread
++public class LockRemover
+ {
++ public static final long DEFAULT_THREAD_TIMEOUT = 30000; // 30 sec
+
+- private final Log log = ExoLogger.getLogger("exo.jcr.component.core.LockRemover");
++ private final WorkerService workerService;
+
+- public static final long DEFAULT_THREAD_TIMEOUT = 30000; // 30
++ private final WorkspaceLockManager lockManager;
+
+- // sec
++ private final long timeout;
+
+- private final WorkspaceLockManager lockManagerImpl;
++ private ScheduledFuture lockRemoverTask = null;
+
+- public LockRemover(WorkspaceLockManager lockManagerImpl)
++ class LockRemoverTask implements Runnable
+ {
+- this(lockManagerImpl, DEFAULT_THREAD_TIMEOUT);
++ private final WorkspaceLockManager lockManager;
++
++ LockRemoverTask(WorkspaceLockManager lockManager)
++ {
++ this.lockManager = lockManager;
++ }
++
++ public void run()
++ {
++ lockManager.removeExpired();
++ }
+ }
+
+- private LockRemover(WorkspaceLockManager lockManagerImpl, long timeout)
++ protected LockRemover(WorkerService workerService, WorkspaceLockManager lockManager)
+ {
+- super(timeout);
+- this.lockManagerImpl = lockManagerImpl;
+- setName("LockRemover " + getId());
+- setPriority(Thread.MIN_PRIORITY);
+- setDaemon(true);
+- start();
+- if (log.isDebugEnabled())
+- log.debug("LockRemover instantiated name= " + getName() + " timeout= " + timeout);
++ this(workerService, lockManager, DEFAULT_THREAD_TIMEOUT);
+ }
+
+- @Override
+- protected void callPeriodically() throws Exception
++ protected LockRemover(WorkerService workerService, WorkspaceLockManager lockManager, long timeout)
+ {
+- lockManagerImpl.removeExpired();
++ this.workerService = workerService;
++ this.lockManager = lockManager;
++ this.timeout = timeout;
+ }
++
++ public void start()
++ {
++ if (lockRemoverTask != null)
++ {
++ stop();
++ }
++ lockRemoverTask = workerService.executePeriodically(new LockRemoverTask(lockManager), timeout);
++ }
++
++ public void stop()
++ {
++ lockRemoverTask.cancel(false);
++ lockRemoverTask = null;
++ }
++
+ }
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.java (revision 0)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.java (revision 0)
+@@ -0,0 +1,65 @@
++package org.exoplatform.services.jcr.impl.core.lock;
++
++import org.exoplatform.services.jcr.config.RepositoryEntry;
++import org.exoplatform.services.jcr.impl.proccess.WorkerService;
++
++/**
++ * LockRemoverHolder holds is a single per-repository LockRemover container.
++ * @author <a href="mailto:foo@bar.org">Foo Bar</a>
++ * @version $Id: exo-jboss-codetemplates.xml 34360 2009-07-22 23:58:59Z aheritier $
++ *
++ */
++public class LockRemoverHolder
++{
++
++ /**
++ * Default amount of thread that may be used by WorkerService to serve LockRemovers.
++ */
++ public final int DEFAULT_THREAD_COUNT = 1;
++
++ /**
++ * WorkerService that executed LockRemover.
++ */
++ private final WorkerService workerService;
++
++ /**
++ * Constructor.
++ * @param entry - RepositoryEntry that may contain lock-remover-max-threads parameter.
++ */
++ public LockRemoverHolder(RepositoryEntry entry)
++ {
++ int threadCount = DEFAULT_THREAD_COUNT;
++ if (entry != null)
++ {
++ if (entry.getLockRemoverThreadsCount() > 0)
++ {
++ threadCount = entry.getLockRemoverThreadsCount();
++ }
++ }
++ workerService = new WorkerService(threadCount, "lock-remover");
++ }
++
++ /**
++ * Returns LockRemover object that removes expired locks from LockManager. Default timeout used.
++ *
++ * @param lockManager - LockManager that going to be cleaned with returned LockRemover.
++ * @return LockRemover
++ */
++ public LockRemover getLockRemover(WorkspaceLockManager lockManager)
++ {
++ return new LockRemover(workerService, lockManager);
++ }
++
++ /**
++ * Returns LockRemover object that removes expired locks from LockManager.
++ *
++ * @param lockManager - LockManager that going to be cleaned with returned LockRemover.
++ * @param timeout - LockRemover will check LockManager with delay setted in timeout parameter
++ * @return LockRemover
++ */
++ public LockRemover getLockRemover(WorkspaceLockManager lockManager, long timeout)
++ {
++ return new LockRemover(workerService, lockManager, timeout);
++ }
++
++}
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java (working copy)
+@@ -42,7 +42,7 @@
+ import org.exoplatform.services.jcr.impl.dataflow.persistent.LocalWorkspaceDataManagerStub;
+ import org.exoplatform.services.jcr.impl.ext.action.SessionActionCatalog;
+ import org.exoplatform.services.jcr.impl.ext.action.SessionActionInterceptor;
+-import org.exoplatform.services.jcr.impl.util.io.WorkspaceFileCleanerHolder;
++import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
+ import org.exoplatform.services.jcr.impl.xml.ExportImportFactory;
+ import org.exoplatform.services.jcr.impl.xml.ItemDataKeeperAdapter;
+ import org.exoplatform.services.jcr.impl.xml.XmlMapping;
+@@ -162,8 +162,8 @@
+ this.lazyReadThreshold =
+ wsConfig.getLazyReadThreshold() > 0 ? wsConfig.getLazyReadThreshold() : DEFAULT_LAZY_READ_THRESHOLD;
+
+- WorkspaceFileCleanerHolder cleanerHolder =
+- (WorkspaceFileCleanerHolder)container.getComponentInstanceOfType(WorkspaceFileCleanerHolder.class);
++ FileCleanerHolder cleanerHolder =
++ (FileCleanerHolder)container.getComponentInstanceOfType(FileCleanerHolder.class);
+
+ this.locationFactory = new LocationFactory(this);
+ this.valueFactory = new ValueFactoryImpl(locationFactory, wsConfig, cleanerHolder);
+@@ -242,8 +242,8 @@
+
+ WorkspaceEntry wsConfig = (WorkspaceEntry)container.getComponentInstanceOfType(WorkspaceEntry.class);
+
+- WorkspaceFileCleanerHolder cleanerHolder =
+- (WorkspaceFileCleanerHolder)container.getComponentInstanceOfType(WorkspaceFileCleanerHolder.class);
++ FileCleanerHolder cleanerHolder =
++ (FileCleanerHolder)container.getComponentInstanceOfType(FileCleanerHolder.class);
+
+ ValueFactoryImpl valueFactoryImpl = new ValueFactoryImpl(factory, wsConfig, cleanerHolder);
+
+@@ -281,8 +281,8 @@
+
+ WorkspaceEntry wsConfig = (WorkspaceEntry)container.getComponentInstanceOfType(WorkspaceEntry.class);
+
+- WorkspaceFileCleanerHolder cleanerHolder =
+- (WorkspaceFileCleanerHolder)container.getComponentInstanceOfType(WorkspaceFileCleanerHolder.class);
++ FileCleanerHolder cleanerHolder =
++ (FileCleanerHolder)container.getComponentInstanceOfType(FileCleanerHolder.class);
+
+ ValueFactoryImpl valueFactoryImpl = new ValueFactoryImpl(factory, wsConfig, cleanerHolder);
+
+@@ -322,8 +322,8 @@
+
+ WorkspaceEntry wsConfig = (WorkspaceEntry)container.getComponentInstanceOfType(WorkspaceEntry.class);
+
+- WorkspaceFileCleanerHolder cleanerHolder =
+- (WorkspaceFileCleanerHolder)container.getComponentInstanceOfType(WorkspaceFileCleanerHolder.class);
++ FileCleanerHolder cleanerHolder =
++ (FileCleanerHolder)container.getComponentInstanceOfType(FileCleanerHolder.class);
+
+ ValueFactoryImpl valueFactoryImpl = new ValueFactoryImpl(factory, wsConfig, cleanerHolder);
+
+@@ -361,8 +361,8 @@
+
+ WorkspaceEntry wsConfig = (WorkspaceEntry)container.getComponentInstanceOfType(WorkspaceEntry.class);
+
+- WorkspaceFileCleanerHolder cleanerHolder =
+- (WorkspaceFileCleanerHolder)container.getComponentInstanceOfType(WorkspaceFileCleanerHolder.class);
++ FileCleanerHolder cleanerHolder =
++ (FileCleanerHolder)container.getComponentInstanceOfType(FileCleanerHolder.class);
+
+ ValueFactoryImpl valueFactoryImpl = new ValueFactoryImpl(factory, wsConfig, cleanerHolder);
+ try
+@@ -397,8 +397,8 @@
+
+ WorkspaceEntry wsConfig = (WorkspaceEntry)container.getComponentInstanceOfType(WorkspaceEntry.class);
+
+- WorkspaceFileCleanerHolder cleanerHolder =
+- (WorkspaceFileCleanerHolder)container.getComponentInstanceOfType(WorkspaceFileCleanerHolder.class);
++ FileCleanerHolder cleanerHolder =
++ (FileCleanerHolder)container.getComponentInstanceOfType(FileCleanerHolder.class);
+
+ ValueFactoryImpl valueFactoryImpl = new ValueFactoryImpl(factory, wsConfig, cleanerHolder);
+ try
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SysViewWorkspaceInitializer.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SysViewWorkspaceInitializer.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SysViewWorkspaceInitializer.java (working copy)
+@@ -265,7 +265,8 @@
+ else if (tmpFile == null && (((TempOutputStream)buff).getSize() + buffer.length) > maxBufferSize)
+ {
+ // spool to file
+- FileOutputStream fout = new FileOutputStream(tmpFile = SpoolFile.createTempFile("jcrrestorewi", ".tmp", tempDir));
++ FileOutputStream fout =
++ new FileOutputStream(tmpFile = SpoolFile.createTempFile("jcrrestorewi", ".tmp", tempDir));
+ fout.write(((TempOutputStream)buff).getBuffer());
+ buff.close();
+ buff = fout; // use file
+@@ -398,7 +399,7 @@
+ this.namespaceRegistry = namespaceRegistry;
+ this.locationFactory = locationFactory;
+
+- this.fileCleaner = new FileCleaner(false); // cleaner should be started!
++ this.fileCleaner = valueFactory.getFileCleaner();
+ this.maxBufferSize =
+ config.getContainer().getParameterInteger(WorkspaceDataContainer.MAXBUFFERSIZE_PROP,
+ WorkspaceDataContainer.DEF_MAXBUFFERSIZE);
+@@ -409,7 +410,7 @@
+ throw new RepositoryConfigurationException("Workspace (" + workspaceName
+ + ") RestoreIntializer should have mandatory parameter "
+ + SysViewWorkspaceInitializer.RESTORE_PATH_PARAMETER);
+-
++
+ this.tempDir = new File(System.getProperty("java.io.tmpdir"));
+ }
+
+@@ -450,12 +451,12 @@
+ this.namespaceRegistry = namespaceRegistry;
+ this.locationFactory = locationFactory;
+
+- this.fileCleaner = new FileCleaner(false); // cleaner should be started!
++ this.fileCleaner = valueFactory.getFileCleaner();
+ this.maxBufferSize =
+ config.getContainer().getParameterInteger(WorkspaceDataContainer.MAXBUFFERSIZE_PROP,
+ WorkspaceDataContainer.DEF_MAXBUFFERSIZE);
+ this.restorePath = restorePath;
+-
++
+ this.tempDir = new File(System.getProperty("java.io.tmpdir"));
+ }
+
+@@ -771,7 +772,7 @@
+ }
+ else
+ {
+-
++
+ File pfile = propertyValue.getFile();
+ if (pfile != null)
+ {
+@@ -811,7 +812,6 @@
+
+ public void start()
+ {
+- fileCleaner.start();
+ }
+
+ public void stop()
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/ValueFactoryImpl.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/ValueFactoryImpl.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/ValueFactoryImpl.java (working copy)
+@@ -30,7 +30,7 @@
+ import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
+ import org.exoplatform.services.jcr.impl.util.JCRDateFormat;
+ import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+-import org.exoplatform.services.jcr.impl.util.io.WorkspaceFileCleanerHolder;
++import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
+ import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
+ import org.exoplatform.services.log.ExoLogger;
+ import org.exoplatform.services.log.Log;
+@@ -71,7 +71,7 @@
+ private int maxBufferSize;
+
+ public ValueFactoryImpl(LocationFactory locationFactory, WorkspaceEntry workspaceConfig,
+- WorkspaceFileCleanerHolder cleanerHolder)
++ FileCleanerHolder cleanerHolder)
+ {
+
+ this.locationFactory = locationFactory;
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/proccess/WorkerService.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/proccess/WorkerService.java (revision 0)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/proccess/WorkerService.java (revision 0)
+@@ -0,0 +1,84 @@
++package org.exoplatform.services.jcr.impl.proccess;
++
++import java.util.concurrent.ScheduledFuture;
++import java.util.concurrent.ScheduledThreadPoolExecutor;
++import java.util.concurrent.ThreadFactory;
++import java.util.concurrent.TimeUnit;
++import java.util.concurrent.atomic.AtomicInteger;
++
++public class WorkerService
++{
++ /**
++ * Executor that process assigned command periodically.
++ */
++ private final ScheduledThreadPoolExecutor executor;
++
++ class WorkerThreadFactory implements ThreadFactory
++ {
++ final AtomicInteger poolNumber = new AtomicInteger(1);
++
++ final ThreadGroup group;
++
++ final AtomicInteger threadNumber = new AtomicInteger(1);
++
++ final String namePrefix;
++
++ WorkerThreadFactory(String namePrefix)
++ {
++ SecurityManager s = System.getSecurityManager();
++ group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
++ this.namePrefix = namePrefix + poolNumber.getAndIncrement() + "-thread-";
++ }
++
++ public Thread newThread(Runnable r)
++ {
++ Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
++ if (t.isDaemon())
++ t.setDaemon(false);
++ if (t.getPriority() != Thread.NORM_PRIORITY)
++ t.setPriority(Thread.NORM_PRIORITY);
++ return t;
++ }
++ }
++
++ /**
++ * Constructor.
++ *
++ * @param threadCount - max thread count that executor may use
++ */
++ public WorkerService(int threadCount)
++ {
++ executor = new ScheduledThreadPoolExecutor(threadCount);
++ }
++
++ /**
++ * Constructor.
++ *
++ * @param threadCount - max thread count that executor may use
++ * @param threadNamePrefix - thread name prefix
++ */
++ public WorkerService(int threadCount, String threadNamePrefix)
++ {
++ executor = new ScheduledThreadPoolExecutor(threadCount, new WorkerThreadFactory(threadNamePrefix));
++ }
++
++ /**
++ * Execute specified <code>command</code> periodically with <code>delay</code>.
++ *
++ * @param command - command that must be executed
++ * @param delay - delay between each command execution
++ * @return
++ */
++ public ScheduledFuture executePeriodically(Runnable command, long delay)
++ {
++ return executor.scheduleWithFixedDelay(command, 0, delay, TimeUnit.MILLISECONDS);
++ }
++
++ /**
++ * Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
++ */
++ public void stop()
++ {
++ executor.shutdown();
++ }
++}
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java (working copy)
+@@ -41,6 +41,7 @@
+ import org.exoplatform.services.jcr.impl.core.WorkspaceInitializer;
+ import org.exoplatform.services.jcr.impl.core.access.DefaultAccessManagerImpl;
+ import org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl;
++import org.exoplatform.services.jcr.impl.core.lock.LockRemoverHolder;
+ import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeDataManagerImpl;
+ import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
+ import org.exoplatform.services.jcr.impl.core.nodetype.registration.JCRNodeTypeDataPersister;
+@@ -56,15 +57,12 @@
+ import org.exoplatform.services.jcr.impl.dataflow.persistent.LocalWorkspaceDataManagerStub;
+ import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder;
+ import org.exoplatform.services.jcr.impl.storage.value.StandaloneStoragePluginProvider;
+-import org.exoplatform.services.jcr.impl.util.io.WorkspaceFileCleanerHolder;
++import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
+ 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;
+
+-import java.util.ArrayList;
+-import java.util.Collections;
+-import java.util.Comparator;
+ import java.util.List;
+
+ import javax.jcr.NamespaceRegistry;
+@@ -335,7 +333,6 @@
+ }
+ workspaceContainer.registerComponentImplementation(initilizerType);
+ workspaceContainer.registerComponentImplementation(SessionFactory.class);
+- workspaceContainer.registerComponentImplementation(WorkspaceFileCleanerHolder.class);
+
+ LocalWorkspaceDataManagerStub wsDataManager =
+ (LocalWorkspaceDataManagerStub)workspaceContainer
+@@ -480,7 +477,10 @@
+ {
+
+ registerComponentInstance(config);
+-
++ // WorkspaceFileCleanerHolder - is a common holder for all workspaces.
++ // It is used to initialize FileValueStorage
++ registerComponentImplementation(FileCleanerHolder.class);
++ registerComponentImplementation(LockRemoverHolder.class);
+ registerWorkspacesComponents();
+ registerRepositoryComponents();
+ }
+@@ -492,7 +492,6 @@
+
+ registerComponentImplementation(RepositoryIndexSearcherHolder.class);
+
+- registerComponentImplementation(WorkspaceFileCleanerHolder.class);
+ registerComponentImplementation(LocationFactory.class);
+ registerComponentImplementation(ValueFactoryImpl.class);
+
+@@ -583,5 +582,5 @@
+ ntManager.start();
+
+ }
+-
++
+ }
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java (working copy)
+@@ -34,6 +34,7 @@
+ import org.exoplatform.services.jcr.impl.storage.jdbc.statistics.StatisticsJDBCStorageConnection;
+ import org.exoplatform.services.jcr.impl.storage.jdbc.update.StorageUpdateManager;
+ import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
++import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
+ import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerException;
+ import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
+ import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
+@@ -202,8 +203,9 @@
+ * if JNDI exception (on DataSource lookup)
+ */
+ public JDBCWorkspaceDataContainer(WorkspaceEntry wsConfig, RepositoryEntry repConfig,
+- InitialContextInitializer contextInit, ValueStoragePluginProvider valueStorageProvider)
+- throws RepositoryConfigurationException, NamingException, RepositoryException, IOException
++ InitialContextInitializer contextInit, ValueStoragePluginProvider valueStorageProvider,
++ FileCleanerHolder fileCleanerHolder) throws RepositoryConfigurationException, NamingException,
++ RepositoryException, IOException
+ {
+
+ // This recall is workaround for tenants creation. There is a trouble in visibility datasource
+@@ -393,7 +395,7 @@
+ if (!swapDirectory.exists())
+ swapDirectory.mkdirs();
+
+- this.swapCleaner = new FileCleaner(false);
++ this.swapCleaner = fileCleanerHolder.getFileCleaner();
+
+ initDatabase();
+
+@@ -834,7 +836,6 @@
+ */
+ public void start()
+ {
+- this.swapCleaner.start();
+ }
+
+ /**
+@@ -842,8 +843,6 @@
+ */
+ public void stop()
+ {
+- this.swapCleaner.halt();
+- this.swapCleaner.interrupt();
+
+ // TODO HSQLDB Stop (debug)
+ // if (dbDialect.equals(DB_DIALECT_GENERIC) ||
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java (working copy)
+@@ -33,6 +33,7 @@
+ import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.HSQLDBConnectionFactory;
+ import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.MySQLConnectionFactory;
+ import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.OracleConnectionFactory;
++import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
+ import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerException;
+ import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+ import org.exoplatform.services.naming.InitialContextInitializer;
+@@ -67,10 +68,11 @@
+ * if JNDI exception (on DataSource lookup)
+ */
+ public CQJDBCWorkspaceDataContainer(WorkspaceEntry wsConfig, RepositoryEntry repConfig,
+- InitialContextInitializer contextInit, ValueStoragePluginProvider valueStorageProvider)
+- throws RepositoryConfigurationException, NamingException, RepositoryException, IOException
++ InitialContextInitializer contextInit, ValueStoragePluginProvider valueStorageProvider,
++ FileCleanerHolder fileCleanerHolder) throws RepositoryConfigurationException, NamingException,
++ RepositoryException, IOException
+ {
+- super(wsConfig, repConfig, contextInit, valueStorageProvider);
++ super(wsConfig, repConfig, contextInit, valueStorageProvider, fileCleanerHolder);
+ }
+
+ /**
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/CASableSimpleFileValueStorage.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/CASableSimpleFileValueStorage.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/CASableSimpleFileValueStorage.java (working copy)
+@@ -21,6 +21,7 @@
+ import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+ import org.exoplatform.services.jcr.impl.storage.value.ValueDataResourceHolder;
+ import org.exoplatform.services.jcr.impl.storage.value.cas.ValueContentAddressStorage;
++import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+ import org.exoplatform.services.jcr.storage.value.ValueIOChannel;
+
+ import java.io.IOException;
+@@ -40,6 +41,11 @@
+
+ private String digestAlgo;
+
++ public CASableSimpleFileValueStorage(FileCleaner cleaner)
++ {
++ super(cleaner);
++ }
++
+ @Override
+ public void init(Properties props, ValueDataResourceHolder resources) throws IOException,
+ RepositoryConfigurationException
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/CASableTreeFileValueStorage.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/CASableTreeFileValueStorage.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/CASableTreeFileValueStorage.java (working copy)
+@@ -21,6 +21,7 @@
+ import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+ import org.exoplatform.services.jcr.impl.storage.value.ValueDataResourceHolder;
+ import org.exoplatform.services.jcr.impl.storage.value.cas.ValueContentAddressStorage;
++import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+
+ import java.io.IOException;
+ import java.util.Properties;
+@@ -38,6 +39,11 @@
+
+ private String digestAlgo;
+
++ public CASableTreeFileValueStorage(FileCleaner cleaner)
++ {
++ super(cleaner);
++ }
++
+ /**
+ * {@inheritDoc}
+ */
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/FileValueStorage.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/FileValueStorage.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/FileValueStorage.java (working copy)
+@@ -59,9 +59,9 @@
+ * FileValueStorage constructor.
+ *
+ */
+- public FileValueStorage()
++ public FileValueStorage(FileCleaner cleaner)
+ {
+- this.cleaner = new FileCleaner(); // TODO use container cleaner
++ this.cleaner = cleaner;
+ }
+
+ /**
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/SimpleFileValueStorage.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/SimpleFileValueStorage.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/SimpleFileValueStorage.java (working copy)
+@@ -18,6 +18,7 @@
+ */
+ package org.exoplatform.services.jcr.impl.storage.value.fs;
+
++import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+ import org.exoplatform.services.jcr.storage.value.ValueIOChannel;
+
+ import java.io.IOException;
+@@ -32,6 +33,11 @@
+ public class SimpleFileValueStorage extends FileValueStorage
+ {
+
++ public SimpleFileValueStorage(FileCleaner cleaner)
++ {
++ super(cleaner);
++ }
++
+ /**
+ * @see org.exoplatform.services.jcr.storage.value.ValueStoragePlugin#openIOChannel()
+ */
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/TreeFileValueStorage.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/TreeFileValueStorage.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/TreeFileValueStorage.java (working copy)
+@@ -21,7 +21,6 @@
+ import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+ import org.exoplatform.services.jcr.storage.value.ValueIOChannel;
+
+-import java.io.File;
+ import java.io.IOException;
+
+ /**
+@@ -33,20 +32,11 @@
+ public class TreeFileValueStorage extends FileValueStorage
+ {
+
+- protected class TreeFileCleaner extends FileCleaner
++ public TreeFileValueStorage(FileCleaner cleaner)
+ {
+- @Override
+- public synchronized void addFile(File file)
+- {
+- super.addFile(new TreeFile(file.getAbsolutePath(), cleaner, rootDir));
+- }
++ super(cleaner);
+ }
+
+- public TreeFileValueStorage()
+- {
+- this.cleaner = new TreeFileCleaner(); // TODO use container cleaner
+- }
+-
+ @Override
+ public ValueIOChannel openIOChannel() throws IOException
+ {
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/StandaloneStoragePluginProvider.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/StandaloneStoragePluginProvider.java (revision 3339)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/StandaloneStoragePluginProvider.java (working copy)
+@@ -24,6 +24,8 @@
+ import org.exoplatform.services.jcr.config.ValueStorageFilterEntry;
+ import org.exoplatform.services.jcr.config.WorkspaceEntry;
+ import org.exoplatform.services.jcr.datamodel.PropertyData;
++import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
++import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
+ import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
+ import org.exoplatform.services.jcr.storage.value.ValueIOChannel;
+ import org.exoplatform.services.jcr.storage.value.ValuePluginFilter;
+@@ -60,7 +62,8 @@
+ */
+ private final ValueDataResourceHolder resorcesHolder;
+
+- public StandaloneStoragePluginProvider(WorkspaceEntry wsConfig) throws RepositoryConfigurationException, IOException
++ public StandaloneStoragePluginProvider(WorkspaceEntry wsConfig, FileCleanerHolder holder)
++ throws RepositoryConfigurationException, IOException
+ {
+
+ this.resorcesHolder = new ValueDataResourceHolder();
+@@ -82,7 +85,10 @@
+ Object o = null;
+ try
+ {
+- o = Class.forName(storageEntry.getType()).newInstance();
++ o =
++ Class.forName(storageEntry.getType()).getConstructor(FileCleaner.class).newInstance(
++ holder.getFileCleaner());
++
+ }
+ catch (Exception e)
+ {
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java (revision 0)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java (revision 0)
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2009 eXo Platform SAS.
++ *
++ * This is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU Lesser General Public License as
++ * published by the Free Software Foundation; either version 2.1 of
++ * the License, or (at your option) any later version.
++ *
++ * This software is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this software; if not, write to the Free
++ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
++ */
++package org.exoplatform.services.jcr.impl.util.io;
++
++/**
++ * Created by The eXo Platform SAS. <br/> per workspace container file cleaner holder object
++ *
++ * @author Gennady Azarenkov
++ * @version $Id: WorkspaceFileCleanerHolder.java 11907 2008-03-13 15:36:21Z ksm $
++ */
++
++public class FileCleanerHolder
++{
++
++ private final FileCleaner fileCleaner;
++
++ public FileCleanerHolder()
++ {
++ this.fileCleaner = new FileCleaner();
++ }
++
++ public FileCleaner getFileCleaner()
++ {
++ return fileCleaner;
++ }
++
++}
+Index: exo.jcr.component.core/src/main/resources/binding.xml
+===================================================================
+--- exo.jcr.component.core/src/main/resources/binding.xml (revision 3339)
++++ exo.jcr.component.core/src/main/resources/binding.xml (working copy)
+@@ -17,6 +17,8 @@
+ <value name="access-control" field="accessControl" usage="optional" />
+ <value name="session-max-age" field="sessionTimeOut"
+ deserializer="org.exoplatform.services.jcr.util.ConfigurationFormat.parseTime" usage="optional" />
++ <value name="lock-remover-max-threads" field="lockRemoverMaxThreadCount"
++ deserializer="org.exoplatform.services.jcr.util.ConfigurationFormat.parseInt" usage="optional" />
+ <value name="authentication-policy" field="authenticationPolicy" />
+ <collection name="workspaces" field="workspaces" item-type="org.exoplatform.services.jcr.config.WorkspaceEntry" />
+ </mapping>
+Index: exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/BaseStandaloneTest.java
+===================================================================
+--- exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/BaseStandaloneTest.java (revision 3339)
++++ exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/BaseStandaloneTest.java (working copy)
+@@ -30,7 +30,7 @@
+ import org.exoplatform.services.jcr.impl.core.SessionImpl;
+ import org.exoplatform.services.jcr.impl.dataflow.serialization.ReaderSpoolFileHolder;
+ import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+-import org.exoplatform.services.jcr.impl.util.io.WorkspaceFileCleanerHolder;
++import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
+ import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
+ import org.exoplatform.services.log.ExoLogger;
+ import org.exoplatform.services.log.Log;
+@@ -153,8 +153,7 @@
+ wconf.getContainer().getParameterInteger(WorkspaceDataContainer.MAXBUFFERSIZE_PROP,
+ WorkspaceDataContainer.DEF_MAXBUFFERSIZE);
+
+- WorkspaceFileCleanerHolder wfcleaner =
+- (WorkspaceFileCleanerHolder)wsc.getComponent(WorkspaceFileCleanerHolder.class);
++ FileCleanerHolder wfcleaner = (FileCleanerHolder)wsc.getComponent(FileCleanerHolder.class);
+ fileCleaner = wfcleaner.getFileCleaner();
+ holder = new ReaderSpoolFileHolder();
+ }
+Index: exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java
+===================================================================
+--- exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java (revision 3339)
++++ exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java (working copy)
+@@ -35,6 +35,7 @@
+ import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
+ import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
+ import org.exoplatform.services.jcr.impl.storage.value.StandaloneStoragePluginProvider;
++import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
+ import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
+ import org.exoplatform.services.log.ExoLogger;
+ import org.exoplatform.services.log.Log;
+@@ -103,9 +104,11 @@
+ // ref.add(new StringRefAddr("database", "jdbc:hsqldb:file:data/test"));
+
+ // SimpleJNDIContextInitializer.initialize(sourceName, ref);
++ FileCleanerHolder holder = new FileCleanerHolder();
+
+ container =
+- new JDBCWorkspaceDataContainer(config, repositoryEntry, null, new StandaloneStoragePluginProvider(config));
++ new JDBCWorkspaceDataContainer(config, repositoryEntry, null, new StandaloneStoragePluginProvider(config,
++ holder), holder);
+
+ Properties logProps = new Properties();
+ logProps.put("org.apache.commons.logging.simplelog.defaultlog", "debug");
+Index: exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/CASableFileIOChannelTestBase.java
+===================================================================
+--- exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/CASableFileIOChannelTestBase.java (revision 3339)
++++ exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/CASableFileIOChannelTestBase.java (working copy)
+@@ -24,7 +24,6 @@
+ import org.exoplatform.services.jcr.impl.storage.value.cas.RecordAlreadyExistsException;
+ import org.exoplatform.services.jcr.impl.storage.value.cas.RecordNotFoundException;
+ import org.exoplatform.services.jcr.impl.storage.value.cas.ValueContentAddressStorage;
+-import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+ import org.exoplatform.services.jcr.util.IdGenerator;
+ import org.exoplatform.services.log.ExoLogger;
+ import org.exoplatform.services.log.Log;
+@@ -48,8 +47,6 @@
+
+ protected ValueContentAddressStorage vcas;
+
+- protected FileCleaner fileCleaner;
+-
+ protected File rootDir;
+
+ protected String storageId;
+@@ -61,9 +58,6 @@
+ {
+ super.setUp();
+
+- if (fileCleaner == null)
+- fileCleaner = new FileCleaner();
+-
+ if (vcas == null)
+ initVCAS();
+
+Index: exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java
+===================================================================
+--- exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java (revision 3339)
++++ exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java (working copy)
+@@ -43,7 +43,7 @@
+
+ private File rootDir;
+
+- private FileCleaner cleaner = new FileCleaner(2000);
++ private FileCleaner cleaner;
+
+ private ValueDataResourceHolder resources = new ValueDataResourceHolder();
+
+@@ -57,6 +57,8 @@
+ {
+ super.setUp();
+
++ cleaner = new FileCleaner(2000);
++
+ rootDir = new File(new File("target"), "vs1");
+ rootDir.mkdirs();
+
+@@ -67,6 +69,15 @@
+
+ }
+
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ protected void tearDown() throws Exception
++ {
++ cleaner.halt();
++ }
++
+ public void testRead() throws Exception
+ {
+
+Index: exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestPersistedValueData.java
+===================================================================
+--- exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestPersistedValueData.java (revision 3339)
++++ exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestPersistedValueData.java (working copy)
+@@ -81,27 +81,34 @@
+
+ public void testIfFinalizeRemovesTempFileStreamValueData() throws Exception
+ {
++ FileCleaner testFileCleaner = new FileCleaner(1000, true);
++ try
++ {
++ byte[] buf = "0123456789".getBytes();
++ SwapFile file = SwapFile.get(new File("target"), "testIfFinalizeRemovesTempFileStreamValueData");
++ //File file = new File("target/testIfFinalizeRemovesTempFileStreamValueData");
++ //if (file.exists())
++ // file.delete();
++ FileOutputStream out = new FileOutputStream(file);
++ out.write(buf);
++ out.close();
+
+- byte[] buf = "0123456789".getBytes();
+- SwapFile file = SwapFile.get(new File("target"), "testIfFinalizeRemovesTempFileStreamValueData");
+- //File file = new File("target/testIfFinalizeRemovesTempFileStreamValueData");
+- //if (file.exists())
+- // file.delete();
+- FileOutputStream out = new FileOutputStream(file);
+- out.write(buf);
+- out.close();
++ CleanableFilePersistedValueData vd = new CleanableFilePersistedValueData(0, file, testFileCleaner);
++ assertTrue(file.exists());
+
+- CleanableFilePersistedValueData vd = new CleanableFilePersistedValueData(0, file, new FileCleaner(1000, true));
+- assertTrue(file.exists());
++ vd = null;
++ System.gc();
+
+- vd = null;
+- System.gc();
++ // allows GC to call finalize on vd
++ Thread.sleep(2500);
++ System.gc();
+
+- // allows GC to call finalize on vd
+- Thread.sleep(2500);
+- System.gc();
+-
+- assertFalse(file.exists());
++ assertFalse(file.exists());
++ }
++ finally
++ {
++ testFileCleaner.halt();
++ }
+ }
+
+ public void testConcurrentFileStreamValueDataReading() throws Exception
+Index: exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestTransientValueData.java
+===================================================================
+--- exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestTransientValueData.java (revision 3339)
++++ exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestTransientValueData.java (working copy)
+@@ -66,37 +66,46 @@
+
+ public void testCreateFileStreamTransientValueData() throws Exception
+ {
++ FileCleaner testFileCleaner = new FileCleaner();
++ try
++ {
++ byte[] buf = "0123456789".getBytes();
++ File file = new File("target/testCreateFileStreamTransientValueData");
++ if (file.exists())
++ file.delete();
++ FileOutputStream out = new FileOutputStream(file);
++ out.write(buf);
++ out.close();
+
+- byte[] buf = "0123456789".getBytes();
+- File file = new File("target/testCreateFileStreamTransientValueData");
+- if (file.exists())
+- file.delete();
+- FileOutputStream out = new FileOutputStream(file);
+- out.write(buf);
+- out.close();
++ FileInputStream fs1 = new FileInputStream(file);
++ TransientValueData vd =
++ new TransientValueData(0, null, fs1, null, testFileCleaner, 5, new File("target"), true);
+
+- FileInputStream fs1 = new FileInputStream(file);
+- TransientValueData vd = new TransientValueData(0, null, fs1, null, new FileCleaner(), 5, new File("target"), true);
++ // spool to file
++ InputStream fs2 = vd.getAsStream();
++ assertEquals(10, vd.getLength());
++ assertTrue(fs2 instanceof FileInputStream);
+
+- // spool to file
+- InputStream fs2 = vd.getAsStream();
+- assertEquals(10, vd.getLength());
+- assertTrue(fs2 instanceof FileInputStream);
++ // not the same object as new is is from spool file
++ assertNotSame(fs1, fs2);
++ // spooled to file so not a byte array
++ assertFalse(vd.isByteArray());
+
+- // not the same object as new is is from spool file
+- assertNotSame(fs1, fs2);
+- // spooled to file so not a byte array
+- assertFalse(vd.isByteArray());
++ // next call return not the same object as well
++ // (new stream every time)
++ assertNotSame(vd.getAsStream(), fs2);
++ assertEquals(10, vd.getLength());
+
+- // next call return not the same object as well
+- // (new stream every time)
+- assertNotSame(vd.getAsStream(), fs2);
+- assertEquals(10, vd.getLength());
++ // gets as byte array
++ assertEquals(10, vd.getAsByteArray().length);
++ // but still spooled to file
++ assertFalse(vd.isByteArray());
+
+- // gets as byte array
+- assertEquals(10, vd.getAsByteArray().length);
+- // but still spooled to file
+- assertFalse(vd.isByteArray());
++ }
++ finally
++ {
++ testFileCleaner.halt();
++ }
+
+ }
+
+@@ -118,7 +127,7 @@
+ // TODO not influenced here as will be spooled to byte array anyway
+ //vd.setMaxBufferSize(5);
+ //vd.setFileCleaner(new FileCleaner());
+-
++
+ //
+ InputStream fs2 = vd.getAsStream();
+ assertEquals(10, vd.getLength());
+Index: exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestValueImpl.java
+===================================================================
+--- exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestValueImpl.java (revision 3339)
++++ exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/value/TestValueImpl.java (working copy)
+@@ -50,43 +50,51 @@
+
+ public void testNewBinaryValue() throws Exception
+ {
++ FileCleaner testFileCleaner = new FileCleaner();
+
+- byte[] buf = "012345678901234567890123456789".getBytes();
+- File file = new File("target/testNewBinaryValue");
+- if (file.exists())
+- file.delete();
+- FileOutputStream out = new FileOutputStream(file);
+- out.write(buf);
+- out.close();
++ try
++ {
++ byte[] buf = "012345678901234567890123456789".getBytes();
++ File file = new File("target/testNewBinaryValue");
++ if (file.exists())
++ file.delete();
++ FileOutputStream out = new FileOutputStream(file);
++ out.write(buf);
++ out.close();
+
+- FileInputStream fs1 = new FileInputStream(file);
+- BinaryValue val = new BinaryValue(fs1, new FileCleaner(), tempDirectory, maxFufferSize);
+- InputStream str1 = val.getStream();
+- assertNotNull(str1);
++ FileInputStream fs1 = new FileInputStream(file);
++ BinaryValue val = new BinaryValue(fs1, testFileCleaner, tempDirectory, maxFufferSize);
++ InputStream str1 = val.getStream();
++ assertNotNull(str1);
+
+- // obj returned by getStream() is not the same as incoming stream
+- assertNotSame(str1, fs1);
++ // obj returned by getStream() is not the same as incoming stream
++ assertNotSame(str1, fs1);
+
+- // streams returned by subsequent call of val.getStream() are equals
+- assertEquals(str1, val.getStream());
++ // streams returned by subsequent call of val.getStream() are equals
++ assertEquals(str1, val.getStream());
+
+- // another one value using the same string
+- BinaryValue val2 = new BinaryValue(fs1, new FileCleaner(), tempDirectory, maxFufferSize);
+- InputStream str2 = val2.getStream();
++ // another one value using the same string
++ BinaryValue val2 = new BinaryValue(fs1, testFileCleaner, tempDirectory, maxFufferSize);
++ InputStream str2 = val2.getStream();
+
+- // are not the same although created from same Stream
+- assertNotSame(str1, str2);
++ // are not the same although created from same Stream
++ assertNotSame(str1, str2);
+
+- // stream already consumed
+- try
+- {
+- val.getString();
+- fail("IllegalStateException should have been thrown");
++ // stream already consumed
++ try
++ {
++ val.getString();
++ fail("IllegalStateException should have been thrown");
++ }
++ catch (IllegalStateException e)
++ {
++ }
++ // System.out.println(" >>>>>>>>STRING >>> "+);
+ }
+- catch (IllegalStateException e)
++ finally
+ {
++ testFileCleaner.halt();
+ }
+- // System.out.println(" >>>>>>>>STRING >>> "+);
+ }
+
+ public void testNewBinaryValueFromString() throws Exception
+Index: exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/replication/ReplicationService.java
+===================================================================
+--- exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/replication/ReplicationService.java (revision 3339)
++++ exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/replication/ReplicationService.java (working copy)
+@@ -43,7 +43,7 @@
+ import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
+ import org.exoplatform.services.jcr.impl.dataflow.serialization.ReaderSpoolFileHolder;
+ import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+-import org.exoplatform.services.jcr.impl.util.io.WorkspaceFileCleanerHolder;
++import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
+ import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
+ import org.exoplatform.services.jcr.util.IdGenerator;
+ import org.exoplatform.services.log.ExoLogger;
+@@ -398,8 +398,8 @@
+ wconf.getContainer().getParameterInteger(WorkspaceDataContainer.MAXBUFFERSIZE_PROP,
+ WorkspaceDataContainer.DEF_MAXBUFFERSIZE);
+
+- WorkspaceFileCleanerHolder wfcleaner =
+- (WorkspaceFileCleanerHolder)wsFacade.getComponent(WorkspaceFileCleanerHolder.class);
++ FileCleanerHolder wfcleaner =
++ (FileCleanerHolder)wsFacade.getComponent(FileCleanerHolder.class);
+ FileCleaner fileCleaner = wfcleaner.getFileCleaner();
+
+ // create the RecoveryManager
+Index: exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/BaseStandaloneTest.java
+===================================================================
+--- exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/BaseStandaloneTest.java (revision 3339)
++++ exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/BaseStandaloneTest.java (working copy)
+@@ -1,489 +1,489 @@
+-/*
+- * 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.ext;
+-
+-import junit.framework.TestCase;
+-
+-import org.exoplatform.container.StandaloneContainer;
+-import org.exoplatform.services.jcr.RepositoryService;
+-import org.exoplatform.services.jcr.config.WorkspaceEntry;
+-import org.exoplatform.services.jcr.core.CredentialsImpl;
+-import org.exoplatform.services.jcr.core.ManageableRepository;
+-import org.exoplatform.services.jcr.core.WorkspaceContainerFacade;
+-import org.exoplatform.services.jcr.dataflow.ItemState;
+-import org.exoplatform.services.jcr.dataflow.PersistentDataManager;
+-import org.exoplatform.services.jcr.datamodel.ItemData;
+-import org.exoplatform.services.jcr.datamodel.PropertyData;
+-import org.exoplatform.services.jcr.datamodel.ValueData;
+-import org.exoplatform.services.jcr.impl.core.NodeImpl;
+-import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
+-import org.exoplatform.services.jcr.impl.core.SessionImpl;
+-import org.exoplatform.services.jcr.impl.dataflow.serialization.ReaderSpoolFileHolder;
+-import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+-import org.exoplatform.services.jcr.impl.util.io.WorkspaceFileCleanerHolder;
+-import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
+-import org.exoplatform.services.log.ExoLogger;
+-import org.exoplatform.services.log.Log;
+-
+-import java.io.File;
+-import java.io.FileOutputStream;
+-import java.io.IOException;
+-import java.io.InputStream;
+-import java.util.Iterator;
+-import java.util.List;
+-import java.util.Random;
+-
+-import javax.jcr.Node;
+-import javax.jcr.NodeIterator;
+-import javax.jcr.PathNotFoundException;
+-import javax.jcr.RepositoryException;
+-import javax.jcr.ValueFactory;
+-import javax.jcr.Workspace;
+-
+-/**
+- * Created by The eXo Platform SAS .
+- *
+- * @author <a href="mailto:geaz@users.sourceforge.net">Gennady Azarenkov </a>
+- * @version $Id: BaseStandaloneTest.java 12004 2007-01-17 12:03:57Z geaz $
+- */
+-public abstract class BaseStandaloneTest extends TestCase
+-{
+-
+- private static final Log log = ExoLogger.getLogger("exo.jcr.component.ext.BaseStandaloneTest");
+-
+- public static final String WS_NAME = "ws";
+-
+- protected SessionImpl session;
+-
+- protected RepositoryImpl repository;
+-
+- protected CredentialsImpl credentials;
+-
+- protected Workspace workspace;
+-
+- protected RepositoryService repositoryService;
+-
+- protected Node root;
+-
+- protected PersistentDataManager dataManager;
+-
+- protected ValueFactory valueFactory;
+-
+- protected StandaloneContainer container;
+-
+- public int maxBufferSize = 200 * 1024;
+-
+- public FileCleaner fileCleaner;
+-
+- public ReaderSpoolFileHolder holder;
+-
+- protected class CompareStreamException extends Exception
+- {
+-
+- CompareStreamException(String message)
+- {
+- super(message);
+- }
+-
+- CompareStreamException(String message, Throwable e)
+- {
+- super(message, e);
+- }
+- }
+-
+- public void setUp() throws Exception
+- {
+- String containerConf = BaseStandaloneTest.class.getResource("/conf/standalone/test-configuration.xml").toString();
+-
+- StandaloneContainer.addConfigurationURL(containerConf);
+-
+- container = StandaloneContainer.getInstance();
+-
+- if (System.getProperty("java.security.auth.login.config") == null)
+- System.setProperty("java.security.auth.login.config", Thread.currentThread().getContextClassLoader()
+- .getResource("login.conf").toString());
+-
+- credentials = new CredentialsImpl("root", "exo".toCharArray());
+-
+- repositoryService = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
+-
+- repository = (RepositoryImpl)repositoryService.getDefaultRepository();
+-
+- session = (SessionImpl)repository.login(credentials, WS_NAME);
+- workspace = session.getWorkspace();
+- root = session.getRootNode();
+- valueFactory = session.getValueFactory();
+-
+- ManageableRepository repository = repositoryService.getDefaultRepository();
+- WorkspaceContainerFacade wsc = repository.getWorkspaceContainer(WS_NAME);
+-
+- WorkspaceEntry wconf = (WorkspaceEntry)wsc.getComponent(WorkspaceEntry.class);
+-
+- maxBufferSize =
+- wconf.getContainer().getParameterInteger(WorkspaceDataContainer.MAXBUFFERSIZE_PROP,
+- WorkspaceDataContainer.DEF_MAXBUFFERSIZE);
+-
+- WorkspaceFileCleanerHolder wfcleaner =
+- (WorkspaceFileCleanerHolder)wsc.getComponent(WorkspaceFileCleanerHolder.class);
+- fileCleaner = wfcleaner.getFileCleaner();
+- holder = new ReaderSpoolFileHolder();
+-
+- wsc = repository.getWorkspaceContainer("ws4");
+- dataManager = (PersistentDataManager)wsc.getComponent(PersistentDataManager.class);
+- }
+-
+- protected void tearDown() throws Exception
+- {
+-
+- log.info("tearDown() BEGIN " + getClass().getName() + "." + getName());
+- if (session != null)
+- {
+- try
+- {
+- session.refresh(false);
+- Node rootNode = session.getRootNode();
+- if (rootNode.hasNodes())
+- {
+- // clean test root
+- for (NodeIterator children = rootNode.getNodes(); children.hasNext();)
+- {
+- Node node = children.nextNode();
+- if (!node.getPath().startsWith("/jcr:system") && !node.getPath().startsWith("/exo:audit")
+- && !node.getPath().startsWith("/exo:organization"))
+- {
+- // log.info("DELETing ------------- "+node.getPath());
+- node.remove();
+- }
+- }
+- session.save();
+- }
+- }
+- catch (Exception e)
+- {
+- e.printStackTrace();
+- log.error("===== Exception in tearDown() " + e.toString());
+- }
+- finally
+- {
+- session.logout();
+- }
+- }
+-
+- super.tearDown();
+- // log.info("tearDown() END " + getClass().getName() + "." + getName());
+- }
+-
+- // protected abstract String getConfPath();
+- //
+- // public void initRepository() throws RepositoryException {
+- // }
+-
+- // ====== utils =======
+-
+- protected void checkItemsExisted(String[] exists, String[] notExists) throws RepositoryException
+- {
+- String path = null;
+- if (exists != null)
+- {
+- try
+- {
+- for (String nodePath : exists)
+- {
+- path = nodePath;
+- session.getItem(path);
+- }
+- }
+- catch (PathNotFoundException e)
+- {
+- fail("Item must exists " + path + ". " + e.getMessage());
+- }
+- }
+- if (notExists != null)
+- {
+- try
+- {
+- for (String nodePath : notExists)
+- {
+- session.getItem(nodePath);
+- fail("Item must not exists " + nodePath);
+- }
+- }
+- catch (PathNotFoundException e)
+- {
+- // ok
+- }
+- }
+- }
+-
+- protected void checkNodesExistedByUUID(String[] exists, String[] notExists) throws RepositoryException
+- {
+- String uuid = null;
+- if (exists != null)
+- {
+- try
+- {
+- for (String nodePath : exists)
+- {
+- uuid = nodePath;
+- session.getNodeByUUID(uuid);
+- }
+- }
+- catch (PathNotFoundException e)
+- {
+- fail("Node must exists, UUID " + uuid + ". " + e.getMessage());
+- }
+- }
+- if (notExists != null)
+- {
+- try
+- {
+- for (String nodeUUID : notExists)
+- {
+- session.getNodeByUUID(nodeUUID);
+- fail("Node must not exists, UUID " + nodeUUID);
+- }
+- }
+- catch (PathNotFoundException e)
+- {
+- // ok
+- }
+- }
+- }
+-
+- protected void compareStream(InputStream etalon, InputStream data) throws IOException
+- {
+- try
+- {
+- compareStream(etalon, data, 0, 0, -1);
+- }
+- catch (CompareStreamException e)
+- {
+- fail(e.getMessage());
+- }
+- }
+-
+- /**
+- * Compare etalon stream with data stream begining from the offset in etalon and position in data.
+- * Length bytes will be readed and compared. if length is lower 0 then compare streams till one of
+- * them will be read.
+- *
+- * @param etalon
+- * @param data
+- * @param etalonPos
+- * @param length
+- * @param dataPos
+- * @throws IOException
+- */
+- protected void compareStream(InputStream etalon, InputStream data, long etalonPos, long dataPos, long length)
+- throws IOException, CompareStreamException
+- {
+-
+- int dindex = 0;
+-
+- skipStream(etalon, etalonPos);
+- skipStream(data, dataPos);
+-
+- byte[] ebuff = new byte[1024];
+- int eread = 0;
+-
+- while ((eread = etalon.read(ebuff)) > 0)
+- {
+-
+- byte[] dbuff = new byte[eread];
+- int erindex = 0;
+- while (erindex < eread)
+- {
+- int dread = -1;
+- try
+- {
+- dread = data.read(dbuff);
+- }
+- catch (IOException e)
+- {
+- throw new CompareStreamException("Streams is not equals by length or data stream is unreadable. Cause: "
+- + e.getMessage());
+- }
+-
+- if (dread == -1)
+- throw new CompareStreamException(
+- "Streams is not equals by length. Data end-of-stream reached at position " + dindex);
+-
+- for (int i = 0; i < dread; i++)
+- {
+- byte eb = ebuff[i];
+- byte db = dbuff[i];
+- if (eb != db)
+- throw new CompareStreamException("Streams is not equals. Wrong byte stored at position " + dindex
+- + " of data stream. Expected 0x" + Integer.toHexString(eb) + " '" + new String(new byte[]{eb})
+- + "' but found 0x" + Integer.toHexString(db) + " '" + new String(new byte[]{db}) + "'");
+-
+- erindex++;
+- dindex++;
+- if (length > 0 && dindex >= length)
+- return; // tested length reached
+- }
+-
+- if (dread < eread)
+- dbuff = new byte[eread - dread];
+- }
+- }
+-
+- if (data.available() > 0)
+- throw new CompareStreamException("Streams is not equals by length. Data stream contains more data. Were read "
+- + dindex);
+- }
+-
+- protected void skipStream(InputStream stream, long pos) throws IOException
+- {
+- long curPos = pos;
+- long sk = 0;
+- while ((sk = stream.skip(curPos)) > 0)
+- {
+- curPos -= sk;
+- };
+- if (sk < 0)
+- fail("Can not read the stream (skip bytes)");
+- if (curPos != 0)
+- fail("Can not skip bytes from the stream (" + pos + " bytes)");
+- }
+-
+- protected File createBLOBTempFile(int sizeInKb) throws IOException
+- {
+- return createBLOBTempFile("exo_jcr_test_temp_file_", sizeInKb);
+- }
+-
+- protected File createBLOBTempFile(String prefix, int sizeInKb) throws IOException
+- {
+- // create test file
+- byte[] data = new byte[1024]; // 1Kb
+-
+- File testFile = File.createTempFile(prefix, ".tmp");
+- FileOutputStream tempOut = new FileOutputStream(testFile);
+- Random random = new Random();
+-
+- for (int i = 0; i < sizeInKb; i++)
+- {
+- random.nextBytes(data);
+- tempOut.write(data);
+- }
+- tempOut.close();
+- testFile.deleteOnExit(); // delete on test exit
+- log.info("Temp file created: " + testFile.getAbsolutePath() + " size: " + testFile.length());
+- return testFile;
+- }
+-
+- protected void checkMixins(String[] mixins, NodeImpl node) throws RepositoryException
+- {
+- try
+- {
+- String[] nodeMixins = node.getMixinTypeNames();
+- assertEquals("Mixins count is different", mixins.length, nodeMixins.length);
+-
+- compareMixins(mixins, nodeMixins);
+- }
+- catch (RepositoryException e)
+- {
+- fail("Mixins isn't accessible on the node " + node.getPath());
+- }
+- }
+-
+- protected void compareMixins(String[] mixins, String[] nodeMixins)
+- {
+- nextMixin : for (String mixin : mixins)
+- {
+- for (String nodeMixin : nodeMixins)
+- {
+- if (mixin.equals(nodeMixin))
+- continue nextMixin;
+- }
+-
+- fail("Mixin '" + mixin + "' isn't accessible");
+- }
+- }
+-
+- protected String memoryInfo()
+- {
+- String info = "";
+- info =
+- "free: " + mb(Runtime.getRuntime().freeMemory()) + "M of " + mb(Runtime.getRuntime().totalMemory())
+- + "M (max: " + mb(Runtime.getRuntime().maxMemory()) + "M)";
+- return info;
+- }
+-
+- // bytes to Mbytes
+- protected String mb(long mem)
+- {
+- return String.valueOf(Math.round(mem * 100d / (1024d * 1024d)) / 100d);
+- }
+-
+- protected String execTime(long from)
+- {
+- return Math.round(((System.currentTimeMillis() - from) * 100.00d / 60000.00d)) / 100.00d + "min";
+- }
+-
+- public void checkItemStatesIterator(Iterator<ItemState> expected, Iterator<ItemState> changes, boolean checklast,
+- boolean isRepValDat) throws Exception
+- {
+-
+- while (expected.hasNext())
+- {
+-
+- assertTrue(changes.hasNext());
+- ItemState expect = expected.next();
+- ItemState elem = changes.next();
+-
+- assertEquals(expect.getState(), elem.getState());
+- // assertEquals(expect.getAncestorToSave(), elem.getAncestorToSave());
+- ItemData expData = expect.getData();
+- ItemData elemData = elem.getData();
+- assertEquals(expData.getQPath(), elemData.getQPath());
+- assertEquals(expData.isNode(), elemData.isNode());
+- assertEquals(expData.getIdentifier(), elemData.getIdentifier());
+- assertEquals(expData.getParentIdentifier(), elemData.getParentIdentifier());
+-
+- if (!expData.isNode())
+- {
+- PropertyData expProp = (PropertyData)expData;
+- PropertyData elemProp = (PropertyData)elemData;
+- assertEquals(expProp.getType(), elemProp.getType());
+- assertEquals(expProp.isMultiValued(), elemProp.isMultiValued());
+-
+- List<ValueData> expValDat = expProp.getValues();
+- List<ValueData> elemValDat = elemProp.getValues();
+- assertEquals(expValDat.size(), elemValDat.size());
+- for (int j = 0; j < expValDat.size(); j++)
+- {
+- assertTrue(java.util.Arrays
+- .equals(expValDat.get(j).getAsByteArray(), elemValDat.get(j).getAsByteArray()));
+-
+- /*if (isRepValDat) {
+- // check is received property values ReplicableValueData
+- assertTrue(elemValDat.get(j) instanceof ReplicableValueData);
+- }*/
+- }
+- }
+- }
+-
+- if (checklast)
+- {
+- assertFalse(changes.hasNext());
+- }
+-
+- }
+-}
++/*
++ * 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.ext;
++
++import junit.framework.TestCase;
++
++import org.exoplatform.container.StandaloneContainer;
++import org.exoplatform.services.jcr.RepositoryService;
++import org.exoplatform.services.jcr.config.WorkspaceEntry;
++import org.exoplatform.services.jcr.core.CredentialsImpl;
++import org.exoplatform.services.jcr.core.ManageableRepository;
++import org.exoplatform.services.jcr.core.WorkspaceContainerFacade;
++import org.exoplatform.services.jcr.dataflow.ItemState;
++import org.exoplatform.services.jcr.dataflow.PersistentDataManager;
++import org.exoplatform.services.jcr.datamodel.ItemData;
++import org.exoplatform.services.jcr.datamodel.PropertyData;
++import org.exoplatform.services.jcr.datamodel.ValueData;
++import org.exoplatform.services.jcr.impl.core.NodeImpl;
++import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
++import org.exoplatform.services.jcr.impl.core.SessionImpl;
++import org.exoplatform.services.jcr.impl.dataflow.serialization.ReaderSpoolFileHolder;
++import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
++import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
++import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
++import org.exoplatform.services.log.ExoLogger;
++import org.exoplatform.services.log.Log;
++
++import java.io.File;
++import java.io.FileOutputStream;
++import java.io.IOException;
++import java.io.InputStream;
++import java.util.Iterator;
++import java.util.List;
++import java.util.Random;
++
++import javax.jcr.Node;
++import javax.jcr.NodeIterator;
++import javax.jcr.PathNotFoundException;
++import javax.jcr.RepositoryException;
++import javax.jcr.ValueFactory;
++import javax.jcr.Workspace;
++
++/**
++ * Created by The eXo Platform SAS .
++ *
++ * @author <a href="mailto:geaz@users.sourceforge.net">Gennady Azarenkov </a>
++ * @version $Id: BaseStandaloneTest.java 12004 2007-01-17 12:03:57Z geaz $
++ */
++public abstract class BaseStandaloneTest extends TestCase
++{
++
++ private static final Log log = ExoLogger.getLogger("exo.jcr.component.ext.BaseStandaloneTest");
++
++ public static final String WS_NAME = "ws";
++
++ protected SessionImpl session;
++
++ protected RepositoryImpl repository;
++
++ protected CredentialsImpl credentials;
++
++ protected Workspace workspace;
++
++ protected RepositoryService repositoryService;
++
++ protected Node root;
++
++ protected PersistentDataManager dataManager;
++
++ protected ValueFactory valueFactory;
++
++ protected StandaloneContainer container;
++
++ public int maxBufferSize = 200 * 1024;
++
++ public FileCleaner fileCleaner;
++
++ public ReaderSpoolFileHolder holder;
++
++ protected class CompareStreamException extends Exception
++ {
++
++ CompareStreamException(String message)
++ {
++ super(message);
++ }
++
++ CompareStreamException(String message, Throwable e)
++ {
++ super(message, e);
++ }
++ }
++
++ public void setUp() throws Exception
++ {
++ String containerConf = BaseStandaloneTest.class.getResource("/conf/standalone/test-configuration.xml").toString();
++
++ StandaloneContainer.addConfigurationURL(containerConf);
++
++ container = StandaloneContainer.getInstance();
++
++ if (System.getProperty("java.security.auth.login.config") == null)
++ System.setProperty("java.security.auth.login.config", Thread.currentThread().getContextClassLoader()
++ .getResource("login.conf").toString());
++
++ credentials = new CredentialsImpl("root", "exo".toCharArray());
++
++ repositoryService = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
++
++ repository = (RepositoryImpl)repositoryService.getDefaultRepository();
++
++ session = (SessionImpl)repository.login(credentials, WS_NAME);
++ workspace = session.getWorkspace();
++ root = session.getRootNode();
++ valueFactory = session.getValueFactory();
++
++ ManageableRepository repository = repositoryService.getDefaultRepository();
++ WorkspaceContainerFacade wsc = repository.getWorkspaceContainer(WS_NAME);
++
++ WorkspaceEntry wconf = (WorkspaceEntry)wsc.getComponent(WorkspaceEntry.class);
++
++ maxBufferSize =
++ wconf.getContainer().getParameterInteger(WorkspaceDataContainer.MAXBUFFERSIZE_PROP,
++ WorkspaceDataContainer.DEF_MAXBUFFERSIZE);
++
++ FileCleanerHolder wfcleaner =
++ (FileCleanerHolder)wsc.getComponent(FileCleanerHolder.class);
++ fileCleaner = wfcleaner.getFileCleaner();
++ holder = new ReaderSpoolFileHolder();
++
++ wsc = repository.getWorkspaceContainer("ws4");
++ dataManager = (PersistentDataManager)wsc.getComponent(PersistentDataManager.class);
++ }
++
++ protected void tearDown() throws Exception
++ {
++
++ log.info("tearDown() BEGIN " + getClass().getName() + "." + getName());
++ if (session != null)
++ {
++ try
++ {
++ session.refresh(false);
++ Node rootNode = session.getRootNode();
++ if (rootNode.hasNodes())
++ {
++ // clean test root
++ for (NodeIterator children = rootNode.getNodes(); children.hasNext();)
++ {
++ Node node = children.nextNode();
++ if (!node.getPath().startsWith("/jcr:system") && !node.getPath().startsWith("/exo:audit")
++ && !node.getPath().startsWith("/exo:organization"))
++ {
++ // log.info("DELETing ------------- "+node.getPath());
++ node.remove();
++ }
++ }
++ session.save();
++ }
++ }
++ catch (Exception e)
++ {
++ e.printStackTrace();
++ log.error("===== Exception in tearDown() " + e.toString());
++ }
++ finally
++ {
++ session.logout();
++ }
++ }
++
++ super.tearDown();
++ // log.info("tearDown() END " + getClass().getName() + "." + getName());
++ }
++
++ // protected abstract String getConfPath();
++ //
++ // public void initRepository() throws RepositoryException {
++ // }
++
++ // ====== utils =======
++
++ protected void checkItemsExisted(String[] exists, String[] notExists) throws RepositoryException
++ {
++ String path = null;
++ if (exists != null)
++ {
++ try
++ {
++ for (String nodePath : exists)
++ {
++ path = nodePath;
++ session.getItem(path);
++ }
++ }
++ catch (PathNotFoundException e)
++ {
++ fail("Item must exists " + path + ". " + e.getMessage());
++ }
++ }
++ if (notExists != null)
++ {
++ try
++ {
++ for (String nodePath : notExists)
++ {
++ session.getItem(nodePath);
++ fail("Item must not exists " + nodePath);
++ }
++ }
++ catch (PathNotFoundException e)
++ {
++ // ok
++ }
++ }
++ }
++
++ protected void checkNodesExistedByUUID(String[] exists, String[] notExists) throws RepositoryException
++ {
++ String uuid = null;
++ if (exists != null)
++ {
++ try
++ {
++ for (String nodePath : exists)
++ {
++ uuid = nodePath;
++ session.getNodeByUUID(uuid);
++ }
++ }
++ catch (PathNotFoundException e)
++ {
++ fail("Node must exists, UUID " + uuid + ". " + e.getMessage());
++ }
++ }
++ if (notExists != null)
++ {
++ try
++ {
++ for (String nodeUUID : notExists)
++ {
++ session.getNodeByUUID(nodeUUID);
++ fail("Node must not exists, UUID " + nodeUUID);
++ }
++ }
++ catch (PathNotFoundException e)
++ {
++ // ok
++ }
++ }
++ }
++
++ protected void compareStream(InputStream etalon, InputStream data) throws IOException
++ {
++ try
++ {
++ compareStream(etalon, data, 0, 0, -1);
++ }
++ catch (CompareStreamException e)
++ {
++ fail(e.getMessage());
++ }
++ }
++
++ /**
++ * Compare etalon stream with data stream begining from the offset in etalon and position in data.
++ * Length bytes will be readed and compared. if length is lower 0 then compare streams till one of
++ * them will be read.
++ *
++ * @param etalon
++ * @param data
++ * @param etalonPos
++ * @param length
++ * @param dataPos
++ * @throws IOException
++ */
++ protected void compareStream(InputStream etalon, InputStream data, long etalonPos, long dataPos, long length)
++ throws IOException, CompareStreamException
++ {
++
++ int dindex = 0;
++
++ skipStream(etalon, etalonPos);
++ skipStream(data, dataPos);
++
++ byte[] ebuff = new byte[1024];
++ int eread = 0;
++
++ while ((eread = etalon.read(ebuff)) > 0)
++ {
++
++ byte[] dbuff = new byte[eread];
++ int erindex = 0;
++ while (erindex < eread)
++ {
++ int dread = -1;
++ try
++ {
++ dread = data.read(dbuff);
++ }
++ catch (IOException e)
++ {
++ throw new CompareStreamException("Streams is not equals by length or data stream is unreadable. Cause: "
++ + e.getMessage());
++ }
++
++ if (dread == -1)
++ throw new CompareStreamException(
++ "Streams is not equals by length. Data end-of-stream reached at position " + dindex);
++
++ for (int i = 0; i < dread; i++)
++ {
++ byte eb = ebuff[i];
++ byte db = dbuff[i];
++ if (eb != db)
++ throw new CompareStreamException("Streams is not equals. Wrong byte stored at position " + dindex
++ + " of data stream. Expected 0x" + Integer.toHexString(eb) + " '" + new String(new byte[]{eb})
++ + "' but found 0x" + Integer.toHexString(db) + " '" + new String(new byte[]{db}) + "'");
++
++ erindex++;
++ dindex++;
++ if (length > 0 && dindex >= length)
++ return; // tested length reached
++ }
++
++ if (dread < eread)
++ dbuff = new byte[eread - dread];
++ }
++ }
++
++ if (data.available() > 0)
++ throw new CompareStreamException("Streams is not equals by length. Data stream contains more data. Were read "
++ + dindex);
++ }
++
++ protected void skipStream(InputStream stream, long pos) throws IOException
++ {
++ long curPos = pos;
++ long sk = 0;
++ while ((sk = stream.skip(curPos)) > 0)
++ {
++ curPos -= sk;
++ };
++ if (sk < 0)
++ fail("Can not read the stream (skip bytes)");
++ if (curPos != 0)
++ fail("Can not skip bytes from the stream (" + pos + " bytes)");
++ }
++
++ protected File createBLOBTempFile(int sizeInKb) throws IOException
++ {
++ return createBLOBTempFile("exo_jcr_test_temp_file_", sizeInKb);
++ }
++
++ protected File createBLOBTempFile(String prefix, int sizeInKb) throws IOException
++ {
++ // create test file
++ byte[] data = new byte[1024]; // 1Kb
++
++ File testFile = File.createTempFile(prefix, ".tmp");
++ FileOutputStream tempOut = new FileOutputStream(testFile);
++ Random random = new Random();
++
++ for (int i = 0; i < sizeInKb; i++)
++ {
++ random.nextBytes(data);
++ tempOut.write(data);
++ }
++ tempOut.close();
++ testFile.deleteOnExit(); // delete on test exit
++ log.info("Temp file created: " + testFile.getAbsolutePath() + " size: " + testFile.length());
++ return testFile;
++ }
++
++ protected void checkMixins(String[] mixins, NodeImpl node) throws RepositoryException
++ {
++ try
++ {
++ String[] nodeMixins = node.getMixinTypeNames();
++ assertEquals("Mixins count is different", mixins.length, nodeMixins.length);
++
++ compareMixins(mixins, nodeMixins);
++ }
++ catch (RepositoryException e)
++ {
++ fail("Mixins isn't accessible on the node " + node.getPath());
++ }
++ }
++
++ protected void compareMixins(String[] mixins, String[] nodeMixins)
++ {
++ nextMixin : for (String mixin : mixins)
++ {
++ for (String nodeMixin : nodeMixins)
++ {
++ if (mixin.equals(nodeMixin))
++ continue nextMixin;
++ }
++
++ fail("Mixin '" + mixin + "' isn't accessible");
++ }
++ }
++
++ protected String memoryInfo()
++ {
++ String info = "";
++ info =
++ "free: " + mb(Runtime.getRuntime().freeMemory()) + "M of " + mb(Runtime.getRuntime().totalMemory())
++ + "M (max: " + mb(Runtime.getRuntime().maxMemory()) + "M)";
++ return info;
++ }
++
++ // bytes to Mbytes
++ protected String mb(long mem)
++ {
++ return String.valueOf(Math.round(mem * 100d / (1024d * 1024d)) / 100d);
++ }
++
++ protected String execTime(long from)
++ {
++ return Math.round(((System.currentTimeMillis() - from) * 100.00d / 60000.00d)) / 100.00d + "min";
++ }
++
++ public void checkItemStatesIterator(Iterator<ItemState> expected, Iterator<ItemState> changes, boolean checklast,
++ boolean isRepValDat) throws Exception
++ {
++
++ while (expected.hasNext())
++ {
++
++ assertTrue(changes.hasNext());
++ ItemState expect = expected.next();
++ ItemState elem = changes.next();
++
++ assertEquals(expect.getState(), elem.getState());
++ // assertEquals(expect.getAncestorToSave(), elem.getAncestorToSave());
++ ItemData expData = expect.getData();
++ ItemData elemData = elem.getData();
++ assertEquals(expData.getQPath(), elemData.getQPath());
++ assertEquals(expData.isNode(), elemData.isNode());
++ assertEquals(expData.getIdentifier(), elemData.getIdentifier());
++ assertEquals(expData.getParentIdentifier(), elemData.getParentIdentifier());
++
++ if (!expData.isNode())
++ {
++ PropertyData expProp = (PropertyData)expData;
++ PropertyData elemProp = (PropertyData)elemData;
++ assertEquals(expProp.getType(), elemProp.getType());
++ assertEquals(expProp.isMultiValued(), elemProp.isMultiValued());
++
++ List<ValueData> expValDat = expProp.getValues();
++ List<ValueData> elemValDat = elemProp.getValues();
++ assertEquals(expValDat.size(), elemValDat.size());
++ for (int j = 0; j < expValDat.size(); j++)
++ {
++ assertTrue(java.util.Arrays
++ .equals(expValDat.get(j).getAsByteArray(), elemValDat.get(j).getAsByteArray()));
++
++ /*if (isRepValDat) {
++ // check is received property values ReplicableValueData
++ assertTrue(elemValDat.get(j) instanceof ReplicableValueData);
++ }*/
++ }
++ }
++ }
++
++ if (checklast)
++ {
++ assertFalse(changes.hasNext());
++ }
++
++ }
++}
13 years, 6 months