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

80669: Merged WAT1 (5.0/Cloud) to HEAD-BUG-FIX (5.0/Cloud)
      78166: ACE-1582: Enhancements to the facet service to persist only the modified value(s) rather than the whole facet's properties. Also fixed facets cache and facets reordering NPE.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@82966 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Will Abson
2014-09-03 16:18:39 +00:00
parent 5d5409019e
commit a740ca67cb
16 changed files with 544 additions and 306 deletions

View File

@@ -119,16 +119,6 @@
<tokenised>false</tokenised>
</index>
</property>
<property name="srft:index">
<title>Index</title>
<type>d:int</type>
<mandatory>true</mandatory>
<index enabled="false">
<atomic>false</atomic>
<stored>false</stored>
<tokenised>false</tokenised>
</index>
</property>
<property name="srft:isEnabled">
<title>Is enabled</title>
<type>d:boolean</type>

View File

@@ -1,6 +1,6 @@
#
# Alfresco default facets
# Note: If you have changed the filters default value(s) via Share, then any subsequent changes of the default values wont be applied to the filter on server startup.
# Note: If you have changed the filter's<> default value(s) via Share, then any subsequent changes of those default values won't be applied to the filter on server startup.
#
# Field-Facet-Qname => cm:content.mimetype
@@ -11,9 +11,8 @@ default.cm\:content.mimetype.maxFilters=5
default.cm\:content.mimetype.hitThreshold=1
default.cm\:content.mimetype.minFilterValueLength=4
default.cm\:content.mimetype.sortBy=DESCENDING
default.cm\:content.mimetype.scope=SCOPED_SITES
default.cm\:content.mimetype.scope=ALL
default.cm\:content.mimetype.scopedSites=
default.cm\:content.mimetype.index=0
default.cm\:content.mimetype.isEnabled=true
# Field-Facet-Qname => cm:description.__
@@ -24,10 +23,9 @@ default.cm\:description.__.maxFilters=5
default.cm\:description.__.hitThreshold=1
default.cm\:description.__.minFilterValueLength=4
default.cm\:description.__.sortBy=DESCENDING
default.cm\:description.__.scope=SCOPED_SITES
default.cm\:description.__.scope=ALL
default.cm\:description.__.scopedSites=
default.cm\:description.__.index=1
default.cm\:description.__.isEnabled=true
default.cm\:description.__.isEnabled=false
# Field-Facet-Qname => cm:creator.__.u
default.cm\:creator.__.u.filterID=filter_creator
@@ -37,9 +35,8 @@ default.cm\:creator.__.u.maxFilters=5
default.cm\:creator.__.u.hitThreshold=1
default.cm\:creator.__.u.minFilterValueLength=4
default.cm\:creator.__.u.sortBy=ALPHABETICALLY
default.cm\:creator.__.u.scope=SCOPED_SITES
default.cm\:creator.__.u.scope=ALL
default.cm\:creator.__.u.scopedSites=
default.cm\:creator.__.u.index=2
default.cm\:creator.__.u.isEnabled=true
# Field-Facet-Qname => cm:modifier.__.u
@@ -50,9 +47,8 @@ default.cm\:modifier.__.u.maxFilters=5
default.cm\:modifier.__.u.hitThreshold=1
default.cm\:modifier.__.u.minFilterValueLength=4
default.cm\:modifier.__.u.sortBy=ALPHABETICALLY
default.cm\:modifier.__.u.scope=SCOPED_SITES
default.cm\:modifier.__.u.scope=ALL
default.cm\:modifier.__.u.scopedSites=
default.cm\:modifier.__.u.index=3
default.cm\:modifier.__.u.isEnabled=true
# Field-Facet-Qname => cm:created
@@ -63,9 +59,8 @@ default.cm\:created.maxFilters=5
default.cm\:created.hitThreshold=1
default.cm\:created.minFilterValueLength=4
default.cm\:created.sortBy=ALPHABETICALLY
default.cm\:created.scope=SCOPED_SITES
default.cm\:created.scope=ALL
default.cm\:created.scopedSites=
default.cm\:created.index=4
default.cm\:created.isEnabled=true
default.cm\:created.EXTRA-PROP.blockIncludeFacetRequest=true
@@ -77,9 +72,8 @@ default.cm\:modified.maxFilters=5
default.cm\:modified.hitThreshold=1
default.cm\:modified.minFilterValueLength=4
default.cm\:modified.sortBy=ALPHABETICALLY
default.cm\:modified.scope=SCOPED_SITES
default.cm\:modified.scope=ALL
default.cm\:modified.scopedSites=
default.cm\:modified.index=5
default.cm\:modified.isEnabled=true
default.cm\:modified.EXTRA-PROP.blockIncludeFacetRequest=true
@@ -91,8 +85,7 @@ default.cm\:content.size.maxFilters=5
default.cm\:content.size.hitThreshold=1
default.cm\:content.size.minFilterValueLength=4
default.cm\:content.size.sortBy=ALPHABETICALLY
default.cm\:content.size.scope=SCOPED_SITES
default.cm\:content.size.scope=ALL
default.cm\:content.size.scopedSites=
default.cm\:content.size.index=6
default.cm\:content.size.isEnabled=true
default.cm\:content.size.EXTRA-PROP.blockIncludeFacetRequest=true

View File

