mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Tag cloud support
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@7449 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -318,7 +318,7 @@
|
||||
<!-- -->
|
||||
<bean id="indexerAndSearcherFactory" class="org.alfresco.repo.service.StoreRedirectorProxyFactory">
|
||||
<property name="proxyInterface">
|
||||
<value>org.alfresco.repo.search.IndexerAndSearcher</value>
|
||||
<value>org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcher</value>
|
||||
</property>
|
||||
<property name="defaultBinding">
|
||||
<ref bean="admLuceneIndexerAndSearcherFactory"></ref>
|
||||
@@ -502,6 +502,9 @@
|
||||
<bean id="luceneCategoryService" class="org.alfresco.repo.search.impl.lucene.LuceneCategoryServiceImpl">
|
||||
<property name="nodeService">
|
||||
<ref bean="nodeService" />
|
||||
</property>
|
||||
<property name="publicNodeService">
|
||||
<ref bean="NodeService" />
|
||||
</property>
|
||||
<property name="tenantService">
|
||||
<ref bean="tenantService"/>
|
||||
|
@@ -668,7 +668,7 @@
|
||||
<index enabled="true">
|
||||
<atomic>true</atomic>
|
||||
<stored>true</stored>
|
||||
<tokenised>true</tokenised>
|
||||
<tokenised>false</tokenised>
|
||||
</index>
|
||||
</property>
|
||||
</properties>
|
||||
|
@@ -456,6 +456,8 @@
|
||||
|
||||
<!-- Category queries are filtered for nodes that are visible to the current user -->
|
||||
<!-- Other methods are unrestricted at the moment -->
|
||||
|
||||
<!-- Uses the public node service for all mutations - access is allowed here and enforced by the public node service -->
|
||||
|
||||
<bean id="CategoryService_security" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
|
||||
@@ -468,11 +470,12 @@
|
||||
org.alfresco.service.cmr.search.CategoryService.getClassifications=AFTER_ACL_NODE.sys:base.ReadProperties
|
||||
org.alfresco.service.cmr.search.CategoryService.getRootCategories=AFTER_ACL_NODE.sys:base.ReadProperties
|
||||
org.alfresco.service.cmr.search.CategoryService.getClassificationAspects=ACL_ALLOW
|
||||
org.alfresco.service.cmr.search.CategoryService.createClassifiction=ACL_METHOD.ROLE_ADMINISTRATOR
|
||||
org.alfresco.service.cmr.search.CategoryService.createRootCategory=ACL_METHOD.ROLE_ADMINISTRATOR
|
||||
org.alfresco.service.cmr.search.CategoryService.createCategory=ACL_METHOD.ROLE_ADMINISTRATOR
|
||||
org.alfresco.service.cmr.search.CategoryService.deleteClassification=ACL_METHOD.ROLE_ADMINISTRATOR
|
||||
org.alfresco.service.cmr.search.CategoryService.deleteCategory=ACL_METHOD.ROLE_ADMINISTRATOR
|
||||
org.alfresco.service.cmr.search.CategoryService.createClassifiction=ACL_ALLOW
|
||||
org.alfresco.service.cmr.search.CategoryService.createRootCategory=ACL_ALLOW
|
||||
org.alfresco.service.cmr.search.CategoryService.createCategory=ACL_ALLOW
|
||||
org.alfresco.service.cmr.search.CategoryService.deleteClassification=ACL_ALLOW
|
||||
org.alfresco.service.cmr.search.CategoryService.deleteCategory=ACL_ALLOW
|
||||
org.alfresco.service.cmr.search.CategoryService.getTopCategories=ACL_ALLOW
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
@@ -28,8 +28,11 @@ import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.transaction.NotSupportedException;
|
||||
import javax.transaction.SystemException;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
@@ -58,6 +61,7 @@ import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
@@ -282,7 +286,7 @@ public class ADMLuceneCategoryTest extends TestCase
|
||||
genCatProp.setMandatory(true);
|
||||
genCatProp.setMultiValued(true);
|
||||
genCatProp.setStoredInIndex(true);
|
||||
genCatProp.setTokenisedInIndex(true);
|
||||
genCatProp.setTokenisedInIndex(false);
|
||||
genCatProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName());
|
||||
|
||||
assetClassCategorisationQName = QName.createQName(TEST_NAMESPACE, "AssetClass");
|
||||
@@ -294,7 +298,7 @@ public class ADMLuceneCategoryTest extends TestCase
|
||||
acProp.setMandatory(true);
|
||||
acProp.setMultiValued(true);
|
||||
acProp.setStoredInIndex(true);
|
||||
acProp.setTokenisedInIndex(true);
|
||||
acProp.setTokenisedInIndex(false);
|
||||
acProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName());
|
||||
|
||||
investmentRegionCategorisationQName = QName.createQName(TEST_NAMESPACE, "InvestmentRegion");
|
||||
@@ -306,7 +310,7 @@ public class ADMLuceneCategoryTest extends TestCase
|
||||
irProp.setMandatory(true);
|
||||
irProp.setMultiValued(true);
|
||||
irProp.setStoredInIndex(true);
|
||||
irProp.setTokenisedInIndex(true);
|
||||
irProp.setTokenisedInIndex(false);
|
||||
irProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName());
|
||||
|
||||
marketingRegionCategorisationQName = QName.createQName(TEST_NAMESPACE, "MarketingRegion");
|
||||
@@ -318,7 +322,7 @@ public class ADMLuceneCategoryTest extends TestCase
|
||||
mrProp.setMandatory(true);
|
||||
mrProp.setMultiValued(true);
|
||||
mrProp.setStoredInIndex(true);
|
||||
mrProp.setTokenisedInIndex(true);
|
||||
mrProp.setTokenisedInIndex(false);
|
||||
mrProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName());
|
||||
|
||||
dictionaryDAO.putModel(model);
|
||||
@@ -798,6 +802,52 @@ public class ADMLuceneCategoryTest extends TestCase
|
||||
|
||||
}
|
||||
|
||||
public void testCatCount() throws Exception
|
||||
{
|
||||
TransactionService transactionService = serviceRegistry.getTransactionService();
|
||||
UserTransaction tx = transactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
|
||||
|
||||
assertEquals(1, categoryService.getChildren(catACBase , CategoryService.Mode.MEMBERS, CategoryService.Depth.IMMEDIATE).size());
|
||||
assertEquals(2, categoryService.getChildren(catACBase , CategoryService.Mode.SUB_CATEGORIES, CategoryService.Depth.IMMEDIATE).size());
|
||||
assertEquals(3, categoryService.getChildren(catACBase , CategoryService.Mode.ALL, CategoryService.Depth.IMMEDIATE).size());
|
||||
assertEquals(14, categoryService.getChildren(catACBase , CategoryService.Mode.MEMBERS, CategoryService.Depth.ANY).size());
|
||||
assertEquals(3, categoryService.getChildren(catACBase , CategoryService.Mode.SUB_CATEGORIES, CategoryService.Depth.ANY).size());
|
||||
assertEquals(17, categoryService.getChildren(catACBase , CategoryService.Mode.ALL, CategoryService.Depth.ANY).size());
|
||||
assertEquals(2, categoryService.getClassifications(rootNodeRef.getStoreRef()).size());
|
||||
assertEquals(2, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.IMMEDIATE).size());
|
||||
assertEquals(3, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.ANY).size());
|
||||
assertEquals(6, categoryService.getClassificationAspects().size());
|
||||
assertEquals(2, categoryService.getRootCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass")).size());
|
||||
|
||||
List<Pair<NodeRef, Integer>> top = categoryService.getTopCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), 10);
|
||||
for(Pair<NodeRef, Integer> current : top)
|
||||
{
|
||||
System.out.println(""+nodeService.getPaths(current.getFirst(), true) + " "+current.getSecond());
|
||||
}
|
||||
|
||||
top = categoryService.getTopCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "InvestmentRegion"), 10);
|
||||
for(Pair<NodeRef, Integer> current : top)
|
||||
{
|
||||
System.out.println(""+nodeService.getPaths(current.getFirst(), true) + " "+current.getSecond());
|
||||
}
|
||||
|
||||
top = categoryService.getTopCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "MarketingRegion"), 10);
|
||||
for(Pair<NodeRef, Integer> current : top)
|
||||
{
|
||||
System.out.println(""+nodeService.getPaths(current.getFirst(), true) + " "+current.getSecond());
|
||||
}
|
||||
|
||||
top = categoryService.getTopCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "Region"), 10);
|
||||
for(Pair<NodeRef, Integer> current : top)
|
||||
{
|
||||
System.out.println(""+nodeService.getPaths(current.getFirst(), true) + " "+current.getSecond());
|
||||
}
|
||||
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private int getTotalScore(ResultSet results)
|
||||
{
|
||||
|
@@ -27,8 +27,10 @@ package org.alfresco.repo.search.impl.lucene;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
@@ -60,11 +62,13 @@ import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.ISO9075;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.alfresco.util.SearchLanguageConversion;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.index.TermDocs;
|
||||
import org.apache.lucene.index.TermEnum;
|
||||
import org.apache.lucene.search.Hits;
|
||||
import org.apache.lucene.search.Query;
|
||||
@@ -93,7 +97,7 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
private NamespacePrefixResolver namespacePrefixResolver;
|
||||
|
||||
private NodeService nodeService;
|
||||
|
||||
|
||||
private TenantService tenantService;
|
||||
|
||||
private QueryRegisterComponent queryRegister;
|
||||
@@ -156,13 +160,12 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
|
||||
public void setTenantService(TenantService tenantService)
|
||||
{
|
||||
this.tenantService = tenantService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the query register
|
||||
*
|
||||
@@ -175,8 +178,8 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
|
||||
public ResultSet query(StoreRef store, String language, String queryString, Path[] queryOptions, QueryParameterDefinition[] queryParameterDefinitions) throws SearcherException
|
||||
{
|
||||
store = tenantService.getName(store);
|
||||
|
||||
store = tenantService.getName(store);
|
||||
|
||||
SearchParameters sp = new SearchParameters();
|
||||
sp.addStore(store);
|
||||
sp.setLanguage(language);
|
||||
@@ -206,9 +209,9 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
{
|
||||
throw new IllegalStateException("Only one store can be searched at present");
|
||||
}
|
||||
|
||||
|
||||
ArrayList<StoreRef> stores = searchParameters.getStores();
|
||||
stores.set(0, tenantService.getName(searchParameters.getStores().get(0)));
|
||||
stores.set(0, tenantService.getName(searchParameters.getStores().get(0)));
|
||||
|
||||
String parameterisedQueryString;
|
||||
if (searchParameters.getQueryParameterDefinitions().size() > 0)
|
||||
@@ -243,18 +246,9 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
}
|
||||
|
||||
ClosingIndexSearcher searcher = getSearcher(indexer);
|
||||
Query query = LuceneQueryParser.parse(
|
||||
parameterisedQueryString, DEFAULT_FIELD,
|
||||
new LuceneAnalyser(
|
||||
getDictionaryService(),
|
||||
searchParameters.getMlAnalaysisMode() == null ? getLuceneConfig().getDefaultMLSearchAnalysisMode() : searchParameters.getMlAnalaysisMode()),
|
||||
namespacePrefixResolver,
|
||||
getDictionaryService(),
|
||||
tenantService,
|
||||
defaultOperator,
|
||||
searchParameters,
|
||||
getLuceneConfig(),
|
||||
searcher.getIndexReader());
|
||||
Query query = LuceneQueryParser.parse(parameterisedQueryString, DEFAULT_FIELD, new LuceneAnalyser(getDictionaryService(),
|
||||
searchParameters.getMlAnalaysisMode() == null ? getLuceneConfig().getDefaultMLSearchAnalysisMode() : searchParameters.getMlAnalaysisMode()),
|
||||
namespacePrefixResolver, getDictionaryService(), tenantService, defaultOperator, searchParameters, getLuceneConfig(), searcher.getIndexReader());
|
||||
if (s_logger.isDebugEnabled())
|
||||
{
|
||||
s_logger.debug("Query is " + query.toString());
|
||||
@@ -277,24 +271,24 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
{
|
||||
case FIELD:
|
||||
String field = sd.getField();
|
||||
if(field.startsWith("@"))
|
||||
if (field.startsWith("@"))
|
||||
{
|
||||
field = expandAttributeFieldName(field);
|
||||
PropertyDefinition propertyDef = getDictionaryService().getProperty(QName.createQName(field.substring(1)));
|
||||
field = expandAttributeFieldName(field);
|
||||
PropertyDefinition propertyDef = getDictionaryService().getProperty(QName.createQName(field.substring(1)));
|
||||
|
||||
if (propertyDef.getDataType().getName().equals(DataTypeDefinition.DATETIME))
|
||||
{
|
||||
DataTypeDefinition dataType = propertyDef.getDataType();
|
||||
String analyserClassName = dataType.getAnalyserClassName();
|
||||
if(analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()))
|
||||
{
|
||||
field = field + ".sort";
|
||||
}
|
||||
}
|
||||
if (propertyDef.getDataType().getName().equals(DataTypeDefinition.DATETIME))
|
||||
{
|
||||
DataTypeDefinition dataType = propertyDef.getDataType();
|
||||
String analyserClassName = dataType.getAnalyserClassName();
|
||||
if (analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()))
|
||||
{
|
||||
field = field + ".sort";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (fieldHasTerm(searcher.getReader(), field))
|
||||
{
|
||||
{
|
||||
fields[index++] = new SortField(field, !sd.isAscending());
|
||||
}
|
||||
else
|
||||
@@ -319,13 +313,7 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
}
|
||||
|
||||
Path[] paths = searchParameters.getAttributePaths().toArray(new Path[0]);
|
||||
return new LuceneResultSet(
|
||||
hits,
|
||||
searcher,
|
||||
nodeService,
|
||||
tenantService,
|
||||
paths,
|
||||
searchParameters);
|
||||
return new LuceneResultSet(hits, searcher, nodeService, tenantService, paths, searchParameters);
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
@@ -358,13 +346,7 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
return new EmptyResultSet();
|
||||
}
|
||||
Hits hits = searcher.search(query);
|
||||
return new LuceneResultSet(
|
||||
hits,
|
||||
searcher,
|
||||
nodeService,
|
||||
tenantService,
|
||||
searchParameters.getAttributePaths().toArray(new Path[0]),
|
||||
searchParameters);
|
||||
return new LuceneResultSet(hits, searcher, nodeService, tenantService, searchParameters.getAttributePaths().toArray(new Path[0]), searchParameters);
|
||||
}
|
||||
catch (SAXPathException e)
|
||||
{
|
||||
@@ -584,9 +566,9 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
boolean followAllParentLinks, String language) throws InvalidNodeRefException, XPathException
|
||||
{
|
||||
NodeSearcher nodeSearcher = new NodeSearcher(nodeService, getDictionaryService(), this);
|
||||
|
||||
|
||||
contextNodeRef = tenantService.getName(contextNodeRef);
|
||||
|
||||
|
||||
return nodeSearcher.selectNodes(contextNodeRef, xpath, parameters, namespacePrefixResolver, followAllParentLinks, language);
|
||||
}
|
||||
|
||||
@@ -750,4 +732,91 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
}
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
public List<Pair<String, Integer>> getTopTerms(String field, int count)
|
||||
{
|
||||
ClosingIndexSearcher searcher = null;
|
||||
try
|
||||
{
|
||||
LinkedList<Pair<String, Integer>> answer = new LinkedList<Pair<String, Integer>>();
|
||||
searcher = getSearcher(indexer);
|
||||
IndexReader reader = searcher.getIndexReader();
|
||||
TermEnum terms = reader.terms(new Term(field, ""));
|
||||
while (terms.next())
|
||||
{
|
||||
Term term = terms.term();
|
||||
if(!term.field().equals(field))
|
||||
{
|
||||
break;
|
||||
}
|
||||
int freq = terms.docFreq();
|
||||
Pair<String, Integer> pair = new Pair<String, Integer>(term.text(), Integer.valueOf(freq));
|
||||
if (answer.size() < count)
|
||||
{
|
||||
if (answer.size() == 0)
|
||||
{
|
||||
answer.add(pair);
|
||||
}
|
||||
else if (answer.get(answer.size() - 1).getSecond().compareTo(pair.getSecond()) >= 0)
|
||||
{
|
||||
answer.add(pair);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ListIterator<Pair<String, Integer>> it = answer.listIterator(); it.hasNext(); /**/)
|
||||
{
|
||||
Pair<String, Integer> test = it.next();
|
||||
if (test.getSecond().compareTo(pair.getSecond()) < 0)
|
||||
{
|
||||
it.previous();
|
||||
it.add(pair);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (answer.get(count - 1).getSecond().compareTo(pair.getSecond()) < 0)
|
||||
{
|
||||
for (ListIterator<Pair<String, Integer>> it = answer.listIterator(); it.hasNext(); /**/)
|
||||
{
|
||||
Pair<String, Integer> test = it.next();
|
||||
if (test.getSecond().compareTo(pair.getSecond()) < 0)
|
||||
{
|
||||
it.previous();
|
||||
it.add(pair);
|
||||
break;
|
||||
}
|
||||
}
|
||||
answer.removeLast();
|
||||
}
|
||||
else
|
||||
{
|
||||
// off the end
|
||||
}
|
||||
}
|
||||
terms.close();
|
||||
return answer;
|
||||
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new SearcherException(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (searcher != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
searcher.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new SearcherException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -31,6 +31,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
@@ -38,7 +39,10 @@ import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.search.IndexerAndSearcher;
|
||||
import org.alfresco.repo.search.IndexerException;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
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;
|
||||
@@ -47,22 +51,25 @@ import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.ISO9075;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* Category service implementation
|
||||
*
|
||||
* @author andyh
|
||||
*
|
||||
*/
|
||||
public class LuceneCategoryServiceImpl implements CategoryService
|
||||
{
|
||||
private NodeService nodeService;
|
||||
|
||||
private NodeService publicNodeService;
|
||||
|
||||
private TenantService tenantService;
|
||||
|
||||
|
||||
private NamespacePrefixResolver namespacePrefixResolver;
|
||||
|
||||
private DictionaryService dictionaryService;
|
||||
@@ -81,6 +88,7 @@ public class LuceneCategoryServiceImpl implements CategoryService
|
||||
|
||||
/**
|
||||
* Set the node service
|
||||
*
|
||||
* @param nodeService
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
@@ -88,8 +96,19 @@ public class LuceneCategoryServiceImpl implements CategoryService
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the public node service
|
||||
*
|
||||
* @param nodeService
|
||||
*/
|
||||
public void setPublicNodeService(NodeService publicNodeService)
|
||||
{
|
||||
this.publicNodeService = publicNodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tenant service
|
||||
*
|
||||
* @param tenantService
|
||||
*/
|
||||
public void setTenantService(TenantService tenantService)
|
||||
@@ -99,6 +118,7 @@ public class LuceneCategoryServiceImpl implements CategoryService
|
||||
|
||||
/**
|
||||
* Set the service to map prefixes to uris
|
||||
*
|
||||
* @param namespacePrefixResolver
|
||||
*/
|
||||
public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver)
|
||||
@@ -108,6 +128,7 @@ public class LuceneCategoryServiceImpl implements CategoryService
|
||||
|
||||
/**
|
||||
* Set the dictionary service
|
||||
*
|
||||
* @param dictionaryService
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
@@ -117,6 +138,7 @@ public class LuceneCategoryServiceImpl implements CategoryService
|
||||
|
||||
/**
|
||||
* Set the indexer and searcher
|
||||
*
|
||||
* @param indexerAndSearcher
|
||||
*/
|
||||
public void setIndexerAndSearcher(IndexerAndSearcher indexerAndSearcher)
|
||||
@@ -132,13 +154,13 @@ public class LuceneCategoryServiceImpl implements CategoryService
|
||||
}
|
||||
|
||||
categoryRef = tenantService.getName(categoryRef);
|
||||
|
||||
|
||||
ResultSet resultSet = null;
|
||||
try
|
||||
{
|
||||
StringBuilder luceneQuery = new StringBuilder(64);
|
||||
|
||||
switch(mode)
|
||||
switch (mode)
|
||||
{
|
||||
case ALL:
|
||||
luceneQuery.append("PATH:\"");
|
||||
@@ -264,15 +286,15 @@ public class LuceneCategoryServiceImpl implements CategoryService
|
||||
ResultSet resultSet = null;
|
||||
try
|
||||
{
|
||||
resultSet = indexerAndSearcher.getSearcher(storeRef, false).query(storeRef, "lucene", "PATH:\"/" + getPrefix(qname.getNamespaceURI()) + ISO9075.encode(qname.getLocalName()) + "\"",
|
||||
null, null);
|
||||
resultSet = indexerAndSearcher.getSearcher(storeRef, false).query(storeRef, "lucene",
|
||||
"PATH:\"/" + getPrefix(qname.getNamespaceURI()) + ISO9075.encode(qname.getLocalName()) + "\"", null, null);
|
||||
|
||||
Set<NodeRef> nodeRefs = new HashSet<NodeRef>(resultSet.length());
|
||||
for (ResultSetRow row : resultSet)
|
||||
{
|
||||
nodeRefs.add(row.getNodeRef());
|
||||
}
|
||||
|
||||
|
||||
return nodeRefs;
|
||||
}
|
||||
finally
|
||||
@@ -305,7 +327,7 @@ public class LuceneCategoryServiceImpl implements CategoryService
|
||||
|
||||
public Collection<QName> getClassificationAspects()
|
||||
{
|
||||
return dictionaryService.getSubAspects(ContentModel.ASPECT_CLASSIFIABLE, true);
|
||||
return dictionaryService.getSubAspects(ContentModel.ASPECT_CLASSIFIABLE, true);
|
||||
}
|
||||
|
||||
public NodeRef createClassifiction(StoreRef storeRef, QName typeName, String attributeName)
|
||||
@@ -326,23 +348,23 @@ public class LuceneCategoryServiceImpl implements CategoryService
|
||||
|
||||
public NodeRef createCategory(NodeRef parent, String name)
|
||||
{
|
||||
if(!nodeService.exists(parent))
|
||||
if (!nodeService.exists(parent))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Missing category?");
|
||||
}
|
||||
String uri = nodeService.getPrimaryParent(parent).getQName().getNamespaceURI();
|
||||
String validLocalName = QName.createValidLocalName(name);
|
||||
NodeRef newCategory = nodeService.createNode(parent, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(uri, validLocalName), ContentModel.TYPE_CATEGORY).getChildRef();
|
||||
nodeService.setProperty(newCategory, ContentModel.PROP_NAME, name);
|
||||
NodeRef newCategory = publicNodeService.createNode(parent, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(uri, validLocalName), ContentModel.TYPE_CATEGORY).getChildRef();
|
||||
publicNodeService.setProperty(newCategory, ContentModel.PROP_NAME, name);
|
||||
return newCategory;
|
||||
}
|
||||
|
||||
public NodeRef createRootCategory(StoreRef storeRef, QName aspectName, String name)
|
||||
{
|
||||
Set<NodeRef> nodeRefs = getClassificationNodes(storeRef, aspectName);
|
||||
if(nodeRefs.size() == 0)
|
||||
if (nodeRefs.size() == 0)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Missing classification: "+aspectName);
|
||||
throw new AlfrescoRuntimeException("Missing classification: " + aspectName);
|
||||
}
|
||||
NodeRef parent = nodeRefs.iterator().next();
|
||||
return createCategory(parent, name);
|
||||
@@ -350,16 +372,78 @@ public class LuceneCategoryServiceImpl implements CategoryService
|
||||
|
||||
public void deleteCategory(NodeRef nodeRef)
|
||||
{
|
||||
nodeService.deleteNode(nodeRef);
|
||||
publicNodeService.deleteNode(nodeRef);
|
||||
}
|
||||
|
||||
public void deleteClassification(StoreRef storeRef, QName aspectName)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public List<Pair<NodeRef, Integer>> getTopCategories(StoreRef storeRef, QName aspectName, int count)
|
||||
{
|
||||
if (indexerAndSearcher instanceof LuceneIndexerAndSearcher)
|
||||
{
|
||||
AspectDefinition definition = dictionaryService.getAspect(aspectName);
|
||||
if(definition == null)
|
||||
{
|
||||
throw new IllegalStateException("Unknown aspect");
|
||||
}
|
||||
QName catProperty = null;
|
||||
Map<QName, PropertyDefinition> properties = definition.getProperties();
|
||||
for(QName pName : properties.keySet())
|
||||
{
|
||||
if(pName.getNamespaceURI().equals(aspectName.getNamespaceURI()))
|
||||
{
|
||||
if(pName.getLocalName().equalsIgnoreCase(aspectName.getLocalName()))
|
||||
{
|
||||
PropertyDefinition def = properties.get(pName);
|
||||
if(def.getDataType().getName().equals(DataTypeDefinition.CATEGORY))
|
||||
{
|
||||
catProperty = pName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(catProperty == null)
|
||||
{
|
||||
throw new IllegalStateException("Aspect does not have category property mirroring the aspect name");
|
||||
}
|
||||
|
||||
|
||||
LuceneIndexerAndSearcher lias = (LuceneIndexerAndSearcher) indexerAndSearcher;
|
||||
String field = "@" + catProperty;
|
||||
SearchService searchService = lias.getSearcher(storeRef, true);
|
||||
if (searchService instanceof LuceneSearcher)
|
||||
{
|
||||
LuceneSearcher luceneSearcher = (LuceneSearcher)searchService;
|
||||
List<Pair<String, Integer>> topTerms = luceneSearcher.getTopTerms(field, count);
|
||||
List<Pair<NodeRef, Integer>> answer = new ArrayList<Pair<NodeRef, Integer>>();
|
||||
for (Pair<String, Integer> term : topTerms)
|
||||
{
|
||||
Pair<NodeRef, Integer> toAdd;
|
||||
NodeRef nodeRef = new NodeRef(term.getFirst());
|
||||
if (nodeService.exists(nodeRef))
|
||||
{
|
||||
toAdd = new Pair<NodeRef, Integer>(nodeRef, term.getSecond());
|
||||
}
|
||||
else
|
||||
{
|
||||
toAdd = new Pair<NodeRef, Integer>(null, term.getSecond());
|
||||
}
|
||||
answer.add(toAdd);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedOperationException("getPolularCategories is only supported for lucene indexes");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedOperationException("getPolularCategories is only supported for lucene indexes");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -24,8 +24,13 @@
|
||||
*/
|
||||
package org.alfresco.repo.search.impl.lucene;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.search.IndexerAndSearcher;
|
||||
import org.alfresco.repo.search.IndexerException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
public interface LuceneIndexerAndSearcher extends IndexerAndSearcher, LuceneConfig
|
||||
{
|
||||
@@ -40,4 +45,5 @@ public interface LuceneIndexerAndSearcher extends IndexerAndSearcher, LuceneConf
|
||||
}
|
||||
|
||||
public <R> R doWithAllWriteLocks(WithAllWriteLocksWork<R> lockWork);
|
||||
|
||||
}
|
||||
|
@@ -24,9 +24,13 @@
|
||||
*/
|
||||
package org.alfresco.repo.search.impl.lucene;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* Lucene implementation specific entension to the seracher API
|
||||
@@ -50,4 +54,13 @@ public interface LuceneSearcher extends SearchService
|
||||
* @param namespacePrefixResolver
|
||||
*/
|
||||
public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver);
|
||||
|
||||
/**
|
||||
* Get top terms
|
||||
*
|
||||
* @param field
|
||||
* @param count
|
||||
* @return
|
||||
*/
|
||||
public List<Pair<String, Integer>> getTopTerms(String field, int count);
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@
|
||||
package org.alfresco.service.cmr.search;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.Auditable;
|
||||
import org.alfresco.service.PublicService;
|
||||
@@ -32,6 +33,7 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* Category Service
|
||||
@@ -163,4 +165,14 @@ public interface CategoryService
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"nodeRef"})
|
||||
public void deleteCategory(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* Get the most polular categories
|
||||
*
|
||||
* @param storeRef
|
||||
* @param aspectName
|
||||
* @param count
|
||||
* @return
|
||||
*/
|
||||
public List<Pair<NodeRef, Integer>> getTopCategories(StoreRef storeRef, QName aspectName, int count);
|
||||
}
|
||||
|
Reference in New Issue
Block a user