Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (5.0/Cloud)

84902: Merged PLATFORM1 (5.0/Cloud) to HEAD-BUG-FIX (5.0/Cloud)
      83412: Preliminary implementation of ACE-2639.
      This check-in allows any user to hit the repo at http://localhost:8080/alfresco/service/api/facet/facetable-properties
      or at http://localhost:8080/alfresco/service/api/facet/classes/cm:thumbnail/facetable-properties and get details on facetable properties for all properties in the system or all properties on the specified type/aspect, respectively.
      I'm checking this in in order to start to get some feedback on what the global list contains and how we might restrict it. The JSON response is very basic currently and it will be enhanced also.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@85222 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2014-09-20 09:02:07 +00:00
parent 6f3e0aa430
commit 2731b9a7bb
3 changed files with 119 additions and 0 deletions

View File

@@ -20,7 +20,15 @@
package org.alfresco.repo.search.impl.solr.facet;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.dictionary.Facetable;
import org.alfresco.repo.search.impl.solr.facet.Exceptions.DuplicateFacetId;
import org.alfresco.repo.search.impl.solr.facet.Exceptions.MissingFacetId;
import org.alfresco.repo.search.impl.solr.facet.Exceptions.UnrecognisedFacetId;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* Solr Facet service configuration API.
@@ -96,4 +104,21 @@ public interface SolrFacetService
* @throws DuplicateFacetId if there is a duplicate filter ID in the list.
*/
public void reorderFacets(List<String> filterIds);
/**
* This method offers a convenient access point for getting all Facetable
* content properties defined in the repository.
* @return a collection of facetable {@link PropertyDefinition}s.
* @see Facetable
*/
public Set<PropertyDefinition> getFacetableProperties();
/**
* This method offers a convenient access point for getting all Facetable
* content properties defined on the specified content class (type or aspect).
* @param contentClass the QName of an aspect or type, whose facetable properties are sought.
* @return a collection of facetable {@link PropertyDefinition}s.
* @see Facetable
*/
public Set<PropertyDefinition> getFacetableProperties(QName contentClass);
}

View File

@@ -38,6 +38,7 @@ import java.util.concurrent.ConcurrentMap;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.dictionary.Facetable;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy;
import org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy;
@@ -53,6 +54,9 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
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.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -91,6 +95,7 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
private static final StoreRef FACET_STORE = new StoreRef("workspace://SpacesStore");
private AuthorityService authorityService;
private DictionaryService dictionaryService;
protected NodeService nodeService;
private NamespaceService namespaceService;
private SearchService searchService;
@@ -112,6 +117,14 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
this.authorityService = authorityService;
}
/**
* @param dictionaryService the dictionaryService to set
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* @param nodeService the nodeService to set
*/
@@ -755,4 +768,84 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
nodeService.setProperty(getFacetsRoot(), SolrFacetModel.PROP_FACET_ORDER, serializableProp);
}
}
@Override public Set<PropertyDefinition> getFacetableProperties()
{
final Set<PropertyDefinition> result = new HashSet<>();
final List<QName> allContentClasses = CollectionUtils.flatten(dictionaryService.getAllAspects(), dictionaryService.getAllTypes());
for (QName contentClass : allContentClasses)
{
result.addAll(getFacetableProperties(contentClass));
}
return result;
}
@Override public Set<PropertyDefinition> getFacetableProperties(QName contentClass)
{
final Set<PropertyDefinition> result = new HashSet<>();
final Map<QName, PropertyDefinition> propertyDefs = dictionaryService.getPropertyDefs(contentClass);
if (propertyDefs != null)
{
for (Map.Entry<QName, PropertyDefinition> prop : propertyDefs.entrySet())
{
final Facetable propIsFacetable = prop.getValue().getFacetable();
switch (propIsFacetable)
{
case TRUE:
result.add(prop.getValue());
break;
case FALSE:
// The value is not facetable. Do nothing.
break;
case UNSET:
// These values may be facetable.
final DataTypeDefinition datatype = prop.getValue().getDataType();
if (isNumeric(datatype) || isDateLike(datatype) || isFacetableText(datatype))
{
result.add(prop.getValue());
break;
}
break;
default:
// This should never happen. If it does, it's a programming error.
throw new IllegalStateException("Failed to handle " + Facetable.class.getSimpleName() + " type: " + propIsFacetable);
}
}
}
return result;
}
// TODO Consider moving into dictionary code.
private boolean isNumeric(DataTypeDefinition datatype)
{
boolean result;
try
{
Class<?> clazz = Class.forName(datatype.getJavaClassName());
result = Number.class.isAssignableFrom(clazz);
} catch (ClassNotFoundException e)
{
result = false;
}
return result;
}
private boolean isDateLike(DataTypeDefinition datatype)
{
return DataTypeDefinition.DATE.equals(datatype.getName()) ||
DataTypeDefinition.DATETIME.equals(datatype.getName());
}
private boolean isFacetableText(DataTypeDefinition datatype)
{
// For now at least, we're excluding MLTEXT
return DataTypeDefinition.TEXT.equals(datatype.getName());
}
}