@@ -38,6 +38,11 @@ public class SolrFacetComparator implements Comparator<SolrFacetProperties>
@Override public int compare(SolrFacetProperties facet1, SolrFacetProperties facet2)
{
if (sortedIDs.isEmpty())
{
return facet1.getFilterID().compareTo(facet2.getFilterID());
}
Pair<Integer, Integer> facetIndicesInSortedList = find(facet1, facet2);
if (bothSorted(facetIndicesInSortedList))
@@ -47,19 +52,7 @@ public class SolrFacetComparator implements Comparator<SolrFacetProperties>
}
else if (neitherSorted(facetIndicesInSortedList))
{
// Sorting is by the index value defined in the facet itself.
final int indexDifference = facet1.getIndex() - facet2.getIndex();
if (indexDifference == 0)
{
// This could happen if an end user defines/overrides indexes to be equal.
// We'll sort based on facet ID if it does happen.
return facet1.getFilterID().compareTo(facet2.getFilterID());
}
else
{
return indexDifference;
}
return facet1.getFilterID().compareTo(facet2.getFilterID());
}
else
{

View File

@@ -39,6 +39,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
import org.springframework.extensions.surf.util.ParameterCheck;
/**
* This class picks up all the loaded properties passed to it and uses a naming
@@ -58,7 +59,6 @@ import org.springframework.extensions.surf.util.AbstractLifecycleBean;
* <li>custom.cm\:content.mimetype.sortBy=DESCENDING</li>
* <li>custom.cm\:content.mimetype.scope=SCOPED_SITES</li>
* <li>custom.cm\:content.mimetype.scopedSites=site1,site2,site3</li>
* <li>custom.cm\:content.mimetype.index=0</li>
* <li>custom.cm\:content.mimetype.isEnabled=true</li>
* </ul>
* Also, if there is a need to add additional properties, the following needs to be
@@ -91,8 +91,8 @@ public class SolrFacetConfig extends AbstractLifecycleBean
public SolrFacetConfig(Properties rawProperties, String inheritanceOrder)
{
PropertyCheck.mandatory(this, "rawProperties", rawProperties);
PropertyCheck.mandatory(this, "inheritanceOrder", inheritanceOrder);
ParameterCheck.mandatory("rawProperties", rawProperties);
ParameterCheck.mandatory("inheritanceOrder", inheritanceOrder);
this.rawProperties = rawProperties;
@@ -223,12 +223,7 @@ public class SolrFacetConfig extends AbstractLifecycleBean
String sortBy = propValues.get(ValueName.PROP_SORTBY.getPropValueName(field));
String scope = propValues.get(ValueName.PROP_SCOPE.getPropValueName(field));
Set<String> scopedSites = getScopedSites(propValues.get(ValueName.PROP_SCOPED_SITES.getPropValueName(field)));
int index = getIntegerValue(propValues.get(ValueName.PROP_INDEX.getPropValueName(field)));
if(index < 0)
{
throw new SolrFacetConfigException("Index must be greater than or equal to 0");
}
boolean isEnabled = Boolean.valueOf(propValues.get(ValueName.PROP_IS_ENABLED.getPropValueName(field)));
Boolean isEnabled = Boolean.valueOf(propValues.get(ValueName.PROP_IS_ENABLED.getPropValueName(field)));
Set<CustomProperties> customProps = getCustomProps(facetFields.get(field), field, propValues);
// Construct the FacetProperty object
@@ -242,7 +237,6 @@ public class SolrFacetConfig extends AbstractLifecycleBean
.minFilterValueLength(minFilterValueLength)
.sortBy(sortBy)
.scope(scope)
.index(index)
.isEnabled(isEnabled)
.isDefault(true)
.scopedSites(scopedSites)
@@ -385,7 +379,7 @@ public class SolrFacetConfig extends AbstractLifecycleBean
{
PROP_FILTER_ID("filterID"), PROP_DISPLAY_NAME("displayName"), PROP_MAX_FILTERS("maxFilters"), PROP_HIT_THRESHOLD("hitThreshold"),
PROP_MIN_FILTER_VALUE_LENGTH("minFilterValueLength"), PROP_SORTBY("sortBy"), PROP_SCOPE("scope"), PROP_SCOPED_SITES("scopedSites"),
PROP_INDEX("index"), PROP_IS_ENABLED("isEnabled"), PROP_DISPLAY_CONTROL("displayControl");
PROP_IS_ENABLED("isEnabled"), PROP_DISPLAY_CONTROL("displayControl");
private ValueName(String propValueName)
{

View File

@@ -56,8 +56,6 @@ public interface SolrFacetModel
public static final QName PROP_SCOPED_SITES = QName.createQName(SOLR_FACET_MODEL_URL, "scopedSites");
public static final QName PROP_INDEX = QName.createQName(SOLR_FACET_MODEL_URL, "index");
public static final QName PROP_IS_ENABLED = QName.createQName(SOLR_FACET_MODEL_URL, "isEnabled");
public static final QName PROP_IS_DEFAULT = QName.createQName(SOLR_FACET_MODEL_URL, "isDefault");

View File

@@ -46,8 +46,7 @@ public class SolrFacetProperties implements Serializable
private final String sortBy;
private final String scope;
private final Set<String> scopedSites;
private final int index;
private final boolean isEnabled;
private final Boolean isEnabled;
private final boolean isDefault; // is loaded from properties files?
private final Set<CustomProperties> customProperties;
@@ -67,7 +66,6 @@ public class SolrFacetProperties implements Serializable
this.minFilterValueLength = builder.minFilterValueLength;
this.sortBy = builder.sortBy;
this.scope = builder.scope;
this.index = builder.index;
this.isEnabled = builder.isEnabled;
this.isDefault = builder.isDefault;
this.scopedSites = Collections.unmodifiableSet(new HashSet<String>(builder.scopedSites));
@@ -157,17 +155,9 @@ public class SolrFacetProperties implements Serializable
}
/**
* @return the index
* @return null if the value is not set
*/
public int getIndex()
{
return this.index;
}
/**
* @return the isEnabled
*/
public boolean isEnabled()
public Boolean isEnabled()
{
return this.isEnabled;
}
@@ -192,7 +182,6 @@ public class SolrFacetProperties implements Serializable
return Collections.unmodifiableSet(new HashSet<CustomProperties>(this.customProperties));
}
/*
* @see java.lang.Object#hashCode()
*/
@@ -251,7 +240,7 @@ public class SolrFacetProperties implements Serializable
.append(this.maxFilters).append(", hitThreshold=").append(this.hitThreshold)
.append(", minFilterValueLength=").append(this.minFilterValueLength).append(", sortBy=")
.append(this.sortBy).append(", scope=").append(this.scope).append(", scopedSites=")
.append(this.scopedSites).append(", index=").append(this.index).append(", isEnabled=").append(this.isEnabled)
.append(this.scopedSites).append(", isEnabled=").append(this.isEnabled)
.append(", isDefault=").append(this.isDefault).append(", customProperties=").append(this.customProperties)
.append("]");
return sb.toString();
@@ -263,14 +252,13 @@ public class SolrFacetProperties implements Serializable
private QName facetQName;
private String displayName;
private String displayControl;
private int maxFilters;
private int hitThreshold;
private int minFilterValueLength;
private int maxFilters = -1;
private int hitThreshold = -1;;
private int minFilterValueLength = -1;
private String sortBy;
private String scope;
private Set<String> scopedSites = Collections.emptySet();
private int index;
private boolean isEnabled;
private Boolean isEnabled;
private boolean isDefault;
private Set<CustomProperties> customProperties = Collections.emptySet();
@@ -295,7 +283,6 @@ public class SolrFacetProperties implements Serializable
this.sortBy = that.sortBy;
this.scope = that.scope;
this.scopedSites = that.scopedSites;
this.index = that.index;
this.isEnabled = that.isEnabled;
this.isDefault = that.isDefault;
this.customProperties = that.customProperties;
@@ -364,13 +351,7 @@ public class SolrFacetProperties implements Serializable
return this;
}
public Builder index(int index)
{
this.index = index;
return this;
}
public Builder isEnabled(boolean isEnabled)
public Builder isEnabled(Boolean isEnabled)
{
this.isEnabled = isEnabled;
return this;

View File

@@ -20,17 +20,13 @@
package org.alfresco.repo.search.impl.solr.facet;
import java.util.List;
import org.alfresco.repo.search.impl.solr.facet.Exceptions.DuplicateFacetId;
import org.alfresco.repo.search.impl.solr.facet.Exceptions.IllegalArgument;
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.repository.NodeRef;
/**
* Solr Facet service configuration API.
*
* @author Jamal Kaabi-Mofrad
* @since 5.0
*/
public interface SolrFacetService
{
@@ -90,8 +86,6 @@ public interface SolrFacetService
*/
public void deleteFacet(String filterID);
public int getNextIndex();
/**
* Reorders existing facets to the provided order.
*

View File

@@ -21,27 +21,26 @@ package org.alfresco.repo.search.impl.solr.facet;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy;
import org.alfresco.repo.node.NodeServicePolicies.BeforeUpdateNodePolicy;
import org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy;
import org.alfresco.repo.node.NodeServicePolicies.OnUpdateNodePolicy;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
@@ -71,13 +70,14 @@ import org.springframework.context.ApplicationEvent;
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
/**
* Solr Facet Service Implementation.
*
* @author Jamal Kaabi-Mofrad
* @since 5.0
*/
public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrFacetService,
NodeServicePolicies.OnCreateNodePolicy,
NodeServicePolicies.OnUpdateNodePolicy,
NodeServicePolicies.BeforeDeleteNodePolicy,
NodeServicePolicies.BeforeUpdateNodePolicy
NodeServicePolicies.BeforeDeleteNodePolicy
{
private static final Log logger = LogFactory.getLog(SolrFacetServiceImpl.class);
/**
@@ -102,8 +102,7 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
private SimpleCache<String, Object> singletonCache; // eg. for facetsHomeNodeRef
private final String KEY_FACETS_HOME_NODEREF = "key.facetshome.noderef";
private SimpleCache<String, NodeRef> facetNodeRefCache; // for filterID to nodeRef lookup
private NavigableMap<Integer, SolrFacetProperties> facetsMap = new ConcurrentSkipListMap<>(); // TODO
private int maxAllowedFilters = 100;
private ConcurrentMap<String, SolrFacetProperties> defaultFacetsMap = new ConcurrentHashMap<String, SolrFacetProperties>(10);
/**
* @param authorityService the authorityService to set
@@ -193,14 +192,6 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
this.facetNodeRefCache = facetNodeRefCache;
}
/**
* @param maxAllowedFilters the maxAllowedFilters to set
*/
public void setMaxAllowedFilters(int maxAllowedFilters)
{
this.maxAllowedFilters = maxAllowedFilters;
}
@Override
public boolean isSearchAdmin(String userName)
{
@@ -219,7 +210,14 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
final SolrFacetComparator comparator = new SolrFacetComparator(getFacetOrder());
SortedSet<SolrFacetProperties> result = new TreeSet<>(comparator);
result.addAll(facetsMap.values());
List<ChildAssociationRef> children = nodeService.getChildAssocs(getFacetsRoot());
for (ChildAssociationRef ref : children)
{
result.add(getFacetProperties(ref.getChildRef()));
}
// add the default filters
result.addAll(defaultFacetsMap.values());
return new ArrayList<>(result);
}
@@ -242,12 +240,7 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
* the nodeService.
*/
NodeRef nodeRef = getFacetNodeRef(filterID);
return (nodeRef == null) ? getDefaultLoadedFacet(filterID) : getFacetProperties(nodeRef);
}
private SolrFacetProperties getDefaultLoadedFacet(String filterID)
{
return facetConfig.getDefaultFacets().get(filterID);
return (nodeRef == null) ? defaultFacetsMap.get(filterID) : getFacetProperties(nodeRef);
}
@Override
@@ -297,26 +290,40 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
}
String filterID = (String) properties.get(ContentModel.PROP_NAME);
QName fieldQName = (QName) properties.get(SolrFacetModel.PROP_FIELD_TYPE);
String displayName = (String) properties.get(SolrFacetModel.PROP_FIELD_LABEL);
String displayControl = (String) properties.get(SolrFacetModel.PROP_DISPLAY_CONTROL);
int maxFilters = (Integer) properties.get(SolrFacetModel.PROP_MAX_FILTERS);
int hitThreshold = (Integer) properties.get(SolrFacetModel.PROP_HIT_THRESHOLD);
int minFilterValueLength = (Integer) properties.get(SolrFacetModel.PROP_MIN_FILTER_VALUE_LENGTH);
String sortBy = (String) properties.get(SolrFacetModel.PROP_SORT_BY);
String scope = (String) properties.get(SolrFacetModel.PROP_SCOPE);
int index = (Integer) properties.get(SolrFacetModel.PROP_INDEX);
boolean isEnabled = (Boolean) properties.get(SolrFacetModel.PROP_IS_ENABLED);
boolean isDefault = (Boolean) properties.get(SolrFacetModel.PROP_IS_DEFAULT);
SolrFacetProperties defaultFacet = defaultFacetsMap.get(filterID);
if(defaultFacet == null)
{
defaultFacet = new SolrFacetProperties.Builder().build();
}
QName fieldQName = getDefaultIfNull(defaultFacet.getFacetQName(), (QName) properties.get(SolrFacetModel.PROP_FIELD_TYPE));
String displayName = getDefaultIfNull(defaultFacet.getDisplayName(), (String) properties.get(SolrFacetModel.PROP_FIELD_LABEL));
String displayControl = getDefaultIfNull(defaultFacet.getDisplayControl(), (String) properties.get(SolrFacetModel.PROP_DISPLAY_CONTROL));
int maxFilters = getDefaultIfNull(defaultFacet.getMaxFilters(), (Integer) properties.get(SolrFacetModel.PROP_MAX_FILTERS));
int hitThreshold = getDefaultIfNull(defaultFacet.getHitThreshold(), (Integer) properties.get(SolrFacetModel.PROP_HIT_THRESHOLD));
int minFilterValueLength = getDefaultIfNull(defaultFacet.getMinFilterValueLength(), (Integer) properties.get(SolrFacetModel.PROP_MIN_FILTER_VALUE_LENGTH));
String sortBy = getDefaultIfNull(defaultFacet.getSortBy(), (String) properties.get(SolrFacetModel.PROP_SORT_BY));
String scope = getDefaultIfNull(defaultFacet.getScope(), (String) properties.get(SolrFacetModel.PROP_SCOPE));
Boolean isEnabled = getDefaultIfNull(defaultFacet.isEnabled(), (Boolean) properties.get(SolrFacetModel.PROP_IS_ENABLED));
@SuppressWarnings("unchecked")
List<String> scSites = (List<String>) properties.get(SolrFacetModel.PROP_SCOPED_SITES);
Set<String> scopedSites = (scSites == null) ? null : new HashSet<>(scSites);
Set<String> scopedSites = getDefaultIfNull(defaultFacet.getScopedSites(), (scSites == null) ? null : new HashSet<>(scSites));
Set<CustomProperties> extraProps = null;
Map<QName, Serializable> customProperties = getFacetCustomProperties(properties);
Set<CustomProperties> extraProps = new HashSet<>(customProperties.size());
for(Entry<QName, Serializable> cp : customProperties.entrySet())
if (customProperties.isEmpty())
{
extraProps.add(new CustomProperties(cp.getKey(), (String) properties.get(ContentModel.PROP_TITLE), null, cp.getValue()));
extraProps = defaultFacet.getCustomProperties();
}
else
{
extraProps = new HashSet<>(customProperties.size());
for (Entry<QName, Serializable> cp : customProperties.entrySet())
{
extraProps.add(new CustomProperties(cp.getKey(), (String) properties.get(ContentModel.PROP_TITLE), null, cp.getValue()));
}
}
// Construct the FacetProperty object
SolrFacetProperties fp = new SolrFacetProperties.Builder()
@@ -329,7 +336,6 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
.minFilterValueLength(minFilterValueLength)
.sortBy(sortBy)
.scope(scope)
.index(index)
.isEnabled(isEnabled)
.isDefault(isDefault)
.scopedSites(scopedSites)
@@ -338,6 +344,11 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
return fp;
}
private <T> T getDefaultIfNull(T defaultValue, T newValue)
{
return (newValue == null) ? defaultValue : newValue;
}
@Override
public NodeRef createFacetNode(SolrFacetProperties facetProperties)
{
@@ -346,12 +357,11 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
private NodeRef createFacetNodeImpl(final SolrFacetProperties facetProperties, boolean checkDefaultFP)
{
final String filterID = facetProperties.getFilterID();
NodeRef facetNodeRef = getFacetNodeRef(filterID);
// We need to check the bootstrapped Facet properties (i.e loaded from properties file(s)) as well,
// in order to not allow the user to create a new facet with the same filterID as the bootstrapped FP.
if (facetNodeRef != null || (checkDefaultFP && getDefaultLoadedFacet(filterID) != null))
if (facetNodeRef != null || (checkDefaultFP && defaultFacetsMap.get(filterID) != null))
{
throw new SolrFacetConfigException("Unable to create facet because the filterID [" + filterID + "] is already in use.");
}
@@ -406,7 +416,7 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
NodeRef facetNodeRef = getFacetNodeRef(filterID);
if (facetNodeRef == null)
{
SolrFacetProperties fp = getDefaultLoadedFacet(filterID);
SolrFacetProperties fp = defaultFacetsMap.get(filterID);
if (fp != null)
{
// As we don't create nodes for the bootstrapped FP on server
@@ -436,6 +446,51 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
}
}
private SolrFacetProperties makeValidFacetPropObj(SolrFacetProperties newFP)
{
SolrFacetProperties bootstraptedFP = defaultFacetsMap.get(newFP.getFilterID());
// null means there is no default facet
if(bootstraptedFP == null)
{
return new SolrFacetProperties.Builder(newFP).isDefault(false).build();
}
QName fieldQName = getValue(bootstraptedFP.getFacetQName(), newFP.getFacetQName(), null);
String displayName = getValue(bootstraptedFP.getDisplayName(), newFP.getDisplayName(), null);
String displayControl = getValue(bootstraptedFP.getDisplayControl(), newFP.getDisplayControl(), null);
int maxFilters = getValue(bootstraptedFP.getMaxFilters(), newFP.getMaxFilters(), -1);
int hitThreshold = getValue(bootstraptedFP.getHitThreshold(), newFP.getHitThreshold(), -1);
int minFilterValueLength = getValue(bootstraptedFP.getMinFilterValueLength(), newFP.getMinFilterValueLength(), -1);
String sortBy = getValue(bootstraptedFP.getSortBy(), newFP.getSortBy(), null);
String scope = getValue(bootstraptedFP.getScope(), newFP.getScope(), null);
Boolean isEnabled = getValue(bootstraptedFP.isEnabled(), newFP.isEnabled(), null);
Set<String> scopedSites = getValue(bootstraptedFP.getScopedSites(), newFP.getScopedSites(), null);
Set<CustomProperties> extraProps = getValue(bootstraptedFP.getCustomProperties(), newFP.getCustomProperties(), null);
// Construct the FacetProperty object
SolrFacetProperties fp = new SolrFacetProperties.Builder()
.filterID(newFP.getFilterID())
.facetQName(fieldQName)
.displayName(displayName)
.displayControl(displayControl)
.maxFilters(maxFilters)
.hitThreshold(hitThreshold)
.minFilterValueLength(minFilterValueLength)
.sortBy(sortBy)
.scope(scope)
.isEnabled(isEnabled)
.isDefault(true)
.scopedSites(scopedSites)
.customProperties(extraProps).build();
return fp;
}
private <T> T getValue(T originalValue, T newValue, T defaultValueIfEquals)
{
return (originalValue.equals(newValue) ? defaultValueIfEquals : newValue);
}
@Override
public void deleteFacet(String filterID)
{
@@ -445,7 +500,7 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
throw new SolrFacetConfigException("The [" + filterID + "] facet cannot be found.");
}
SolrFacetProperties defaultFP = getDefaultLoadedFacet(filterID);
SolrFacetProperties defaultFP = defaultFacetsMap.get(filterID);
if (defaultFP != null)
{
throw new SolrFacetConfigException("The default [" + filterID + "] facet cannot be deleted. It can only be disabled.");
@@ -464,33 +519,51 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
throw new SolrFacetConfigException("Filter Id cannot be null.");
}
// construct a valid facet property object
facetProperties = makeValidFacetPropObj(facetProperties);
Set<CustomProperties> customProperties = facetProperties.getCustomProperties();
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(14 + customProperties.size());
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(13 + customProperties.size());
properties.put(ContentModel.PROP_NAME, facetProperties.getFilterID());
properties.put(SolrFacetModel.PROP_FIELD_TYPE, facetProperties.getFacetQName());
properties.put(SolrFacetModel.PROP_FIELD_LABEL, facetProperties.getDisplayName());
properties.put(SolrFacetModel.PROP_DISPLAY_CONTROL, facetProperties.getDisplayControl());
properties.put(SolrFacetModel.PROP_MAX_FILTERS, facetProperties.getMaxFilters());
properties.put(SolrFacetModel.PROP_HIT_THRESHOLD, facetProperties.getHitThreshold());
properties.put(SolrFacetModel.PROP_MIN_FILTER_VALUE_LENGTH, facetProperties.getMinFilterValueLength());
properties.put(SolrFacetModel.PROP_SCOPE, facetProperties.getScope());
properties.put(SolrFacetModel.PROP_SORT_BY, facetProperties.getSortBy());
properties.put(SolrFacetModel.PROP_SCOPED_SITES, (Serializable) facetProperties.getScopedSites());
properties.put(SolrFacetModel.PROP_INDEX, facetProperties.getIndex());
properties.put(SolrFacetModel.PROP_IS_ENABLED, facetProperties.isEnabled());
properties.put(SolrFacetModel.PROP_IS_DEFAULT, facetProperties.isDefault());
SolrFacetProperties fp = getDefaultLoadedFacet(facetProperties.getFilterID());
properties.put(SolrFacetModel.PROP_IS_DEFAULT, (fp == null) ? false : fp.isDefault());
addNodeProperty(properties, SolrFacetModel.PROP_FIELD_TYPE, facetProperties.getFacetQName());
addNodeProperty(properties, SolrFacetModel.PROP_FIELD_LABEL, facetProperties.getDisplayName());
addNodeProperty(properties, SolrFacetModel.PROP_DISPLAY_CONTROL, facetProperties.getDisplayControl());
addNodeProperty(properties, SolrFacetModel.PROP_MAX_FILTERS, facetProperties.getMaxFilters());
addNodeProperty(properties, SolrFacetModel.PROP_HIT_THRESHOLD, facetProperties.getHitThreshold());
addNodeProperty(properties, SolrFacetModel.PROP_MIN_FILTER_VALUE_LENGTH, facetProperties.getMinFilterValueLength());
addNodeProperty(properties, SolrFacetModel.PROP_SCOPE, facetProperties.getScope());
addNodeProperty(properties, SolrFacetModel.PROP_SORT_BY, facetProperties.getSortBy());
addNodeProperty(properties, SolrFacetModel.PROP_SCOPED_SITES, (Serializable) facetProperties.getScopedSites());
addNodeProperty(properties, SolrFacetModel.PROP_IS_ENABLED, facetProperties.isEnabled());
for (CustomProperties cp : customProperties)
{
properties.put(cp.getName(), cp.getValue());
addNodeProperty(properties, cp.getName(), cp.getValue());
}
return properties;
}
private void addNodeProperty(Map<QName, Serializable> properties, QName qname, Serializable propValue)
{
if (propValue == null)
{
return;
}
if (propValue instanceof Integer && ((Integer) propValue) < 0)
{
return;
}
if (propValue instanceof Collection<?> && ((Collection<?>) propValue).isEmpty())
{
return;
}
properties.put(qname, propValue);
}
public NodeRef getFacetsRoot()
{
NodeRef facetHomeRef = (NodeRef) singletonCache.get(KEY_FACETS_HOME_NODEREF);
@@ -535,18 +608,6 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
SolrFacetModel.TYPE_FACET_FIELD,
new JavaBehaviour(this, "onCreateNode"));
// Filter before update
this.policyComponent.bindClassBehaviour(
BeforeUpdateNodePolicy.QNAME,
SolrFacetModel.TYPE_FACET_FIELD,
new JavaBehaviour(this, "beforeUpdateNode"));
// Filter update
this.policyComponent.bindClassBehaviour(
OnUpdateNodePolicy.QNAME,
SolrFacetModel.TYPE_FACET_FIELD,
new JavaBehaviour(this, "onUpdateNode"));
// Filter before deletion
this.policyComponent.bindClassBehaviour(
BeforeDeleteNodePolicy.QNAME,
@@ -556,6 +617,7 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
Map<String, SolrFacetProperties> mergedMap = new HashMap<>(100);
// Loaded facets
Map<String, SolrFacetProperties> defaultFP = facetConfig.getDefaultFacets();
defaultFacetsMap.putAll(defaultFP); // add the default facets to a ConcurrentHashMap for performance reasons
mergedMap.putAll(defaultFP);
// Persisted facets
@@ -563,51 +625,43 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
// The persisted facets will override the default facets
mergedMap.putAll(persistedProperties);
List<String> facetOrder = getFacetOrder();
// Sort the merged maps
Comparator<Entry<String, SolrFacetProperties>> entryComparator = CollectionUtils.toEntryComparator(new SolrFacetComparator(getFacetOrder()));
Comparator<Entry<String, SolrFacetProperties>> entryComparator = CollectionUtils.toEntryComparator(new SolrFacetComparator(facetOrder));
Map<String, SolrFacetProperties> sortedMap = CollectionUtils.sortMapByValue(mergedMap, entryComparator);
LinkedList<SolrFacetProperties> orderedFacets = new LinkedList<>(sortedMap.values());
// Get the last index, as the map is sorted by the FP's index value
int maxIndex = orderedFacets.getLast().getIndex();
int previousIndex = -1;
SolrFacetProperties previousFP = null;
for (SolrFacetProperties facet : orderedFacets)
{
String filterID = facet.getFilterID();
int index = facet.getIndex();
if (index == previousIndex)
{
// we can be sure that previousFP is never null, as we don't
// allow the index to be -1;
if (defaultFP.get(previousFP.getFilterID()) != null && persistedProperties.get(filterID) != null)
{
SolrFacetProperties updatedPreviousFacet = new SolrFacetProperties.Builder(previousFP).index(++maxIndex).build();
mergedMap.put(previousFP.getFilterID(), updatedPreviousFacet);
mergedMap.put(filterID, facet);
}
else
{
SolrFacetProperties updatedCurrentFacet = new SolrFacetProperties.Builder(facet).index(++maxIndex).build();
mergedMap.put(updatedCurrentFacet.getFilterID(), updatedCurrentFacet);
}
}
else
{
mergedMap.put(filterID, facet);
}
previousIndex = index;
previousFP = facet;
}
for (SolrFacetProperties fp : mergedMap.values())
{
facetsMap.put(fp.getIndex(), fp);
}
if (logger.isDebugEnabled() && persistedProperties.size() > 0)
{
logger.debug("The facets [" + persistedProperties + "] have overridden their matched default facets.");
}
final Set<String> newFacetOrder = (facetOrder == null) ? new LinkedHashSet<String>(sortedMap.size()) : new LinkedHashSet<String>(facetOrder);
for (SolrFacetProperties fp : sortedMap.values())
{
newFacetOrder.add(fp.getFilterID());
}
AuthenticationUtil.runAs(new RunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
return retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
public Void execute() throws Exception
{
reorderFacets(new ArrayList<String>(newFacetOrder));
return null;
}
}, false);
}
}, AuthenticationUtil.getSystemUserName());
if (logger.isDebugEnabled())
{
logger.debug("The facets order [" + newFacetOrder + "] have been persisted.");
}
}
private Map<String, SolrFacetProperties> getPersistedFacetProperties()
@@ -629,26 +683,10 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
// nothing to do
}
@Override
public void beforeUpdateNode(NodeRef nodeRef)
{
// Remove the facet, in order to not end up with duplicate facets but different index
SolrFacetProperties fp = getFacetProperties(nodeRef);
this.facetsMap.remove(fp.getIndex());
}
@Override
public void onUpdateNode(NodeRef nodeRef)
{
SolrFacetProperties fp = getFacetProperties(nodeRef);
this.facetsMap.put(fp.getIndex(), fp);
}
@Override
public void onCreateNode(ChildAssociationRef childAssocRef)
{
SolrFacetProperties fp = getFacetProperties(childAssocRef.getChildRef());
this.facetsMap.put(fp.getIndex(), fp);
this.facetNodeRefCache.put(fp.getFilterID(), childAssocRef.getChildRef());
// We must also add the new filterID to the facetOrder property.
@@ -656,8 +694,15 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
@SuppressWarnings("unchecked")
ArrayList<String> facetOrder = (ArrayList<String>) nodeService.getProperty(facetsRoot, SolrFacetModel.PROP_FACET_ORDER);
// FIXME This could be null.
if (facetOrder == null)
{
List<SolrFacetProperties> facets = getFacets();
facetOrder = new ArrayList<String>(facets.size());
for (SolrFacetProperties facet : facets)
{
facetOrder.add(facet.getFilterID());
}
}
// We'll put it at the end (arbitrarily).
facetOrder.add(fp.getFilterID());
@@ -668,9 +713,6 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
public void beforeDeleteNode(NodeRef nodeRef)
{
String filterID = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
int index = (Integer) nodeService.getProperty(nodeRef, SolrFacetModel.PROP_INDEX);
this.facetsMap.remove(index);
this.facetNodeRefCache.remove(filterID);
// We must also remove the filterID from the facetOrder property.
@@ -685,26 +727,6 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
}
}
@Override
public int getNextIndex()
{
synchronized (facetsMap)
{
if (facetsMap.size() >= maxAllowedFilters)
{
throw new SolrFacetConfigException("You have reached the maximum number of allowed filters. Please delete an existing filter in order to make a new one!");
}
int max = facetsMap.lastKey();
if (max >= Integer.MAX_VALUE)
{
reorder();
max = facetsMap.lastKey();
}
return max + 1;
}
}
/**
* Gets a map containing the facet's custom properties
*
@@ -724,46 +746,6 @@ public class SolrFacetServiceImpl extends AbstractLifecycleBean implements SolrF
return customProperties;
}
/**
* This will reorder the facetsMap, hence, the invoker needs to use an
* appropriate locking mechanism
*/
private void reorder()
{
boolean order = false;
int previous = 0;
for (int i : facetsMap.keySet())
{
if (i != previous)
{
order = true;
break;
}
previous++;
}
if (order)
{
Map<Integer, SolrFacetProperties> tempMap = new LinkedHashMap<>();
int index = 0;
for (SolrFacetProperties fp : facetsMap.values())
{
if (fp.getIndex() != index)
{
fp = new SolrFacetProperties.Builder(fp).index(index).build();
}
tempMap.put(index, fp);
index++;
}
facetsMap.clear();
for (SolrFacetProperties fp : tempMap.values())
{
updateFacet(fp);
}
}
}
@Override public void reorderFacets(List<String> facetIds)
{
// We need to validate the provided facet IDs

View File

@@ -416,4 +416,9 @@ public class Repository01TestSuite extends TestSuite
suite.addTestSuite(org.alfresco.repo.dictionary.DictionaryModelTypeTest.class);
suite.addTestSuite(org.alfresco.repo.tagging.UpdateTagScopesActionExecuterTest.class);
}
static void tests66(TestSuite suite)
{
suite.addTest(org.alfresco.repo.search.impl.solr.facet.SolrFacetTestSuite.suite());
}
}

