diff --git a/config/alfresco/application-context.xml b/config/alfresco/application-context.xml
index 58739f596a..4c104d7706 100644
--- a/config/alfresco/application-context.xml
+++ b/config/alfresco/application-context.xml
@@ -64,6 +64,12 @@
-->
+
+
+
+
-
+
+
+
@@ -131,7 +130,8 @@
-
+
+
@@ -197,6 +197,9 @@
classpath*:alfresco/module/*/log4j.properties
+
+ classpath*:alfresco/enterprise/*-log4j.properties
+
classpath*:alfresco/extension/*-log4j.properties
diff --git a/config/alfresco/scheduled-jobs-context.xml b/config/alfresco/scheduled-jobs-context.xml
index 44b5eb0ec2..1db34c306a 100644
--- a/config/alfresco/scheduled-jobs-context.xml
+++ b/config/alfresco/scheduled-jobs-context.xml
@@ -3,6 +3,24 @@
+
+
+
+
+
+ classpath:alfresco/domain/quartz.properties
+ classpath*:alfresco/enterprise/*-quartz.properties
+ classpath*:alfresco/extension/*-quartz.properties
+
+
+
+
+
+
+
+
+
+
@@ -10,8 +28,8 @@
true
-
- classpath:alfresco/domain/quartz.properties
+
+ DefaultScheduler
diff --git a/source/java/org/alfresco/repo/content/AbstractReadOnlyContentStoreTest.java b/source/java/org/alfresco/repo/content/AbstractReadOnlyContentStoreTest.java
index 43a01efc1d..9a02579eb6 100644
--- a/source/java/org/alfresco/repo/content/AbstractReadOnlyContentStoreTest.java
+++ b/source/java/org/alfresco/repo/content/AbstractReadOnlyContentStoreTest.java
@@ -40,7 +40,7 @@ import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
/**
* Abstract base class that provides a set of tests for implementations
@@ -54,7 +54,7 @@ import org.springframework.context.ApplicationContext;
*/
public abstract class AbstractReadOnlyContentStoreTest extends TestCase
{
- private static final ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
+ protected static final ConfigurableApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
private static Log logger = LogFactory.getLog(AbstractReadOnlyContentStoreTest.class);
diff --git a/source/java/org/alfresco/repo/content/RoutingContentService.java b/source/java/org/alfresco/repo/content/RoutingContentService.java
index fdb13d6f85..fe4a9b884b 100644
--- a/source/java/org/alfresco/repo/content/RoutingContentService.java
+++ b/source/java/org/alfresco/repo/content/RoutingContentService.java
@@ -69,6 +69,10 @@ import org.alfresco.util.Pair;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
/**
@@ -77,7 +81,7 @@ import org.apache.commons.logging.LogFactory;
*
* @author Derek Hulley
*/
-public class RoutingContentService implements ContentService
+public class RoutingContentService implements ContentService, ApplicationContextAware
{
private static Log logger = LogFactory.getLog(RoutingContentService.class);
@@ -85,6 +89,7 @@ public class RoutingContentService implements ContentService
private NodeService nodeService;
private AVMService avmService;
private RetryingTransactionHelper transactionHelper;
+ private ApplicationContext applicationContext;
/** a registry of all available content transformers */
private ContentTransformerRegistry transformerRegistry;
@@ -105,14 +110,6 @@ public class RoutingContentService implements ContentService
ClassPolicyDelegate onContentUpdateDelegate;
ClassPolicyDelegate onContentReadDelegate;
- /**
- * Default constructor sets up a temporary store
- */
- public RoutingContentService()
- {
- this.tempStore = new FileContentStore(TempFileProvider.getTempDir().getAbsolutePath());
- }
-
/**
* @deprecated Replaced by {@link #setRetryingTransactionHelper(RetryingTransactionHelper)}
*/
@@ -161,11 +158,24 @@ public class RoutingContentService implements ContentService
this.imageMagickContentTransformer = imageMagickContentTransformer;
}
+
+ /* (non-Javadoc)
+ * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
+ */
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
+ {
+ this.applicationContext = applicationContext;
+ }
+
/**
* Service initialise
*/
public void init()
{
+ // Set up a temporary store
+ this.tempStore = new FileContentStore((ConfigurableApplicationContext) this.applicationContext,
+ TempFileProvider.getTempDir().getAbsolutePath());
+
// Bind on update properties behaviour
this.policyComponent.bindClassBehaviour(
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
diff --git a/source/java/org/alfresco/repo/content/RoutingContentStoreTest.java b/source/java/org/alfresco/repo/content/RoutingContentStoreTest.java
index 81cfb2e443..3fb6a2c081 100644
--- a/source/java/org/alfresco/repo/content/RoutingContentStoreTest.java
+++ b/source/java/org/alfresco/repo/content/RoutingContentStoreTest.java
@@ -65,13 +65,13 @@ public class RoutingContentStoreTest extends AbstractWritableContentStoreTest
File tempDir = TempFileProvider.getTempDir();
// Create a subdirectory for A
File storeADir = new File(tempDir, "A");
- storeA = new FileContentStore(storeADir);
+ storeA = new FileContentStore(ctx, storeADir);
// Create a subdirectory for B
File storeBDir = new File(tempDir, "B");
- storeB = new FileContentStore(storeBDir);
+ storeB = new FileContentStore(ctx, storeBDir);
// Create a subdirectory for C
File storeCDir = new File(tempDir, "C");
- storeC = new DumbReadOnlyFileStore(new FileContentStore(storeCDir));
+ storeC = new DumbReadOnlyFileStore(new FileContentStore(ctx, storeCDir));
// No subdirectory for D
storeD = new SupportsNoUrlFormatStore();
// Create the routing store
diff --git a/source/java/org/alfresco/repo/content/TenantRoutingFileContentStore.java b/source/java/org/alfresco/repo/content/TenantRoutingFileContentStore.java
index 40f504caa7..d202287a3f 100755
--- a/source/java/org/alfresco/repo/content/TenantRoutingFileContentStore.java
+++ b/source/java/org/alfresco/repo/content/TenantRoutingFileContentStore.java
@@ -36,18 +36,23 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.Tenant;
import org.alfresco.repo.tenant.TenantDeployer;
import org.alfresco.repo.tenant.TenantService;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
/**
* Content Store that supports tenant routing, if multi-tenancy is enabled.
*
* Note: Need to initialise before the dictionary service, in the case that models are dynamically loaded for the tenant.
*/
-public class TenantRoutingFileContentStore extends AbstractRoutingContentStore implements TenantDeployer
+public class TenantRoutingFileContentStore extends AbstractRoutingContentStore implements TenantDeployer, ApplicationContextAware
{
Map tenantFileStores = new HashMap();
private String defaultRootDirectory;
private TenantService tenantService;
+ private ApplicationContext applicationContext;
public void setDefaultRootDir(String defaultRootDirectory)
@@ -59,6 +64,16 @@ public class TenantRoutingFileContentStore extends AbstractRoutingContentStore i
{
this.tenantService = tenantService;
}
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.
+ * ApplicationContext)
+ */
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
+ {
+ this.applicationContext = applicationContext;
+ }
protected ContentStore selectWriteStore(ContentContext ctx)
{
@@ -114,7 +129,8 @@ public class TenantRoutingFileContentStore extends AbstractRoutingContentStore i
tenantDomain = tenant.getTenantDomain();
}
- putTenantFileStore(tenantDomain, new FileContentStore(new File(rootDir)));
+ putTenantFileStore(tenantDomain, new FileContentStore((ConfigurableApplicationContext) this.applicationContext,
+ new File(rootDir)));
}
public void destroy()
diff --git a/source/java/org/alfresco/repo/content/cleanup/ContentStoreCleanerTest.java b/source/java/org/alfresco/repo/content/cleanup/ContentStoreCleanerTest.java
index 9662609c62..bee446676a 100644
--- a/source/java/org/alfresco/repo/content/cleanup/ContentStoreCleanerTest.java
+++ b/source/java/org/alfresco/repo/content/cleanup/ContentStoreCleanerTest.java
@@ -29,6 +29,8 @@ import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
+import junit.framework.TestCase;
+
import org.alfresco.repo.avm.AVMNodeDAO;
import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.content.filestore.FileContentStore;
@@ -42,9 +44,7 @@ import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.TempFileProvider;
-import org.springframework.context.ApplicationContext;
-
-import junit.framework.TestCase;
+import org.springframework.context.ConfigurableApplicationContext;
/**
* @see org.alfresco.repo.content.cleanup.ContentStoreCleaner
@@ -53,7 +53,7 @@ import junit.framework.TestCase;
*/
public class ContentStoreCleanerTest extends TestCase
{
- private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
+ private static ConfigurableApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
private ContentStoreCleaner cleaner;
private ContentStore store;
@@ -71,7 +71,7 @@ public class ContentStoreCleanerTest extends TestCase
ContentUrlDAO contentUrlDAO = (ContentUrlDAO) ctx.getBean("contentUrlDAO");
// we need a store
- store = new FileContentStore(TempFileProvider.getTempDir().getAbsolutePath());
+ store = new FileContentStore(ctx, TempFileProvider.getTempDir().getAbsolutePath());
// and a listener
listener = new DummyCleanerListener();
// initialise record of deleted URLs
diff --git a/source/java/org/alfresco/repo/content/filestore/FileContentStore.java b/source/java/org/alfresco/repo/content/filestore/FileContentStore.java
index b7629e719c..b221577067 100644
--- a/source/java/org/alfresco/repo/content/filestore/FileContentStore.java
+++ b/source/java/org/alfresco/repo/content/filestore/FileContentStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007 Alfresco Software Limited.
+ * Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -18,7 +18,7 @@
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
- * FLOSS exception. You should have recieved a copy of the text describing
+ * FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
@@ -43,6 +43,10 @@ import org.alfresco.util.GUID;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.event.ContextRefreshedEvent;
/**
* Provides a store of node content directly to the file system. The writers
@@ -53,7 +57,7 @@ import org.apache.commons.logging.LogFactory;
*
* @author Derek Hulley
*/
-public class FileContentStore extends AbstractContentStore
+public class FileContentStore extends AbstractContentStore implements ApplicationListener
{
/**
* store is the new prefix for file content URLs
@@ -69,21 +73,24 @@ public class FileContentStore extends AbstractContentStore
private boolean readOnly;
/**
- * @param rootDirectoryStr the root under which files will be stored.
- * The directory will be created if it does not exist.
- *
+ * Private: for Spring-constructed instances only.
+ *
+ * @param rootDirectoryStr
+ * the root under which files will be stored. The directory will be created if it does not exist.
* @see FileContentStore#FileContentStore(File)
*/
- public FileContentStore(String rootDirectoryStr)
+ private FileContentStore(String rootDirectoryStr)
{
this(new File(rootDirectoryStr));
}
/**
- * @param rootDirectory the root under which files will be stored.
- * The directory will be created if it does not exist.
+ * Private: for Spring-constructed instances only.
+ *
+ * @param rootDirectory
+ * the root under which files will be stored. The directory will be created if it does not exist.
*/
- public FileContentStore(File rootDirectory)
+ private FileContentStore(File rootDirectory)
{
if (!rootDirectory.exists())
{
@@ -98,6 +105,36 @@ public class FileContentStore extends AbstractContentStore
readOnly = false;
}
+ /**
+ * Public constructor for programmatic use.
+ *
+ * @param context
+ * application context through which events can be published
+ * @param rootDirectoryStr
+ * the root under which files will be stored. The directory will be created if it does not exist.
+ * @see FileContentStore#FileContentStore(File)
+ */
+ public FileContentStore(ConfigurableApplicationContext context, String rootDirectoryStr)
+ {
+ this(rootDirectoryStr);
+ publishEvent(context);
+ }
+
+ /**
+ * Public constructor for programmatic use.
+ *
+ * @param context
+ * application context through which events can be published
+ * @param rootDirectory
+ * the root under which files will be stored. The directory will be created if it does not exist.
+ */
+ public FileContentStore(ConfigurableApplicationContext context, File rootDirectory)
+ {
+ this(rootDirectory);
+ publishEvent(context);
+ }
+
+
public String toString()
{
StringBuilder sb = new StringBuilder(36);
@@ -159,9 +196,9 @@ public class FileContentStore extends AbstractContentStore
* @param newContentUrl the specific URL to use, which may not be in use
* @return Returns a new and unique file
* @throws IOException
- * if the file or parent directories couldn't be created or if the URL is already in use.
+ * if the file or parent directories couldn't be created or if the URL is already in use.
* @throws UnsupportedOperationException
- * if the store is read-only
+ * if the store is read-only
*
* @see #setReadOnly(boolean)
*/
@@ -298,7 +335,7 @@ public class FileContentStore extends AbstractContentStore
}
/**
- * @return Returns true always
+ * @return Returns true always
*/
public boolean isWriteSupported()
{
@@ -358,6 +395,12 @@ public class FileContentStore extends AbstractContentStore
}
/**
+ * Returns a writer onto a location based on the date.
+ *
+ * @param existingContentReader
+ * the existing content reader
+ * @param newContentUrl
+ * the new content url
* @return Returns a writer onto a location based on the date
*/
public ContentWriter getWriterInternal(ContentReader existingContentReader, String newContentUrl)
@@ -396,6 +439,17 @@ public class FileContentStore extends AbstractContentStore
}
}
+ /**
+ * Gets the urls.
+ *
+ * @param createdAfter
+ * the created after date
+ * @param createdBefore
+ * the created before dat6e
+ * @param handler
+ * the handler
+ * @return the urls
+ */
public void getUrls(Date createdAfter, Date createdBefore, ContentUrlHandler handler)
{
// recursively get all files within the root
@@ -409,11 +463,12 @@ public class FileContentStore extends AbstractContentStore
}
/**
+ * Returns a list of all files within the given directory and all subdirectories.
* @param directory the current directory to get the files from
* @param handler the callback to use for each URL
* @param createdAfter only get URLs for content create after this date
* @param createdBefore only get URLs for content created before this date
- * @return Returns a list of all files within the given directory and all subdirectories
+ * @return a list of all files within the given directory and all subdirectories
*/
private void getUrls(File directory, ContentUrlHandler handler, Date createdAfter, Date createdBefore)
{
@@ -516,4 +571,41 @@ public class FileContentStore extends AbstractContentStore
// done
return newContentUrl;
}
+
+ /**
+ * Publishes an event to the application context that will notify any interested parties of the existence of this
+ * content store.
+ *
+ * @param context
+ * the application context
+ */
+ private void publishEvent(ConfigurableApplicationContext context)
+ {
+ // If the context isn't running yet, we have to wait until the refresh event
+ try
+ {
+ // Neither context.isActive() or context.isRunning() seem to detect whether the refresh() has completed
+ context.publishEvent(new FileContentStoreCreatedEvent(this, rootDirectory));
+ }
+ catch (IllegalStateException e)
+ {
+ context.addApplicationListener(this);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
+ */
+ public void onApplicationEvent(ApplicationEvent event)
+ {
+ // Once the context has been refreshed, we tell other interested beans about the existence of this content store
+ // (e.g. for monitoring purposes)
+ if (event instanceof ContextRefreshedEvent)
+ {
+ ((ContextRefreshedEvent) event).getApplicationContext().publishEvent(
+ new FileContentStoreCreatedEvent(this, rootDirectory));
+ }
+ }
}
diff --git a/source/java/org/alfresco/repo/content/filestore/FileContentStoreCreatedEvent.java b/source/java/org/alfresco/repo/content/filestore/FileContentStoreCreatedEvent.java
new file mode 100644
index 0000000000..3bb3f0fa11
--- /dev/null
+++ b/source/java/org/alfresco/repo/content/filestore/FileContentStoreCreatedEvent.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2005-2008 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have received a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.repo.content.filestore;
+
+import java.io.File;
+
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * A class of event that notifies the listener of the existence of a {@link FileContentStore}. Useful for Monitoring
+ * purposes.
+ *
+ * @author dward
+ */
+public class FileContentStoreCreatedEvent extends ApplicationEvent
+{
+ private static final long serialVersionUID = 7090069096441126707L;
+
+ /** The root directory of the store. */
+ private final File rootDirectory;
+
+ /**
+ * The Constructor.
+ *
+ * @param source
+ * the source content store
+ * @param rootDirectory
+ * the root directory
+ */
+ public FileContentStoreCreatedEvent(FileContentStore source, File rootDirectory)
+ {
+ super(source);
+ this.rootDirectory = rootDirectory;
+ }
+
+ /**
+ * Gets the root directory.
+ *
+ * @return the root directory
+ */
+ public File getRootDirectory()
+ {
+ return this.rootDirectory;
+ }
+}
diff --git a/source/java/org/alfresco/repo/content/filestore/FileContentStoreTest.java b/source/java/org/alfresco/repo/content/filestore/FileContentStoreTest.java
index 8a9cbdfc64..25c6c92d67 100644
--- a/source/java/org/alfresco/repo/content/filestore/FileContentStoreTest.java
+++ b/source/java/org/alfresco/repo/content/filestore/FileContentStoreTest.java
@@ -52,7 +52,7 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
// create a store that uses a subdirectory of the temp directory
File tempDir = TempFileProvider.getTempDir();
- store = new FileContentStore(
+ store = new FileContentStore(ctx,
tempDir.getAbsolutePath() +
File.separatorChar +
getName());
diff --git a/source/java/org/alfresco/repo/content/filestore/NoRandomAccessFileContentStoreTest.java b/source/java/org/alfresco/repo/content/filestore/NoRandomAccessFileContentStoreTest.java
index 4a6a5a3c3a..f376b2dd24 100644
--- a/source/java/org/alfresco/repo/content/filestore/NoRandomAccessFileContentStoreTest.java
+++ b/source/java/org/alfresco/repo/content/filestore/NoRandomAccessFileContentStoreTest.java
@@ -49,7 +49,7 @@ public class NoRandomAccessFileContentStoreTest extends AbstractWritableContentS
// create a store that uses a subdirectory of the temp directory
File tempDir = TempFileProvider.getTempDir();
- store = new FileContentStore(
+ store = new FileContentStore(ctx,
tempDir.getAbsolutePath() +
File.separatorChar +
getName());
diff --git a/source/java/org/alfresco/repo/content/filestore/ReadOnlyFileContentStoreTest.java b/source/java/org/alfresco/repo/content/filestore/ReadOnlyFileContentStoreTest.java
index af0bda971e..89a60ebe94 100644
--- a/source/java/org/alfresco/repo/content/filestore/ReadOnlyFileContentStoreTest.java
+++ b/source/java/org/alfresco/repo/content/filestore/ReadOnlyFileContentStoreTest.java
@@ -50,7 +50,7 @@ public class ReadOnlyFileContentStoreTest extends AbstractReadOnlyContentStoreTe
// create a store that uses a subdirectory of the temp directory
File tempDir = TempFileProvider.getTempDir();
- store = new FileContentStore(
+ store = new FileContentStore(ctx,
tempDir.getAbsolutePath() +
File.separatorChar +
getName());
diff --git a/source/java/org/alfresco/repo/content/replication/ContentStoreReplicatorTest.java b/source/java/org/alfresco/repo/content/replication/ContentStoreReplicatorTest.java
index 0f9f710838..9e92944486 100644
--- a/source/java/org/alfresco/repo/content/replication/ContentStoreReplicatorTest.java
+++ b/source/java/org/alfresco/repo/content/replication/ContentStoreReplicatorTest.java
@@ -30,7 +30,6 @@ import java.util.Set;
import junit.framework.TestCase;
-import org.alfresco.repo.content.AbstractContentStore;
import org.alfresco.repo.content.ContentContext;
import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.content.ContentStore.ContentUrlHandler;
@@ -38,6 +37,8 @@ import org.alfresco.repo.content.filestore.FileContentStore;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.util.GUID;
import org.alfresco.util.TempFileProvider;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.StaticApplicationContext;
/**
* Tests the content store replicator.
@@ -60,13 +61,17 @@ public class ContentStoreReplicatorTest extends TestCase
{
super.setUp();
+ // Create a dummy context for message broadcasting
+ StaticApplicationContext ctx = new StaticApplicationContext();
+ ctx.refresh();
+
File tempDir = TempFileProvider.getTempDir();
// create the source file store
String storeDir = tempDir.getAbsolutePath() + File.separatorChar + getName() + File.separatorChar + GUID.generate();
- sourceStore = new FileContentStore(storeDir);
+ sourceStore = new FileContentStore(ctx, storeDir);
// create the target file store
storeDir = tempDir.getAbsolutePath() + File.separatorChar + getName() + File.separatorChar + GUID.generate();
- targetStore = new FileContentStore(storeDir);
+ targetStore = new FileContentStore(ctx, storeDir);
// create the replicator
replicator = new ContentStoreReplicator();
diff --git a/source/java/org/alfresco/repo/content/replication/ReplicatingContentStoreTest.java b/source/java/org/alfresco/repo/content/replication/ReplicatingContentStoreTest.java
index 4cc8962cf4..d2e4d5efcb 100644
--- a/source/java/org/alfresco/repo/content/replication/ReplicatingContentStoreTest.java
+++ b/source/java/org/alfresco/repo/content/replication/ReplicatingContentStoreTest.java
@@ -70,13 +70,13 @@ public class ReplicatingContentStoreTest extends AbstractWritableContentStoreTes
File tempDir = TempFileProvider.getTempDir();
// create a primary file store
String storeDir = tempDir.getAbsolutePath() + File.separatorChar + GUID.generate();
- primaryStore = new FileContentStore(storeDir);
+ primaryStore = new FileContentStore(ctx, storeDir);
// create some secondary file stores
secondaryStores = new ArrayList(3);
for (int i = 0; i < 4; i++)
{
storeDir = tempDir.getAbsolutePath() + File.separatorChar + GUID.generate();
- FileContentStore store = new FileContentStore(storeDir);
+ FileContentStore store = new FileContentStore(ctx, storeDir);
secondaryStores.add(store);
// Only the first 3 are writable
if (i >= 3)
diff --git a/source/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformer.java b/source/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformer.java
index f7bf4da7b4..7fb4836ed5 100644
--- a/source/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformer.java
+++ b/source/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007 Alfresco Software Limited.
+ * Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -18,7 +18,7 @@
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
- * FLOSS exception. You should have recieved a copy of the text describing
+ * FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
@@ -32,6 +32,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.TransformationOptions;
import org.alfresco.util.exec.RuntimeExec;
+import org.alfresco.util.exec.RuntimeExec.ExecutionResult;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -53,6 +54,12 @@ public class ImageMagickContentTransformer extends AbstractImageMagickContentTra
/** the system command executer */
private RuntimeExec executer;
+
+ /** the check command executer */
+ private RuntimeExec checkCommand;
+
+ /** the output from the check command */
+ private String versionString;
/**
* Default constructor
@@ -79,6 +86,29 @@ public class ImageMagickContentTransformer extends AbstractImageMagickContentTra
{
this.executer = executer;
}
+
+
+ /**
+ * Sets the command that must be executed in order to retrieve version information from the converting executable
+ * and thus test that the executable itself is present.
+ *
+ * @param checkCommand
+ * command executer to retrieve version information
+ */
+ public void setCheckCommand(RuntimeExec checkCommand)
+ {
+ this.checkCommand = checkCommand;
+ }
+
+ /**
+ * Gets the version string captured from the check command.
+ *
+ * @return the version string
+ */
+ public String getVersionString()
+ {
+ return this.versionString;
+ }
/**
* Checks for the JMagick and ImageMagick dependencies, using the common
@@ -92,6 +122,30 @@ public class ImageMagickContentTransformer extends AbstractImageMagickContentTra
throw new AlfrescoRuntimeException("System runtime executer not set");
}
super.init();
+ if (isAvailable())
+ {
+ try
+ {
+ ExecutionResult result = this.checkCommand.execute();
+ if (result.getSuccess())
+ {
+ this.versionString = result.getStdOut().trim();
+ }
+ else
+ {
+ setAvailable(false);
+ }
+ }
+ catch (Throwable e)
+ {
+ setAvailable(false);
+ logger.error(getClass().getSimpleName() + " not available: "
+ + (e.getMessage() != null ? e.getMessage() : ""));
+ // debug so that we can trace the issue if required
+ logger.debug(e);
+ }
+
+ }
}
/**
diff --git a/source/java/org/alfresco/repo/content/transform/swf/PDFToSWFContentTransformer.java b/source/java/org/alfresco/repo/content/transform/swf/PDFToSWFContentTransformer.java
index 4ed02ef1ce..5b377a3a5b 100644
--- a/source/java/org/alfresco/repo/content/transform/swf/PDFToSWFContentTransformer.java
+++ b/source/java/org/alfresco/repo/content/transform/swf/PDFToSWFContentTransformer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007 Alfresco Software Limited.
+ * Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -18,7 +18,7 @@
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
- * FLOSS exception. You should have recieved a copy of the text describing
+ * FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
@@ -54,6 +54,9 @@ public class PDFToSWFContentTransformer extends AbstractContentTransformer2
/** Used to indicate whether the transformaer in available or not */
private boolean available = false;
+ /** Stores the output from the check command */
+ private String versionString;
+
/** Check and transform command */
private RuntimeExec checkCommand;
private RuntimeExec transformCommand;
@@ -130,15 +133,13 @@ public class PDFToSWFContentTransformer extends AbstractContentTransformer2
{
ExecutionResult result = getCheckCommand().execute();
// check the return code
- this.available = result.getSuccess();
- if (this.available == false)
+ if (this.available = result.getSuccess())
{
- logger.error("Failed to start SWF2PDF transformer: \n" + result);
+ this.versionString = result.getStdOut().trim();
}
else
{
- // no check - just assume it is available
- this.available = true;
+ logger.error("Failed to start SWF2PDF transformer: \n" + result);
}
// call the base class to make sure that it gets registered
@@ -249,4 +250,24 @@ public class PDFToSWFContentTransformer extends AbstractContentTransformer2
return result;
}
+
+ /**
+ * Signals whether this transformer is available.
+ *
+ * @return true, if is available
+ */
+ public boolean isAvailable()
+ {
+ return this.available;
+ }
+
+ /**
+ * Gets the version string captured from the check command.
+ *
+ * @return the version string
+ */
+ public String getVersionString()
+ {
+ return this.versionString;
+ }
}
diff --git a/source/java/org/alfresco/repo/descriptor/DescriptorServiceAvailableEvent.java b/source/java/org/alfresco/repo/descriptor/DescriptorServiceAvailableEvent.java
new file mode 100644
index 0000000000..b27065e64e
--- /dev/null
+++ b/source/java/org/alfresco/repo/descriptor/DescriptorServiceAvailableEvent.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2005-2008 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have received a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.repo.descriptor;
+
+import org.alfresco.service.descriptor.DescriptorService;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * A class of event that notifies the listener of the availability of the {@link DescriptorService}. Useful for
+ * Monitoring purposes.
+ *
+ * @author dward
+ */
+public class DescriptorServiceAvailableEvent extends ApplicationEvent
+{
+
+ private static final long serialVersionUID = 8217523101300405165L;
+
+ /**
+ * The Constructor.
+ *
+ * @param source
+ * the source descriptor service
+ */
+ public DescriptorServiceAvailableEvent(DescriptorService source)
+ {
+ super(source);
+ }
+
+ /**
+ * Gets the descriptor service that raised the event.
+ *
+ * @return the descriptor service
+ */
+ public DescriptorService getDescriptorService()
+ {
+ return (DescriptorService) getSource();
+ }
+}
diff --git a/source/java/org/alfresco/repo/descriptor/DescriptorServiceImpl.java b/source/java/org/alfresco/repo/descriptor/DescriptorServiceImpl.java
index 1334730bdb..74a22921fa 100644
--- a/source/java/org/alfresco/repo/descriptor/DescriptorServiceImpl.java
+++ b/source/java/org/alfresco/repo/descriptor/DescriptorServiceImpl.java
@@ -183,6 +183,8 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
};
installedRepoDescriptor = transactionService.getRetryingTransactionHelper().doInTransaction(
createDescriptorWork, transactionService.isReadOnly(), false);
+
+ ((ApplicationContext)event.getSource()).publishEvent(new DescriptorServiceAvailableEvent(this));
}
/*
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java b/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java
index 2986148e11..237a4eb270 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java
@@ -70,7 +70,11 @@ import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
+import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
/**
* This class is resource manager LuceneIndexers and LuceneSearchers. It supports two phase commit inside XA
@@ -80,7 +84,8 @@ import org.springframework.beans.factory.InitializingBean;
* @author andyh
*/
-public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneIndexerAndSearcher, XAResource
+public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneIndexerAndSearcher, XAResource,
+ ApplicationContextAware
{
private static Log logger = LogFactory.getLog(AbstractLuceneIndexerAndSearcherFactory.class);
@@ -180,6 +185,8 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
private boolean cacheEnabled = true;
+ private ConfigurableApplicationContext applicationContext;
+
/**
* Private constructor for the singleton TODO: FIt in with IOC
*/
@@ -189,6 +196,26 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
super();
}
+
+ /*
+ * (non-Javadoc)
+ * @seeorg.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.
+ * ApplicationContext)
+ */
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
+ {
+ this.applicationContext = (ConfigurableApplicationContext) applicationContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.repo.search.impl.lucene.LuceneConfig#getApplicationContext()
+ */
+ public ConfigurableApplicationContext getApplicationContext()
+ {
+ return this.applicationContext;
+ }
+
/**
* Set the directory that contains the indexes
*
@@ -995,7 +1022,6 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
private Set factories;
- @SuppressWarnings("unused")
private NodeService nodeService;
private String targetLocation;
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java
index 28b8a8d663..460a2377eb 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java
@@ -28,6 +28,7 @@ import java.util.concurrent.ThreadPoolExecutor;
import org.alfresco.repo.domain.hibernate.BulkLoader;
import org.alfresco.repo.search.MLAnalysisMode;
+import org.springframework.context.ConfigurableApplicationContext;
public interface LuceneConfig
{
@@ -208,4 +209,10 @@ public interface LuceneConfig
* @return
*/
public int getMaxLinkAspectCacheSize();
+
+ /**
+ * Gets the application context through which events can be broadcast
+ * @return
+ */
+ public ConfigurableApplicationContext getApplicationContext();
}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexEvent.java b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexEvent.java
new file mode 100644
index 0000000000..408ad2b903
--- /dev/null
+++ b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexEvent.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2005-2008 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have received a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.repo.search.impl.lucene.index;
+
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * A class of event that notifies the listener of a significant event relating to a Lucene index. Useful for Monitoring
+ * purposes.
+ *
+ * @author dward
+ */
+public class IndexEvent extends ApplicationEvent
+{
+
+ private static final long serialVersionUID = -4616231785087405506L;
+
+ /** The event description. */
+ private final String description;
+
+ /** Its instance count. */
+ private final int count;
+
+ /**
+ * The Constructor.
+ *
+ * @param source
+ * the source index monitor
+ * @param description
+ * the event description
+ * @param count
+ * its instance count
+ */
+ public IndexEvent(IndexMonitor source, String description, int count)
+ {
+ super(source);
+ this.description = description;
+ this.count = count;
+ }
+
+ /**
+ * Gets the source index monitor.
+ *
+ * @return the index monitor
+ */
+ public IndexMonitor getIndexMonitor()
+ {
+ return (IndexMonitor) getSource();
+ }
+
+ /**
+ * Gets the event description.
+ *
+ * @return the description
+ */
+ public String getDescription()
+ {
+ return this.description;
+ }
+
+ /**
+ * Gets the event instance count.
+ *
+ * @return the count
+ */
+ public int getCount()
+ {
+ return this.count;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java
index 999191c0df..964b6ddefb 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java
@@ -46,11 +46,13 @@ import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
+import java.util.TreeMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
@@ -84,6 +86,10 @@ import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.RAMDirectory;
import org.safehaus.uuid.UUID;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.event.ContextRefreshedEvent;
/**
* The information that makes up an index. IndexInfoVersion Repeated information of the form
@@ -118,7 +124,7 @@ import org.safehaus.uuid.UUID;
*
* @author Andy Hind
*/
-public class IndexInfo
+public class IndexInfo implements IndexMonitor
{
public static final String MAIN_READER = "MainReader";
@@ -164,6 +170,11 @@ public class IndexInfo
*/
private File indexDirectory;
+ /**
+ * The directory relative to the root path
+ */
+ private String relativePath;
+
/**
* The file holding the index information
*/
@@ -312,7 +323,9 @@ public class IndexInfo
private ThreadPoolExecutor threadPoolExecutor;
private LuceneConfig config;
-
+
+ private List applicationListeners = new LinkedList();
+
static
{
// We do not require any of the lucene in-built locking.
@@ -426,6 +439,17 @@ public class IndexInfo
throw new AlfrescoRuntimeException("The index must be held in a directory");
}
+ // Work out the relative path of the index
+ try
+ {
+ String indexRoot = new File(config.getIndexRootLocation()).getCanonicalPath();
+ this.relativePath = this.indexDirectory.getCanonicalPath().substring(indexRoot.length() + 1);
+ }
+ catch (IOException e)
+ {
+ throw new AlfrescoRuntimeException("Failed to determine index relative path", e);
+ }
+
// Create the info files.
File indexInfoFile = new File(this.indexDirectory, INDEX_INFO);
File indexInfoBackupFile = new File(this.indexDirectory, INDEX_INFO_BACKUP);
@@ -628,6 +652,8 @@ public class IndexInfo
cleaner.schedule();
}
}, 0, 20000);
+
+ publishDiscoveryEvent();
}
private class DeleteUnknownGuidDirectories implements LockWork