mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
17717: This check-in contains changes in Java and .NET TCK tests related to CMIS-43 and CMIS-44 JIRA tasks. Also some bugs were faced out and fixed in 17727: CMIS-69: Alfresco to CMIS ACL mapping: Part 1: API 17732: Merge HEAD to DEV/CMIS10 17756: MOB-563: SQL Tests - Lexer 17764: CMIS-69: Alfresco to CMIS ACL mapping: get ACL support 17802: More for CMIS-69: Alfresco to CMIS ACL mapping. Implementation for applyAcl. 17830: Fixes for CMIS lexer and parser tests 17838: Access fix ups for access by the WS/Rest layers 17869: 1) remote-api: 17874: SAIL-146: Alfresco to CMIS ACL mapping: Support to group ACEs by principal id 17883: Adjust version properties for dev/cmis10 branch. 17885: Update OASIS CMIS TC status. 17889: Fix issue where objectid is not rendered correctly for CMIS private working copies. 17890: SAIL-146: Alfresco to CMIS ACL mapping: Fixes for ACL merging when reporting and ordering of ACEs. Report full permissions and not unique short names. 17902: Fix issue where CMIS queries via GET used incorrect defaults for paging. 17909: Fix CMIS link relations for folder tree. 17912: Fix CMIS type descendants atompub link 17922: Update AtomPub binding to CMIS 1.0 CD05 XSDs. 17924: SAIL-146: Alfresco to CMIS ACL mapping: Test set using full permissions (as opposed to short unique names) 17927: Fix content stream create/update status to comply with CMIS 1.0 CD05. 17934: Resolve encoding issues in CMIS AtomPub binding. 17973: SAIL-171: CMIS Renditions REST binding 17975: SAIL-146: Alfresco to CMIS ACL mapping: Completed AllowedAction and Permissions mapping. Added missing canDeleteTree. 17990: Update CMIS AtomPub to CD06 17996: Updates for cmis.alfresco.com for CD06 in prep for public review 2. 18007: WS-Bindings were updated with CMIS 1.0 cd06 changes. 18016: CMIS web services: Add missing generated files from WSDL 18018: CMIS index page updates for cmis.alfresco.com 18041: Merged HEAD to DEV/CMIS_10 18059: SAIL-227: 18067: SAIL-157: Strict vs Non-Strict Query Language: Enforce restrictions on the use of SCORE() and CONTAINS() 18080: Fix for SAIL-213:Bug: Query engine does not check that select list properties are valid for selectors 18131: SAIL-156: Query Language Compliance: Fix support for LIKE, including escaping of '%' and '_' with '\'. 18132: SAIL-156: Query Language Compliance: Fix support for LIKE, including escaping of '%' and '_' with '\': Fix underlying lucene impl for prefix and fuzzy queries to match wildcard/like 18143: SAIL-156: Query Language Compliance: Fix and check qualifiers in IN_TREE and IN_FOLDER. Improved scoring for CONTAINS() 18173: SAIL-245: Exclude thumbnails from normal query results 18179: SAIL 214: Query Language Compliance: Check for valid object ids in IN_FOLDER and IN_TREE 18210: SAIL-156: Query Language Compliance: Support for simple column aliases in predicates/function arguments/embedded FTS. Check property/selector binding in embedded FTS. 18211: SAIL-156: Query Language Compliance: Support for simple column aliases in predicates/function arguments/embedded FTS. Check property/selector binding in embedded FTS. 18215: SAIL 156: Query Language Compliance: Fix CMIS type info to reflect the underlying settings of the Alfresco type for includeInSuperTypeQuery 18244: SAIL 156: Query Language Compliance: includeInSuperTypeQuery -> includedInSuperTypeQuery: First cut of cmis query test model. Fixed modelSchema.xml to validate 18255: SAIL 156: Query Language Compliance: First set of tests for predicates using properties mapped to CMIS Strings. 18261: CMIS-49 SAIL-163: Alfresco to CMIS Change Log mapping - New CMIS Audit mapping is implemented. ChangeLogDataExtractor was added. 18263: Build Fix 18285: SAIL 156: Query Language Compliance: Restrictions on predicates that may be used by single-valued and multi-valued properties 18287: SAIL-186: Changes to make CMIS Rendition REST bindings pass new TCK tests 18291: Fix Eclipse classpath problems 18323: CMIS-44 SAIL-187: Change Log tests (WS) – Java and .NET tests for change log were implemented. 18325: SAIL 156: Query Language Compliance: Fixes and tests for d:mltext mappings 18329: Updated Chemistry TCK jar including Dave W's rendition tests. 18333: Fix compile error - spurious imports. 18334: Fix issue where absurl web script method failed when deployed to root context. 18339: Update CMIS index page for start of public review 2. 18387: SAIL-147: CMIS ACL REST bindings + framework fixes 18392: Fix typo 18394: SAIL 156: Query Language Compliance: Fixes and tests for d:<numeric> 18406: SAIL 156: Query Language Compliance: Remaining type/predicate combinations. Restriction of In/Comparisons for ID/Boolean 18408: CMIS Query language - remove (pointless) multi-valued column from language definition 18409: Formatting change for CMIS.g 18410: Formatting change for FTS.g 18411: CMIS TCK tests were updated to CMIS 1.0 cd06 schemas. 18412: SAIL 156: Query Language Compliance: Tests and fixes for aliases for all data types in simple predicates (they behave as the direct column reference) 18417: Update Chemistry TCK which now incorporates Dave W's ACL tests. 18419: Update CMIS index page to include public review end date. 18427: SAIL 156: Query Language Compliance: Expose multi-valued properties in queries. Tests for all accessors. Fix content length to be long. 18435: SAIL 156: Query Language Compliance: Use queryable correctly and fix up model mappings. Add tests for baseTypeId, contentStreamId and path. 18472: SAIL 156: Query Language Compliance: Tests and fixes for FTS/Contains expressions. Adhere strictly to the spec - no extensions available by default. Improved FTS error reporting (and stop any recovery). 18477: SAIL-164: CMIS change log REST bindings 18495: SAIL 156: Query Language Compliance: Tests and fixes for escaping in string literals, LIKE and FTS expressions. 18537: SAIL 156: Query Language Compliance: Sorting support. Basic sort test for all orderable/indexed CMIS properties. 18538: SAIL-164: CMIS change log fixes for TCK compliance 18547: SAIL 156: Query Language Compliance: Ordering tests for all datatypes, including null values. 18582: Incorporate latest Chemistry TCK 18583: Update list of supported CMIS capabilities in index page. 18606: SAIL-156, SAIL-157, SAIL-158: Query Language Compliance: Respect all query options including locale. Fixes and tests for MLText cross language support. 18608: SAIL-159: Java / Javascript API access to CMIS Query Language 18617: SAIL-158: Query Tests: Check policy and relationship types are not queryable. 18636: SAIL-184: ACL tests (WS) 18663: ACL tests were updated in accordance with last requirements by David Caruana. 18680: Update to CMIS CD07 18681: Fix CMIS ContentStreamId property when document has no content. 18700: CMIS: Head merge problem resolution. Phase 1: Merge up to and including revision 18700, as this the point where both AtomPub and Web Services TCK tests succeed completely on dev branch. Note: includes CMIS rendition support ready for integration and testing with DM renditions. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18790 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
1073 lines
31 KiB
Java
1073 lines
31 KiB
Java
/*
|
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program 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 General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
* As a special exception to the terms and conditions of version 2.0 of
|
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
|
* FLOSS exception. You should have recieved a copy of the text describing
|
|
* the FLOSS exception, and it is also available here:
|
|
* http://www.alfresco.com/legal/licensing"
|
|
*/
|
|
package org.alfresco.web.bean.admin;
|
|
|
|
import java.io.Serializable;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import javax.faces.application.FacesMessage;
|
|
import javax.faces.context.FacesContext;
|
|
import javax.faces.model.DataModel;
|
|
import javax.faces.model.ListDataModel;
|
|
import javax.faces.model.SelectItem;
|
|
|
|
import org.alfresco.error.AlfrescoRuntimeException;
|
|
import org.alfresco.repo.domain.PropertyValue;
|
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
|
import org.alfresco.service.cmr.avm.AVMService;
|
|
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.AssociationRef;
|
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|
import org.alfresco.service.cmr.repository.NodeRef;
|
|
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.ResultSet;
|
|
import org.alfresco.service.cmr.search.SearchService;
|
|
import org.alfresco.service.cmr.security.AccessPermission;
|
|
import org.alfresco.service.cmr.security.AccessStatus;
|
|
import org.alfresco.service.cmr.security.PermissionService;
|
|
import org.alfresco.service.namespace.NamespaceService;
|
|
import org.alfresco.service.namespace.QName;
|
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
|
import org.alfresco.service.transaction.TransactionService;
|
|
import org.alfresco.util.ISO9075;
|
|
import org.alfresco.web.app.servlet.DownloadContentServlet;
|
|
import org.alfresco.web.bean.repository.Repository;
|
|
|
|
// TODO: DownloadServlet - use of request parameter for property name?
|
|
// TODO: Anyway to switch content view url link / property value text?
|
|
|
|
/**
|
|
* Backing bean to support the Admin Node Browser
|
|
*/
|
|
public class AdminNodeBrowseBean implements Serializable
|
|
{
|
|
private static final long serialVersionUID = -8702324672426537379L;
|
|
|
|
/** selected query language */
|
|
private String queryLanguage = null;
|
|
|
|
/** available query languages */
|
|
private static List<SelectItem> queryLanguages = new ArrayList<SelectItem>();
|
|
static
|
|
{
|
|
queryLanguages.add(new SelectItem("noderef"));
|
|
queryLanguages.add(new SelectItem(SearchService.LANGUAGE_XPATH));
|
|
queryLanguages.add(new SelectItem(SearchService.LANGUAGE_LUCENE));
|
|
queryLanguages.add(new SelectItem(SearchService.LANGUAGE_FTS_ALFRESCO));
|
|
queryLanguages.add(new SelectItem(SearchService.LANGUAGE_CMIS_STRICT));
|
|
queryLanguages.add(new SelectItem(SearchService.LANGUAGE_CMIS_ALFRESCO));
|
|
queryLanguages.add(new SelectItem("selectnodes"));
|
|
}
|
|
|
|
// query and results
|
|
private String query = null;
|
|
private SearchResults searchResults = new SearchResults((List<NodeRef>) null);
|
|
|
|
private NodeRef nodeRef = null;
|
|
private QName nodeType = null;
|
|
private Path primaryPath = null;
|
|
private Boolean inheritPermissions = null;
|
|
|
|
// stores and node
|
|
transient private DataModel stores = null;
|
|
transient private DataModel parents = null;
|
|
transient private DataModel aspects = null;
|
|
transient private DataModel properties = null;
|
|
transient private DataModel children = null;
|
|
transient private DataModel assocs = null;
|
|
transient private DataModel permissions = null;
|
|
transient private DataModel permissionMasks = null;
|
|
transient private DataModel avmStoreProps = null;
|
|
|
|
// supporting repository services
|
|
transient private TransactionService transactionService;
|
|
transient private NodeService nodeService;
|
|
transient private DictionaryService dictionaryService;
|
|
transient private SearchService searchService;
|
|
transient private NamespaceService namespaceService;
|
|
transient private PermissionService permissionService;
|
|
transient private AVMService avmService;
|
|
|
|
/**
|
|
* @param transactionService transaction service
|
|
*/
|
|
public void setTransactionService(TransactionService transactionService)
|
|
{
|
|
this.transactionService = transactionService;
|
|
}
|
|
|
|
private TransactionService getTransactionService()
|
|
{
|
|
if (transactionService == null)
|
|
{
|
|
transactionService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getTransactionService();
|
|
}
|
|
return transactionService;
|
|
}
|
|
|
|
/**
|
|
* @param nodeService node service
|
|
*/
|
|
public void setNodeService(NodeService nodeService)
|
|
{
|
|
this.nodeService = nodeService;
|
|
}
|
|
|
|
private NodeService getNodeService()
|
|
{
|
|
if (nodeService == null)
|
|
{
|
|
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService();
|
|
}
|
|
return nodeService;
|
|
}
|
|
|
|
/**
|
|
* @param searchService search service
|
|
*/
|
|
public void setSearchService(SearchService searchService)
|
|
{
|
|
this.searchService = searchService;
|
|
}
|
|
|
|
private SearchService getSearchService()
|
|
{
|
|
if (searchService == null)
|
|
{
|
|
searchService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getSearchService();
|
|
}
|
|
return searchService;
|
|
}
|
|
|
|
/**
|
|
* @param dictionaryService dictionary service
|
|
*/
|
|
public void setDictionaryService(DictionaryService dictionaryService)
|
|
{
|
|
this.dictionaryService = dictionaryService;
|
|
}
|
|
|
|
private DictionaryService getDictionaryService()
|
|
{
|
|
if (dictionaryService == null)
|
|
{
|
|
dictionaryService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getDictionaryService();
|
|
}
|
|
return dictionaryService;
|
|
}
|
|
|
|
/**
|
|
* @param namespaceService namespace service
|
|
*/
|
|
public void setNamespaceService(NamespaceService namespaceService)
|
|
{
|
|
this.namespaceService = namespaceService;
|
|
}
|
|
|
|
private NamespaceService getNamespaceService()
|
|
{
|
|
if (namespaceService == null)
|
|
{
|
|
namespaceService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNamespaceService();
|
|
}
|
|
return namespaceService;
|
|
}
|
|
|
|
/**
|
|
* @param permissionService permission service
|
|
*/
|
|
public void setPermissionService(PermissionService permissionService)
|
|
{
|
|
this.permissionService = permissionService;
|
|
}
|
|
|
|
private PermissionService getPermissionService()
|
|
{
|
|
if (permissionService == null)
|
|
{
|
|
permissionService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getPermissionService();
|
|
}
|
|
return permissionService;
|
|
}
|
|
|
|
/**
|
|
* @param avmService AVM service
|
|
*/
|
|
public void setAVMService(AVMService avmService)
|
|
{
|
|
this.avmService = avmService;
|
|
}
|
|
|
|
private AVMService getAVMService()
|
|
{
|
|
if (avmService == null)
|
|
{
|
|
avmService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAVMService();
|
|
}
|
|
return avmService;
|
|
}
|
|
|
|
/**
|
|
* Gets the list of repository stores
|
|
*
|
|
* @return stores
|
|
*/
|
|
public DataModel getStores()
|
|
{
|
|
if (stores == null)
|
|
{
|
|
List<StoreRef> storeRefs = getNodeService().getStores();
|
|
stores = new ListDataModel(storeRefs);
|
|
}
|
|
return stores;
|
|
}
|
|
|
|
/**
|
|
* Gets the selected node reference
|
|
*
|
|
* @return node reference (defaults to system store root)
|
|
*/
|
|
public NodeRef getNodeRef()
|
|
{
|
|
if (nodeRef == null)
|
|
{
|
|
nodeRef = getNodeService().getRootNode(new StoreRef("system", "system"));
|
|
}
|
|
return nodeRef;
|
|
}
|
|
|
|
/**
|
|
* Sets the selected node reference
|
|
*
|
|
* @param nodeRef node reference
|
|
*/
|
|
private void setNodeRef(NodeRef nodeRef)
|
|
{
|
|
this.nodeRef = nodeRef;
|
|
|
|
// clear cache
|
|
primaryPath = null;
|
|
nodeType = null;
|
|
parents = null;
|
|
aspects = null;
|
|
properties = null;
|
|
children = null;
|
|
assocs = null;
|
|
inheritPermissions = null;
|
|
permissions = null;
|
|
permissionMasks = null;
|
|
}
|
|
|
|
/**
|
|
* Gets the current node type
|
|
*
|
|
* @return node type
|
|
*/
|
|
public QName getNodeType()
|
|
{
|
|
if (nodeType == null)
|
|
{
|
|
nodeType = getNodeService().getType(getNodeRef());
|
|
}
|
|
return nodeType;
|
|
}
|
|
|
|
/**
|
|
* Gets the current node primary path
|
|
*
|
|
* @return primary path
|
|
*/
|
|
public String getPrimaryPath()
|
|
{
|
|
if (primaryPath == null)
|
|
{
|
|
primaryPath = getNodeService().getPath(getNodeRef());
|
|
}
|
|
return ISO9075.decode(primaryPath.toString());
|
|
}
|
|
|
|
/**
|
|
* Gets the current node primary parent reference
|
|
*
|
|
* @return primary parent ref
|
|
*/
|
|
public NodeRef getPrimaryParent()
|
|
{
|
|
getPrimaryPath();
|
|
Path.Element element = primaryPath.last();
|
|
NodeRef parentRef = ((Path.ChildAssocElement) element).getRef().getParentRef();
|
|
return parentRef;
|
|
}
|
|
|
|
/**
|
|
* Gets the current node aspects
|
|
*
|
|
* @return node aspects
|
|
*/
|
|
public DataModel getAspects()
|
|
{
|
|
if (aspects == null)
|
|
{
|
|
List<QName> aspectNames = new ArrayList<QName>(getNodeService().getAspects(getNodeRef()));
|
|
aspects = new ListDataModel(aspectNames);
|
|
}
|
|
return aspects;
|
|
}
|
|
|
|
/**
|
|
* Gets the current node parents
|
|
*
|
|
* @return node parents
|
|
*/
|
|
public DataModel getParents()
|
|
{
|
|
if (parents == null)
|
|
{
|
|
List<ChildAssociationRef> parentRefs = getNodeService().getParentAssocs(getNodeRef());
|
|
parents = new ListDataModel(parentRefs);
|
|
}
|
|
return parents;
|
|
}
|
|
|
|
/**
|
|
* Gets the current node properties
|
|
*
|
|
* @return properties
|
|
*/
|
|
public DataModel getProperties()
|
|
{
|
|
if (properties == null)
|
|
{
|
|
Map<QName, Serializable> propertyValues = getNodeService().getProperties(getNodeRef());
|
|
List<Property> nodeProperties = new ArrayList<Property>(propertyValues.size());
|
|
for (Map.Entry<QName, Serializable> property : propertyValues.entrySet())
|
|
{
|
|
nodeProperties.add(new Property(property.getKey(), property.getValue()));
|
|
}
|
|
properties = new ListDataModel(nodeProperties);
|
|
}
|
|
return properties;
|
|
}
|
|
|
|
/**
|
|
* Gets whether the current node inherits its permissions from a parent node
|
|
*
|
|
* @return true => inherits permissions
|
|
*/
|
|
public boolean getInheritPermissions()
|
|
{
|
|
if (inheritPermissions == null)
|
|
{
|
|
inheritPermissions = this.getPermissionService().getInheritParentPermissions(nodeRef);
|
|
}
|
|
return inheritPermissions.booleanValue();
|
|
}
|
|
|
|
/**
|
|
* Gets the current node permissions
|
|
*
|
|
* @return the permissions
|
|
*/
|
|
public DataModel getPermissions()
|
|
{
|
|
if (permissions == null)
|
|
{
|
|
AccessStatus readPermissions = this.getPermissionService().hasPermission(nodeRef, PermissionService.READ_PERMISSIONS);
|
|
if (readPermissions.equals(AccessStatus.ALLOWED))
|
|
{
|
|
List<AccessPermission> nodePermissions = new ArrayList<AccessPermission>(getPermissionService().getAllSetPermissions(nodeRef));
|
|
permissions = new ListDataModel(nodePermissions);
|
|
}
|
|
else
|
|
{
|
|
List<NoReadPermissionGranted> noReadPermissions = new ArrayList<NoReadPermissionGranted>(1);
|
|
noReadPermissions.add(new NoReadPermissionGranted());
|
|
permissions = new ListDataModel(noReadPermissions);
|
|
}
|
|
}
|
|
return permissions;
|
|
}
|
|
|
|
/**
|
|
* Gets the current node permissions
|
|
*
|
|
* @return the permissions
|
|
*/
|
|
public DataModel getStorePermissionMasks()
|
|
{
|
|
if (permissionMasks == null)
|
|
{
|
|
if (nodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM))
|
|
{
|
|
List<AccessPermission> nodePermissions = new ArrayList<AccessPermission>(getPermissionService().getAllSetPermissions(nodeRef.getStoreRef()));
|
|
permissionMasks = new ListDataModel(nodePermissions);
|
|
}
|
|
else
|
|
{
|
|
List<NoStoreMask> noReadPermissions = new ArrayList<NoStoreMask>(1);
|
|
noReadPermissions.add(new NoStoreMask());
|
|
permissionMasks = new ListDataModel(noReadPermissions);
|
|
}
|
|
}
|
|
return permissionMasks;
|
|
}
|
|
|
|
/**
|
|
* Gets the current node children
|
|
*
|
|
* @return node children
|
|
*/
|
|
public DataModel getChildren()
|
|
{
|
|
if (children == null)
|
|
{
|
|
List<ChildAssociationRef> assocRefs = getNodeService().getChildAssocs(getNodeRef());
|
|
children = new ListDataModel(assocRefs);
|
|
}
|
|
return children;
|
|
}
|
|
|
|
/**
|
|
* Gets the current node associations
|
|
*
|
|
* @return associations
|
|
*/
|
|
public DataModel getAssocs()
|
|
{
|
|
if (assocs == null)
|
|
{
|
|
try
|
|
{
|
|
List<AssociationRef> assocRefs = getNodeService().getTargetAssocs(getNodeRef(), RegexQNamePattern.MATCH_ALL);
|
|
assocs = new ListDataModel(assocRefs);
|
|
}
|
|
catch (UnsupportedOperationException err)
|
|
{
|
|
// some stores do not support associations
|
|
}
|
|
}
|
|
return assocs;
|
|
}
|
|
|
|
public boolean getInAVMStore()
|
|
{
|
|
return nodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM);
|
|
}
|
|
|
|
public DataModel getAVMStoreProperties()
|
|
{
|
|
if (avmStoreProps == null)
|
|
{
|
|
// work out the store name from current nodeRef
|
|
String store = nodeRef.getStoreRef().getIdentifier();
|
|
Map<QName, PropertyValue> props = getAVMService().getStoreProperties(store);
|
|
List<Map<String, String>> storeProperties = new ArrayList<Map<String, String>>();
|
|
|
|
for (Map.Entry<QName, PropertyValue> property : props.entrySet())
|
|
{
|
|
Map<String, String> map = new HashMap<String, String>(2);
|
|
map.put("name", property.getKey().toString());
|
|
map.put("type", property.getValue().getActualTypeString());
|
|
String val = property.getValue().getStringValue();
|
|
if (val == null)
|
|
{
|
|
val = "null";
|
|
}
|
|
map.put("value", val);
|
|
|
|
storeProperties.add(map);
|
|
}
|
|
|
|
avmStoreProps = new ListDataModel(storeProperties);
|
|
}
|
|
|
|
return avmStoreProps;
|
|
}
|
|
|
|
/**
|
|
* Gets the current query language
|
|
*
|
|
* @return query language
|
|
*/
|
|
public String getQueryLanguage()
|
|
{
|
|
return queryLanguage;
|
|
}
|
|
|
|
/**
|
|
* Sets the current query language
|
|
*
|
|
* @param queryLanguage query language
|
|
*/
|
|
public void setQueryLanguage(String queryLanguage)
|
|
{
|
|
this.queryLanguage = queryLanguage;
|
|
}
|
|
|
|
/**
|
|
* Gets the current query
|
|
*
|
|
* @return query statement
|
|
*/
|
|
public String getQuery()
|
|
{
|
|
return query;
|
|
}
|
|
|
|
/**
|
|
* Set the current query
|
|
*
|
|
* @param query query statement
|
|
*/
|
|
public void setQuery(String query)
|
|
{
|
|
this.query = query;
|
|
}
|
|
|
|
/**
|
|
* Gets the list of available query languages
|
|
*
|
|
* @return query languages
|
|
*/
|
|
public List<SelectItem> getQueryLanguages()
|
|
{
|
|
return queryLanguages;
|
|
}
|
|
|
|
/**
|
|
* Gets the current search results
|
|
*
|
|
* @return search results
|
|
*/
|
|
public SearchResults getSearchResults()
|
|
{
|
|
return searchResults;
|
|
}
|
|
|
|
/**
|
|
* Action to select a store
|
|
*
|
|
* @return next action
|
|
*/
|
|
public String selectStore()
|
|
{
|
|
StoreRef storeRef = (StoreRef) getStores().getRowData();
|
|
NodeRef rootNode = getNodeService().getRootNode(storeRef);
|
|
setNodeRef(rootNode);
|
|
|
|
this.avmStoreProps = null;
|
|
|
|
return "success";
|
|
}
|
|
|
|
/**
|
|
* Action to select stores list
|
|
*
|
|
* @return next action
|
|
*/
|
|
public String selectStores()
|
|
{
|
|
stores = null;
|
|
return "success";
|
|
}
|
|
|
|
/**
|
|
* Action to select primary path
|
|
*
|
|
* @return next action
|
|
*/
|
|
public String selectPrimaryPath()
|
|
{
|
|
// force refresh of self
|
|
setNodeRef(nodeRef);
|
|
return "success";
|
|
}
|
|
|
|
/**
|
|
* Action to select primary parent
|
|
*
|
|
* @return next action
|
|
*/
|
|
public String selectPrimaryParent()
|
|
{
|
|
setNodeRef(getPrimaryParent());
|
|
return "success";
|
|
}
|
|
|
|
/**
|
|
* Action to select parent
|
|
*
|
|
* @return next action
|
|
*/
|
|
public String selectParent()
|
|
{
|
|
ChildAssociationRef assocRef = (ChildAssociationRef) getParents().getRowData();
|
|
NodeRef parentRef = assocRef.getParentRef();
|
|
setNodeRef(parentRef);
|
|
return "success";
|
|
}
|
|
|
|
/**
|
|
* Action to select association To node
|
|
*
|
|
* @return next action
|
|
*/
|
|
public String selectToNode()
|
|
{
|
|
AssociationRef assocRef = (AssociationRef) getAssocs().getRowData();
|
|
NodeRef targetRef = assocRef.getTargetRef();
|
|
setNodeRef(targetRef);
|
|
return "success";
|
|
}
|
|
|
|
/**
|
|
* Action to select node property
|
|
*
|
|
* @return next action
|
|
*/
|
|
public String selectNodeProperty()
|
|
{
|
|
Property property = (Property) getProperties().getRowData();
|
|
Property.Value value = (Property.Value) property.getValues().getRowData();
|
|
NodeRef nodeRef = (NodeRef) value.getValue();
|
|
setNodeRef(nodeRef);
|
|
return "success";
|
|
}
|
|
|
|
/**
|
|
* Action to select child
|
|
*
|
|
* @return next action
|
|
*/
|
|
public String selectChild()
|
|
{
|
|
ChildAssociationRef assocRef = (ChildAssociationRef) getChildren().getRowData();
|
|
NodeRef childRef = assocRef.getChildRef();
|
|
setNodeRef(childRef);
|
|
return "success";
|
|
}
|
|
|
|
/**
|
|
* Action to select search result node
|
|
*
|
|
* @return next action
|
|
*/
|
|
public String selectResultNode()
|
|
{
|
|
ChildAssociationRef assocRef = (ChildAssociationRef) searchResults.getRows().getRowData();
|
|
NodeRef childRef = assocRef.getChildRef();
|
|
setNodeRef(childRef);
|
|
return "success";
|
|
}
|
|
|
|
/**
|
|
* Action to submit search
|
|
*
|
|
* @return next action
|
|
*/
|
|
public String submitSearch()
|
|
{
|
|
RetryingTransactionCallback<String> searchCallback = new RetryingTransactionCallback<String>()
|
|
{
|
|
public String execute() throws Throwable
|
|
{
|
|
if (queryLanguage.equals("noderef"))
|
|
{
|
|
// ensure node exists
|
|
NodeRef nodeRef = new NodeRef(query);
|
|
boolean exists = getNodeService().exists(nodeRef);
|
|
if (!exists)
|
|
{
|
|
throw new AlfrescoRuntimeException("Node " + nodeRef + " does not exist.");
|
|
}
|
|
setNodeRef(nodeRef);
|
|
return "node";
|
|
}
|
|
else if (queryLanguage.equals("selectnodes"))
|
|
{
|
|
List<NodeRef> nodes = getSearchService().selectNodes(getNodeRef(), query, null, getNamespaceService(), false);
|
|
searchResults = new SearchResults(nodes);
|
|
return "search";
|
|
}
|
|
|
|
// perform search
|
|
searchResults = new SearchResults(getSearchService().query(getNodeRef().getStoreRef(), queryLanguage, query));
|
|
return "search";
|
|
}
|
|
};
|
|
|
|
try
|
|
{
|
|
return getTransactionService().getRetryingTransactionHelper().doInTransaction(searchCallback, true);
|
|
}
|
|
catch (Throwable e)
|
|
{
|
|
FacesContext context = FacesContext.getCurrentInstance();
|
|
FacesMessage message = new FacesMessage();
|
|
message.setSeverity(FacesMessage.SEVERITY_ERROR);
|
|
message.setDetail("Search failed due to: " + e.toString());
|
|
context.addMessage("searchForm:query", message);
|
|
return "error";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Property wrapper class
|
|
*/
|
|
public class Property
|
|
{
|
|
private QName name;
|
|
|
|
private boolean isCollection = false;
|
|
|
|
private DataModel values;
|
|
|
|
private String datatype;
|
|
|
|
private String residual;
|
|
|
|
/**
|
|
* Construct
|
|
*
|
|
* @param name property name
|
|
* @param value property values
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public Property(QName name, Serializable value)
|
|
{
|
|
this.name = name;
|
|
|
|
PropertyDefinition propDef = getDictionaryService().getProperty(name);
|
|
if (propDef != null)
|
|
{
|
|
datatype = propDef.getDataType().getName().toString();
|
|
residual = "false";
|
|
}
|
|
else
|
|
{
|
|
residual = "true";
|
|
}
|
|
|
|
// handle multi/single values
|
|
final List<Value> values;
|
|
if (value instanceof Collection)
|
|
{
|
|
Collection<Serializable> oldValues = (Collection<Serializable>) value;
|
|
values = new ArrayList<Value>(oldValues.size());
|
|
isCollection = true;
|
|
for (Serializable multiValue : oldValues)
|
|
{
|
|
values.add(new Value(multiValue));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
values = Collections.singletonList(new Value(value));
|
|
}
|
|
this.values = new ListDataModel(values);
|
|
}
|
|
|
|
/**
|
|
* Gets the property name
|
|
*
|
|
* @return name
|
|
*/
|
|
public QName getName()
|
|
{
|
|
return name;
|
|
}
|
|
|
|
/**
|
|
* Gets the property data type
|
|
*
|
|
* @return data type
|
|
*/
|
|
public String getDataType()
|
|
{
|
|
return datatype;
|
|
}
|
|
|
|
/**
|
|
* Gets the property value
|
|
*
|
|
* @return value
|
|
*/
|
|
public DataModel getValues()
|
|
{
|
|
return values;
|
|
}
|
|
|
|
/**
|
|
* Determines whether the property is residual
|
|
*
|
|
* @return true => property is not defined in dictionary
|
|
*/
|
|
public String getResidual()
|
|
{
|
|
return residual;
|
|
}
|
|
|
|
/**
|
|
* Determines whether the property is of ANY type
|
|
*
|
|
* @return true => is any
|
|
*/
|
|
public boolean isAny()
|
|
{
|
|
return (datatype == null) ? false : datatype.equals(DataTypeDefinition.ANY.toString());
|
|
}
|
|
|
|
/**
|
|
* Determines whether the property is a collection
|
|
*
|
|
* @return true => is collection
|
|
*/
|
|
public boolean isCollection()
|
|
{
|
|
return isCollection;
|
|
}
|
|
|
|
/**
|
|
* Value wrapper
|
|
*/
|
|
public class Value
|
|
{
|
|
private Serializable value;
|
|
|
|
/**
|
|
* Construct
|
|
*
|
|
* @param value value
|
|
*/
|
|
public Value(Serializable value)
|
|
{
|
|
this.value = value;
|
|
}
|
|
|
|
/**
|
|
* Gets the value
|
|
*
|
|
* @return the value
|
|
*/
|
|
public Serializable getValue()
|
|
{
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Gets the value datatype
|
|
*
|
|
* @return the value datatype
|
|
*/
|
|
public String getDataType()
|
|
{
|
|
String datatype = Property.this.getDataType();
|
|
if (datatype == null || datatype.equals(DataTypeDefinition.ANY.toString()))
|
|
{
|
|
if (value != null)
|
|
{
|
|
DataTypeDefinition dataTypeDefinition = getDictionaryService().getDataType(value.getClass());
|
|
if (dataTypeDefinition != null)
|
|
{
|
|
datatype = getDictionaryService().getDataType(value.getClass()).getName().toString();
|
|
}
|
|
}
|
|
}
|
|
return datatype;
|
|
}
|
|
|
|
/**
|
|
* Gets the download url (for content properties)
|
|
*
|
|
* @return url
|
|
*/
|
|
public String getUrl()
|
|
{
|
|
String url = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
|
|
url += DownloadContentServlet.generateBrowserURL(nodeRef, "file.bin");
|
|
url += "?property=" + name;
|
|
return url;
|
|
}
|
|
|
|
/**
|
|
* Determines whether the value is content
|
|
*
|
|
* @return true => is content
|
|
*/
|
|
public boolean isContent()
|
|
{
|
|
String datatype = getDataType();
|
|
return (datatype == null) ? false : datatype.equals(DataTypeDefinition.CONTENT.toString());
|
|
}
|
|
|
|
/**
|
|
* Determines whether the value is a node ref
|
|
*
|
|
* @return true => is node ref
|
|
*/
|
|
public boolean isNodeRef()
|
|
{
|
|
String datatype = getDataType();
|
|
return (datatype == null) ? false : datatype.equals(DataTypeDefinition.NODE_REF.toString()) || datatype.equals(DataTypeDefinition.CATEGORY.toString());
|
|
}
|
|
|
|
/**
|
|
* Determines whether the value is null
|
|
*
|
|
* @return true => value is null
|
|
*/
|
|
public boolean isNullValue()
|
|
{
|
|
return value == null;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Permission representing the fact that "Read Permissions" has not been granted
|
|
*/
|
|
public static class NoReadPermissionGranted implements Serializable
|
|
{
|
|
private static final long serialVersionUID = -6256369557521402921L;
|
|
|
|
public String getPermission()
|
|
{
|
|
return PermissionService.READ_PERMISSIONS;
|
|
}
|
|
|
|
public String getAuthority()
|
|
{
|
|
return "[Current Authority]";
|
|
}
|
|
|
|
public String getAccessStatus()
|
|
{
|
|
return "Not Granted";
|
|
}
|
|
}
|
|
|
|
public static class NoStoreMask implements Serializable
|
|
{
|
|
private static final long serialVersionUID = -6256369557521402921L;
|
|
|
|
public String getPermission()
|
|
{
|
|
return "All <No Mask>";
|
|
}
|
|
|
|
public String getAuthority()
|
|
{
|
|
return "All";
|
|
}
|
|
|
|
public String getAccessStatus()
|
|
{
|
|
return "Allowed";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Wrapper class for Search Results
|
|
*/
|
|
public class SearchResults implements Serializable
|
|
{
|
|
private static final long serialVersionUID = 7402906720039176001L;
|
|
|
|
private int length = 0;
|
|
private SerialListDataModel rows;
|
|
|
|
/**
|
|
* Construct
|
|
*
|
|
* @param resultSet query result set
|
|
*/
|
|
public SearchResults(ResultSet resultSet)
|
|
{
|
|
rows = new SerialListDataModel();
|
|
if (resultSet != null)
|
|
{
|
|
rows.setWrappedData(resultSet.getChildAssocRefs());
|
|
length = resultSet.length();
|
|
resultSet.close();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Construct
|
|
*
|
|
* @param resultSet query result set
|
|
*/
|
|
public SearchResults(List<NodeRef> resultSet)
|
|
{
|
|
rows = new SerialListDataModel();
|
|
if (resultSet != null)
|
|
{
|
|
List<ChildAssociationRef> assocRefs = new ArrayList<ChildAssociationRef>(resultSet.size());
|
|
for (NodeRef nodeRef : resultSet)
|
|
{
|
|
ChildAssociationRef childAssocRef = getNodeService().getPrimaryParent(nodeRef);
|
|
assocRefs.add(childAssocRef);
|
|
}
|
|
rows.setWrappedData(assocRefs);
|
|
length = resultSet.size();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the row count
|
|
*
|
|
* @return count of rows
|
|
*/
|
|
public int getLength()
|
|
{
|
|
return length;
|
|
}
|
|
|
|
/**
|
|
* Gets the rows
|
|
*
|
|
* @return the rows
|
|
*/
|
|
public DataModel getRows()
|
|
{
|
|
return rows;
|
|
}
|
|
|
|
private class SerialListDataModel extends ListDataModel implements Serializable
|
|
{
|
|
private static final long serialVersionUID = 4154583769762846020L;
|
|
}
|
|
}
|
|
}
|