View File

@@ -18,7 +18,6 @@
*/
package org.alfresco.repo.search;
import junit.framework.JUnit4TestAdapter;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -31,7 +30,6 @@ import org.alfresco.repo.search.impl.lucene.index.IndexInfoTest;
import org.alfresco.repo.search.impl.parsers.CMISTest;
import org.alfresco.repo.search.impl.parsers.CMIS_FTSTest;
import org.alfresco.repo.search.impl.parsers.FTSTest;
import org.alfresco.repo.search.impl.solr.facet.SolrFacetHelperTest;
import org.alfresco.util.NumericEncodingTest;
/**
@@ -63,10 +61,6 @@ public class SearchTestSuite extends TestSuite
suite.addTestSuite(CMIS_FTSTest.class);
suite.addTestSuite(CMISTest.class);
suite.addTestSuite(FTSTest.class);
suite.addTest(new JUnit4TestAdapter(SolrFacetHelperTest.class));
return suite;
}

View File

@@ -34,15 +34,16 @@ public class SolrFacetComparatorTest
{
@Test public void simpleSortOfSortedFacets() throws Exception
{
List<String> expectedIds = Arrays.asList(new String[] { "a", "b", "c"});
List<String> expectedIds = Arrays.asList(new String[] { "a", "b", "c", "d"});
SolrFacetProperties.Builder builder = new SolrFacetProperties.Builder();
List<SolrFacetProperties> facets = Arrays.asList(new SolrFacetProperties[]
{
builder.filterID("c").index(1).build(),
builder.filterID("b").index(2).build(),
builder.filterID("a").index(3).build(),
builder.filterID("a").build(),
builder.filterID("d").build(),
builder.filterID("b").build(),
builder.filterID("c").build(),
});
Collections.sort(facets, new SolrFacetComparator(expectedIds));

View File

@@ -0,0 +1,184 @@
/*
* Copyright (C) 2005-2014 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.search.impl.solr.facet;
import java.util.Map;
import java.util.Properties;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.util.ApplicationContextHelper;
import org.junit.*;
import static org.junit.Assert.*;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* This class contains tests for the class {@link SolrFacetConfig}
*
* @author Jamal Kaabi-Mofrad
* @since 5.0
*/
public class SolrFacetConfigTest
{
private static ClassPathXmlApplicationContext context;
private static Properties rawProperties;
private static SolrFacetConfig facetConfig;
@BeforeClass
public static void setUp() throws Exception
{
context = new ClassPathXmlApplicationContext(new String[] { "classpath:facets/test-facet-property-context.xml" },
ApplicationContextHelper.getApplicationContext());
rawProperties = context.getBean("solrFacetRawPropertiesTest", Properties.class);
facetConfig = context.getBean("solrFacetConfigsTest", SolrFacetConfig.class);
}
@AfterClass
public static void tearDown() throws Exception
{
context.close();
}
@Test
public void testBasic() throws Exception
{
SolrFacetConfig config = null;
try
{
config = new SolrFacetConfig(null, "");
fail("Null properties should have been detected");
}
catch (IllegalArgumentException e)
{
// Expected
}
try
{
config = new SolrFacetConfig(rawProperties, null);
fail("Null properties should have been detected");
}
catch (IllegalArgumentException e)
{
// Expected
}
config = new SolrFacetConfig(rawProperties, "default,custom");
config.setNamespaceService(context.getBean("namespaceService", NamespaceService.class));
try
{
config.getDefaultFacets();
fail("Initialization should be done.");
}
catch (IllegalStateException e)
{
// Expected
}
}
@Test
public void testDefault() throws Exception
{
Map<String, SolrFacetProperties> defaultProps = facetConfig.getDefaultFacets();
assertNotNull(defaultProps);
assertEquals("Incorrect number of properties", 4, defaultProps.size());
// loaded from /facets/facets-config-sample.properties
SolrFacetProperties contentSizeFP = defaultProps.get("test_filter_content_size");
assertEquals("Incorrect QNAME", "{http://www.alfresco.org/model/content/1.0}content.size", contentSizeFP.getFacetQName().toString());
assertEquals("faceted-search.facet-menu.facet.size", contentSizeFP.getDisplayName());
assertEquals("alfresco/search/FacetFilters", contentSizeFP.getDisplayControl());
assertEquals(5, contentSizeFP.getMaxFilters());
assertEquals(1, contentSizeFP.getHitThreshold());
assertEquals(4, contentSizeFP.getMinFilterValueLength());
assertEquals("ALPHABETICALLY", contentSizeFP.getSortBy());
assertEquals("ALL", contentSizeFP.getScope());
assertEquals(0, contentSizeFP.getScopedSites().size());
assertEquals(true, contentSizeFP.isEnabled());
assertEquals(1, contentSizeFP.getCustomProperties().size());
String customValue = (String) contentSizeFP.getCustomProperties().iterator().next().getValue();
assertTrue(Boolean.valueOf(customValue));
// loaded from /facets/extension/facets-config-custom-sample.properties
SolrFacetProperties descFP = defaultProps.get("test_filter_description");
assertEquals("Incorrect QNAME", "{http://www.alfresco.org/model/content/1.0}description", descFP.getFacetQName().toString());
assertEquals("faceted-search.facet-menu.facet.description", descFP.getDisplayName());
assertEquals("alfresco/search/FacetFilters", descFP.getDisplayControl());
assertEquals(3, descFP.getMaxFilters());
assertEquals(1, descFP.getHitThreshold());
assertEquals(2, descFP.getMinFilterValueLength());
assertEquals("DESCENDING", descFP.getSortBy());
assertEquals("SCOPED_SITES", descFP.getScope());
assertEquals(0, descFP.getScopedSites().size());
assertEquals(true, descFP.isEnabled());
// See if the overrides worked
SolrFacetProperties creatorFP = defaultProps.get("test_filter_creator");
assertEquals("Incorrect QNAME", "{http://www.alfresco.org/model/content/1.0}creator.__.u", creatorFP.getFacetQName().toString());
String msg = "The value has not been overridden with the value from the custom properties";
assertEquals(msg, 10, creatorFP.getMaxFilters());
assertEquals(msg, 5, creatorFP.getHitThreshold());
assertEquals(msg, 14, creatorFP.getMinFilterValueLength());
assertEquals(msg, 1, creatorFP.getScopedSites().size());
assertEquals("site1", creatorFP.getScopedSites().iterator().next());
}
@Test
public void testOverrideOrder() throws Exception
{
ApplicationEvent applicationEvent = new ApplicationEvent(this)
{
private static final long serialVersionUID = 1L;
};
/*
* Override order: default,custom
*/
SolrFacetConfig config = new SolrFacetConfig(rawProperties, "default,custom");
config.setNamespaceService(context.getBean("namespaceService", NamespaceService.class));
config.onBootstrap(applicationEvent);
SolrFacetProperties creatorFP = config.getDefaultFacets().get("test_filter_creator");
assertEquals("Incorrect QNAME", "{http://www.alfresco.org/model/content/1.0}creator.__.u", creatorFP.getFacetQName().toString());
assertEquals(10, creatorFP.getMaxFilters());
assertEquals(5, creatorFP.getHitThreshold());
assertEquals(14, creatorFP.getMinFilterValueLength());
assertEquals(1, creatorFP.getScopedSites().size());
assertEquals("site1", creatorFP.getScopedSites().iterator().next());
/*
* Override order: custom,default
*/
config = new SolrFacetConfig(rawProperties, "custom,default");
config.setNamespaceService(context.getBean("namespaceService", NamespaceService.class));
config.onBootstrap(applicationEvent);
creatorFP = config.getDefaultFacets().get("test_filter_creator");
assertEquals("Incorrect QNAME", "{http://www.alfresco.org/model/content/1.0}creator.__.u", creatorFP.getFacetQName().toString());
assertEquals(5, creatorFP.getMaxFilters());
assertEquals(1, creatorFP.getHitThreshold());
assertEquals(4, creatorFP.getMinFilterValueLength());
assertEquals(0, creatorFP.getScopedSites().size());
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2005-2014 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.search.impl.solr.facet;
import junit.framework.JUnit4TestAdapter;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* @author Jamal Kaabi-Mofrad
*/
public class SolrFacetTestSuite extends TestSuite
{
/**
* Creates the test suite
*
* @return the test suite
*/
public static Test suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new JUnit4TestAdapter(SolrFacetHelperTest.class));
suite.addTest(new JUnit4TestAdapter(SolrFacetServiceImplTest.class));
suite.addTest(new JUnit4TestAdapter(SolrFacetConfigTest.class));
return suite;
}
}

