diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml index cb97dc6ae5..62ec8aee76 100644 --- a/config/alfresco/core-services-context.xml +++ b/config/alfresco/core-services-context.xml @@ -347,6 +347,9 @@ + + + @@ -464,6 +467,9 @@ + + + diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerAndSearcherFactory.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerAndSearcherFactory.java index 46d1afc2f2..b8a3eeb2f2 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerAndSearcherFactory.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerAndSearcherFactory.java @@ -96,8 +96,11 @@ public class ADMLuceneIndexerAndSearcherFactory extends AbstractLuceneIndexerAnd protected LuceneIndexer createIndexer(StoreRef storeRef, String deltaId) { + storeRef = tenantService.getName(storeRef); + ADMLuceneIndexerImpl indexer = ADMLuceneIndexerImpl.getUpdateIndexer(storeRef, deltaId, this); indexer.setNodeService(nodeService); + indexer.setTenantService(tenantService); indexer.setDictionaryService(dictionaryService); // indexer.setLuceneIndexLock(luceneIndexLock); indexer.setFullTextSearchIndexer(fullTextSearchIndexer); @@ -108,10 +111,13 @@ public class ADMLuceneIndexerAndSearcherFactory extends AbstractLuceneIndexerAnd protected LuceneSearcher getSearcher(StoreRef storeRef, LuceneIndexer indexer) throws SearcherException { + storeRef = tenantService.getName(storeRef); + ADMLuceneSearcherImpl searcher = ADMLuceneSearcherImpl.getSearcher(storeRef, indexer, this); searcher.setNamespacePrefixResolver(nameSpaceService); // searcher.setLuceneIndexLock(luceneIndexLock); searcher.setNodeService(nodeService); + searcher.setTenantService(tenantService); searcher.setDictionaryService(dictionaryService); searcher.setQueryRegister(getQueryRegister()); return searcher; diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java index 777d1a4f82..7041795e40 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java @@ -48,6 +48,7 @@ import org.alfresco.repo.content.transform.ContentTransformer; import org.alfresco.repo.search.IndexerException; import org.alfresco.repo.search.impl.lucene.fts.FTSIndexerAware; import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer; +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; @@ -97,6 +98,11 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp * The node service we use to get information about nodes */ NodeService nodeService; + + /** + * The tenant service we use for multi-tenancy + */ + TenantService tenantService; /** * Content service to get content for indexing. @@ -127,24 +133,34 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp } /** - * IOC setting of dictionary service + * IOC setting of the dictionary service + * + * @param dictionaryService */ - public void setDictionaryService(DictionaryService dictionaryService) { super.setDictionaryService(dictionaryService); } /** - * Setter for getting the node service via IOC Used in the Spring container + * IOC setting of the node service * * @param nodeService */ - public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } + + /** + * IOC setting of the tenant service + * + * @param tenantService + */ + public void setTenantService(TenantService tenantService) + { + this.tenantService = tenantService; + } /** * IOC setting of the content service @@ -171,7 +187,8 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp { NodeRef childRef = relationshipRef.getChildRef(); // If we have the root node we delete all other root nodes first - if ((relationshipRef.getParentRef() == null) && childRef.equals(nodeService.getRootNode(childRef.getStoreRef()))) + if ((relationshipRef.getParentRef() == null) + && tenantService.getBaseName(childRef).equals(nodeService.getRootNode(childRef.getStoreRef()))) { addRootNodesToDeletionList(); s_logger.warn("Detected root node addition: deleting all nodes from the index"); @@ -226,6 +243,8 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp public void updateNode(NodeRef nodeRef) throws LuceneIndexException { + nodeRef = tenantService.getName(nodeRef); + if (s_logger.isDebugEnabled()) { s_logger.debug("Update node " + nodeRef); @@ -547,7 +566,7 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp } } - boolean isRoot = nodeRef.equals(nodeService.getRootNode(nodeRef.getStoreRef())); + boolean isRoot = nodeRef.equals(tenantService.getName(nodeService.getRootNode(nodeRef.getStoreRef()))); StringBuilder qNameBuffer = new StringBuilder(64); @@ -588,7 +607,7 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp qNameBuffer.append(";/"); } qNameBuffer.append(ISO9075.getXPathName(qNameRef.getQName())); - xdoc.add(new Field("PARENT", qNameRef.getParentRef().toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("PARENT", tenantService.getName(qNameRef.getParentRef()).toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); xdoc.add(new Field("ASSOCTYPEQNAME", ISO9075.getXPathName(qNameRef.getTypeQName()), Field.Store.YES, Field.Index.NO, Field.TermVector.NO)); xdoc.add(new Field("LINKASPECT", (pair.getSecond() == null) ? "" : ISO9075.getXPathName(pair.getSecond()), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); @@ -613,7 +632,7 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp directoryEntry.add(new Field("PATH", pathString, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); for (NodeRef parent : getParents(pair.getFirst())) { - directoryEntry.add(new Field("ANCESTOR", parent.toString(), Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + directoryEntry.add(new Field("ANCESTOR", tenantService.getName(parent).toString(), Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } directoryEntry.add(new Field("ISCONTAINER", "T", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); @@ -650,7 +669,7 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp // true)); ChildAssociationRef primary = nodeService.getPrimaryParent(nodeRef); - xdoc.add(new Field("PRIMARYPARENT", primary.getParentRef().toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("PRIMARYPARENT", tenantService.getName(primary.getParentRef()).toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); xdoc.add(new Field("PRIMARYASSOCTYPEQNAME", ISO9075.getXPathName(primary.getTypeQName()), Field.Store.YES, Field.Index.NO, Field.TermVector.NO)); QName typeQName = nodeService.getType(nodeRef); @@ -1061,6 +1080,9 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp { if (catRef != null) { + // can be running in context of System user, hence use input nodeRef + catRef = tenantService.getName(nodeRef, catRef); + try { for (Path path : nodeService.getPaths(catRef, false)) diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java index be338b1ef2..458f67b67c 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java @@ -40,6 +40,7 @@ import org.alfresco.repo.search.QueryRegisterComponent; import org.alfresco.repo.search.SearcherException; import org.alfresco.repo.search.impl.NodeSearcher; import org.alfresco.repo.search.impl.lucene.QueryParser.Operator; +import org.alfresco.repo.tenant.TenantService; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; @@ -85,6 +86,8 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS private NamespacePrefixResolver namespacePrefixResolver; private NodeService nodeService; + + private TenantService tenantService; private DictionaryService dictionaryService; @@ -147,6 +150,11 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS { this.nodeService = nodeService; } + + public void setTenantService(TenantService tenantService) + { + this.tenantService = tenantService; + } public void setDictionaryService(DictionaryService dictionaryService) { @@ -165,6 +173,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); + SearchParameters sp = new SearchParameters(); sp.addStore(store); sp.setLanguage(language); @@ -194,6 +204,9 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS { throw new IllegalStateException("Only one store can be searched at present"); } + + ArrayList stores = searchParameters.getStores(); + stores.set(0, tenantService.getName(searchParameters.getStores().get(0))); String parameterisedQueryString; if (searchParameters.getQueryParameterDefinitions().size() > 0) @@ -227,8 +240,10 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS defaultOperator = LuceneQueryParser.OR_OPERATOR; } - Query query = LuceneQueryParser.parse(parameterisedQueryString, DEFAULT_FIELD, new LuceneAnalyser( - dictionaryService, searchParameters.getMlAnalaysisMode() == null ? getLuceneConfig().getDefaultMLSearchAnalysisMode() : searchParameters.getMlAnalaysisMode()), namespacePrefixResolver, dictionaryService, defaultOperator, searchParameters, getLuceneConfig()); + Query query = LuceneQueryParser.parse(parameterisedQueryString, DEFAULT_FIELD, + new LuceneAnalyser(dictionaryService, searchParameters.getMlAnalaysisMode() == null ? getLuceneConfig().getDefaultMLSearchAnalysisMode() : searchParameters.getMlAnalaysisMode()), + namespacePrefixResolver, dictionaryService, tenantService, defaultOperator, searchParameters, getLuceneConfig()); + ClosingIndexSearcher searcher = getSearcher(indexer); if (searcher == null) { @@ -277,6 +292,7 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS hits, searcher, nodeService, + tenantService, paths, searchParameters); @@ -312,7 +328,7 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS return new EmptyResultSet(); } Hits hits = searcher.search(query); - return new LuceneResultSet(hits, searcher, nodeService, searchParameters.getAttributePaths().toArray( + return new LuceneResultSet(hits, searcher, nodeService, tenantService, searchParameters.getAttributePaths().toArray( new Path[0]), searchParameters); } catch (SAXPathException e) @@ -536,6 +552,9 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS throws InvalidNodeRefException, XPathException { NodeSearcher nodeSearcher = new NodeSearcher(nodeService, dictionaryService, this); + + contextNodeRef = tenantService.getName(contextNodeRef); + return nodeSearcher.selectNodes(contextNodeRef, xpath, parameters, namespacePrefixResolver, followAllParentLinks, language); } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java b/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java index f16cf468cb..ce69c4f7d9 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java @@ -45,6 +45,7 @@ import org.alfresco.repo.search.SearcherException; import org.alfresco.repo.search.impl.lucene.index.IndexInfo; import org.alfresco.repo.search.transaction.SimpleTransaction; import org.alfresco.repo.search.transaction.SimpleTransactionManager; +import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.repository.NodeService; @@ -106,10 +107,8 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI */ private static final int DEFAULT_TIMEOUT = 600000; - /** - * The node service we use to get information about nodes - */ - + protected TenantService tenantService; + private String indexRootLocation; private QueryRegisterComponent queryRegister; @@ -149,6 +148,16 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI this.indexRootLocation = indexRootLocation; } + /** + * Set the tenant service + * + * @param tenantService + */ + public void setTenantService(TenantService tenantService) + { + this.tenantService = tenantService; + } + /** * Set the query register * @@ -235,6 +244,8 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI */ public LuceneIndexer getIndexer(StoreRef storeRef) throws IndexerException { + storeRef = tenantService.getName(storeRef); + // register to receive txn callbacks // TODO: make this conditional on whether the XA stuff is being used // directly on not @@ -346,6 +357,8 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI */ public LuceneSearcher getSearcher(StoreRef storeRef, boolean searchDelta) throws SearcherException { + storeRef = tenantService.getName(storeRef); + String deltaId = null; LuceneIndexer indexer = null; if (searchDelta) diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryServiceImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryServiceImpl.java index e6dfdf174b..97b1b132bb 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryServiceImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryServiceImpl.java @@ -37,6 +37,7 @@ import org.alfresco.error.AlfrescoRuntimeException; 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.DictionaryService; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; @@ -60,6 +61,8 @@ public class LuceneCategoryServiceImpl implements CategoryService { private NodeService nodeService; + private TenantService tenantService; + private NamespacePrefixResolver namespacePrefixResolver; private DictionaryService dictionaryService; @@ -84,6 +87,15 @@ public class LuceneCategoryServiceImpl implements CategoryService { this.nodeService = nodeService; } + + /** + * Set the tenant service + * @param tenantService + */ + public void setTenantService(TenantService tenantService) + { + this.tenantService = tenantService; + } /** * Set the service to map prefixes to uris @@ -118,6 +130,9 @@ public class LuceneCategoryServiceImpl implements CategoryService { return Collections. emptyList(); } + + categoryRef = tenantService.getName(categoryRef); + ResultSet resultSet = null; try { @@ -244,6 +259,8 @@ public class LuceneCategoryServiceImpl implements CategoryService private Set getClassificationNodes(StoreRef storeRef, QName qname) { + storeRef = tenantService.getName(storeRef); + ResultSet resultSet = null; try { @@ -269,6 +286,8 @@ public class LuceneCategoryServiceImpl implements CategoryService public Collection getClassifications(StoreRef storeRef) { + storeRef = tenantService.getName(storeRef); + ResultSet resultSet = null; try { diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java index 534a52b03b..6ef4a59119 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java @@ -40,11 +40,14 @@ import org.alfresco.repo.search.SearcherException; import org.alfresco.repo.search.impl.lucene.analysis.MLTokenDuplicator; import org.alfresco.repo.search.impl.lucene.analysis.VerbatimAnalyser; import org.alfresco.repo.search.impl.lucene.query.PathQuery; +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.dictionary.TypeDefinition; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.namespace.NamespacePrefixResolver; import org.alfresco.service.namespace.QName; @@ -70,6 +73,8 @@ public class LuceneQueryParser extends QueryParser private DictionaryService dictionaryService; + private TenantService tenantService; + private SearchParameters searchParameters; private LuceneConfig config; @@ -88,7 +93,7 @@ public class LuceneQueryParser extends QueryParser * if the parsing fails */ static public Query parse(String query, String field, Analyzer analyzer, - NamespacePrefixResolver namespacePrefixResolver, DictionaryService dictionaryService, + NamespacePrefixResolver namespacePrefixResolver, DictionaryService dictionaryService, TenantService tenantService, Operator defaultOperator, SearchParameters searchParameters, LuceneConfig config) throws ParseException { if (s_logger.isDebugEnabled()) @@ -99,6 +104,7 @@ public class LuceneQueryParser extends QueryParser parser.setDefaultOperator(defaultOperator); parser.setNamespacePrefixResolver(namespacePrefixResolver); parser.setDictionaryService(dictionaryService); + parser.setTenantService(tenantService); parser.setSearchParameters(searchParameters); parser.setLuceneConfig(config); // TODO: Apply locale contstraints at the top level if required for the non ML doc types. @@ -124,6 +130,11 @@ public class LuceneQueryParser extends QueryParser { this.namespacePrefixResolver = namespacePrefixResolver; } + + public void setTenantService(TenantService tenantService) + { + this.tenantService = tenantService; + } public LuceneQueryParser(String arg0, Analyzer arg1) { @@ -212,6 +223,11 @@ public class LuceneQueryParser extends QueryParser } else if (field.equals("ID")) { + if (tenantService.isTenantUser() && (queryText.contains(StoreRef.URI_FILLER))) + { + // assume NodeRef, since it contains StorRef URI filler + queryText = tenantService.getName(new NodeRef(queryText)).toString(); + } TermQuery termQuery = new TermQuery(new Term(field, queryText)); return termQuery; } @@ -237,11 +253,21 @@ public class LuceneQueryParser extends QueryParser } else if (field.equals("PARENT")) { + if (tenantService.isTenantUser() && (queryText.contains(StoreRef.URI_FILLER))) + { + // assume NodeRef, since it contains StoreRef URI filler + queryText = tenantService.getName(new NodeRef(queryText)).toString(); + } TermQuery termQuery = new TermQuery(new Term(field, queryText)); return termQuery; } else if (field.equals("PRIMARYPARENT")) { + if (tenantService.isTenantUser() && (queryText.contains(StoreRef.URI_FILLER))) + { + // assume NodeRef, since it contains StoreRef URI filler + queryText = tenantService.getName(new NodeRef(queryText)).toString(); + } TermQuery termQuery = new TermQuery(new Term(field, queryText)); return termQuery; } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneResultSet.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneResultSet.java index 920d3045d7..dc1f79be2b 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneResultSet.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneResultSet.java @@ -30,6 +30,7 @@ import org.alfresco.repo.search.AbstractResultSet; import org.alfresco.repo.search.ResultSetRowIterator; import org.alfresco.repo.search.SearcherException; import org.alfresco.repo.search.SimpleResultSetMetaData; +import org.alfresco.repo.tenant.TenantService; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; @@ -60,6 +61,8 @@ public class LuceneResultSet extends AbstractResultSet private NodeService nodeService; + private TenantService tenantService; + SearchParameters searchParameters; /** @@ -68,12 +71,13 @@ public class LuceneResultSet extends AbstractResultSet * @param storeRef * @param hits */ - public LuceneResultSet(Hits hits, Searcher searcher, NodeService nodeService, Path[]propertyPaths, SearchParameters searchParameters) + public LuceneResultSet(Hits hits, Searcher searcher, NodeService nodeService, TenantService tenantService, Path[]propertyPaths, SearchParameters searchParameters) { super(propertyPaths); this.hits = hits; this.searcher = searcher; this.nodeService = nodeService; + this.tenantService = tenantService; this.searchParameters = searchParameters; } @@ -98,8 +102,8 @@ public class LuceneResultSet extends AbstractResultSet // We have to get the document to resolve this // It is possible the store ref is also stored in the index Document doc = hits.doc(n); - String id = doc.get("ID"); - return new NodeRef(id); + String id = doc.get("ID"); + return tenantService.getBaseName(new NodeRef(id)); } catch (IOException e) {