mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merged DEV/3.1_ENTERPRISE_ONLY to HEAD
12465: Supporting changes for enterprise-only monitoring code. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12495 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -64,6 +64,12 @@
|
||||
-->
|
||||
<import resource="classpath*:alfresco/module-context.xml" />
|
||||
|
||||
|
||||
<!--
|
||||
Import Enterprise-Only Extensions
|
||||
-->
|
||||
<import resource="classpath*:alfresco/enterprise/*-context.xml"/>
|
||||
|
||||
<!--
|
||||
Import of general extensions and bean overrides.
|
||||
|
||||
|
@@ -383,6 +383,26 @@
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="checkCommand">
|
||||
<bean name="transformer.ImageMagick.CheckCommand" class="org.alfresco.util.exec.RuntimeExec">
|
||||
<property name="commandsAndArguments">
|
||||
<map>
|
||||
<entry key="Windows.*">
|
||||
<list>
|
||||
<value>imconvert</value>
|
||||
<value>-version</value>
|
||||
</list>
|
||||
</entry>
|
||||
<entry key=".*">
|
||||
<list>
|
||||
<value>convert</value>
|
||||
<value>-version</value>
|
||||
</list>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
@@ -53,7 +53,9 @@
|
||||
|
||||
|
||||
<!-- Custom MBeanServer -->
|
||||
<bean id="alfrescoMBeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
|
||||
<bean id="alfrescoMBeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
|
||||
<property name="locateExistingServerIfPossible" value="true" />
|
||||
</bean>
|
||||
|
||||
<bean id="registry"
|
||||
class="org.springframework.remoting.rmi.RmiRegistryFactoryBean"
|
||||
@@ -85,10 +87,7 @@
|
||||
<property name="beans">
|
||||
<map>
|
||||
<!-- MBeans to register with alfrescoMBeanServer -->
|
||||
<entry key="Alfresco:Name=VirtServerRegistry,Type=VirtServerRegistry" value-ref="VirtServerRegistry"/>
|
||||
<entry key="Alfresco:Name=FileServerConfig,Type=FileServerConfig" value-ref="FileServerConfig"/>
|
||||
<entry key="Alfresco:Name=Log4jHierarchy,Type=Log4JHierarchy" value-ref="log4jHierarchy"/>
|
||||
<entry key="Alfresco:Name=RepoServerMgmt,Type=RepoServerMgmt" value-ref="RepoServerMgmt"/>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
@@ -131,7 +130,8 @@
|
||||
<!-- Log4J Hierarchy -->
|
||||
<bean id="log4jHierarchy" class="org.apache.log4j.jmx.HierarchyDynamicMBean"/>
|
||||
|
||||
<bean id="log4JHierarchyInit" class="org.alfresco.repo.admin.Log4JHierarchyInit" init-method="init">
|
||||
<!-- This bean will attempt to export extra beans to log4jHierarchy's MBeanServer, so it's vital that the exporter has been initialised -->
|
||||
<bean id="log4JHierarchyInit" class="org.alfresco.repo.admin.Log4JHierarchyInit" depends-on="exporter" init-method="init">
|
||||
<property name="log4jHierarchy" ref="log4jHierarchy"/>
|
||||
|
||||
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
|
||||
@@ -197,6 +197,9 @@
|
||||
<!-- Installed AMP modules -->
|
||||
<value>classpath*:alfresco/module/*/log4j.properties</value>
|
||||
|
||||
<!-- Enterprise extensions -->
|
||||
<value>classpath*:alfresco/enterprise/*-log4j.properties</value>
|
||||
|
||||
<!-- Other installed extensions -->
|
||||
<value>classpath*:alfresco/extension/*-log4j.properties</value>
|
||||
|
||||
|
@@ -3,6 +3,24 @@
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="resourceFinder" class="org.alfresco.util.ResourceFinder"/>
|
||||
|
||||
<bean id="schedulerResources" factory-bean="resourceFinder" factory-method="getResources">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<value>classpath:alfresco/domain/quartz.properties</value>
|
||||
<value>classpath*:alfresco/enterprise/*-quartz.properties</value>
|
||||
<value>classpath*:alfresco/extension/*-quartz.properties</value>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="schedulerProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
|
||||
<property name="locations">
|
||||
<ref bean="schedulerResources" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Task scheduler -->
|
||||
<!-- Triggers should not appear here - the scheduler should be injected into the trigger definition -->
|
||||
<!-- This bean should not need to apear else where in extension configuration -->
|
||||
@@ -10,8 +28,8 @@
|
||||
<property name="waitForJobsToCompleteOnShutdown">
|
||||
<value>true</value>
|
||||
</property>
|
||||
<property name="configLocation">
|
||||
<value>classpath:alfresco/domain/quartz.properties</value>
|
||||
<property name="quartzProperties">
|
||||
<ref bean="schedulerProperties" />
|
||||
</property>
|
||||
<property name="schedulerName">
|
||||
<value>DefaultScheduler</value>
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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<ContentServicePolicies.OnContentUpdatePolicy> onContentUpdateDelegate;
|
||||
ClassPolicyDelegate<ContentServicePolicies.OnContentReadPolicy> 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"),
|
||||
|
@@ -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
|
||||
|
@@ -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<String, FileContentStore> tenantFileStores = new HashMap<String, FileContentStore>();
|
||||
|
||||
private String defaultRootDirectory;
|
||||
private TenantService tenantService;
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
|
||||
public void setDefaultRootDir(String defaultRootDirectory)
|
||||
@@ -60,6 +65,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)
|
||||
{
|
||||
return getTenantFileStore(tenantService.getCurrentUserDomain());
|
||||
@@ -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()
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
{
|
||||
/**
|
||||
* <b>store</b> 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 <tt>true</tt> always
|
||||
* @return Returns <tt>true</tt> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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());
|
||||
|
@@ -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());
|
||||
|
@@ -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());
|
||||
|
@@ -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();
|
||||
|
@@ -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<ContentStore>(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)
|
||||
|
@@ -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;
|
||||
|
||||
@@ -54,6 +55,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
|
||||
*/
|
||||
@@ -80,6 +87,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
|
||||
* {@link #transformInternal(File, File) transformation method} to check
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -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<LuceneIndexerAndSearcher> factories;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private NodeService nodeService;
|
||||
|
||||
private String targetLocation;
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -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
|
||||
*/
|
||||
@@ -313,6 +324,8 @@ public class IndexInfo
|
||||
|
||||
private LuceneConfig config;
|
||||
|
||||
private List<ApplicationListener> applicationListeners = new LinkedList<ApplicationListener>();
|
||||
|
||||
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<Object>
|
||||
@@ -1501,6 +1527,7 @@ public class IndexInfo
|
||||
{
|
||||
throw new IndexerException("Invalid transition for " + id + " from " + entry.getStatus() + " to " + TransactionStatus.COMMITTED);
|
||||
}
|
||||
notifyListeners("CommittedTransactions", 1);
|
||||
}
|
||||
|
||||
public boolean requiresFileLock()
|
||||
@@ -3221,6 +3248,8 @@ public class IndexInfo
|
||||
|
||||
dumpInfo();
|
||||
|
||||
notifyListeners("MergedDeletions", toDelete.size());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -3230,6 +3259,7 @@ public class IndexInfo
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -3475,6 +3505,8 @@ public class IndexInfo
|
||||
|
||||
registerReferenceCountingIndexReader(finalMergeTargetId, finalNewReader);
|
||||
|
||||
notifyListeners("MergedIndexes", toMerge.size());
|
||||
|
||||
dumpInfo();
|
||||
|
||||
writeStatus();
|
||||
@@ -3634,9 +3666,200 @@ public class IndexInfo
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getRelativePath()
|
||||
*/
|
||||
public String getRelativePath()
|
||||
{
|
||||
return this.relativePath;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getStatusSnapshot()
|
||||
*/
|
||||
public Map<String, Integer> getStatusSnapshot()
|
||||
{
|
||||
Map<String, Integer> snapShot = new TreeMap<String, Integer>();
|
||||
readWriteLock.writeLock().lock();
|
||||
try
|
||||
{
|
||||
for (IndexEntry entry : indexEntries.values())
|
||||
{
|
||||
String stateKey = entry.getType() + "-" + entry.getStatus();
|
||||
Integer count = snapShot.get(stateKey);
|
||||
snapShot.put(stateKey, count == null ? 1 : count + 1);
|
||||
}
|
||||
return snapShot;
|
||||
}
|
||||
finally
|
||||
{
|
||||
readWriteLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getActualSize()
|
||||
*/
|
||||
public long getActualSize() throws IOException
|
||||
{
|
||||
getReadLock();
|
||||
try
|
||||
{
|
||||
int size = 0;
|
||||
for (IndexEntry entry : this.indexEntries.values())
|
||||
{
|
||||
File location = new File(this.indexDirectory, entry.getName()).getCanonicalFile();
|
||||
File[] contents = location.listFiles();
|
||||
for (File file : contents)
|
||||
{
|
||||
if (file.isFile())
|
||||
{
|
||||
size += file.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
finally
|
||||
{
|
||||
releaseReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getUsedSize()
|
||||
*/
|
||||
public long getUsedSize() throws IOException
|
||||
{
|
||||
getReadLock();
|
||||
try
|
||||
{
|
||||
return sizeRecurse(this.indexDirectory);
|
||||
}
|
||||
finally
|
||||
{
|
||||
releaseReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getNumberOfDocuments()
|
||||
*/
|
||||
public int getNumberOfDocuments() throws IOException
|
||||
{
|
||||
IndexReader reader = getMainIndexReferenceCountingReadOnlyIndexReader();
|
||||
try
|
||||
{
|
||||
return reader.numDocs();
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getNumberOfFields()
|
||||
*/
|
||||
public int getNumberOfFields() throws IOException
|
||||
{
|
||||
|
||||
IndexReader reader = getMainIndexReferenceCountingReadOnlyIndexReader();
|
||||
try
|
||||
{
|
||||
return reader.getFieldNames(IndexReader.FieldOption.ALL).size();
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getNumberOfIndexedFields()
|
||||
*/
|
||||
public int getNumberOfIndexedFields() throws IOException
|
||||
{
|
||||
IndexReader reader = getMainIndexReferenceCountingReadOnlyIndexReader();
|
||||
try
|
||||
{
|
||||
return reader.getFieldNames(IndexReader.FieldOption.INDEXED).size();
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#addApplicationListener(org.springframework.context.
|
||||
* ApplicationListener)
|
||||
*/
|
||||
public void addApplicationListener(ApplicationListener listener)
|
||||
{
|
||||
this.applicationListeners.add(listener);
|
||||
}
|
||||
|
||||
private long sizeRecurse(File fileOrDir)
|
||||
{
|
||||
long size = 0;
|
||||
if (fileOrDir.isDirectory())
|
||||
{
|
||||
File[] files = fileOrDir.listFiles();
|
||||
for (File file : files)
|
||||
{
|
||||
size += sizeRecurse(file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size = fileOrDir.length();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
private void publishDiscoveryEvent()
|
||||
{
|
||||
final IndexEvent discoveryEvent = new IndexEvent(this, "Discovery", 1);
|
||||
final ConfigurableApplicationContext applicationContext = this.config.getApplicationContext();
|
||||
try
|
||||
{
|
||||
applicationContext.publishEvent(discoveryEvent);
|
||||
}
|
||||
catch (IllegalStateException e)
|
||||
{
|
||||
// There's a possibility that the application context hasn't fully refreshed yet, so register a listener
|
||||
// that will fire when it has
|
||||
applicationContext.addApplicationListener(new ApplicationListener()
|
||||
{
|
||||
|
||||
public void onApplicationEvent(ApplicationEvent event)
|
||||
{
|
||||
if (event instanceof ContextRefreshedEvent)
|
||||
{
|
||||
applicationContext.publishEvent(discoveryEvent);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListeners(String description, int count)
|
||||
{
|
||||
if (!this.applicationListeners.isEmpty())
|
||||
{
|
||||
IndexEvent event = new IndexEvent(this, description, count);
|
||||
for (ApplicationListener listener : this.applicationListeners)
|
||||
{
|
||||
listener.onApplicationEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Schedulable
|
||||
{
|
||||
void schedule();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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 java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.ApplicationListener;
|
||||
|
||||
/**
|
||||
* An interface that exposes information about a Lucene Index and that allows registration of a listener for event
|
||||
* notifications.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public interface IndexMonitor
|
||||
{
|
||||
/**
|
||||
* Gets the relative path of the index directory.
|
||||
*
|
||||
* @return the relative path
|
||||
*/
|
||||
public String getRelativePath();
|
||||
|
||||
/**
|
||||
* Gets a snapshot of the statuses of the individual entries in this index.
|
||||
*
|
||||
* @return a map of entry status names to entry counts
|
||||
*/
|
||||
public Map<String, Integer> getStatusSnapshot();
|
||||
|
||||
/**
|
||||
* Gets the actual size of the index in bytes.
|
||||
*
|
||||
* @return the actual size in bytes
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public long getActualSize() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the size used on disk by the index directory. A large discrepancy from the value returned by
|
||||
* {@link #getActualSize()} may indicate that there are unused data files.
|
||||
*
|
||||
* @return the size on disk in bytes
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public long getUsedSize() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the number of documents in the index.
|
||||
*
|
||||
* @return the number of documents
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public int getNumberOfDocuments() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the number of fields known to the index.
|
||||
*
|
||||
* @return the number of fields
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public int getNumberOfFields() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the number of indexed fields.
|
||||
*
|
||||
* @return the number of indexed fields
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public int getNumberOfIndexedFields() throws IOException;
|
||||
|
||||
/**
|
||||
* Registers a listener for events on this index.
|
||||
*
|
||||
* @param listener
|
||||
* the listener
|
||||
*/
|
||||
public void addApplicationListener(ApplicationListener listener);
|
||||
}
|
@@ -24,7 +24,7 @@
|
||||
*/
|
||||
package org.alfresco.util;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ public class ApplicationContextHelper
|
||||
*
|
||||
* @return Returns a new application context
|
||||
*/
|
||||
public synchronized static ApplicationContext getApplicationContext()
|
||||
public synchronized static ConfigurableApplicationContext getApplicationContext()
|
||||
{
|
||||
if (instance != null)
|
||||
{
|
||||
|
62
source/java/org/alfresco/util/OpenOfficeConnectionEvent.java
Normal file
62
source/java/org/alfresco/util/OpenOfficeConnectionEvent.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* A class of event that notifies the listener of the status of the Open Office Connection. Useful for Monitoring
|
||||
* purposes.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class OpenOfficeConnectionEvent extends ApplicationEvent
|
||||
{
|
||||
private static final long serialVersionUID = 8834274840220309384L;
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*
|
||||
* @param metaData
|
||||
* the meta data map
|
||||
*/
|
||||
public OpenOfficeConnectionEvent(Map<String, Object> metaData)
|
||||
{
|
||||
super(metaData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the meta data map.
|
||||
*
|
||||
* @return the meta data map
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> getMetaData()
|
||||
{
|
||||
return (Map<String, Object>) getSource();
|
||||
}
|
||||
}
|
@@ -24,8 +24,12 @@
|
||||
*/
|
||||
package org.alfresco.util;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.ConnectException;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.sf.jooreports.openoffice.connection.AbstractOpenOfficeConnection;
|
||||
import net.sf.jooreports.openoffice.connection.OpenOfficeConnection;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
@@ -37,8 +41,14 @@ import org.quartz.Job;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import com.sun.star.registry.RegistryValueType;
|
||||
import com.sun.star.registry.XRegistryKey;
|
||||
import com.sun.star.registry.XSimpleRegistry;
|
||||
import com.sun.star.uno.UnoRuntime;
|
||||
|
||||
/**
|
||||
* A bootstrap class that checks for the presence of a valid <b>OpenOffice</b> connection, as provided by the
|
||||
* <code>net.sf.jooreports.openoffice.connection.OpenOfficeConnection</code> implementations.
|
||||
@@ -47,6 +57,7 @@ import org.springframework.context.ApplicationEvent;
|
||||
*/
|
||||
public class OpenOfficeConnectionTester extends AbstractLifecycleBean
|
||||
{
|
||||
private static final String ATTRIBUTE_AVAILABLE = "available";
|
||||
private static final String INFO_CONNECTION_VERIFIED = "system.openoffice.info.connection_verified";
|
||||
private static final String ERR_CONNECTION_FAILED = "system.openoffice.err.connection_failed";
|
||||
private static final String ERR_CONNECTION_LOST = "system.openoffice.err.connection_lost";
|
||||
@@ -55,6 +66,7 @@ public class OpenOfficeConnectionTester extends AbstractLifecycleBean
|
||||
private static Log logger = LogFactory.getLog(OpenOfficeConnectionTester.class);
|
||||
|
||||
private OpenOfficeConnection connection;
|
||||
private Map<String, Object> openOfficeMetadata = new TreeMap<String, Object>();
|
||||
private boolean strict;
|
||||
|
||||
public OpenOfficeConnectionTester()
|
||||
@@ -87,6 +99,7 @@ public class OpenOfficeConnectionTester extends AbstractLifecycleBean
|
||||
protected void onBootstrap(ApplicationEvent event)
|
||||
{
|
||||
checkConnection();
|
||||
((ApplicationContext) event.getSource()).publishEvent(new OpenOfficeConnectionEvent(this.openOfficeMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +122,7 @@ public class OpenOfficeConnectionTester extends AbstractLifecycleBean
|
||||
* then a disconnected {@link #setConnection(OpenOfficeConnection) connection} will result in a
|
||||
* runtime exception being generated.
|
||||
*/
|
||||
private synchronized void checkConnection()
|
||||
private void checkConnection()
|
||||
{
|
||||
String connectedMessage = I18NUtil.getMessage(INFO_CONNECTION_VERIFIED);
|
||||
boolean connected = testAndConnect();
|
||||
@@ -134,24 +147,66 @@ public class OpenOfficeConnectionTester extends AbstractLifecycleBean
|
||||
|
||||
public boolean testAndConnect()
|
||||
{
|
||||
PropertyCheck.mandatory(this, "connection", connection);
|
||||
if (connection.isConnected())
|
||||
synchronized (this.openOfficeMetadata)
|
||||
{
|
||||
// the connection is fine
|
||||
return true;
|
||||
}
|
||||
// attempt to make the connection
|
||||
try
|
||||
{
|
||||
connection.connect();
|
||||
// that worked
|
||||
return true;
|
||||
}
|
||||
catch (ConnectException e)
|
||||
{
|
||||
// No luck
|
||||
return false;
|
||||
PropertyCheck.mandatory(this, "connection", connection);
|
||||
if (!connection.isConnected())
|
||||
{
|
||||
try
|
||||
{
|
||||
connection.connect();
|
||||
}
|
||||
catch (ConnectException e)
|
||||
{
|
||||
// No luck
|
||||
this.openOfficeMetadata.clear();
|
||||
this.openOfficeMetadata.put(ATTRIBUTE_AVAILABLE, Boolean.FALSE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Let's try to get at the version metadata
|
||||
Boolean lastAvailability = (Boolean)this.openOfficeMetadata.get(ATTRIBUTE_AVAILABLE);
|
||||
if (lastAvailability == null || !lastAvailability.booleanValue())
|
||||
{
|
||||
this.openOfficeMetadata.put(ATTRIBUTE_AVAILABLE, Boolean.TRUE);
|
||||
try
|
||||
{
|
||||
// We have to peak inside the connection class to get the service we want!
|
||||
Method getServiceMethod = AbstractOpenOfficeConnection.class.getDeclaredMethod("getService",
|
||||
String.class);
|
||||
getServiceMethod.setAccessible(true);
|
||||
Object configurationRegistry = getServiceMethod.invoke(connection,
|
||||
"com.sun.star.configuration.ConfigurationRegistry");
|
||||
XSimpleRegistry registry = (XSimpleRegistry) UnoRuntime.queryInterface(
|
||||
com.sun.star.registry.XSimpleRegistry.class, configurationRegistry);
|
||||
registry.open("org.openoffice.Setup", true, false);
|
||||
XRegistryKey root = registry.getRootKey();
|
||||
XRegistryKey product = root.openKey("Product");
|
||||
for (XRegistryKey key : product.openKeys())
|
||||
{
|
||||
switch (key.getValueType().getValue())
|
||||
{
|
||||
case RegistryValueType.LONG_value:
|
||||
openOfficeMetadata.put(key.getKeyName(), key.getLongValue());
|
||||
break;
|
||||
case RegistryValueType.ASCII_value:
|
||||
openOfficeMetadata.put(key.getKeyName(), key.getAsciiValue());
|
||||
break;
|
||||
case RegistryValueType.STRING_value:
|
||||
openOfficeMetadata.put(key.getKeyName(), key.getStringValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
registry.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.warn("Error trying to query Open Office version information", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
92
source/java/org/alfresco/util/ResourceFinder.java
Normal file
92
source/java/org/alfresco/util/ResourceFinder.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
|
||||
/**
|
||||
* Can be used in Spring configuration to search for all resources matching an array of patterns.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class ResourceFinder extends PathMatchingResourcePatternResolver
|
||||
{
|
||||
/**
|
||||
* Instantiates a new resource finder.
|
||||
*/
|
||||
public ResourceFinder()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*
|
||||
* @param classLoader
|
||||
* the class loader
|
||||
*/
|
||||
public ResourceFinder(ClassLoader classLoader)
|
||||
{
|
||||
super(classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*
|
||||
* @param resourceLoader
|
||||
* the resource loader
|
||||
*/
|
||||
public ResourceFinder(ResourceLoader resourceLoader)
|
||||
{
|
||||
super(resourceLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of resources matching the given location patterns.
|
||||
*
|
||||
* @param locationPatterns
|
||||
* the location patterns
|
||||
* @return the matching resources, ordered by locationPattern index and location in the classpath
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public Resource[] getResources(String[] locationPatterns) throws IOException
|
||||
{
|
||||
List<Resource> resources = new LinkedList<Resource>();
|
||||
for (String locationPattern : locationPatterns)
|
||||
{
|
||||
resources.addAll(Arrays.asList(getResources(locationPattern)));
|
||||
}
|
||||
Resource[] resourceArray = new Resource[resources.size()];
|
||||
resources.toArray(resourceArray);
|
||||
return resourceArray;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user