View File

@@ -0,0 +1,26 @@
# Overrides test_filter_creator in the /facets/facets-config-sample.properties
custom.cm\:creator.__.u.filterID=test_filter_creator
custom.cm\:creator.__.u.displayName=faceted-search.facet-menu.facet.creator
custom.cm\:creator.__.u.displayControl=alfresco/search/FacetFilters
custom.cm\:creator.__.u.maxFilters=10
custom.cm\:creator.__.u.hitThreshold=5
custom.cm\:creator.__.u.minFilterValueLength=14
custom.cm\:creator.__.u.sortBy=ALPHABETICALLY
custom.cm\:creator.__.u.scope=ALL
custom.cm\:creator.__.u.scopedSites=site1
custom.cm\:creator.__.u.index=0
custom.cm\:creator.__.u.isEnabled=true
# Add a new Filter
# Field-Facet-Qname => cm:description.__
custom.cm\:description.filterID=test_filter_description
custom.cm\:description.displayName=faceted-search.facet-menu.facet.description
custom.cm\:description.displayControl=alfresco/search/FacetFilters
custom.cm\:description.maxFilters=3
custom.cm\:description.hitThreshold=1
custom.cm\:description.minFilterValueLength=2
custom.cm\:description.sortBy=DESCENDING
custom.cm\:description.scope=SCOPED_SITES
custom.cm\:description.scopedSites=
custom.cm\:description.index=4
custom.cm\:description.isEnabled=true

