/*
* 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 .
*/
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 queryLanguages = new ArrayList();
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(SearchService.LANGUAGE_SOLR_FTS_ALFRESCO));
queryLanguages.add(new SelectItem(SearchService.LANGUAGE_SOLR_CMIS));
queryLanguages.add(new SelectItem("selectnodes"));
}
// query and results
private String query = null;
private SearchResults searchResults = new SearchResults((List) 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 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 aspectNames = new ArrayList(getNodeService().getAspects(getNodeRef()));
aspects = new ListDataModel(aspectNames);
}
return aspects;
}
/**
* Gets the current node parents
*
* @return node parents
*/
public DataModel getParents()
{
if (parents == null)
{
List parentRefs = getNodeService().getParentAssocs(getNodeRef());
parents = new ListDataModel(parentRefs);
}
return parents;
}
/**
* Gets the current node properties
*
* @return properties
*/
public DataModel getProperties()
{
if (properties == null)
{
Map propertyValues = getNodeService().getProperties(getNodeRef());
List nodeProperties = new ArrayList(propertyValues.size());
for (Map.Entry 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 nodePermissions = new ArrayList(getPermissionService().getAllSetPermissions(nodeRef));
permissions = new ListDataModel(nodePermissions);
}
else
{
List noReadPermissions = new ArrayList(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 nodePermissions = new ArrayList(getPermissionService().getAllSetPermissions(nodeRef.getStoreRef()));
permissionMasks = new ListDataModel(nodePermissions);
}
else
{
List noReadPermissions = new ArrayList(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 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 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 props = getAVMService().getStoreProperties(store);
List