mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Dictionary optimisation: improve performance when getting sub classes and property defs
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6825 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -126,6 +126,15 @@ public class DictionaryComponent implements DictionaryService, TenantDeployer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.dictionary.DictionaryService#getSubTypes(org.alfresco.service.namespace.QName, boolean)
|
||||||
|
*/
|
||||||
|
public Collection<QName> getSubTypes(QName superType, boolean follow)
|
||||||
|
{
|
||||||
|
return dictionaryDAO.getSubTypes(superType, follow);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.dictionary.DictionaryService#getTypes(org.alfresco.repo.ref.QName)
|
* @see org.alfresco.repo.dictionary.DictionaryService#getTypes(org.alfresco.repo.ref.QName)
|
||||||
*/
|
*/
|
||||||
@@ -155,6 +164,15 @@ public class DictionaryComponent implements DictionaryService, TenantDeployer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.dictionary.DictionaryService#getSubAspects(org.alfresco.service.namespace.QName, boolean)
|
||||||
|
*/
|
||||||
|
public Collection<QName> getSubAspects(QName superAspect, boolean follow)
|
||||||
|
{
|
||||||
|
return dictionaryDAO.getSubAspects(superAspect, follow);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.dictionary.DictionaryService#getAspects(org.alfresco.repo.ref.QName)
|
* @see org.alfresco.repo.dictionary.DictionaryService#getAspects(org.alfresco.repo.ref.QName)
|
||||||
*/
|
*/
|
||||||
@@ -278,6 +296,19 @@ public class DictionaryComponent implements DictionaryService, TenantDeployer
|
|||||||
}
|
}
|
||||||
return propDef;
|
return propDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.dictionary.DictionaryService#getPropertyDefs(org.alfresco.service.namespace.QName)
|
||||||
|
*/
|
||||||
|
public Map<QName,PropertyDefinition> getPropertyDefs(QName className)
|
||||||
|
{
|
||||||
|
ClassDefinition classDef = dictionaryDAO.getClass(className);
|
||||||
|
if (classDef != null)
|
||||||
|
{
|
||||||
|
return classDef.getProperties();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@@ -65,12 +65,26 @@ public interface DictionaryDAO extends ModelQuery
|
|||||||
* @return the types of the model
|
* @return the types of the model
|
||||||
*/
|
*/
|
||||||
public Collection<TypeDefinition> getTypes(QName model);
|
public Collection<TypeDefinition> getTypes(QName model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param superType
|
||||||
|
* @param follow true => follow up the super-class hierarchy, false => immediate sub types only
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Collection<QName> getSubTypes(QName superType, boolean follow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param model the model to retrieve aspects for
|
* @param model the model to retrieve aspects for
|
||||||
* @return the aspects of the model
|
* @return the aspects of the model
|
||||||
*/
|
*/
|
||||||
public Collection<AspectDefinition> getAspects(QName model);
|
public Collection<AspectDefinition> getAspects(QName model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param superAspect
|
||||||
|
* @param follow true => follow up the super-class hierarchy, false => immediate sub aspects only
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Collection<QName> getSubAspects(QName superAspect, boolean follow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param model the model for which to get properties for
|
* @param model the model for which to get properties for
|
||||||
|
@@ -511,6 +511,54 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.dictionary.DictionaryDAO#getSubTypes(org.alfresco.service.namespace.QName, boolean)
|
||||||
|
*/
|
||||||
|
public Collection<QName> getSubTypes(QName superType, boolean follow)
|
||||||
|
{
|
||||||
|
// note: could be optimised further, if compiled into the model
|
||||||
|
|
||||||
|
// Get all types (with parent type) for all models
|
||||||
|
Map<QName, QName> allTypesAndParents = new HashMap<QName, QName>(); // name, parent
|
||||||
|
|
||||||
|
for (CompiledModel model : getCompiledModels().values())
|
||||||
|
{
|
||||||
|
for (TypeDefinition type : model.getTypes())
|
||||||
|
{
|
||||||
|
allTypesAndParents.put(type.getName(), type.getParentName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get sub types
|
||||||
|
HashSet<QName> subTypes = new HashSet<QName>();
|
||||||
|
for (QName type : allTypesAndParents.keySet())
|
||||||
|
{
|
||||||
|
if (follow)
|
||||||
|
{
|
||||||
|
// all sub types
|
||||||
|
QName current = type;
|
||||||
|
while ((current != null) && !current.equals(superType))
|
||||||
|
{
|
||||||
|
current = allTypesAndParents.get(current); // get parent
|
||||||
|
}
|
||||||
|
if (current != null)
|
||||||
|
{
|
||||||
|
subTypes.add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// immediate sub types only
|
||||||
|
if (allTypesAndParents.get(type).equals(superType))
|
||||||
|
{
|
||||||
|
subTypes.add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return subTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -529,6 +577,53 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.dictionary.DictionaryDAO#getSubAspects(org.alfresco.service.namespace.QName, boolean)
|
||||||
|
*/
|
||||||
|
public Collection<QName> getSubAspects(QName superAspect, boolean follow)
|
||||||
|
{
|
||||||
|
// note: could be optimised further, if compiled into the model
|
||||||
|
|
||||||
|
// Get all aspects (with parent aspect) for all models
|
||||||
|
Map<QName, QName> allAspectsAndParents = new HashMap<QName, QName>(); // name, parent
|
||||||
|
|
||||||
|
for (CompiledModel model : getCompiledModels().values())
|
||||||
|
{
|
||||||
|
for (AspectDefinition aspect : model.getAspects())
|
||||||
|
{
|
||||||
|
allAspectsAndParents.put(aspect.getName(), aspect.getParentName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get sub aspects
|
||||||
|
HashSet<QName> subAspects = new HashSet<QName>();
|
||||||
|
for (QName aspect : allAspectsAndParents.keySet())
|
||||||
|
{
|
||||||
|
if (follow)
|
||||||
|
{
|
||||||
|
// all sub aspects
|
||||||
|
QName current = aspect;
|
||||||
|
while ((current != null) && !current.equals(superAspect))
|
||||||
|
{
|
||||||
|
current = allAspectsAndParents.get(current); // get parent
|
||||||
|
}
|
||||||
|
if (current != null)
|
||||||
|
{
|
||||||
|
subAspects.add(aspect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// immediate sub aspects only
|
||||||
|
if (allAspectsAndParents.get(aspect).equals(superAspect))
|
||||||
|
{
|
||||||
|
subAspects.add(aspect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return subAspects;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -608,34 +703,32 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
* @see org.alfresco.repo.dictionary.impl.DictionaryDAO#getModels()
|
* @see org.alfresco.repo.dictionary.impl.DictionaryDAO#getModels()
|
||||||
*/
|
*/
|
||||||
public Collection<QName> getModels()
|
public Collection<QName> getModels()
|
||||||
|
{
|
||||||
|
return getCompiledModels().keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
// return all tenant-specific models and all shared (non-overridden) models
|
||||||
|
private Map<QName,CompiledModel> getCompiledModels()
|
||||||
{
|
{
|
||||||
String tenantDomain = tenantService.getCurrentUserDomain();
|
String tenantDomain = tenantService.getCurrentUserDomain();
|
||||||
if (tenantDomain != "")
|
if (tenantDomain != "")
|
||||||
{
|
{
|
||||||
// return all tenant-specific models and all shared (non-overridden) models
|
// return all tenant-specific models and all shared (non-overridden) models
|
||||||
Collection<QName> filteredModels = new ArrayList<QName>();
|
Map<QName, CompiledModel> filteredModels = new HashMap<QName, CompiledModel>();
|
||||||
Collection<QName> tenantModels = new ArrayList<QName>();
|
|
||||||
Collection<QName> nontenantModels = new ArrayList<QName>();
|
|
||||||
|
|
||||||
// get tenant models (if any)
|
// get tenant models (if any)
|
||||||
for (QName key : getCompiledModels(tenantDomain).keySet())
|
Map<QName,CompiledModel> tenantModels = getCompiledModels(tenantDomain);
|
||||||
{
|
|
||||||
tenantModels.add(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get non-tenant models (if any)
|
// get non-tenant models (if any)
|
||||||
// note: these will be shared, if not overridden - could be core/system model or additional custom model shared between tenants
|
// note: these will be shared, if not overridden - could be core/system model or additional custom model shared between tenants
|
||||||
for (QName key : getCompiledModels("").keySet())
|
Map<QName,CompiledModel> nontenantModels = getCompiledModels("");
|
||||||
{
|
|
||||||
nontenantModels.add(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for overrides
|
// check for overrides
|
||||||
filteredModels.addAll(nontenantModels);
|
filteredModels.putAll(nontenantModels);
|
||||||
|
|
||||||
for (QName tenantModel : tenantModels)
|
for (QName tenantModel : tenantModels.keySet())
|
||||||
{
|
{
|
||||||
for (QName nontenantModel : nontenantModels)
|
for (QName nontenantModel : nontenantModels.keySet())
|
||||||
{
|
{
|
||||||
if (tenantModel.equals(nontenantModel))
|
if (tenantModel.equals(nontenantModel))
|
||||||
{
|
{
|
||||||
@@ -646,12 +739,12 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filteredModels.addAll(tenantModels);
|
filteredModels.putAll(tenantModels);
|
||||||
return filteredModels;
|
return filteredModels;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return getCompiledModels("").keySet();
|
return getCompiledModels("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -970,6 +970,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
|
|
||||||
private Map<QName, Serializable> getPropertiesImpl(Node node) throws InvalidNodeRefException
|
private Map<QName, Serializable> getPropertiesImpl(Node node) throws InvalidNodeRefException
|
||||||
{
|
{
|
||||||
|
Map<QName,PropertyDefinition> propDefs = dictionaryService.getPropertyDefs(node.getTypeQName());
|
||||||
|
|
||||||
Map<QName, PropertyValue> nodeProperties = node.getProperties();
|
Map<QName, PropertyValue> nodeProperties = node.getProperties();
|
||||||
Map<QName, Serializable> ret = new HashMap<QName, Serializable>(nodeProperties.size());
|
Map<QName, Serializable> ret = new HashMap<QName, Serializable>(nodeProperties.size());
|
||||||
// copy values
|
// copy values
|
||||||
@@ -978,7 +980,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
QName propertyQName = entry.getKey();
|
QName propertyQName = entry.getKey();
|
||||||
PropertyValue propertyValue = entry.getValue();
|
PropertyValue propertyValue = entry.getValue();
|
||||||
// get the property definition
|
// get the property definition
|
||||||
PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
|
PropertyDefinition propertyDef = propDefs.get(propertyQName);
|
||||||
|
|
||||||
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.NODE_REF)) &&
|
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.NODE_REF)) &&
|
||||||
(propertyValue != null) && (propertyValue.getStringValue() != null))
|
(propertyValue != null) && (propertyValue.getStringValue() != null))
|
||||||
|
@@ -305,15 +305,7 @@ public class LuceneCategoryServiceImpl implements CategoryService
|
|||||||
|
|
||||||
public Collection<QName> getClassificationAspects()
|
public Collection<QName> getClassificationAspects()
|
||||||
{
|
{
|
||||||
List<QName> list = new ArrayList<QName>();
|
return dictionaryService.getSubAspects(ContentModel.ASPECT_CLASSIFIABLE, true);
|
||||||
for (QName aspect : dictionaryService.getAllAspects())
|
|
||||||
{
|
|
||||||
if (dictionaryService.isSubClass(aspect, ContentModel.ASPECT_CLASSIFIABLE))
|
|
||||||
{
|
|
||||||
list.add(aspect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeRef createClassifiction(StoreRef storeRef, QName typeName, String attributeName)
|
public NodeRef createClassifiction(StoreRef storeRef, QName typeName, String attributeName)
|
||||||
|
@@ -341,20 +341,7 @@ public class LuceneQueryParser extends QueryParser
|
|||||||
{
|
{
|
||||||
throw new SearcherException("Invalid type: " + queryText);
|
throw new SearcherException("Invalid type: " + queryText);
|
||||||
}
|
}
|
||||||
QName targetQName = target.getName();
|
Collection<QName> subclasses = dictionaryService.getSubTypes(target.getName(), true);
|
||||||
HashSet<QName> subclasses = new HashSet<QName>();
|
|
||||||
for (QName classRef : dictionaryService.getAllTypes())
|
|
||||||
{
|
|
||||||
TypeDefinition current = dictionaryService.getType(classRef);
|
|
||||||
while ((current != null) && !current.getName().equals(targetQName))
|
|
||||||
{
|
|
||||||
current = (current.getParentName() == null) ? null : dictionaryService.getType(current.getParentName());
|
|
||||||
}
|
|
||||||
if (current != null)
|
|
||||||
{
|
|
||||||
subclasses.add(classRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BooleanQuery booleanQuery = new BooleanQuery();
|
BooleanQuery booleanQuery = new BooleanQuery();
|
||||||
for (QName qname : subclasses)
|
for (QName qname : subclasses)
|
||||||
{
|
{
|
||||||
@@ -420,21 +407,9 @@ public class LuceneQueryParser extends QueryParser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QName targetQName = target.getName();
|
|
||||||
HashSet<QName> subclasses = new HashSet<QName>();
|
|
||||||
for (QName classRef : dictionaryService.getAllAspects())
|
|
||||||
{
|
|
||||||
AspectDefinition current = dictionaryService.getAspect(classRef);
|
|
||||||
while ((current != null) && !current.getName().equals(targetQName))
|
|
||||||
{
|
|
||||||
current = (current.getParentName() == null) ? null : dictionaryService.getAspect(current.getParentName());
|
|
||||||
}
|
|
||||||
if (current != null)
|
|
||||||
{
|
|
||||||
subclasses.add(classRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Collection<QName> subclasses = dictionaryService.getSubAspects(target.getName(), true);
|
||||||
|
|
||||||
BooleanQuery booleanQuery = new BooleanQuery();
|
BooleanQuery booleanQuery = new BooleanQuery();
|
||||||
for (QName qname : subclasses)
|
for (QName qname : subclasses)
|
||||||
{
|
{
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
package org.alfresco.service.cmr.dictionary;
|
package org.alfresco.service.cmr.dictionary;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.service.NotAuditable;
|
import org.alfresco.service.NotAuditable;
|
||||||
import org.alfresco.service.PublicService;
|
import org.alfresco.service.PublicService;
|
||||||
@@ -94,6 +95,14 @@ public interface DictionaryService
|
|||||||
@NotAuditable
|
@NotAuditable
|
||||||
Collection<QName> getAllTypes();
|
Collection<QName> getAllTypes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param type
|
||||||
|
* @param follow true => follow up the super-class hierarchy, false => immediate sub types only
|
||||||
|
* @return the sub types of specified type
|
||||||
|
*/
|
||||||
|
@NotAuditable
|
||||||
|
Collection<QName> getSubTypes(QName type, boolean follow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param model the model to retrieve types for
|
* @param model the model to retrieve types for
|
||||||
* @return the names of all types defined within the specified model
|
* @return the names of all types defined within the specified model
|
||||||
@@ -125,6 +134,14 @@ public interface DictionaryService
|
|||||||
@NotAuditable
|
@NotAuditable
|
||||||
Collection<QName> getAllAspects();
|
Collection<QName> getAllAspects();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param aspect
|
||||||
|
* @param follow true => follow up the super-class hierarchy, false => immediate sub aspects only
|
||||||
|
* @return the sub aspects of specified aspect
|
||||||
|
*/
|
||||||
|
@NotAuditable
|
||||||
|
Collection<QName> getSubAspects(QName aspect, boolean follow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param model the model to retrieve aspects for
|
* @param model the model to retrieve aspects for
|
||||||
* @return the names of all aspects defined within the specified model
|
* @return the names of all aspects defined within the specified model
|
||||||
@@ -168,6 +185,15 @@ public interface DictionaryService
|
|||||||
*/
|
*/
|
||||||
@NotAuditable
|
@NotAuditable
|
||||||
PropertyDefinition getProperty(QName className, QName propertyName);
|
PropertyDefinition getProperty(QName className, QName propertyName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the definitions of the properties defined by the specified Class.
|
||||||
|
*
|
||||||
|
* @param className the class name
|
||||||
|
* @return the property definitions
|
||||||
|
*/
|
||||||
|
@NotAuditable
|
||||||
|
Map<QName,PropertyDefinition> getPropertyDefs(QName className);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the definition of the property as defined by its owning Class.
|
* Gets the definition of the property as defined by its owning Class.
|
||||||
|
Reference in New Issue
Block a user