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

61048: Merged V4.2-BUG-FIX (4.2.2) to HEAD-BUG-FIX (Cloud/4.3)
      60930: Merged V4.1-BUG-FIX (4.1.8) to V4.2-BUG-FIX (4.2.2)
         60804: MNT-9595: Merged DEV to V4.1-BUG-FIX (4.1.8)
            57553: MNT-9595: Tag manager cannot find tags past the value of solr.query.maximumResultsFromUnlimitedQuery
               - Tag queries are unlimited. Make paginator in ConsoleTagManagement to fetch data by portions for tags actually displayed.
            57586: MNT-9595: Tag manager cannot find tags past the value of solr.query.maximumResultsFromUnlimitedQuery
               -  Do filter by tag name on SOLR side.
            60643: MNT-9595: Tag manager cannot find tags past the value of solr.query.maximumResultsFromUnlimitedQuery
               -  Prepend wildcard to the filter to match the old contains behaviour. Add unit tests for the tag and category filtering.
            60765: MNT-9595: Tag manager cannot find tags past the value of solr.query.maximumResultsFromUnlimitedQuery
               -  Add test for wildcard matches support.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@62380 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Alan Davis
2014-02-12 14:48:36 +00:00
parent d62668db53
commit c66a25e95d
8 changed files with 235 additions and 7 deletions

View File

