mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
MOB-659 (part 2 of 2) - improve dictionary cache reset (should work even with null / cache)
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14059 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -148,11 +148,6 @@
|
|||||||
<property name="transactionService" ref="transactionService"/>
|
<property name="transactionService" ref="transactionService"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- Bootstrap MT (multi-tenancy) if applicable -->
|
|
||||||
<bean id="multiTenantBootstrap" class="org.alfresco.repo.tenant.MultiTenantBootstrap" >
|
|
||||||
<property name="tenantAdminService" ref="tenantAdminService" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- Load models -->
|
<!-- Load models -->
|
||||||
<bean id="dictionaryRepositoryBootstrap" class="org.alfresco.repo.dictionary.DictionaryRepositoryBootstrap">
|
<bean id="dictionaryRepositoryBootstrap" class="org.alfresco.repo.dictionary.DictionaryRepositoryBootstrap">
|
||||||
|
|
||||||
@@ -278,6 +273,11 @@
|
|||||||
<property name="repositoryWorkflowDefsLocations" ref="customWorkflowDefsRepositoryLocation"/>
|
<property name="repositoryWorkflowDefsLocations" ref="customWorkflowDefsRepositoryLocation"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<!-- Bootstrap MT (multi-tenancy) if applicable -->
|
||||||
|
<bean id="multiTenantBootstrap" class="org.alfresco.repo.tenant.MultiTenantBootstrap" >
|
||||||
|
<property name="tenantAdminService" ref="tenantAdminService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="personDaoBootstrap" class="org.alfresco.repo.security.person.PersonDaoBootstrap" >
|
<bean id="personDaoBootstrap" class="org.alfresco.repo.security.person.PersonDaoBootstrap" >
|
||||||
<property name="personDaoImpl">
|
<property name="personDaoImpl">
|
||||||
<ref bean="personDaoImpl"/>
|
<ref bean="personDaoImpl"/>
|
||||||
|
@@ -636,39 +636,7 @@
|
|||||||
<!-- Dictionary / Namespace Caches -->
|
<!-- Dictionary / Namespace Caches -->
|
||||||
<!-- ===================================== -->
|
<!-- ===================================== -->
|
||||||
|
|
||||||
<!-- The cross-transaction shared cache for In-Memory UriToModels -->
|
<!-- The cross-transaction shared cache for Dictionary Models -->
|
||||||
|
|
||||||
<bean name="uriToModelsSharedCache" class="org.alfresco.repo.cache.EhCacheAdapter">
|
|
||||||
<property name="cache">
|
|
||||||
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean" >
|
|
||||||
<property name="cacheManager">
|
|
||||||
<ref bean="internalEHCacheManager" />
|
|
||||||
</property>
|
|
||||||
<property name="cacheName">
|
|
||||||
<value>org.alfresco.cache.uriToModelsCache</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- The transactional cache for In-Memory UriToModels -->
|
|
||||||
|
|
||||||
<bean name="uriToModelsCache" class="org.alfresco.repo.cache.TransactionalCache">
|
|
||||||
<property name="sharedCache">
|
|
||||||
<ref bean="uriToModelsSharedCache" />
|
|
||||||
</property>
|
|
||||||
<property name="cacheManager" >
|
|
||||||
<ref bean="transactionalEHCacheManager" />
|
|
||||||
</property>
|
|
||||||
<property name="name">
|
|
||||||
<value>org.alfresco.uriToModelsTransactionalCache</value>
|
|
||||||
</property>
|
|
||||||
<property name="maxCacheSize">
|
|
||||||
<value>100</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- The cross-transaction shared cache for In-Memory CompiledModels -->
|
|
||||||
|
|
||||||
<bean name="compiledModelsSharedCache" class="org.alfresco.repo.cache.EhCacheAdapter">
|
<bean name="compiledModelsSharedCache" class="org.alfresco.repo.cache.EhCacheAdapter">
|
||||||
<property name="cache">
|
<property name="cache">
|
||||||
@@ -683,7 +651,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- The transactional cache for In-Memory CompiledModels -->
|
<!-- The transactional cache for Dictionary Models -->
|
||||||
|
|
||||||
<bean name="compiledModelsCache" class="org.alfresco.repo.cache.TransactionalCache">
|
<bean name="compiledModelsCache" class="org.alfresco.repo.cache.TransactionalCache">
|
||||||
<property name="sharedCache">
|
<property name="sharedCache">
|
||||||
@@ -700,39 +668,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- The cross-transaction shared cache for In-Memory Namespace Uris -->
|
<!-- The cross-transaction shared cache for Dictionary Namespaces -->
|
||||||
|
|
||||||
<bean name="urisSharedCache" class="org.alfresco.repo.cache.EhCacheAdapter">
|
|
||||||
<property name="cache">
|
|
||||||
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean" >
|
|
||||||
<property name="cacheManager">
|
|
||||||
<ref bean="internalEHCacheManager" />
|
|
||||||
</property>
|
|
||||||
<property name="cacheName">
|
|
||||||
<value>org.alfresco.cache.urisCache</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- The transactional cache for In-Memory Namespace Uris -->
|
|
||||||
|
|
||||||
<bean name="urisCache" class="org.alfresco.repo.cache.TransactionalCache">
|
|
||||||
<property name="sharedCache">
|
|
||||||
<ref bean="urisSharedCache" />
|
|
||||||
</property>
|
|
||||||
<property name="cacheManager" >
|
|
||||||
<ref bean="transactionalEHCacheManager" />
|
|
||||||
</property>
|
|
||||||
<property name="name">
|
|
||||||
<value>org.alfresco.urisTransactionalCache</value>
|
|
||||||
</property>
|
|
||||||
<property name="maxCacheSize">
|
|
||||||
<value>100</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- The cross-transaction shared cache for In-Memory Namespace Prefixes -->
|
|
||||||
|
|
||||||
<bean name="prefixesSharedCache" class="org.alfresco.repo.cache.EhCacheAdapter">
|
<bean name="prefixesSharedCache" class="org.alfresco.repo.cache.EhCacheAdapter">
|
||||||
<property name="cache">
|
<property name="cache">
|
||||||
@@ -747,7 +683,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- The transactional cache for In-Memory Namespace Prefixes -->
|
<!-- The transactional cache for Dictionary Namespaces -->
|
||||||
|
|
||||||
<bean name="prefixesCache" class="org.alfresco.repo.cache.TransactionalCache">
|
<bean name="prefixesCache" class="org.alfresco.repo.cache.TransactionalCache">
|
||||||
<property name="sharedCache">
|
<property name="sharedCache">
|
||||||
|
@@ -863,7 +863,7 @@
|
|||||||
<property name="tenantService">
|
<property name="tenantService">
|
||||||
<ref bean="tenantService"/>
|
<ref bean="tenantService"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="namespaceDataCache">
|
<property name="namespaceRegistryCache">
|
||||||
<ref bean="prefixesCache"/>
|
<ref bean="prefixesCache"/>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -890,10 +890,7 @@
|
|||||||
<property name="tenantService">
|
<property name="tenantService">
|
||||||
<ref bean="tenantService"/>
|
<ref bean="tenantService"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="uriToModelsCache">
|
<property name="dictionaryRegistryCache">
|
||||||
<ref bean="uriToModelsCache"/>
|
|
||||||
</property>
|
|
||||||
<property name="compiledModelsCache">
|
|
||||||
<ref bean="compiledModelsCache"/>
|
<ref bean="compiledModelsCache"/>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
@@ -380,13 +380,6 @@
|
|||||||
<!-- Dictionary / Namespace (tenant-based) -->
|
<!-- Dictionary / Namespace (tenant-based) -->
|
||||||
|
|
||||||
<!-- dictionary models -->
|
<!-- dictionary models -->
|
||||||
<cache
|
|
||||||
name="org.alfresco.cache.uriToModelsCache"
|
|
||||||
maxElementsInMemory="100"
|
|
||||||
eternal="true"
|
|
||||||
overflowToDisk="false"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<cache
|
<cache
|
||||||
name="org.alfresco.cache.compiledModelsCache"
|
name="org.alfresco.cache.compiledModelsCache"
|
||||||
maxElementsInMemory="100"
|
maxElementsInMemory="100"
|
||||||
|
@@ -876,22 +876,6 @@
|
|||||||
|
|
||||||
<!-- Dictionary / Namespace (tenant-based) -->
|
<!-- Dictionary / Namespace (tenant-based) -->
|
||||||
|
|
||||||
<cache
|
|
||||||
name="org.alfresco.cache.uriToModelsCache"
|
|
||||||
maxElementsInMemory="100"
|
|
||||||
eternal="true"
|
|
||||||
overflowToDisk="false">
|
|
||||||
|
|
||||||
<cacheEventListenerFactory
|
|
||||||
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
|
|
||||||
properties="replicatePuts = false,
|
|
||||||
replicateUpdates = true,
|
|
||||||
replicateRemovals = true,
|
|
||||||
replicateUpdatesViaCopy = false,
|
|
||||||
replicateAsynchronously = false"/>
|
|
||||||
|
|
||||||
</cache>
|
|
||||||
|
|
||||||
<cache
|
<cache
|
||||||
name="org.alfresco.cache.compiledModelsCache"
|
name="org.alfresco.cache.compiledModelsCache"
|
||||||
maxElementsInMemory="100"
|
maxElementsInMemory="100"
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -275,8 +275,10 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
}
|
}
|
||||||
classes.add(def);
|
classes.add(def);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isTraceEnabled())
|
||||||
logger.debug("Resolving inheritance: class " + def.getName() + " found at depth " + depth);
|
{
|
||||||
|
logger.trace("Resolving inheritance: class " + def.getName() + " found at depth " + depth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve inheritance of each class
|
// Resolve inheritance of each class
|
||||||
|
@@ -137,8 +137,10 @@ public class DictionaryBootstrap implements DictionaryListener
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (logger.isInfoEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.info("Loading model from " + bootstrapModel);
|
{
|
||||||
|
logger.debug("Loading model from " + bootstrapModel);
|
||||||
|
}
|
||||||
|
|
||||||
M2Model model = M2Model.createModel(modelStream);
|
M2Model model = M2Model.createModel(modelStream);
|
||||||
dictionaryDAO.putModel(model);
|
dictionaryDAO.putModel(model);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -64,13 +64,6 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
*/
|
*/
|
||||||
public class DictionaryDAOImpl implements DictionaryDAO
|
public class DictionaryDAOImpl implements DictionaryDAO
|
||||||
{
|
{
|
||||||
// TODO: Allow for the dynamic creation of models. Supporting
|
|
||||||
// this requires the ability to persistently store the
|
|
||||||
// registration of models, the ability to load models
|
|
||||||
// from a persistent store, the refresh of the cache
|
|
||||||
// and concurrent read/write of the models.
|
|
||||||
// (in progress)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock objects
|
* Lock objects
|
||||||
*/
|
*/
|
||||||
@@ -84,11 +77,12 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
// Tenant Service
|
// Tenant Service
|
||||||
private TenantService tenantService;
|
private TenantService tenantService;
|
||||||
|
|
||||||
// Map of Namespace URI usages to Models
|
// Internal cache (clusterable)
|
||||||
private SimpleCache<String, Map<String, List<CompiledModel>>> uriToModelsCache;
|
private SimpleCache<String, DictionaryRegistry> dictionaryRegistryCache;
|
||||||
|
|
||||||
// Map of model name to compiled model
|
// used to reset the cache
|
||||||
private SimpleCache<String, Map<QName,CompiledModel>> compiledModelsCache;
|
private ThreadLocal<DictionaryRegistry> dictionaryRegistryThreadLocal = new ThreadLocal<DictionaryRegistry>();
|
||||||
|
private ThreadLocal<DictionaryRegistry> defaultDictionaryRegistryThreadLocal = new ThreadLocal<DictionaryRegistry>();
|
||||||
|
|
||||||
// Static list of registered dictionary listeners
|
// Static list of registered dictionary listeners
|
||||||
private List<DictionaryListener> dictionaryListeners = new ArrayList<DictionaryListener>();
|
private List<DictionaryListener> dictionaryListeners = new ArrayList<DictionaryListener>();
|
||||||
@@ -104,14 +98,9 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
this.tenantService = tenantService;
|
this.tenantService = tenantService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUriToModelsCache(SimpleCache<String, Map<String, List<CompiledModel>>> uriToModelsCache)
|
public void setDictionaryRegistryCache(SimpleCache<String, DictionaryRegistry> dictionaryRegistryCache)
|
||||||
{
|
{
|
||||||
this.uriToModelsCache = uriToModelsCache;
|
this.dictionaryRegistryCache = dictionaryRegistryCache;
|
||||||
}
|
|
||||||
|
|
||||||
public void setCompiledModelsCache(SimpleCache<String, Map<QName,CompiledModel>> compiledModelsCache)
|
|
||||||
{
|
|
||||||
this.compiledModelsCache = compiledModelsCache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,6 +122,7 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
{
|
{
|
||||||
if (! dictionaryListeners.contains(dictionaryDeployer))
|
if (! dictionaryListeners.contains(dictionaryDeployer))
|
||||||
{
|
{
|
||||||
|
destroy(); // force reload on next get
|
||||||
dictionaryListeners.add(dictionaryDeployer);
|
dictionaryListeners.add(dictionaryDeployer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,27 +132,7 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
*/
|
*/
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
String tenantDomain = tenantService.getCurrentUserDomain();
|
initDictionary(tenantService.getCurrentUserDomain());
|
||||||
|
|
||||||
// initialise empty dictionary & namespaces
|
|
||||||
putCompiledModels(tenantDomain, new HashMap<QName,CompiledModel>());
|
|
||||||
putUriToModels(tenantDomain, new HashMap<String, List<CompiledModel>>());
|
|
||||||
|
|
||||||
namespaceDAO.init();
|
|
||||||
|
|
||||||
// populate the dictionary
|
|
||||||
for (DictionaryListener dictionaryListener : dictionaryListeners)
|
|
||||||
{
|
|
||||||
dictionaryListener.onDictionaryInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// notify registered listeners that dictionary has been initialised
|
|
||||||
for (DictionaryListener dictionaryListener : dictionaryListeners)
|
|
||||||
{
|
|
||||||
dictionaryListener.afterDictionaryInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("Dictionary initialised");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,8 +142,7 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
{
|
{
|
||||||
String tenantDomain = tenantService.getCurrentUserDomain();
|
String tenantDomain = tenantService.getCurrentUserDomain();
|
||||||
|
|
||||||
removeCompiledModels(tenantDomain);
|
removeDictionaryRegistry(tenantDomain);
|
||||||
removeUriToModels(tenantDomain);
|
|
||||||
|
|
||||||
namespaceDAO.destroy();
|
namespaceDAO.destroy();
|
||||||
|
|
||||||
@@ -183,41 +152,117 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
dictionaryDeployer.afterDictionaryDestroy();
|
dictionaryDeployer.afterDictionaryDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Dictionary destroyed");
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Dictionary destroyed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the Dictionary & Namespaces
|
* Reset the Dictionary & Namespaces
|
||||||
*/
|
*/
|
||||||
public void reset()
|
public void reset()
|
||||||
{
|
|
||||||
reset(tenantService.getCurrentUserDomain());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reset(String tenantDomain)
|
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("Resetting dictionary ...");
|
logger.debug("Resetting dictionary ...");
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
|
||||||
{
|
|
||||||
public Object doWork()
|
|
||||||
{
|
|
||||||
destroy();
|
destroy();
|
||||||
init();
|
init();
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("... resetting dictionary completed");
|
logger.debug("... resetting dictionary completed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load dictionary (models and namespaces)
|
||||||
|
private DictionaryRegistry initDictionary(final String tenantDomain)
|
||||||
|
{
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return AuthenticationUtil.runAs(new RunAsWork<DictionaryRegistry>()
|
||||||
|
{
|
||||||
|
public DictionaryRegistry doWork()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// create threadlocal, if needed
|
||||||
|
createDataDictionaryLocal(tenantDomain);
|
||||||
|
|
||||||
|
DictionaryRegistry dictionaryRegistry = initDictionaryRegistry(tenantDomain);
|
||||||
|
|
||||||
|
if (dictionaryRegistry == null)
|
||||||
|
{
|
||||||
|
// unexpected
|
||||||
|
throw new AlfrescoRuntimeException("Failed to init dictionaryRegistry " + tenantDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writeLock.lock();
|
||||||
|
dictionaryRegistryCache.put(tenantDomain, dictionaryRegistry);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return dictionaryRegistry;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
readLock.lock();
|
||||||
|
if (dictionaryRegistryCache.get(tenantDomain) != null)
|
||||||
|
{
|
||||||
|
removeDataDictionaryLocal(tenantDomain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
readLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (logger.isInfoEnabled())
|
||||||
|
{
|
||||||
|
logger.info("Init Dictionary: model count = "+(getModels() != null ? getModels().size() : 0) +" in "+(System.currentTimeMillis()-startTime)+" msecs "+(tenantDomain.equals(TenantService.DEFAULT_DOMAIN) ? "" : " (Tenant: "+tenantDomain+")"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DictionaryRegistry initDictionaryRegistry(String tenantDomain)
|
||||||
|
{
|
||||||
|
getDictionaryRegistry(tenantDomain).setCompiledModels(new HashMap<QName,CompiledModel>());
|
||||||
|
getDictionaryRegistry(tenantDomain).setUriToModels(new HashMap<String, List<CompiledModel>>());
|
||||||
|
|
||||||
|
// initialise empty dictionary & namespaces
|
||||||
|
namespaceDAO.init();
|
||||||
|
|
||||||
|
// populate the dictionary based on registered sources
|
||||||
|
for (DictionaryListener dictionaryDeployer : dictionaryListeners)
|
||||||
|
{
|
||||||
|
dictionaryDeployer.onDictionaryInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// notify registered listeners that dictionary has been initialised (population is complete)
|
||||||
|
for (DictionaryListener dictionaryListener : dictionaryListeners)
|
||||||
|
{
|
||||||
|
dictionaryListener.afterDictionaryInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return getDictionaryRegistryLocal(tenantDomain);
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.dictionary.impl.DictionaryDAO#putModel(org.alfresco.repo.dictionary.impl.M2Model)
|
* @see org.alfresco.repo.dictionary.impl.DictionaryDAO#putModel(org.alfresco.repo.dictionary.impl.M2Model)
|
||||||
*/
|
*/
|
||||||
@@ -260,19 +305,18 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
// Publish new Model Definition
|
// Publish new Model Definition
|
||||||
getCompiledModels(tenantDomain).put(modelName, compiledModel);
|
getCompiledModels(tenantDomain).put(modelName, compiledModel);
|
||||||
|
|
||||||
if (logger.isInfoEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.info("Registered model " + modelName.toPrefixString(namespaceDAO));
|
logger.debug("Registered model " + modelName.toPrefixString(namespaceDAO));
|
||||||
for (M2Namespace namespace : model.getNamespaces())
|
for (M2Namespace namespace : model.getNamespaces())
|
||||||
{
|
{
|
||||||
logger.info("Registered namespace '" + namespace.getUri() + "' (prefix '" + namespace.getPrefix() + "')");
|
logger.debug("Registered namespace '" + namespace.getUri() + "' (prefix '" + namespace.getPrefix() + "')");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return modelName;
|
return modelName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.alfresco.repo.dictionary.DictionaryDAO#removeModel(org.alfresco.service.namespace.QName)
|
* @see org.alfresco.repo.dictionary.DictionaryDAO#removeModel(org.alfresco.service.namespace.QName)
|
||||||
*/
|
*/
|
||||||
@@ -297,7 +341,6 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map Namespace URI to Model
|
* Map Namespace URI to Model
|
||||||
*
|
*
|
||||||
@@ -319,7 +362,6 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unmap Namespace URI from Model
|
* Unmap Namespace URI from Model
|
||||||
*
|
*
|
||||||
@@ -394,7 +436,6 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
return models;
|
return models;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param modelName the model name
|
* @param modelName the model name
|
||||||
* @return the compiled model of the given name
|
* @return the compiled model of the given name
|
||||||
@@ -440,7 +481,6 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.dictionary.ModelQuery#getDataType(java.lang.Class)
|
* @see org.alfresco.repo.dictionary.ModelQuery#getDataType(java.lang.Class)
|
||||||
*/
|
*/
|
||||||
@@ -892,6 +932,120 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
return namespaces;
|
return namespaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// re-entrant (eg. via reset)
|
||||||
|
private DictionaryRegistry getDictionaryRegistry(String tenantDomain)
|
||||||
|
{
|
||||||
|
DictionaryRegistry dictionaryRegistry = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// check cache first - return if set
|
||||||
|
readLock.lock();
|
||||||
|
dictionaryRegistry = dictionaryRegistryCache.get(tenantDomain);
|
||||||
|
|
||||||
|
if (dictionaryRegistry != null)
|
||||||
|
{
|
||||||
|
return dictionaryRegistry; // return cached config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
readLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check threadlocal second - return if set
|
||||||
|
dictionaryRegistry = getDictionaryRegistryLocal(tenantDomain);
|
||||||
|
if (dictionaryRegistry != null)
|
||||||
|
{
|
||||||
|
return dictionaryRegistry; // return local dictionaryRegistry
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset caches - may have been invalidated (e.g. in a cluster)
|
||||||
|
dictionaryRegistry = initDictionary(tenantDomain);
|
||||||
|
|
||||||
|
if (dictionaryRegistry == null)
|
||||||
|
{
|
||||||
|
// unexpected
|
||||||
|
throw new AlfrescoRuntimeException("Failed to get dictionaryRegistry " + tenantDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dictionaryRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create threadlocal
|
||||||
|
private void createDataDictionaryLocal(String tenantDomain)
|
||||||
|
{
|
||||||
|
// create threadlocal, if needed
|
||||||
|
DictionaryRegistry dictionaryRegistry = getDictionaryRegistryLocal(tenantDomain);
|
||||||
|
if (dictionaryRegistry == null)
|
||||||
|
{
|
||||||
|
dictionaryRegistry = new DictionaryRegistry(tenantDomain);
|
||||||
|
|
||||||
|
if (tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
|
||||||
|
{
|
||||||
|
defaultDictionaryRegistryThreadLocal.set(dictionaryRegistry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dictionaryRegistryThreadLocal.set(dictionaryRegistry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get threadlocal
|
||||||
|
private DictionaryRegistry getDictionaryRegistryLocal(String tenantDomain)
|
||||||
|
{
|
||||||
|
DictionaryRegistry dictionaryRegistry = null;
|
||||||
|
|
||||||
|
if (tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
|
||||||
|
{
|
||||||
|
dictionaryRegistry = this.defaultDictionaryRegistryThreadLocal.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dictionaryRegistry = this.dictionaryRegistryThreadLocal.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check to see if domain switched
|
||||||
|
if ((dictionaryRegistry != null) && (tenantDomain.equals(dictionaryRegistry.getTenantDomain())))
|
||||||
|
{
|
||||||
|
return dictionaryRegistry; // return threadlocal, if set
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove threadlocal
|
||||||
|
private void removeDataDictionaryLocal(String tenantDomain)
|
||||||
|
{
|
||||||
|
if (tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
|
||||||
|
{
|
||||||
|
defaultDictionaryRegistryThreadLocal.set(null); // it's in the cache, clear the threadlocal
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dictionaryRegistryThreadLocal.set(null); // it's in the cache, clear the threadlocal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeDictionaryRegistry(String tenantDomain)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writeLock.lock();
|
||||||
|
if (dictionaryRegistryCache.get(tenantDomain) != null)
|
||||||
|
{
|
||||||
|
dictionaryRegistryCache.remove(tenantDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeDataDictionaryLocal(tenantDomain);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get compiledModels from the cache (in the context of the given tenant domain)
|
* Get compiledModels from the cache (in the context of the given tenant domain)
|
||||||
*
|
*
|
||||||
@@ -899,80 +1053,7 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
*/
|
*/
|
||||||
private Map<QName,CompiledModel> getCompiledModels(String tenantDomain)
|
private Map<QName,CompiledModel> getCompiledModels(String tenantDomain)
|
||||||
{
|
{
|
||||||
Map<QName,CompiledModel> compiledModels = null;
|
return getDictionaryRegistry(tenantDomain).getCompiledModels();
|
||||||
try
|
|
||||||
{
|
|
||||||
readLock.lock();
|
|
||||||
compiledModels = compiledModelsCache.get(tenantDomain);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (compiledModels == null)
|
|
||||||
{
|
|
||||||
reset(tenantDomain); // reset caches - may have been invalidated (e.g. in a cluster)
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
readLock.lock();
|
|
||||||
compiledModels = compiledModelsCache.get(tenantDomain);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compiledModels == null)
|
|
||||||
{
|
|
||||||
// unexpected
|
|
||||||
throw new AlfrescoRuntimeException("Failed to re-initialise compiledModelsCache " + tenantDomain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return compiledModels;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Put compiledModels into the cache (in the context of the given tenant domain)
|
|
||||||
*
|
|
||||||
* @param tenantDomain
|
|
||||||
*/
|
|
||||||
private void putCompiledModels(String tenantDomain, Map<QName, CompiledModel> compiledModels)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
writeLock.lock();
|
|
||||||
compiledModelsCache.put(tenantDomain, compiledModels);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove compiledModels from the cache (in the context of the given tenant domain)
|
|
||||||
*
|
|
||||||
* @param tenantDomain
|
|
||||||
*/
|
|
||||||
private void removeCompiledModels(String tenantDomain)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
writeLock.lock();
|
|
||||||
if (compiledModelsCache.get(tenantDomain) != null)
|
|
||||||
{
|
|
||||||
compiledModelsCache.get(tenantDomain).clear();
|
|
||||||
compiledModelsCache.remove(tenantDomain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -982,79 +1063,7 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
*/
|
*/
|
||||||
private Map<String, List<CompiledModel>> getUriToModels(String tenantDomain)
|
private Map<String, List<CompiledModel>> getUriToModels(String tenantDomain)
|
||||||
{
|
{
|
||||||
Map<String, List<CompiledModel>> uriToModels = null;
|
return getDictionaryRegistry(tenantDomain).getUriToModels();
|
||||||
try
|
|
||||||
{
|
|
||||||
readLock.lock();
|
|
||||||
uriToModels = uriToModelsCache.get(tenantDomain);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uriToModels == null)
|
|
||||||
{
|
|
||||||
reset(tenantDomain); // reset caches - may have been invalidated (e.g. in a cluster)
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
readLock.lock();
|
|
||||||
uriToModels = uriToModelsCache.get(tenantDomain);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uriToModels == null)
|
|
||||||
{
|
|
||||||
// unexpected
|
|
||||||
throw new AlfrescoRuntimeException("Failed to re-initialise uriToModelsCache " + tenantDomain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return uriToModels;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Put uriToModels into the cache (in the context of the given tenant domain)
|
|
||||||
*
|
|
||||||
* @param tenantDomain
|
|
||||||
*/
|
|
||||||
private void putUriToModels(String tenantDomain, Map<String, List<CompiledModel>> uriToModels)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
writeLock.lock();
|
|
||||||
uriToModelsCache.put(tenantDomain, uriToModels);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove uriToModels from the cache (in the context of the given tenant domain)
|
|
||||||
*
|
|
||||||
* @param tenantDomain
|
|
||||||
*/
|
|
||||||
private void removeUriToModels(String tenantDomain)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
writeLock.lock();
|
|
||||||
if (uriToModelsCache.get(tenantDomain) != null)
|
|
||||||
{
|
|
||||||
uriToModelsCache.get(tenantDomain).clear();
|
|
||||||
uriToModelsCache.remove(tenantDomain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1205,4 +1214,39 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* package */ class DictionaryRegistry
|
||||||
|
{
|
||||||
|
private Map<String, List<CompiledModel>> uriToModels = new HashMap<String, List<CompiledModel>>(0);
|
||||||
|
private Map<QName,CompiledModel> compiledModels = new HashMap<QName,CompiledModel>(0);
|
||||||
|
|
||||||
|
private String tenantDomain;
|
||||||
|
|
||||||
|
public DictionaryRegistry(String tenantDomain)
|
||||||
|
{
|
||||||
|
this.tenantDomain = tenantDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTenantDomain()
|
||||||
|
{
|
||||||
|
return tenantDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, List<CompiledModel>> getUriToModels()
|
||||||
|
{
|
||||||
|
return uriToModels;
|
||||||
|
}
|
||||||
|
public void setUriToModels(Map<String, List<CompiledModel>> uriToModels)
|
||||||
|
{
|
||||||
|
this.uriToModels = uriToModels;
|
||||||
|
}
|
||||||
|
public Map<QName, CompiledModel> getCompiledModels()
|
||||||
|
{
|
||||||
|
return compiledModels;
|
||||||
|
}
|
||||||
|
public void setCompiledModels(Map<QName, CompiledModel> compiledModels)
|
||||||
|
{
|
||||||
|
this.compiledModels = compiledModels;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -39,7 +39,8 @@ import net.sf.ehcache.CacheManager;
|
|||||||
import org.alfresco.i18n.I18NUtil;
|
import org.alfresco.i18n.I18NUtil;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.cache.EhCacheAdapter;
|
import org.alfresco.repo.cache.EhCacheAdapter;
|
||||||
import org.alfresco.repo.dictionary.NamespaceDAOImpl.NamespaceData;
|
import org.alfresco.repo.dictionary.DictionaryDAOImpl.DictionaryRegistry;
|
||||||
|
import org.alfresco.repo.dictionary.NamespaceDAOImpl.NamespaceRegistry;
|
||||||
import org.alfresco.repo.dictionary.constraint.RegexConstraint;
|
import org.alfresco.repo.dictionary.constraint.RegexConstraint;
|
||||||
import org.alfresco.repo.dictionary.constraint.StringLengthConstraint;
|
import org.alfresco.repo.dictionary.constraint.StringLengthConstraint;
|
||||||
import org.alfresco.repo.tenant.SingleTServiceImpl;
|
import org.alfresco.repo.tenant.SingleTServiceImpl;
|
||||||
@@ -107,19 +108,12 @@ public class DictionaryDAOTest extends TestCase
|
|||||||
{
|
{
|
||||||
CacheManager cacheManager = new CacheManager();
|
CacheManager cacheManager = new CacheManager();
|
||||||
|
|
||||||
Cache uriToModelsEhCache = new Cache("uriToModelsCache", 50, false, true, 0L, 0L);
|
Cache dictionaryEhCache = new Cache("dictionaryCache", 50, false, true, 0L, 0L);
|
||||||
cacheManager.addCache(uriToModelsEhCache);
|
cacheManager.addCache(dictionaryEhCache);
|
||||||
EhCacheAdapter<String, Map<String, List<CompiledModel>>> uriToModelsCache = new EhCacheAdapter<String, Map<String, List<CompiledModel>>>();
|
EhCacheAdapter<String, DictionaryRegistry> dictionaryCache = new EhCacheAdapter<String, DictionaryRegistry>();
|
||||||
uriToModelsCache.setCache(uriToModelsEhCache);
|
dictionaryCache.setCache(dictionaryEhCache);
|
||||||
|
|
||||||
dictionaryDAO.setUriToModelsCache(uriToModelsCache);
|
dictionaryDAO.setDictionaryRegistryCache(dictionaryCache);
|
||||||
|
|
||||||
Cache compileModelsEhCache = new Cache("compiledModelsCache", 50, false, true, 0L, 0L);
|
|
||||||
cacheManager.addCache(compileModelsEhCache);
|
|
||||||
EhCacheAdapter<String, Map<QName,CompiledModel>> compileModelCache = new EhCacheAdapter<String, Map<QName,CompiledModel>>();
|
|
||||||
compileModelCache.setCache(compileModelsEhCache);
|
|
||||||
|
|
||||||
dictionaryDAO.setCompiledModelsCache(compileModelCache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initNamespaceCaches(NamespaceDAOImpl namespaceDAO)
|
private void initNamespaceCaches(NamespaceDAOImpl namespaceDAO)
|
||||||
@@ -128,10 +122,10 @@ public class DictionaryDAOTest extends TestCase
|
|||||||
|
|
||||||
Cache namespaceEhCache = new Cache("namespaceCache", 50, false, true, 0L, 0L);
|
Cache namespaceEhCache = new Cache("namespaceCache", 50, false, true, 0L, 0L);
|
||||||
cacheManager.addCache(namespaceEhCache);
|
cacheManager.addCache(namespaceEhCache);
|
||||||
EhCacheAdapter<String, NamespaceData> namespaceCache = new EhCacheAdapter<String, NamespaceData>();
|
EhCacheAdapter<String, NamespaceRegistry> namespaceCache = new EhCacheAdapter<String, NamespaceRegistry>();
|
||||||
namespaceCache.setCache(namespaceEhCache);
|
namespaceCache.setCache(namespaceEhCache);
|
||||||
|
|
||||||
namespaceDAO.setNamespaceDataCache(namespaceCache);
|
namespaceDAO.setNamespaceRegistryCache(namespaceCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -71,11 +71,12 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
/**
|
/**
|
||||||
* Dictionary model type behaviour.
|
* Dictionary model type behaviour.
|
||||||
*
|
*
|
||||||
* @author Roy Wetherall
|
* @author Roy Wetherall, janv
|
||||||
*/
|
*/
|
||||||
public class DictionaryModelType implements ContentServicePolicies.OnContentUpdatePolicy,
|
public class DictionaryModelType implements ContentServicePolicies.OnContentUpdatePolicy,
|
||||||
NodeServicePolicies.OnUpdatePropertiesPolicy,
|
NodeServicePolicies.OnUpdatePropertiesPolicy,
|
||||||
NodeServicePolicies.BeforeDeleteNodePolicy,
|
NodeServicePolicies.BeforeDeleteNodePolicy,
|
||||||
|
NodeServicePolicies.OnDeleteNodePolicy,
|
||||||
NodeServicePolicies.OnCreateNodePolicy,
|
NodeServicePolicies.OnCreateNodePolicy,
|
||||||
NodeServicePolicies.OnRemoveAspectPolicy
|
NodeServicePolicies.OnRemoveAspectPolicy
|
||||||
{
|
{
|
||||||
@@ -85,6 +86,9 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
/** Key to the pending models */
|
/** Key to the pending models */
|
||||||
private static final String KEY_PENDING_MODELS = "dictionaryModelType.pendingModels";
|
private static final String KEY_PENDING_MODELS = "dictionaryModelType.pendingModels";
|
||||||
|
|
||||||
|
/** Key to the pending deleted models */
|
||||||
|
private static final String KEY_PENDING_DELETE_MODELS = "dictionaryModelType.pendingDeleteModels";
|
||||||
|
|
||||||
/** Key to the removed "workingcopy" aspect */
|
/** Key to the removed "workingcopy" aspect */
|
||||||
private static final String KEY_WORKING_COPY = "dictionaryModelType.workingCopy";
|
private static final String KEY_WORKING_COPY = "dictionaryModelType.workingCopy";
|
||||||
|
|
||||||
@@ -224,25 +228,31 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
ContentModel.TYPE_DICTIONARY_MODEL,
|
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||||
new JavaBehaviour(this, "onContentUpdate"));
|
new JavaBehaviour(this, "onContentUpdate"));
|
||||||
|
|
||||||
// Register interest in the onPropertyUpdate policy for the dictionary model type
|
// Register interest in the onUpdateProperties policy for the dictionary model type
|
||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||||
ContentModel.TYPE_DICTIONARY_MODEL,
|
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||||
new JavaBehaviour(this, "onUpdateProperties"));
|
new JavaBehaviour(this, "onUpdateProperties"));
|
||||||
|
|
||||||
// Register interest in the node delete policy
|
// Register interest in the beforeDeleteNode policy for the dictionary model type
|
||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
|
||||||
ContentModel.TYPE_DICTIONARY_MODEL,
|
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||||
new JavaBehaviour(this, "beforeDeleteNode"));
|
new JavaBehaviour(this, "beforeDeleteNode"));
|
||||||
|
|
||||||
// Register interest in the remove aspect policy
|
// Register interest in the onDeleteNode policy for the dictionary model type
|
||||||
|
policyComponent.bindClassBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"),
|
||||||
|
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||||
|
new JavaBehaviour(this, "onDeleteNode"));
|
||||||
|
|
||||||
|
// Register interest in the onRemoveAspect policy
|
||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onRemoveAspect"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onRemoveAspect"),
|
||||||
this,
|
this,
|
||||||
new JavaBehaviour(this, "onRemoveAspect"));
|
new JavaBehaviour(this, "onRemoveAspect"));
|
||||||
|
|
||||||
// Register interest in the onCreateNode policy for the dictionary model type
|
// Register interest in the onCreateNode policy
|
||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
|
||||||
this,
|
this,
|
||||||
@@ -321,6 +331,7 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public void beforeDeleteNode(NodeRef nodeRef)
|
public void beforeDeleteNode(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
boolean workingCopy = nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY);
|
boolean workingCopy = nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY);
|
||||||
@@ -346,8 +357,48 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
// Validate model delete against usages - content and/or workflows
|
// Validate model delete against usages - content and/or workflows
|
||||||
validateModelDelete(modelName);
|
validateModelDelete(modelName);
|
||||||
|
|
||||||
// Remove the model from the dictionary
|
if (logger.isDebugEnabled())
|
||||||
dictionaryDAO.removeModel(modelName);
|
{
|
||||||
|
logger.debug("beforeDeleteNode: modelName="+modelName+" ("+nodeRef+")");
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<NodeRef> pendingModelDeletes = (Set<NodeRef>)AlfrescoTransactionSupport.getResource(KEY_PENDING_DELETE_MODELS);
|
||||||
|
if (pendingModelDeletes == null)
|
||||||
|
{
|
||||||
|
pendingModelDeletes = new HashSet<NodeRef>();
|
||||||
|
AlfrescoTransactionSupport.bindResource(KEY_PENDING_DELETE_MODELS, pendingModelDeletes);
|
||||||
|
}
|
||||||
|
pendingModelDeletes.add(tenantService.getName(nodeRef));
|
||||||
|
|
||||||
|
AlfrescoTransactionSupport.bindListener(this.transactionListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void onDeleteNode(ChildAssociationRef childAssocRef, boolean isNodeArchived)
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = childAssocRef.getChildRef();
|
||||||
|
|
||||||
|
Set<NodeRef> pendingDeleteModels = (Set<NodeRef>)AlfrescoTransactionSupport.getResource(KEY_PENDING_DELETE_MODELS);
|
||||||
|
|
||||||
|
if (pendingDeleteModels != null)
|
||||||
|
{
|
||||||
|
if (pendingDeleteModels.contains(nodeRef))
|
||||||
|
{
|
||||||
|
String tenantDomain = tenantService.getDomain(nodeRef.getStoreRef().getIdentifier());
|
||||||
|
String tenantSystemUserName = tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain);
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork()
|
||||||
|
{
|
||||||
|
// invalidate - to force lazy re-init
|
||||||
|
dictionaryDAO.destroy();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, tenantSystemUserName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -395,6 +446,11 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
|
|
||||||
if (pendingModels != null)
|
if (pendingModels != null)
|
||||||
{
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("beforeCommit: pendingModelsCnt="+pendingModels.size());
|
||||||
|
}
|
||||||
|
|
||||||
for (NodeRef pendingNodeRef : pendingModels)
|
for (NodeRef pendingNodeRef : pendingModels)
|
||||||
{
|
{
|
||||||
String tenantDomain = tenantService.getDomain(pendingNodeRef.getStoreRef().getIdentifier());
|
String tenantDomain = tenantService.getDomain(pendingNodeRef.getStoreRef().getIdentifier());
|
||||||
@@ -464,8 +520,8 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
// Validate model against dictionary - could be new, unchanged or updated
|
// Validate model against dictionary - could be new, unchanged or updated
|
||||||
dictionaryDAO.validateModel(m2Model);
|
dictionaryDAO.validateModel(m2Model);
|
||||||
|
|
||||||
// Put the model
|
// invalidate - to force lazy re-init
|
||||||
dictionaryDAO.putModel(m2Model);
|
dictionaryDAO.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -476,8 +532,8 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
// Validate model delete against usages - content and/or workflows
|
// Validate model delete against usages - content and/or workflows
|
||||||
validateModelDelete(modelName);
|
validateModelDelete(modelName);
|
||||||
|
|
||||||
// Remove the model from the dictionary
|
// invalidate - to force lazy re-init
|
||||||
dictionaryDAO.removeModel(modelName);
|
dictionaryDAO.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -24,8 +24,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.dictionary;
|
package org.alfresco.repo.dictionary;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
|
import org.alfresco.repo.i18n.MessageService;
|
||||||
|
import org.alfresco.repo.tenant.TenantAdminService;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryException;
|
import org.alfresco.service.cmr.dictionary.DictionaryException;
|
||||||
@@ -33,6 +38,8 @@ import org.alfresco.service.cmr.dictionary.DictionaryService;
|
|||||||
import org.alfresco.service.cmr.dictionary.ModelDefinition;
|
import org.alfresco.service.cmr.dictionary.ModelDefinition;
|
||||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.BaseAlfrescoSpringTest;
|
import org.alfresco.util.BaseAlfrescoSpringTest;
|
||||||
@@ -136,7 +143,35 @@ public class DictionaryModelTypeTest extends BaseAlfrescoSpringTest
|
|||||||
this.namespaceService = (NamespaceService)this.applicationContext.getBean("namespaceService");
|
this.namespaceService = (NamespaceService)this.applicationContext.getBean("namespaceService");
|
||||||
this.cociService = (CheckOutCheckInService)this.applicationContext.getBean("checkOutCheckInService");
|
this.cociService = (CheckOutCheckInService)this.applicationContext.getBean("checkOutCheckInService");
|
||||||
this.dictionaryDAO = (DictionaryDAO)this.applicationContext.getBean("dictionaryDAO");
|
this.dictionaryDAO = (DictionaryDAO)this.applicationContext.getBean("dictionaryDAO");
|
||||||
|
this.nodeService = (NodeService)this.applicationContext.getBean("NodeService");
|
||||||
|
|
||||||
|
SearchService searchService = (SearchService)this.applicationContext.getBean("searchService");
|
||||||
|
TenantAdminService tenantAdminService = (TenantAdminService)this.applicationContext.getBean("tenantAdminService");
|
||||||
|
MessageService messageService = (MessageService)this.applicationContext.getBean("messageService");
|
||||||
|
|
||||||
|
DictionaryRepositoryBootstrap bootstrap = new DictionaryRepositoryBootstrap();
|
||||||
|
bootstrap.setContentService(this.contentService);
|
||||||
|
bootstrap.setSearchService(searchService);
|
||||||
|
bootstrap.setDictionaryDAO(this.dictionaryDAO);
|
||||||
|
bootstrap.setTransactionService(this.transactionService);
|
||||||
|
bootstrap.setTenantAdminService(tenantAdminService);
|
||||||
|
bootstrap.setNodeService(this.nodeService);
|
||||||
|
bootstrap.setNamespaceService(this.namespaceService);
|
||||||
|
bootstrap.setMessageService(messageService);
|
||||||
|
|
||||||
|
RepositoryLocation location = new RepositoryLocation();
|
||||||
|
location.setStoreProtocol(this.storeRef.getProtocol());
|
||||||
|
location.setStoreId(this.storeRef.getIdentifier());
|
||||||
|
location.setQueryLanguage(SearchService.LANGUAGE_XPATH);
|
||||||
|
// NOTE: we are not setting the path for now .. in doing so we are searching the whole store
|
||||||
|
|
||||||
|
List<RepositoryLocation> locations = new ArrayList<RepositoryLocation>();
|
||||||
|
locations.add(location);
|
||||||
|
|
||||||
|
bootstrap.setRepositoryModelsLocations(locations);
|
||||||
|
|
||||||
|
// register with dictionary service
|
||||||
|
bootstrap.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -233,12 +268,19 @@ public class DictionaryModelTypeTest extends BaseAlfrescoSpringTest
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Object>()
|
||||||
|
{
|
||||||
|
public Object execute() throws Exception
|
||||||
|
{
|
||||||
|
DictionaryModelTypeTest.this.nodeService.deleteNode(modelNode);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIsActiveFlagAndDelete()
|
public void testIsActiveFlagAndDelete()
|
||||||
{
|
{
|
||||||
this.dictionaryDAO.removeModel(TEST_MODEL_ONE);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Check that the model has not yet been loaded into the dictionary
|
// Check that the model has not yet been loaded into the dictionary
|
||||||
|
@@ -251,8 +251,8 @@ public class DictionaryRepositoryBootstrap extends AbstractLifecycleBean impleme
|
|||||||
|
|
||||||
for (NodeRef dictionaryModel : nodeRefs)
|
for (NodeRef dictionaryModel : nodeRefs)
|
||||||
{
|
{
|
||||||
// Ignore if the node is a working copy or if its inactive
|
// Ignore if the node is a working copy or archived, or if its inactive
|
||||||
if (nodeService.hasAspect(dictionaryModel, ContentModel.ASPECT_WORKING_COPY) == false)
|
if (! (nodeService.hasAspect(dictionaryModel, ContentModel.ASPECT_WORKING_COPY) || nodeService.hasAspect(dictionaryModel, ContentModel.ASPECT_ARCHIVED)))
|
||||||
{
|
{
|
||||||
Boolean isActive = (Boolean)nodeService.getProperty(dictionaryModel, ContentModel.PROP_MODEL_ACTIVE);
|
Boolean isActive = (Boolean)nodeService.getProperty(dictionaryModel, ContentModel.PROP_MODEL_ACTIVE);
|
||||||
|
|
||||||
@@ -261,6 +261,11 @@ public class DictionaryRepositoryBootstrap extends AbstractLifecycleBean impleme
|
|||||||
M2Model model = createM2Model(dictionaryModel);
|
M2Model model = createM2Model(dictionaryModel);
|
||||||
if (model != null)
|
if (model != null)
|
||||||
{
|
{
|
||||||
|
if (logger.isTraceEnabled())
|
||||||
|
{
|
||||||
|
logger.trace("onDictionaryInit: "+model.getName()+" ("+dictionaryModel+")");
|
||||||
|
}
|
||||||
|
|
||||||
for (M2Namespace namespace : model.getNamespaces())
|
for (M2Namespace namespace : model.getNamespaces())
|
||||||
{
|
{
|
||||||
modelMap.put(namespace.getUri(), model);
|
modelMap.put(namespace.getUri(), model);
|
||||||
@@ -407,21 +412,6 @@ public class DictionaryRepositoryBootstrap extends AbstractLifecycleBean impleme
|
|||||||
@Override
|
@Override
|
||||||
protected void onBootstrap(ApplicationEvent event)
|
protected void onBootstrap(ApplicationEvent event)
|
||||||
{
|
{
|
||||||
// run as System on bootstrap
|
|
||||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
|
||||||
{
|
|
||||||
public Object doWork()
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}, AuthenticationUtil.getSystemUserName());
|
|
||||||
|
|
||||||
if (tenantAdminService.isEnabled())
|
|
||||||
{
|
|
||||||
tenantAdminService.deployTenants(this, logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
register();
|
register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,7 +27,6 @@ package org.alfresco.repo.dictionary;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import net.sf.ehcache.Cache;
|
import net.sf.ehcache.Cache;
|
||||||
@@ -35,7 +34,8 @@ import net.sf.ehcache.CacheManager;
|
|||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.repo.cache.EhCacheAdapter;
|
import org.alfresco.repo.cache.EhCacheAdapter;
|
||||||
import org.alfresco.repo.dictionary.NamespaceDAOImpl.NamespaceData;
|
import org.alfresco.repo.dictionary.DictionaryDAOImpl.DictionaryRegistry;
|
||||||
|
import org.alfresco.repo.dictionary.NamespaceDAOImpl.NamespaceRegistry;
|
||||||
import org.alfresco.repo.tenant.SingleTServiceImpl;
|
import org.alfresco.repo.tenant.SingleTServiceImpl;
|
||||||
import org.alfresco.repo.tenant.TenantService;
|
import org.alfresco.repo.tenant.TenantService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
@@ -789,19 +789,12 @@ public class DiffModelTest extends TestCase
|
|||||||
{
|
{
|
||||||
CacheManager cacheManager = new CacheManager();
|
CacheManager cacheManager = new CacheManager();
|
||||||
|
|
||||||
Cache uriToModelsEhCache = new Cache("uriToModelsCache", 50, false, true, 0L, 0L);
|
Cache dictionaryEhCache = new Cache("dictionaryCache", 50, false, true, 0L, 0L);
|
||||||
cacheManager.addCache(uriToModelsEhCache);
|
cacheManager.addCache(dictionaryEhCache);
|
||||||
EhCacheAdapter<String, Map<String, List<CompiledModel>>> uriToModelsCache = new EhCacheAdapter<String, Map<String, List<CompiledModel>>>();
|
EhCacheAdapter<String, DictionaryRegistry> dictionaryCache = new EhCacheAdapter<String, DictionaryRegistry>();
|
||||||
uriToModelsCache.setCache(uriToModelsEhCache);
|
dictionaryCache.setCache(dictionaryEhCache);
|
||||||
|
|
||||||
dictionaryDAO.setUriToModelsCache(uriToModelsCache);
|
dictionaryDAO.setDictionaryRegistryCache(dictionaryCache);
|
||||||
|
|
||||||
Cache compileModelsEhCache = new Cache("compiledModelsCache", 50, false, true, 0L, 0L);
|
|
||||||
cacheManager.addCache(compileModelsEhCache);
|
|
||||||
EhCacheAdapter<String, Map<QName,CompiledModel>> compileModelCache = new EhCacheAdapter<String, Map<QName,CompiledModel>>();
|
|
||||||
compileModelCache.setCache(compileModelsEhCache);
|
|
||||||
|
|
||||||
dictionaryDAO.setCompiledModelsCache(compileModelCache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initNamespaceCaches(NamespaceDAOImpl namespaceDAO)
|
private void initNamespaceCaches(NamespaceDAOImpl namespaceDAO)
|
||||||
@@ -810,10 +803,10 @@ public class DiffModelTest extends TestCase
|
|||||||
|
|
||||||
Cache namespaceEhCache = new Cache("namespaceCache", 50, false, true, 0L, 0L);
|
Cache namespaceEhCache = new Cache("namespaceCache", 50, false, true, 0L, 0L);
|
||||||
cacheManager.addCache(namespaceEhCache);
|
cacheManager.addCache(namespaceEhCache);
|
||||||
EhCacheAdapter<String, NamespaceData> namespaceCache = new EhCacheAdapter<String, NamespaceData>();
|
EhCacheAdapter<String, NamespaceRegistry> namespaceCache = new EhCacheAdapter<String, NamespaceRegistry>();
|
||||||
namespaceCache.setCache(namespaceEhCache);
|
namespaceCache.setCache(namespaceEhCache);
|
||||||
|
|
||||||
namespaceDAO.setNamespaceDataCache(namespaceCache);
|
namespaceDAO.setNamespaceRegistryCache(namespaceCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDeleteModel()
|
public void testDeleteModel()
|
||||||
|
@@ -56,11 +56,11 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
private Lock writeLock = lock.writeLock();
|
private Lock writeLock = lock.writeLock();
|
||||||
|
|
||||||
// Internal cache (clusterable)
|
// Internal cache (clusterable)
|
||||||
private SimpleCache<String, NamespaceData> namespaceDataCache;
|
private SimpleCache<String, NamespaceRegistry> namespaceRegistryCache;
|
||||||
|
|
||||||
// used to reset the cache
|
// used to reset the cache
|
||||||
private ThreadLocal<NamespaceData> namespaceDataThreadLocal = new ThreadLocal<NamespaceData>();
|
private ThreadLocal<NamespaceRegistry> namespaceRegistryThreadLocal = new ThreadLocal<NamespaceRegistry>();
|
||||||
private ThreadLocal<NamespaceData> defaultNamespaceDataThreadLocal = new ThreadLocal<NamespaceData>();
|
private ThreadLocal<NamespaceRegistry> defaultNamespaceRegistryThreadLocal = new ThreadLocal<NamespaceRegistry>();
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
private TenantService tenantService;
|
private TenantService tenantService;
|
||||||
@@ -72,9 +72,9 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
this.tenantService = tenantService;
|
this.tenantService = tenantService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNamespaceDataCache(SimpleCache<String, NamespaceData> namespaceDataCache)
|
public void setNamespaceRegistryCache(SimpleCache<String, NamespaceRegistry> namespaceRegistryCache)
|
||||||
{
|
{
|
||||||
this.namespaceDataCache = namespaceDataCache;
|
this.namespaceRegistryCache = namespaceRegistryCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerDictionary(DictionaryDAO dictionaryDAO)
|
public void registerDictionary(DictionaryDAO dictionaryDAO)
|
||||||
@@ -98,7 +98,7 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
{
|
{
|
||||||
String tenantDomain = getTenantDomain();
|
String tenantDomain = getTenantDomain();
|
||||||
|
|
||||||
removeNamespaceData(tenantDomain);
|
removeNamespaceRegistry(tenantDomain);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
@@ -109,7 +109,7 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
/**
|
/**
|
||||||
* Resets the namespaces (by re-initialising the dictionary)
|
* Resets the namespaces (by re-initialising the dictionary)
|
||||||
*/
|
*/
|
||||||
private NamespaceData reset(String tenantDomain)
|
private NamespaceRegistry reset(String tenantDomain)
|
||||||
{
|
{
|
||||||
if (dictionaryDAO == null)
|
if (dictionaryDAO == null)
|
||||||
{
|
{
|
||||||
@@ -124,48 +124,48 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
|
|
||||||
dictionaryDAO.init();
|
dictionaryDAO.init();
|
||||||
|
|
||||||
NamespaceData namespaceData = getNamespaceData(tenantDomain);
|
NamespaceRegistry namespaceRegistry = getNamespaceRegistry(tenantDomain);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("... resetting namespaces completed");
|
logger.debug("... resetting namespaces completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return namespaceData;
|
return namespaceRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamespaceData initNamespace(String tenantDomain)
|
private NamespaceRegistry initNamespace(String tenantDomain)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
createNamespaceLocal(tenantDomain);
|
createNamespaceLocal(tenantDomain);
|
||||||
|
|
||||||
NamespaceData namespaceData = initNamespaceData(tenantDomain);
|
NamespaceRegistry namespaceRegistry = initNamespaceRegistry(tenantDomain);
|
||||||
|
|
||||||
if (namespaceData == null)
|
if (namespaceRegistry == null)
|
||||||
{
|
{
|
||||||
// unexpected
|
// unexpected
|
||||||
throw new AlfrescoRuntimeException("Failed to init namespaceData " + tenantDomain);
|
throw new AlfrescoRuntimeException("Failed to init namespaceRegistry " + tenantDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
writeLock.lock();
|
writeLock.lock();
|
||||||
namespaceDataCache.put(tenantDomain, namespaceData);
|
namespaceRegistryCache.put(tenantDomain, namespaceRegistry);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
writeLock.unlock();
|
writeLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
return namespaceData;
|
return namespaceRegistry;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
readLock.lock();
|
readLock.lock();
|
||||||
if (namespaceDataCache.get(tenantDomain) != null)
|
if (namespaceRegistryCache.get(tenantDomain) != null)
|
||||||
{
|
{
|
||||||
removeNamespaceLocal(tenantDomain);
|
removeNamespaceLocal(tenantDomain);
|
||||||
}
|
}
|
||||||
@@ -177,17 +177,17 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamespaceData initNamespaceData(String tenantDomain)
|
private NamespaceRegistry initNamespaceRegistry(String tenantDomain)
|
||||||
{
|
{
|
||||||
getNamespaceData(tenantDomain).setUrisCache(new ArrayList<String>());
|
getNamespaceRegistry(tenantDomain).setUrisCache(new ArrayList<String>());
|
||||||
getNamespaceData(tenantDomain).setPrefixesCache(new HashMap<String, String>());
|
getNamespaceRegistry(tenantDomain).setPrefixesCache(new HashMap<String, String>());
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("Empty namespaces initialised");
|
logger.debug("Empty namespaces initialised");
|
||||||
}
|
}
|
||||||
|
|
||||||
return getNamespaceDataLocal(tenantDomain);
|
return getNamespaceRegistryLocal(tenantDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -393,18 +393,18 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
|
|
||||||
|
|
||||||
// re-entrant (eg. via reset)
|
// re-entrant (eg. via reset)
|
||||||
private NamespaceData getNamespaceData(String tenantDomain)
|
private NamespaceRegistry getNamespaceRegistry(String tenantDomain)
|
||||||
{
|
{
|
||||||
NamespaceData namespaceData = null;
|
NamespaceRegistry namespaceRegistry = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// check cache first - return if set
|
// check cache first - return if set
|
||||||
readLock.lock();
|
readLock.lock();
|
||||||
namespaceData = namespaceDataCache.get(tenantDomain);
|
namespaceRegistry = namespaceRegistryCache.get(tenantDomain);
|
||||||
|
|
||||||
if (namespaceData != null)
|
if (namespaceRegistry != null)
|
||||||
{
|
{
|
||||||
return namespaceData; // return cached config
|
return namespaceRegistry; // return cached config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -413,62 +413,65 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check threadlocal second - return if set
|
// check threadlocal second - return if set
|
||||||
namespaceData = getNamespaceDataLocal(tenantDomain);
|
namespaceRegistry = getNamespaceRegistryLocal(tenantDomain);
|
||||||
if (namespaceData != null)
|
if (namespaceRegistry != null)
|
||||||
{
|
{
|
||||||
return namespaceData; // return local namespaceData
|
return namespaceRegistry; // return local namespaceRegistry
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset caches - may have been invalidated (e.g. in a cluster)
|
// reset caches - may have been invalidated (e.g. in a cluster)
|
||||||
namespaceData = reset(tenantDomain);
|
namespaceRegistry = reset(tenantDomain);
|
||||||
|
|
||||||
if (namespaceData == null)
|
if (namespaceRegistry == null)
|
||||||
{
|
{
|
||||||
// unexpected
|
// unexpected
|
||||||
throw new AlfrescoRuntimeException("Failed to get namespaceData " + tenantDomain);
|
throw new AlfrescoRuntimeException("Failed to get namespaceRegistry " + tenantDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
return namespaceData;
|
return namespaceRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create threadlocal
|
// create threadlocal
|
||||||
private void createNamespaceLocal(String tenantDomain)
|
private void createNamespaceLocal(String tenantDomain)
|
||||||
{
|
{
|
||||||
// create threadlocal, if needed
|
// create threadlocal, if needed
|
||||||
NamespaceData namespaceData = getNamespaceDataLocal(tenantDomain);
|
NamespaceRegistry namespaceRegistry = getNamespaceRegistryLocal(tenantDomain);
|
||||||
if (namespaceData == null)
|
if (namespaceRegistry == null)
|
||||||
{
|
{
|
||||||
namespaceData = new NamespaceData(tenantDomain);
|
namespaceRegistry = new NamespaceRegistry(tenantDomain);
|
||||||
|
|
||||||
if (tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
|
if (! tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
|
||||||
{
|
{
|
||||||
defaultNamespaceDataThreadLocal.set(namespaceData);
|
namespaceRegistryThreadLocal.set(namespaceRegistry);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (defaultNamespaceRegistryThreadLocal.get() == null)
|
||||||
{
|
{
|
||||||
namespaceDataThreadLocal.set(namespaceData);
|
namespaceRegistry = new NamespaceRegistry(TenantService.DEFAULT_DOMAIN);
|
||||||
|
defaultNamespaceRegistryThreadLocal.set(namespaceRegistry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get threadlocal
|
// get threadlocal
|
||||||
private NamespaceData getNamespaceDataLocal(String tenantDomain)
|
private NamespaceRegistry getNamespaceRegistryLocal(String tenantDomain)
|
||||||
{
|
{
|
||||||
NamespaceData namespaceData = null;
|
NamespaceRegistry namespaceRegistry = null;
|
||||||
|
|
||||||
if (tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
|
if (tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
|
||||||
{
|
{
|
||||||
namespaceData = this.defaultNamespaceDataThreadLocal.get();
|
namespaceRegistry = this.defaultNamespaceRegistryThreadLocal.get();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
namespaceData = this.namespaceDataThreadLocal.get();
|
namespaceRegistry = this.namespaceRegistryThreadLocal.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if domain switched (eg. during login)
|
// check to see if domain switched (eg. during login)
|
||||||
if ((namespaceData != null) && (tenantDomain.equals(namespaceData.getTenantDomain())))
|
if ((namespaceRegistry != null) && (tenantDomain.equals(namespaceRegistry.getTenantDomain())))
|
||||||
{
|
{
|
||||||
return namespaceData; // return threadlocal, if set
|
return namespaceRegistry; // return threadlocal, if set
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -479,22 +482,22 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
{
|
{
|
||||||
if (tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
|
if (tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
|
||||||
{
|
{
|
||||||
defaultNamespaceDataThreadLocal.set(null); // it's in the cache, clear the threadlocal
|
defaultNamespaceRegistryThreadLocal.set(null); // it's in the cache, clear the threadlocal
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
namespaceDataThreadLocal.set(null); // it's in the cache, clear the threadlocal
|
namespaceRegistryThreadLocal.set(null); // it's in the cache, clear the threadlocal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeNamespaceData(String tenantDomain)
|
private void removeNamespaceRegistry(String tenantDomain)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
writeLock.lock();
|
writeLock.lock();
|
||||||
if (namespaceDataCache.get(tenantDomain) != null)
|
if (namespaceRegistryCache.get(tenantDomain) != null)
|
||||||
{
|
{
|
||||||
namespaceDataCache.remove(tenantDomain);
|
namespaceRegistryCache.remove(tenantDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeNamespaceLocal(tenantDomain);
|
removeNamespaceLocal(tenantDomain);
|
||||||
@@ -523,7 +526,7 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
*/
|
*/
|
||||||
private List<String> getUrisCtx(String tenantDomain)
|
private List<String> getUrisCtx(String tenantDomain)
|
||||||
{
|
{
|
||||||
return getNamespaceData(tenantDomain).getUrisCache();
|
return getNamespaceRegistry(tenantDomain).getUrisCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -544,7 +547,7 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
*/
|
*/
|
||||||
private Map<String, String> getPrefixesCtx(String tenantDomain)
|
private Map<String, String> getPrefixesCtx(String tenantDomain)
|
||||||
{
|
{
|
||||||
return getNamespaceData(tenantDomain).getPrefixesCache();
|
return getNamespaceRegistry(tenantDomain).getPrefixesCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -555,14 +558,14 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
return tenantService.getCurrentUserDomain();
|
return tenantService.getCurrentUserDomain();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ class NamespaceData
|
/* package */ class NamespaceRegistry
|
||||||
{
|
{
|
||||||
private List<String> urisCache;
|
private List<String> urisCache = new ArrayList<String>(0);
|
||||||
private Map<String, String> prefixesCache;
|
private Map<String, String> prefixesCache = new HashMap<String, String>(0);
|
||||||
|
|
||||||
private String tenantDomain;
|
private String tenantDomain;
|
||||||
|
|
||||||
public NamespaceData(String tenantDomain)
|
public NamespaceRegistry(String tenantDomain)
|
||||||
{
|
{
|
||||||
this.tenantDomain = tenantDomain;
|
this.tenantDomain = tenantDomain;
|
||||||
}
|
}
|
||||||
|
@@ -26,16 +26,15 @@ package org.alfresco.repo.dictionary;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import net.sf.ehcache.Cache;
|
import net.sf.ehcache.Cache;
|
||||||
import net.sf.ehcache.CacheManager;
|
import net.sf.ehcache.CacheManager;
|
||||||
|
|
||||||
import org.alfresco.repo.cache.EhCacheAdapter;
|
import org.alfresco.repo.cache.EhCacheAdapter;
|
||||||
import org.alfresco.repo.dictionary.NamespaceDAOImpl.NamespaceData;
|
import org.alfresco.repo.dictionary.DictionaryDAOImpl.DictionaryRegistry;
|
||||||
|
import org.alfresco.repo.dictionary.NamespaceDAOImpl.NamespaceRegistry;
|
||||||
import org.alfresco.repo.tenant.SingleTServiceImpl;
|
import org.alfresco.repo.tenant.SingleTServiceImpl;
|
||||||
import org.alfresco.repo.tenant.TenantService;
|
import org.alfresco.repo.tenant.TenantService;
|
||||||
import org.alfresco.service.namespace.QName;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,19 +113,12 @@ public class TestModel
|
|||||||
{
|
{
|
||||||
CacheManager cacheManager = new CacheManager();
|
CacheManager cacheManager = new CacheManager();
|
||||||
|
|
||||||
Cache uriToModelsEhCache = new Cache("uriToModelsCache", 50, false, true, 0L, 0L);
|
Cache dictionaryEhCache = new Cache("dictionaryCache", 50, false, true, 0L, 0L);
|
||||||
cacheManager.addCache(uriToModelsEhCache);
|
cacheManager.addCache(dictionaryEhCache);
|
||||||
EhCacheAdapter<String, Map<String, List<CompiledModel>>> uriToModelsCache = new EhCacheAdapter<String, Map<String, List<CompiledModel>>>();
|
EhCacheAdapter<String, DictionaryRegistry> dictionaryCache = new EhCacheAdapter<String, DictionaryRegistry>();
|
||||||
uriToModelsCache.setCache(uriToModelsEhCache);
|
dictionaryCache.setCache(dictionaryEhCache);
|
||||||
|
|
||||||
dictionaryDAO.setUriToModelsCache(uriToModelsCache);
|
dictionaryDAO.setDictionaryRegistryCache(dictionaryCache);
|
||||||
|
|
||||||
Cache compileModelsEhCache = new Cache("compiledModelsCache", 50, false, true, 0L, 0L);
|
|
||||||
cacheManager.addCache(compileModelsEhCache);
|
|
||||||
EhCacheAdapter<String, Map<QName,CompiledModel>> compileModelCache = new EhCacheAdapter<String, Map<QName,CompiledModel>>();
|
|
||||||
compileModelCache.setCache(compileModelsEhCache);
|
|
||||||
|
|
||||||
dictionaryDAO.setCompiledModelsCache(compileModelCache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initNamespaceCaches(NamespaceDAOImpl namespaceDAO)
|
private static void initNamespaceCaches(NamespaceDAOImpl namespaceDAO)
|
||||||
@@ -135,9 +127,9 @@ public class TestModel
|
|||||||
|
|
||||||
Cache namespaceEhCache = new Cache("namespaceCache", 50, false, true, 0L, 0L);
|
Cache namespaceEhCache = new Cache("namespaceCache", 50, false, true, 0L, 0L);
|
||||||
cacheManager.addCache(namespaceEhCache);
|
cacheManager.addCache(namespaceEhCache);
|
||||||
EhCacheAdapter<String, NamespaceData> namespaceCache = new EhCacheAdapter<String, NamespaceData>();
|
EhCacheAdapter<String, NamespaceRegistry> namespaceCache = new EhCacheAdapter<String, NamespaceRegistry>();
|
||||||
namespaceCache.setCache(namespaceEhCache);
|
namespaceCache.setCache(namespaceEhCache);
|
||||||
|
|
||||||
namespaceDAO.setNamespaceDataCache(namespaceCache);
|
namespaceDAO.setNamespaceRegistryCache(namespaceCache);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -29,10 +29,7 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import net.sf.ehcache.Cache;
|
|
||||||
import net.sf.ehcache.CacheManager;
|
|
||||||
|
|
||||||
import org.alfresco.repo.cache.EhCacheAdapter;
|
|
||||||
import org.alfresco.repo.cache.NullCache;
|
import org.alfresco.repo.cache.NullCache;
|
||||||
import org.alfresco.repo.dictionary.DictionaryBootstrap;
|
import org.alfresco.repo.dictionary.DictionaryBootstrap;
|
||||||
import org.alfresco.repo.dictionary.DictionaryComponent;
|
import org.alfresco.repo.dictionary.DictionaryComponent;
|
||||||
@@ -93,30 +90,15 @@ public class PolicyComponentTest extends TestCase
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void initDictionaryCaches(DictionaryDAOImpl dictionaryDAO)
|
private void initDictionaryCaches(DictionaryDAOImpl dictionaryDAO)
|
||||||
{
|
{
|
||||||
CacheManager cacheManager = new CacheManager();
|
// note: unit tested here with null cache
|
||||||
|
dictionaryDAO.setDictionaryRegistryCache(new NullCache());
|
||||||
Cache uriToModelsEhCache = new Cache("uriToModelsCache", 50, false, true, 0L, 0L);
|
|
||||||
cacheManager.addCache(uriToModelsEhCache);
|
|
||||||
//EhCacheAdapter<String, Map<String, List<CompiledModel>>> uriToModelsCache = new EhCacheAdapter<String, Map<String, List<CompiledModel>>>();
|
|
||||||
EhCacheAdapter uriToModelsCache = new EhCacheAdapter();
|
|
||||||
uriToModelsCache.setCache(uriToModelsEhCache);
|
|
||||||
|
|
||||||
dictionaryDAO.setUriToModelsCache(uriToModelsCache);
|
|
||||||
|
|
||||||
Cache compileModelsEhCache = new Cache("compiledModelsCache", 50, false, true, 0L, 0L);
|
|
||||||
cacheManager.addCache(compileModelsEhCache);
|
|
||||||
//EhCacheAdapter<String, Map<QName,CompiledModel>> compileModelCache = new EhCacheAdapter<String, Map<QName,CompiledModel>>();
|
|
||||||
EhCacheAdapter compileModelCache = new EhCacheAdapter();
|
|
||||||
compileModelCache.setCache(compileModelsEhCache);
|
|
||||||
|
|
||||||
dictionaryDAO.setCompiledModelsCache(compileModelCache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void initNamespaceCaches(NamespaceDAOImpl namespaceDAO)
|
private void initNamespaceCaches(NamespaceDAOImpl namespaceDAO)
|
||||||
{
|
{
|
||||||
// note: unit tested here with null cache
|
// note: unit tested here with null cache
|
||||||
namespaceDAO.setNamespaceDataCache(new NullCache());
|
namespaceDAO.setNamespaceRegistryCache(new NullCache());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testJavaBehaviour()
|
public void testJavaBehaviour()
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -34,6 +34,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryService;
|
|||||||
import org.alfresco.service.cmr.repository.ContentService;
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,6 +136,19 @@ public class ADMLuceneIndexerAndSearcherFactory extends AbstractLuceneIndexerAnd
|
|||||||
return searcher;
|
return searcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected SearchService getNodeSearcher() throws SearcherException
|
||||||
|
{
|
||||||
|
ADMLuceneSearcherImpl searcher = ADMLuceneSearcherImpl.getNodeSearcher();
|
||||||
|
searcher.setNamespacePrefixResolver(nameSpaceService);
|
||||||
|
searcher.setNodeService(nodeService);
|
||||||
|
searcher.setTenantService(tenantService);
|
||||||
|
searcher.setDictionaryService(dictionaryService);
|
||||||
|
searcher.setQueryRegister(getQueryRegister());
|
||||||
|
searcher.setQueryEngine(queryEngine);
|
||||||
|
searcher.setDictionaryService(dictionaryService);
|
||||||
|
return searcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected List<StoreRef> getAllStores()
|
protected List<StoreRef> getAllStores()
|
||||||
{
|
{
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -37,7 +37,6 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.cmis.CMISQueryException;
|
|
||||||
import org.alfresco.i18n.I18NUtil;
|
import org.alfresco.i18n.I18NUtil;
|
||||||
import org.alfresco.repo.search.CannedQueryDef;
|
import org.alfresco.repo.search.CannedQueryDef;
|
||||||
import org.alfresco.repo.search.EmptyResultSet;
|
import org.alfresco.repo.search.EmptyResultSet;
|
||||||
@@ -53,11 +52,9 @@ import org.alfresco.repo.search.impl.querymodel.QueryEngine;
|
|||||||
import org.alfresco.repo.search.impl.querymodel.QueryEngineResults;
|
import org.alfresco.repo.search.impl.querymodel.QueryEngineResults;
|
||||||
import org.alfresco.repo.search.impl.querymodel.QueryModelFactory;
|
import org.alfresco.repo.search.impl.querymodel.QueryModelFactory;
|
||||||
import org.alfresco.repo.search.impl.querymodel.QueryOptions;
|
import org.alfresco.repo.search.impl.querymodel.QueryOptions;
|
||||||
import org.alfresco.repo.search.impl.querymodel.Selector;
|
|
||||||
import org.alfresco.repo.search.results.SortedResultSet;
|
import org.alfresco.repo.search.results.SortedResultSet;
|
||||||
import org.alfresco.repo.tenant.TenantService;
|
import org.alfresco.repo.tenant.TenantService;
|
||||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
|
||||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
@@ -162,6 +159,15 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
|||||||
return getSearcher(storeRef, null, config);
|
return getSearcher(storeRef, null, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a select-node-based searcher
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static ADMLuceneSearcherImpl getNodeSearcher()
|
||||||
|
{
|
||||||
|
return new ADMLuceneSearcherImpl();
|
||||||
|
}
|
||||||
|
|
||||||
public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver)
|
public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver)
|
||||||
{
|
{
|
||||||
this.namespacePrefixResolver = namespacePrefixResolver;
|
this.namespacePrefixResolver = namespacePrefixResolver;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -40,9 +40,8 @@ import org.alfresco.service.cmr.dictionary.DictionaryService;
|
|||||||
import org.alfresco.service.cmr.repository.ContentService;
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for AVM indexers and searchers
|
* Factory for AVM indexers and searchers
|
||||||
@@ -52,7 +51,7 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
*/
|
*/
|
||||||
public class AVMLuceneIndexerAndSearcherFactory extends AbstractLuceneIndexerAndSearcherFactory implements SupportsBackgroundIndexing
|
public class AVMLuceneIndexerAndSearcherFactory extends AbstractLuceneIndexerAndSearcherFactory implements SupportsBackgroundIndexing
|
||||||
{
|
{
|
||||||
private static Log s_logger = LogFactory.getLog(AVMLuceneIndexerAndSearcherFactory.class);
|
//private static Log s_logger = LogFactory.getLog(AVMLuceneIndexerAndSearcherFactory.class);
|
||||||
|
|
||||||
private DictionaryService dictionaryService;
|
private DictionaryService dictionaryService;
|
||||||
|
|
||||||
@@ -191,6 +190,12 @@ public class AVMLuceneIndexerAndSearcherFactory extends AbstractLuceneIndexerAnd
|
|||||||
return searcher;
|
return searcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SearchService getNodeSearcher() throws SearcherException
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the full text searcher (done by the seracher bean to break cyclic bean defs)
|
* Register the full text searcher (done by the seracher bean to break cyclic bean defs)
|
||||||
*
|
*
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -60,6 +60,7 @@ import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
|||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@@ -465,6 +466,11 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
|
|||||||
return searcher;
|
return searcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get node-based searcher (for "selectNodes / selectProperties")
|
||||||
|
*/
|
||||||
|
protected abstract SearchService getNodeSearcher() throws SearcherException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a searcher over the index and the current delta
|
* Get a searcher over the index and the current delta
|
||||||
*
|
*
|
||||||
|
@@ -493,12 +493,13 @@ public class MultiTDemoTest extends TestCase
|
|||||||
{
|
{
|
||||||
NodeRef homeSpaceRef = getHomeSpaceFolderNode(tenantUserName);
|
NodeRef homeSpaceRef = getHomeSpaceFolderNode(tenantUserName);
|
||||||
|
|
||||||
NodeRef contentRef = addTextContent(homeSpaceRef, tenantUserName+" quick brown fox.txt", "The quick brown fox jumps over the lazy dog (tenant " + tenantDomain + ")");
|
NodeRef contentRef = addContent(homeSpaceRef, tenantUserName+" quick brown fox.txt", "The quick brown fox jumps over the lazy dog (tenant " + tenantDomain + ")", MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||||
nodeService.addAspect(contentRef, ContentModel.ASPECT_VERSIONABLE, null);
|
nodeService.addAspect(contentRef, ContentModel.ASPECT_VERSIONABLE, null);
|
||||||
|
|
||||||
if (tenantDomain.equals(TEST_TENANT_DOMAIN2))
|
if (tenantDomain.equals(TEST_TENANT_DOMAIN2))
|
||||||
{
|
{
|
||||||
contentRef = addTextContent(homeSpaceRef, tenantUserName+" quick brown fox ANO.txt", "The quick brown fox jumps over the lazy dog ANO (tenant " + tenantDomain + ")");
|
contentRef = addContent(homeSpaceRef, tenantUserName+" quick brown fox ANO.txt", "The quick brown fox jumps over the lazy dog ANO (tenant " + tenantDomain + ")", MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||||
|
|
||||||
nodeService.addAspect(contentRef, ContentModel.ASPECT_VERSIONABLE, null);
|
nodeService.addAspect(contentRef, ContentModel.ASPECT_VERSIONABLE, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,7 +520,12 @@ public class MultiTDemoTest extends TestCase
|
|||||||
{
|
{
|
||||||
public Object doWork() throws Exception
|
public Object doWork() throws Exception
|
||||||
{
|
{
|
||||||
assertTrue("System: ", (nodeService.getStores().size() >= (DEFAULT_STORE_COUNT * (tenants.size()+1))));
|
for (StoreRef storeRef : nodeService.getStores())
|
||||||
|
{
|
||||||
|
System.out.println("StoreRef: "+storeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue("System: "+nodeService.getStores().size()+", "+(tenants.size()+1), (nodeService.getStores().size() >= (DEFAULT_STORE_COUNT * (tenants.size()+1))));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}, AuthenticationUtil.getSystemUserName());
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
@@ -529,7 +535,7 @@ public class MultiTDemoTest extends TestCase
|
|||||||
{
|
{
|
||||||
public Object doWork() throws Exception
|
public Object doWork() throws Exception
|
||||||
{
|
{
|
||||||
assertTrue("Super admin: ", (nodeService.getStores().size() >= DEFAULT_STORE_COUNT));
|
assertTrue("Super admin: "+nodeService.getStores().size(), (nodeService.getStores().size() >= DEFAULT_STORE_COUNT));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}, AuthenticationUtil.getAdminUserName());
|
}, AuthenticationUtil.getAdminUserName());
|
||||||
@@ -644,7 +650,7 @@ public class MultiTDemoTest extends TestCase
|
|||||||
public Object doWork() throws Exception
|
public Object doWork() throws Exception
|
||||||
{
|
{
|
||||||
NodeRef homeSpaceRef = getHomeSpaceFolderNode(tenantUserName);
|
NodeRef homeSpaceRef = getHomeSpaceFolderNode(tenantUserName);
|
||||||
NodeRef contentRef = addTextContent(homeSpaceRef, tenantUserName+" tqbfjotld.txt", "The quick brown fox jumps over the lazy dog (tenant " + tenantDomain + ")");
|
NodeRef contentRef = addContent(homeSpaceRef, tenantUserName+" tqbfjotld.txt", "The quick brown fox jumps over the lazy dog (tenant " + tenantDomain + ")", MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||||
|
|
||||||
NodeRef storeArchiveNode = nodeService.getStoreArchiveNode(contentRef.getStoreRef());
|
NodeRef storeArchiveNode = nodeService.getStoreArchiveNode(contentRef.getStoreRef());
|
||||||
|
|
||||||
@@ -662,9 +668,9 @@ public class MultiTDemoTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCustomDynamicModels()
|
public void testCustomModels()
|
||||||
{
|
{
|
||||||
logger.info("test custom/dynamic models");
|
logger.info("test custom models");
|
||||||
|
|
||||||
final int defaultModelCnt = dictionaryService.getAllModels().size();
|
final int defaultModelCnt = dictionaryService.getAllModels().size();
|
||||||
|
|
||||||
@@ -715,6 +721,33 @@ public class MultiTDemoTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAddCustomWebClient()
|
||||||
|
{
|
||||||
|
// note: add as demo files - need to re-start Alfresco to see custom web client config / messages
|
||||||
|
logger.info("test add custom web client config");
|
||||||
|
|
||||||
|
for (final String tenantDomain : tenants)
|
||||||
|
{
|
||||||
|
final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
NodeRef webClientExtFolder = getWebClientExtensionNodeRef(SPACES_STORE);
|
||||||
|
|
||||||
|
InputStream is = getClass().getClassLoader().getResourceAsStream("tenant/webclient.properties");
|
||||||
|
addContent(webClientExtFolder, "webclient.properties", is, MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||||
|
|
||||||
|
is = getClass().getClassLoader().getResourceAsStream("tenant/web-client-config-custom.xml");
|
||||||
|
addContent(webClientExtFolder, "web-client-config-custom.xml", is, MimetypeMap.MIMETYPE_XML);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, tenantAdminName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createGroup(String shortName, String parentShortName)
|
private void createGroup(String shortName, String parentShortName)
|
||||||
{
|
{
|
||||||
// create new Group using authority Service
|
// create new Group using authority Service
|
||||||
@@ -816,6 +849,12 @@ public class MultiTDemoTest extends TestCase
|
|||||||
return findFolderNodeRef(storeRef, "/app:company_home/app:user_homes");
|
return findFolderNodeRef(storeRef, "/app:company_home/app:user_homes");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NodeRef getWebClientExtensionNodeRef(StoreRef storeRef)
|
||||||
|
{
|
||||||
|
// get the "Web Client Extensions" location
|
||||||
|
return findFolderNodeRef(storeRef, "/app:company_home/app:dictionary/app:webclient_extension");
|
||||||
|
}
|
||||||
|
|
||||||
private NodeRef findFolderNodeRef(StoreRef storeRef, String folderXPath)
|
private NodeRef findFolderNodeRef(StoreRef storeRef, String folderXPath)
|
||||||
{
|
{
|
||||||
ResultSet rs = this.searchService.query(storeRef, SearchService.LANGUAGE_XPATH, folderXPath);
|
ResultSet rs = this.searchService.query(storeRef, SearchService.LANGUAGE_XPATH, folderXPath);
|
||||||
@@ -926,7 +965,7 @@ public class MultiTDemoTest extends TestCase
|
|||||||
return (NodeRef)this.nodeService.getProperty(personService.getPerson(userName), ContentModel.PROP_HOMEFOLDER);
|
return (NodeRef)this.nodeService.getProperty(personService.getPerson(userName), ContentModel.PROP_HOMEFOLDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NodeRef addTextContent(NodeRef spaceRef, String name, String textData)
|
private NodeRef addContent(NodeRef spaceRef, String name, String textData, String mimeType)
|
||||||
{
|
{
|
||||||
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
|
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
|
||||||
contentProps.put(ContentModel.PROP_NAME, name);
|
contentProps.put(ContentModel.PROP_NAME, name);
|
||||||
@@ -947,7 +986,7 @@ public class MultiTDemoTest extends TestCase
|
|||||||
|
|
||||||
ContentWriter writer = contentService.getWriter(content, ContentModel.PROP_CONTENT, true);
|
ContentWriter writer = contentService.getWriter(content, ContentModel.PROP_CONTENT, true);
|
||||||
|
|
||||||
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
writer.setMimetype(mimeType);
|
||||||
writer.setEncoding("UTF-8");
|
writer.setEncoding("UTF-8");
|
||||||
|
|
||||||
writer.putContent(textData);
|
writer.putContent(textData);
|
||||||
@@ -955,6 +994,35 @@ public class MultiTDemoTest extends TestCase
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NodeRef addContent(NodeRef spaceRef, String name, InputStream is, String mimeType)
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
|
||||||
|
contentProps.put(ContentModel.PROP_NAME, name);
|
||||||
|
|
||||||
|
ChildAssociationRef association = nodeService.createNode(spaceRef,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
|
||||||
|
ContentModel.TYPE_CONTENT,
|
||||||
|
contentProps);
|
||||||
|
|
||||||
|
NodeRef content = association.getChildRef();
|
||||||
|
|
||||||
|
// add titled aspect (for Web Client display)
|
||||||
|
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>();
|
||||||
|
titledProps.put(ContentModel.PROP_TITLE, name);
|
||||||
|
titledProps.put(ContentModel.PROP_DESCRIPTION, name);
|
||||||
|
this.nodeService.addAspect(content, ContentModel.ASPECT_TITLED, titledProps);
|
||||||
|
|
||||||
|
ContentWriter writer = contentService.getWriter(content, ContentModel.PROP_CONTENT, true);
|
||||||
|
|
||||||
|
writer.setMimetype(mimeType);
|
||||||
|
writer.setEncoding("UTF-8");
|
||||||
|
|
||||||
|
writer.putContent(is);
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// comment-in to run from command line
|
// comment-in to run from command line
|
||||||
public static void main(String args[])
|
public static void main(String args[])
|
||||||
|
@@ -256,7 +256,7 @@ public class WorkflowDeployer extends AbstractLifecycleBean
|
|||||||
userTransaction.begin();
|
userTransaction.begin();
|
||||||
|
|
||||||
// bootstrap the workflow models and static labels (from classpath)
|
// bootstrap the workflow models and static labels (from classpath)
|
||||||
if (models != null && resourceBundles != null)
|
if (models != null && resourceBundles != null && ((models.size() > 0) || (resourceBundles.size() > 0)))
|
||||||
{
|
{
|
||||||
DictionaryBootstrap dictionaryBootstrap = new DictionaryBootstrap();
|
DictionaryBootstrap dictionaryBootstrap = new DictionaryBootstrap();
|
||||||
dictionaryBootstrap.setDictionaryDAO(dictionaryDAO);
|
dictionaryBootstrap.setDictionaryDAO(dictionaryDAO);
|
||||||
|
121
source/test-resources/tenant/web-client-config-custom.xml
Executable file
121
source/test-resources/tenant/web-client-config-custom.xml
Executable file
@@ -0,0 +1,121 @@
|
|||||||
|
<alfresco-config>
|
||||||
|
|
||||||
|
<!-- Example of overriding the search settings -->
|
||||||
|
<config>
|
||||||
|
<client>
|
||||||
|
<search-max-results>2</search-max-results>
|
||||||
|
|
||||||
|
<!-- Shelf component default visibility, set to false to hide the shelf by default -->
|
||||||
|
<shelf-visible>false</shelf-visible>
|
||||||
|
</client>
|
||||||
|
</config>
|
||||||
|
|
||||||
|
<!-- Example of adding languages to the list in the login page -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<config evaluator="string-compare" condition="Languages">
|
||||||
|
<languages>
|
||||||
|
<language locale="ca_ES">Catalan</language>
|
||||||
|
<language locale="da_DK">Danish</language>
|
||||||
|
<language locale="de_DE">German</language>
|
||||||
|
<language locale="es_ES">Spanish</language>
|
||||||
|
<language locale="el_GR">Greek</language>
|
||||||
|
<language locale="fr_FR">French</language>
|
||||||
|
<language locale="it_IT">Italian</language>
|
||||||
|
<language locale="ja_JP">Japanese</language>
|
||||||
|
<language locale="du_NL">Dutch</language>
|
||||||
|
<language locale="pt_BR">Portuguese (Brazilian)</language>
|
||||||
|
<language locale="ru_RU">Russian</language>
|
||||||
|
<language locale="fi_FI">Finnish</language>
|
||||||
|
<language locale="tr_TR">Turkish</language>
|
||||||
|
<language locale="zh_CN">Simplified Chinese</language>
|
||||||
|
</languages>
|
||||||
|
</config>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Example of configuring advanced search -->
|
||||||
|
<!--
|
||||||
|
<config evaluator="string-compare" condition="Advanced Search">
|
||||||
|
<advanced-search>
|
||||||
|
<content-types>
|
||||||
|
</content-types>
|
||||||
|
<custom-properties>
|
||||||
|
<meta-data aspect="app:simpleworkflow" property="app:approveStep" />
|
||||||
|
</custom-properties>
|
||||||
|
</advanced-search>
|
||||||
|
</config>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Example of changing the sort direction for a view in the client -->
|
||||||
|
<!--
|
||||||
|
<config evaluator="string-compare" condition="Views">
|
||||||
|
<views>
|
||||||
|
<view-defaults>
|
||||||
|
<topic>
|
||||||
|
<sort-direction>ascending</sort-direction>
|
||||||
|
</topic>
|
||||||
|
</view-defaults>
|
||||||
|
</views>
|
||||||
|
</config>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Example of adding a custom icon to the Create Space dialog -->
|
||||||
|
<!--
|
||||||
|
<config evaluator="string-compare" condition="cm:folder icons">
|
||||||
|
<icons>
|
||||||
|
<icon name="space-icon-custom" path="/images/icons/space-icon-custom.gif" />
|
||||||
|
</icons>
|
||||||
|
</config>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- The config below shows how to incorporate the example model-->
|
||||||
|
<!-- into the web client, for this to work you will need to -->
|
||||||
|
<!-- rename example-model-context.xml.sample to example-model-context.xml -->
|
||||||
|
|
||||||
|
<config evaluator="string-compare" condition="Content Wizards">
|
||||||
|
<content-types>
|
||||||
|
<type name="my:sop" />
|
||||||
|
</content-types>
|
||||||
|
</config>
|
||||||
|
|
||||||
|
<config evaluator="node-type" condition="my:sop">
|
||||||
|
<property-sheet>
|
||||||
|
<show-property name="mimetype" display-label-id="content_type"
|
||||||
|
component-generator="MimeTypeSelectorGenerator" />
|
||||||
|
<show-property name="size" display-label-id="size"
|
||||||
|
converter="org.alfresco.faces.ByteSizeConverter"
|
||||||
|
show-in-edit-mode="false" />
|
||||||
|
<show-property name="my:publishedDate" display-label-id="my.publishedDate" />
|
||||||
|
<show-association name="my:signOff" display-label-id="my.signOff" />
|
||||||
|
<show-property name="my:authorisedBy" display-label-id="my.authorisedBy" />
|
||||||
|
<show-child-association name="my:processSteps" display-label-id="my.processSteps" />
|
||||||
|
</property-sheet>
|
||||||
|
</config>
|
||||||
|
|
||||||
|
<config evaluator="aspect-name" condition="my:imageClassification">
|
||||||
|
<property-sheet>
|
||||||
|
<show-property name="my:width" display-label-id="my.width" />
|
||||||
|
<show-property name="my:height" display-label-id="my.height" />
|
||||||
|
<show-property name="my:resolution" display-label-id="my.resolution" />
|
||||||
|
</property-sheet>
|
||||||
|
</config>
|
||||||
|
|
||||||
|
<config evaluator="string-compare" condition="Action Wizards">
|
||||||
|
<aspects>
|
||||||
|
<aspect name="my:imageClassification"/>
|
||||||
|
</aspects>
|
||||||
|
</config>
|
||||||
|
|
||||||
|
<config evaluator="string-compare" condition="Advanced Search">
|
||||||
|
<advanced-search>
|
||||||
|
<content-types>
|
||||||
|
<type name="my:sop" />
|
||||||
|
</content-types>
|
||||||
|
<custom-properties>
|
||||||
|
<meta-data type="my:sop" property="my:authorisedBy" />
|
||||||
|
<meta-data aspect="my:imageClassification" property="my:resolution" />
|
||||||
|
</custom-properties>
|
||||||
|
</advanced-search>
|
||||||
|
</config>
|
||||||
|
|
||||||
|
</alfresco-config>
|
15
source/test-resources/tenant/webclient.properties
Executable file
15
source/test-resources/tenant/webclient.properties
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
# web client custom I18N message properties
|
||||||
|
|
||||||
|
# example model
|
||||||
|
# see display-label-ids added to the web-client-config-custom.xml sample
|
||||||
|
|
||||||
|
# my:sop
|
||||||
|
my.publishedDate= publié Published Date
|
||||||
|
my.authorisedBy=Authorised By
|
||||||
|
my.signOff= publié Sign Off
|
||||||
|
my.processSteps=Process Steps
|
||||||
|
|
||||||
|
# my:imageClassification
|
||||||
|
my.width=Width
|
||||||
|
my.height=Height
|
||||||
|
my.resolution=Resolution
|
Reference in New Issue
Block a user