Merged DEV/SWIFT to HEAD

27125: Subtasks of ALF-7072: RSOLR 013: Remote API to get ACLs and readers
          - ALF-8334: RSOLR 013: Modify ACL schema to record change times
          - ALF-8336: RSOLR 013: DB upgrade scripts for ACL changes
          - TODO: Query APIs
   27128: Added TooManyResultsException as a concurrency detection trigger
          - Usually too many results indicates that the DB table key is not as specific as it should be,
            but it's AVM that showed this up.
   27132: Clean up: javadocs; non-javadocs; uncommented fields; @since tags; etc.
   27134: Removed empty directory
   27135: Fix for ALF-8333: CMIS query: JOIN on an aspect results in CmisInvalidArgumentException
          - incorrect scope used when building orderings
   27139: Fixed SORL transaction tracking queries
          - Queries were using incompatible boolean comparisons
          - Added SOLRDAO to test suite
          - Cleaned up code and reformatted code
   27141: Minor additions to CannedQuery interface
          - get parameter bean
          - construct sort details from a list
          - ALF-7167: Canned queries
   27146: RINF 09 / RINF 10: DB-based paged query for get children (DocLib & CMIS) 
          - milestone check-in for sprint demo & review (WIP)
          - added new FileFolderService (paged) list query (public API is subject to change)
          - moved temp JavaScript sorting to Java
          - example usage by DocLib (via ScriptNode) and CMIS (via AlfrescoCmisService)
          - implemented as demo "canned query" including embedded use of "list" permission interceptor
          - ALF-7402 / ALF-7168
   27150: RINF 09 / RINF 10: DB-based paged query for get children (DocLib & CMIS) 
          - missed file (follow-on to r27146)
   27158: ALF-7070, ALF-7072: SOLR tracking (node and changeset)
          - Pulled non-DAO code into SOLRTrackingComponent
          - DAO code and related tests just test basic CRUD
          - SOLRTrackingComponent does complex cross-schema manipulation
   27159: Fixed line ending and removed svn:eol-style
   27160: ALF-8334: RSOLR 013: Fixed SQL Server syntax
   27165: RINF 09 / RINF 10: DB-based paged query for get children (DocLib & CMIS) 
          - fix listDeepFolders (causing Imap*Test to fail) 
          - all private methods now order files followed by folders
		    (consistent with existing public APIs such as FileFolderService.search & ScriptNode.childFileFolders*)
          - follow-on to r27146
   28271: Consolidate diagnostic logging for max perm checks (ALF-8388 + ALF-8419)
          - note: this should be a trivial merge to HEAD

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28292 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2011-06-08 17:29:54 +00:00
parent 2f697cebb9
commit efbd951a10
55 changed files with 4434 additions and 2609 deletions

View File

