/*
* Copyright (C) 2005-2011 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 .
*/
package org.alfresco.slingshot.web.scripts;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
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.LimitBy;
import org.alfresco.service.cmr.search.SearchParameters;
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.OwnableService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceException;
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.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Node browser web script to handle search results, node details and workspaces
*
* @author dcaruana
* @author wabson
*/
public class NodeBrowserScript extends DeclarativeWebScript
{
/** available query languages */
private static List queryLanguages = new ArrayList();
static
{
queryLanguages.add("storeroot");
queryLanguages.add("noderef");
queryLanguages.add(SearchService.LANGUAGE_XPATH);
queryLanguages.add(SearchService.LANGUAGE_LUCENE);
queryLanguages.add(SearchService.LANGUAGE_FTS_ALFRESCO);
queryLanguages.add(SearchService.LANGUAGE_CMIS_STRICT);
queryLanguages.add(SearchService.LANGUAGE_CMIS_ALFRESCO);
queryLanguages.add(SearchService.LANGUAGE_JCR_XPATH);
}
private Long searchElapsedTime = null;
// stores and node
transient private List stores = 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 OwnableService ownableService;
transient private AVMService avmService;
/**
* @param transactionService transaction service
*/
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
private TransactionService getTransactionService()
{
return transactionService;
}
/**
* @param nodeService node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
private NodeService getNodeService()
{
return nodeService;
}
/**
* @param searchService search service
*/
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
private SearchService getSearchService()
{
return searchService;
}
/**
* @param dictionaryService dictionary service
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
private DictionaryService getDictionaryService()
{
return dictionaryService;
}
/**
* @param namespaceService namespace service
*/
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
private NamespaceService getNamespaceService()
{
return namespaceService;
}
/**
* @param permissionService permission service
*/
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
private PermissionService getPermissionService()
{
return permissionService;
}
public void setOwnableService(OwnableService ownableService)
{
this.ownableService = ownableService;
}
public OwnableService getOwnableService()
{
return ownableService;
}
/**
* @param avmService AVM service
*/
public void setAVMService(AVMService avmService)
{
this.avmService = avmService;
}
private AVMService getAVMService()
{
return avmService;
}
/**
* Gets the list of repository stores
*
* @return stores
*/
public List getStores()
{
if (stores == null)
{
stores = getNodeService().getStores();
}
return stores;
}
/**
* Gets the current node type
*
* @return node type
*/
public QName getNodeType(NodeRef nodeRef)
{
return getNodeService().getType(nodeRef);
}
/**
* Gets the current node primary path
*
* @return primary path
*/
public String getPrimaryPath(NodeRef nodeRef)
{
Path primaryPath = getNodeService().getPath(nodeRef);
return ISO9075.decode(primaryPath.toString());
}
/**
* Gets the current node primary path
*
* @return primary path
*/
public String getPrimaryPrefixedPath(NodeRef nodeRef)
{
Path primaryPath = getNodeService().getPath(nodeRef);
return ISO9075.decode(primaryPath.toPrefixString(getNamespaceService()));
}
/**
* Gets the current node primary parent reference
*
* @return primary parent ref
*/
public NodeRef getPrimaryParent(NodeRef nodeRef)
{
Path primaryPath = getNodeService().getPath(nodeRef);
Path.Element element = primaryPath.last();
NodeRef parentRef = ((Path.ChildAssocElement) element).getRef().getParentRef();
return parentRef;
}
/**
* Gets the current node aspects
*
* @return node aspects
*/
public List getAspects(NodeRef nodeRef)
{
Set qnames = getNodeService().getAspects(nodeRef);
List aspects = new ArrayList(qnames.size());
for (QName qname : qnames)
{
aspects.add(new Aspect(qname));
}
return aspects;
}
/**
* Gets the current node parents
*
* @return node parents
*/
public List getParents(NodeRef nodeRef)
{
List parents = getNodeService().getParentAssocs(nodeRef);
List assocs = new ArrayList(parents.size());
for (ChildAssociationRef ref : parents)
{
assocs.add(new ChildAssociation(ref));
}
return assocs;
}
/**
* Gets the current node properties
*
* @return properties
*/
public List getProperties(NodeRef nodeRef)
{
Map propertyValues = getNodeService().getProperties(nodeRef);
List properties = new ArrayList(propertyValues.size());
for (Map.Entry property : propertyValues.entrySet())
{
properties.add(new Property(property.getKey(), property.getValue()));
}
return properties;
}
/**
* Gets whether the current node inherits its permissions from a parent node
*
* @return true => inherits permissions
*/
public boolean getInheritPermissions(NodeRef nodeRef)
{
Boolean inheritPermissions = this.getPermissionService().getInheritParentPermissions(nodeRef);
return inheritPermissions.booleanValue();
}
/**
* Gets the current node permissions
*
* @return the permissions
*/
public List getPermissions(NodeRef nodeRef)
{
List permissions = null;
AccessStatus readPermissions = this.getPermissionService().hasPermission(nodeRef, PermissionService.READ_PERMISSIONS);
if (readPermissions.equals(AccessStatus.ALLOWED))
{
List nodePermissions = new ArrayList();
for (Iterator iterator = getPermissionService().getAllSetPermissions(nodeRef).iterator(); iterator
.hasNext();)
{
AccessPermission ap = iterator.next();
nodePermissions.add(new Permission(ap.getPermission(), ap.getAuthority(), ap.getAccessStatus().toString()));
}
permissions = nodePermissions;
}
else
{
List noReadPermissions = new ArrayList(1);
noReadPermissions.add(new NoReadPermissionGranted());
permissions = noReadPermissions;
}
return permissions;
}
/**
* Gets the current node permissions
*
* @return the permissions
*/
public List getStorePermissionMasks(NodeRef nodeRef)
{
List permissionMasks = null;
if (nodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM))
{
permissionMasks = new ArrayList();
for (Iterator iterator = getPermissionService().getAllSetPermissions(nodeRef.getStoreRef()).iterator(); iterator
.hasNext();)
{
AccessPermission ap = iterator.next();
permissionMasks.add(new Permission(ap.getPermission(), ap.getAuthority(), ap.getAccessStatus().toString()));
}
}
else
{
permissionMasks = new ArrayList(1);
permissionMasks.add(new NoStoreMask());
}
return permissionMasks;
}
/**
* Gets the current node children
*
* @return node children
*/
public List getChildren(NodeRef nodeRef)
{
List refs = getNodeService().getChildAssocs(nodeRef);
List assocs = new ArrayList(refs.size());
for (ChildAssociationRef ref : refs)
{
assocs.add(new ChildAssociation(ref));
}
return assocs;
}
/**
* Gets the current node associations
*
* @return associations
*/
public List getAssocs(NodeRef nodeRef)
{
List refs = null;
try
{
refs = getNodeService().getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL);
}
catch (UnsupportedOperationException err)
{
// some stores do not support associations
}
List assocs = new ArrayList(refs.size());
for (AssociationRef ref : refs)
{
assocs.add(new PeerAssociation(ref.getTypeQName(), ref.getSourceRef(), ref.getTargetRef()));
}
return assocs;
}
/**
* Gets the current source associations
*
* @return associations
*/
public List getSourceAssocs(NodeRef nodeRef)
{
List refs = null;
try
{
refs = getNodeService().getSourceAssocs(nodeRef, RegexQNamePattern.MATCH_ALL);
}
catch (UnsupportedOperationException err)
{
// some stores do not support associations
}
List assocs = new ArrayList(refs.size());
for (AssociationRef ref : refs)
{
assocs.add(new PeerAssociation(ref.getTypeQName(), ref.getSourceRef(), ref.getTargetRef()));
}
return assocs;
}
public boolean getInAVMStore(NodeRef nodeRef)
{
return nodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM);
}
public List