@@ -47,6 +47,7 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.CategoryService;
import org.alfresco.service.cmr.search.LimitBy;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
@@ -147,10 +148,15 @@ public class LuceneCategoryServiceImpl implements CategoryService
public Collection<ChildAssociationRef> getChildren(NodeRef categoryRef, Mode mode, Depth depth)
{
return getChildren(categoryRef, mode, depth, false);
return getChildren(categoryRef, mode, depth, false, null);
}
public Collection<ChildAssociationRef> getChildren(NodeRef categoryRef, Mode mode, Depth depth, String filter)
{
return getChildren(categoryRef, mode, depth, false, filter);
}
private Collection<ChildAssociationRef> getChildren(NodeRef categoryRef, Mode mode, Depth depth, boolean sortByName)
private Collection<ChildAssociationRef> getChildren(NodeRef categoryRef, Mode mode, Depth depth, boolean sortByName, String filter)
{
if (categoryRef == null)
{
@@ -195,18 +201,26 @@ public class LuceneCategoryServiceImpl implements CategoryService
luceneQuery.append("+TYPE:\"" + ContentModel.TYPE_CATEGORY.toString() + "\"");
break;
}
if (filter != null)
{
luceneQuery.append(" " + "+@cm\\:name:\"*" + filter + "*\"");
}
// Get a searcher that will include Categories added in this transaction
SearchService searcher = indexerAndSearcher.getSearcher(categoryRef.getStoreRef(), true);
// Perform the search
SearchParameters searchParameters = new SearchParameters();
searchParameters.setQuery(luceneQuery.toString());
resultSet = searcher.query(categoryRef.getStoreRef(), "lucene", luceneQuery.toString(), null);
searchParameters.setLanguage("lucene");
if(sortByName)
{
searchParameters.addSort("@" + ContentModel.PROP_NAME, true);
}
searchParameters.setQuery(luceneQuery.toString());
searchParameters.setLimit(-1);
searchParameters.setMaxItems(Integer.MAX_VALUE);
searchParameters.setLimitBy(LimitBy.UNLIMITED);
searchParameters.addStore(categoryRef.getStoreRef());
resultSet = searcher.query(searchParameters);
@@ -368,7 +382,7 @@ public class LuceneCategoryServiceImpl implements CategoryService
OUTER: for(NodeRef nodeRef : nodeRefs)
{
Collection<ChildAssociationRef> children = getChildren(nodeRef, Mode.SUB_CATEGORIES, Depth.IMMEDIATE, sortByName);
Collection<ChildAssociationRef> children = getChildren(nodeRef, Mode.SUB_CATEGORIES, Depth.IMMEDIATE, sortByName, null);
for(ChildAssociationRef child : children)
{
count++;
@@ -418,12 +432,17 @@ public class LuceneCategoryServiceImpl implements CategoryService
}
public Collection<ChildAssociationRef> getRootCategories(StoreRef storeRef, QName aspectName)
{
return getRootCategories(storeRef, aspectName, null);
}
public Collection<ChildAssociationRef> getRootCategories(StoreRef storeRef, QName aspectName, String filter)
{
Collection<ChildAssociationRef> assocs = new LinkedList<ChildAssociationRef>();
Set<NodeRef> nodeRefs = getClassificationNodes(storeRef, aspectName);
for (NodeRef nodeRef : nodeRefs)
{
assocs.addAll(getChildren(nodeRef, Mode.SUB_CATEGORIES, Depth.IMMEDIATE));
assocs.addAll(getChildren(nodeRef, Mode.SUB_CATEGORIES, Depth.IMMEDIATE, false, filter));
}
return assocs;
}

View File

@@ -518,6 +518,36 @@ public class TaggingServiceImpl implements TaggingService,
}
return result;
}
public Pair<List<String>, Integer> getPagedTags(StoreRef storeRef, int fromTag, int pageSize)
{
ParameterCheck.mandatory("storeRef", storeRef);
ParameterCheck.mandatory("fromTag", fromTag);
ParameterCheck.mandatory("pageSize", pageSize);
Collection<ChildAssociationRef> rootCategories = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE);
final int totalCount = rootCategories.size();
final int startIndex = Math.max(fromTag, 0);
final int endIndex = Math.min(fromTag + pageSize, totalCount);
List<String> result = new ArrayList<String>(pageSize);
int index = 0;
// paging for not sorted tag names
for (ChildAssociationRef rootCategory : rootCategories)
{
if (startIndex > index++)
{
continue;
}
String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME);
result.add(name);
if (index == endIndex)
{
break;
}
}
return new Pair<List<String>, Integer> (result, totalCount);
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.StoreRef, java.lang.String)
@@ -547,7 +577,44 @@ public class TaggingServiceImpl implements TaggingService,
return result;
}
public Pair<List<String>, Integer> getPagedTags(StoreRef storeRef, String filter, int fromTag, int pageSize)
{
ParameterCheck.mandatory("storeRef", storeRef);
ParameterCheck.mandatory("fromTag", fromTag);
ParameterCheck.mandatory("pageSize", pageSize);
if (filter == null || filter.length() == 0)
{
return getPagedTags(storeRef, fromTag, pageSize);
}
else
{
Collection<ChildAssociationRef> rootCategories = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE, filter);
final int totalCount = rootCategories.size();
final int startIndex = Math.max(fromTag, 0);
final int endIndex = Math.min(fromTag + pageSize, totalCount);
List<String> result = new ArrayList<String>(pageSize);
int index = 0;
// paging for not sorted tag names
for (ChildAssociationRef rootCategory : rootCategories)
{
if (startIndex > index++)
{
continue;
}
String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME);
result.add(name);
if (index == endIndex)
{
break;
}
}
return new Pair<List<String>, Integer> (result, totalCount);
}
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#hasTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
*/
@@ -1423,5 +1490,6 @@ public class TaggingServiceImpl implements TaggingService,
*/
public void flush()
{
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2005-2013 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.tagging.script;
/**
* Stores total tags count together with tags to be sent to UI
*
* @author Viachaslau Tsikhanovich
*
*/
public class PagedTagsWrapper
{
private String[] tagNames;
private String total;
public PagedTagsWrapper(String[] tagNames, int total)
{
super();
this.setTagNames(tagNames);
this.setTotal(total);
}
public String[] getTagNames()
{
return tagNames;
}
public void setTagNames(String[] tagNames)
{
this.tagNames = tagNames;
}
public String getTotal()
{
return total;
}
public void setTotal(int total)
{
this.total = String.valueOf(total);
}
}

View File

@@ -25,6 +25,7 @@ import org.alfresco.repo.jscript.ScriptNode;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.Pair;
/**
@@ -60,6 +61,22 @@ public class ScriptTaggingService extends BaseScopableProcessorExtension
return (String[])result.toArray(new String[result.size()]);
}
/**
* Get page of tags with totalRecords info
*
* @param store
* @param fromTag
* @param pageSize
* @return
*/
public PagedTagsWrapper getPagedTags(String store, int fromTag, int pageSize)
{
StoreRef storeRef = new StoreRef(store);
Pair<List<String>, Integer> page = this.serviceRegistry.getTaggingService().getPagedTags(storeRef, fromTag, pageSize);
List<String> result = page.getFirst();
return new PagedTagsWrapper((String[])result.toArray(new String[result.size()]), page.getSecond());
}
/**
* Get all the tags available in a store based on a text filter
*
@@ -74,6 +91,14 @@ public class ScriptTaggingService extends BaseScopableProcessorExtension
return (String[])result.toArray(new String[result.size()]);
}
public PagedTagsWrapper getPagedTags(String store, String filter, int fromTag, int pageSize)
{
StoreRef storeRef = new StoreRef(store);
Pair<List<String>, Integer> page = this.serviceRegistry.getTaggingService().getPagedTags(storeRef, filter, fromTag, pageSize);
List<String> result = page.getFirst();
return new PagedTagsWrapper((String[])result.toArray(new String[result.size()]), page.getSecond());
}
/**
* Get a tag by name if available in a store
*

View File

@@ -114,6 +114,17 @@ public interface CategoryService
@Auditable(parameters = {"storeRef", "aspectName", "pagingRequest", "sortByName"})
PagingResults<ChildAssociationRef> getRootCategories(StoreRef storeRef, QName aspectName, PagingRequest pagingRequest, boolean sortByName);
/**
* Get the root categories for an aspect/classification with names that start with filter
*
* @param storeRef
* @param aspectName
* @param filter
* @return
*/
@Auditable(parameters = {"storeRef", "aspectName"})
public Collection<ChildAssociationRef> getRootCategories(StoreRef storeRef, QName aspectName, String filter);
/**
* Looks up a category by name under its immediate parent. Index-independent so can be used for cluster-safe
* existence checks.

View File

@@ -275,6 +275,28 @@ public interface TaggingService
*/
@NotAuditable
List<NodeRef> findTaggedNodes(StoreRef storeRef, String tag, NodeRef nodeRef);
/**
* Get page of the tags currently available
*
* @param storeRef node reference
* @param fromTag offset
* @param pageSize page size
* @return Pair<List<String>, Integer> pair of tag names and total count
*/
@NotAuditable
Pair<List<String>, Integer> getPagedTags(StoreRef storeRef, int fromTag, int pageSize);
/**
*
* @param storeRef node reference
* @param filter tag filter
* @param fromTag page offset
* @param pageSize page size
* @return Pair<List<String>, Integer> pair of tag names and total count
*/
@NotAuditable
Pair<List<String>, Integer> getPagedTags(StoreRef storeRef, String filter, int fromTag, int pageSize);
}