@@ -59,8 +59,11 @@ import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.lock.LockStatus;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.model.PagingFileInfoResults;
import org.alfresco.service.cmr.model.PagingSortRequest;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
@@ -69,6 +72,7 @@ import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.PagingSortProp;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
@@ -135,6 +139,9 @@ public class ScriptNode implements Serializable, Scopeable, NamespacePrefixResol
/** Cached values */
protected NodeRef nodeRef;
private FileInfo nodeInfo;
private String name;
private QName type;
protected String id;
@@ -167,6 +174,7 @@ public class ScriptNode implements Serializable, Scopeable, NamespacePrefixResol
protected ServiceRegistry services = null;
private NodeService nodeService = null;
private FileFolderService fileFolderService = null;
private Boolean isDocument = null;
private Boolean isContainer = null;
private Boolean isLinkToDocument = null;
@@ -201,6 +209,13 @@ public class ScriptNode implements Serializable, Scopeable, NamespacePrefixResol
* @param services The ServiceRegistry the Node can use to access services
* @param scope Root scope for this Node
*/
public ScriptNode(FileInfo nodeInfo, ServiceRegistry services, Scriptable scope)
{
this(nodeInfo.getNodeRef(), services, scope);
this.nodeInfo = nodeInfo;
}
public ScriptNode(NodeRef nodeRef, ServiceRegistry services, Scriptable scope)
{
if (nodeRef == null)
@@ -217,6 +232,7 @@ public class ScriptNode implements Serializable, Scopeable, NamespacePrefixResol
this.id = nodeRef.getId();
this.services = services;
this.nodeService = services.getNodeService();
this.fileFolderService = services.getFileFolderService();
this.scope = scope;
}
@@ -247,6 +263,11 @@ public class ScriptNode implements Serializable, Scopeable, NamespacePrefixResol
return new ScriptNode(nodeRef, services, scope);
}
public ScriptNode newInstance(FileInfo nodeInfo, ServiceRegistry services, Scriptable scope)
{
return new ScriptNode(nodeInfo, services, scope);
}
/**
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable)
*/
@@ -532,34 +553,18 @@ public class ScriptNode implements Serializable, Scopeable, NamespacePrefixResol
* This is equivalent to @see FileFolderService.listFiles() and @see FileFolderService.listFolders()
*/
public Scriptable childFileFolders(boolean files, boolean folders, Object ignoreTypes)
{
return childFileFolders(files, folders, ignoreTypes, -1, -1, null, true).getResult();
}
@SuppressWarnings("unchecked")
public ScriptPagingNodes childFileFolders(boolean files, boolean folders, Object ignoreTypes, int skipOffset, int maxItems, String sortProp, boolean ascending)
{
Object[] results;
// Build a list of file and folder types
DictionaryService dd = services.getDictionaryService();
Set<QName> searchTypeQNames = new HashSet<QName>(16, 1.0f);
if (folders)
{
Collection<QName> qnames = dd.getSubTypes(ContentModel.TYPE_FOLDER, true);
searchTypeQNames.addAll(qnames);
searchTypeQNames.add(ContentModel.TYPE_FOLDER);
}
if (files)
{
Collection<QName> qnames = dd.getSubTypes(ContentModel.TYPE_CONTENT, true);
searchTypeQNames.addAll(qnames);
searchTypeQNames.add(ContentModel.TYPE_CONTENT);
qnames = dd.getSubTypes(ContentModel.TYPE_LINK, true);
searchTypeQNames.addAll(qnames);
searchTypeQNames.add(ContentModel.TYPE_LINK);
}
Set<QName> ignoreTypeQNames = new HashSet<QName>(5);
// Remove 'system' folder types
Collection<QName> qnames = dd.getSubTypes(ContentModel.TYPE_SYSTEM_FOLDER, true);
searchTypeQNames.removeAll(qnames);
searchTypeQNames.remove(ContentModel.TYPE_SYSTEM_FOLDER);
// Add user defined types to ignore from the search
// Add user defined types to ignore
if (ignoreTypes instanceof ScriptableObject)
{
Serializable types = getValueConverter().convertValueForRepo((ScriptableObject)ignoreTypes);
@@ -567,36 +572,41 @@ public class ScriptNode implements Serializable, Scopeable, NamespacePrefixResol
{
for (Serializable typeObj : (List<Serializable>)types)
{
searchTypeQNames.remove(createQName(typeObj.toString()));
ignoreTypeQNames.add(createQName(typeObj.toString()));
}
}
else if (types instanceof String)
{
searchTypeQNames.remove(createQName(types.toString()));
ignoreTypeQNames.add(createQName(types.toString()));
}
}
else if (ignoreTypes instanceof String)
{
searchTypeQNames.remove(createQName(ignoreTypes.toString()));
ignoreTypeQNames.add(createQName(ignoreTypes.toString()));
}
// Perform the query and collect the results
if (searchTypeQNames.size() != 0)
List<PagingSortProp> sortProps = null; // note: null sortProps => get all in default sort order
if (sortProp != null)
{
List<ChildAssociationRef> childAssocRefs = this.nodeService.getChildAssocs(this.nodeRef, searchTypeQNames);
results = new Object[childAssocRefs.size()];
for (int i=0; i<childAssocRefs.size(); i++)
{
ChildAssociationRef assocRef = childAssocRefs.get(i);
results[i] = newInstance(assocRef.getChildRef(), this.services, this.scope);
}
}
else
{
results = new Object[0];
sortProps = new ArrayList<PagingSortProp>(1);
sortProps.add(new PagingSortProp(createQName(sortProp), ascending));
}
return Context.getCurrentContext().newArray(this.scope, results);
PagingSortRequest pageRequest = new PagingSortRequest(skipOffset, maxItems, true, sortProps);
PagingFileInfoResults pageOfNodeInfos = this.fileFolderService.list(this.nodeRef, files, folders, ignoreTypeQNames, pageRequest);
List<FileInfo> nodeInfos = pageOfNodeInfos.getResultsForPage();
int size = nodeInfos.size();
results = new Object[size];
for (int i=0; i<size; i++)
{
FileInfo nodeInfo = nodeInfos.get(i);
results[i] = newInstance(nodeInfo, this.services, this.scope);
}
return new ScriptPagingNodes(Context.getCurrentContext().newArray(this.scope, results), pageOfNodeInfos.getTotalCount(), pageOfNodeInfos.hasMore());
}
/**
@@ -749,7 +759,6 @@ public class ScriptNode implements Serializable, Scopeable, NamespacePrefixResol
*
* @return Array of child associations from this Node that match a specific object type.
*/
@SuppressWarnings("unchecked")
public Scriptable getChildAssocsByType(String type)
{
// get the list of child assoc nodes for each association type
@@ -830,7 +839,16 @@ public class ScriptNode implements Serializable, Scopeable, NamespacePrefixResol
// properties that have not been initialised - see AR-1673.
this.properties = new ContentAwareScriptableQNameMap<String, Serializable>(this, this.services);
Map<QName, Serializable> props = this.nodeService.getProperties(this.nodeRef);
Map<QName, Serializable> props = null;
if (nodeInfo != null)
{
props = nodeInfo.getProperties();
}
else
{
props = this.nodeService.getProperties(this.nodeRef);
}
for (QName qname : props.keySet())
{
Serializable propValue = props.get(qname);

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2005-2010 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.jscript;
import java.io.Serializable;
import org.mozilla.javascript.Scriptable;
/**
* TEMP
*
* @deprecated for review (API is subject to change)
*/
public class ScriptPagingNodes implements Serializable
{
private static final long serialVersionUID = -3252996649397737176L;
private Scriptable result; // array of script nodes
private Boolean hasMore; // null => unknown
private Long totalCount; // null => not requested (or unknown)
public ScriptPagingNodes(Scriptable result, Long totalCount, Boolean hasMore)
{
this.result = result;
this.totalCount = totalCount;
this.hasMore = hasMore;
}
public Scriptable getResult()
{
return result;
}
public Long getTotalCount()
{
return totalCount;
}
public Boolean hasMore()
{
return hasMore;
}
}