View File

@@ -0,0 +1,36 @@
# Field-Facet-Qname => cm:creator.__.u
default.cm\:creator.__.u.filterID=test_filter_creator
default.cm\:creator.__.u.displayName=faceted-search.facet-menu.facet.creator
default.cm\:creator.__.u.displayControl=alfresco/search/FacetFilters
default.cm\:creator.__.u.maxFilters=5
default.cm\:creator.__.u.hitThreshold=1
default.cm\:creator.__.u.minFilterValueLength=4
default.cm\:creator.__.u.sortBy=ALPHABETICALLY
default.cm\:creator.__.u.scope=ALL
default.cm\:creator.__.u.scopedSites=
default.cm\:creator.__.u.isEnabled=true
# Field-Facet-Qname => cm:modifier.__.u
default.cm\:modifier.__.u.filterID=test_filter_modifier
default.cm\:modifier.__.u.displayName=faceted-search.facet-menu.facet.modifier
default.cm\:modifier.__.u.displayControl=alfresco/search/FacetFilters
default.cm\:modifier.__.u.maxFilters=5
default.cm\:modifier.__.u.hitThreshold=1
default.cm\:modifier.__.u.minFilterValueLength=4
default.cm\:modifier.__.u.sortBy=ALPHABETICALLY
default.cm\:modifier.__.u.scope=SCOPED_SITES
default.cm\:modifier.__.u.scopedSites=
default.cm\:modifier.__.u.isEnabled=true
# Field-Facet-Qname => cm:content.size
default.cm\:content.size.filterID=test_filter_content_size
default.cm\:content.size.displayName=faceted-search.facet-menu.facet.size
default.cm\:content.size.displayControl=alfresco/search/FacetFilters
default.cm\:content.size.maxFilters=5
default.cm\:content.size.hitThreshold=1
default.cm\:content.size.minFilterValueLength=4
default.cm\:content.size.sortBy=ALPHABETICALLY
default.cm\:content.size.scope=ALL
default.cm\:content.size.scopedSites=
default.cm\:content.size.isEnabled=true
default.cm\:content.size.EXTRA-PROP.blockIncludeFacetRequest=true

View File

@@ -0,0 +1,21 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="solrFacetRawPropertiesTest" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath*:facets/facets-config-sample.properties</value>
<value>classpath*:facets/extension/facets-config-custom-sample.properties</value>
</list>
</property>
</bean>
<bean id="solrFacetConfigsTest" class="org.alfresco.repo.search.impl.solr.facet.SolrFacetConfig">
<constructor-arg index="0" ref="solrFacetRawPropertiesTest" />
<constructor-arg index="1">
<value>default,custom</value>
</constructor-arg>
<property name="namespaceService" ref="namespaceService" />
</bean>
</beans>