mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Moving to root below branch label
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2005 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
135
source/java/org/alfresco/web/bean/repository/DataDictionary.java
Normal file
135
source/java/org/alfresco/web/bean/repository/DataDictionary.java
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.web.bean.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Lighweight client side representation of the repository data dictionary.
|
||||
* This allows service calls to be kept to a minimum and for bean access, thus enabling JSF
|
||||
* value binding expressions.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public final class DataDictionary
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(DataDictionary.class);
|
||||
private DictionaryService dictionaryService;
|
||||
private NamespaceService namespaceService;
|
||||
private Map<QName, TypeDefinition> types = new HashMap<QName, TypeDefinition>(11, 1.0f);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param dictionaryService The dictionary service to use to retrieve the data
|
||||
*/
|
||||
public DataDictionary(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type definition for the type represented by the given qname
|
||||
*
|
||||
* @param type The qname of the type to lookup the definition for
|
||||
* @return The type definition for the requested type
|
||||
*/
|
||||
public TypeDefinition getTypeDef(QName type)
|
||||
{
|
||||
TypeDefinition typeDef = types.get(type);
|
||||
|
||||
if (typeDef == null)
|
||||
{
|
||||
typeDef = this.dictionaryService.getType(type);
|
||||
|
||||
if (typeDef != null)
|
||||
{
|
||||
types.put(type, typeDef);
|
||||
}
|
||||
}
|
||||
|
||||
return typeDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type definition for the type represented by the given qname
|
||||
* and for all the given aspects
|
||||
*
|
||||
* @param type The type to retrieve the definition for
|
||||
* @param optionalAspects A list of aspects to retrieve the definition for
|
||||
* @return A unified type definition of the given type and aspects
|
||||
*/
|
||||
public TypeDefinition getTypeDef(QName type, Collection<QName> optionalAspects)
|
||||
{
|
||||
return this.dictionaryService.getAnonymousType(type, optionalAspects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property definition for the given property on the given node
|
||||
*
|
||||
* @param node The node from which to get the property
|
||||
* @param property The property to find the definition for
|
||||
* @return The property definition or null if the property is not known
|
||||
*/
|
||||
public PropertyDefinition getPropertyDefinition(Node node, String property)
|
||||
{
|
||||
PropertyDefinition propDef = null;
|
||||
|
||||
TypeDefinition typeDef = getTypeDef(node.getType(), node.getAspects());
|
||||
|
||||
if (typeDef != null)
|
||||
{
|
||||
Map<QName, PropertyDefinition> properties = typeDef.getProperties();
|
||||
propDef = properties.get(Repository.resolveToQName(property));
|
||||
}
|
||||
|
||||
return propDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the association definition for the given association on the given node
|
||||
*
|
||||
* @param node The node from which to get the association
|
||||
* @param association The association to find the definition for
|
||||
* @return The association definition or null if the association is not known
|
||||
*/
|
||||
public AssociationDefinition getAssociationDefinition(Node node, String association)
|
||||
{
|
||||
AssociationDefinition assocDef = null;
|
||||
|
||||
TypeDefinition typeDef = getTypeDef(node.getType(), node.getAspects());
|
||||
|
||||
if (typeDef != null)
|
||||
{
|
||||
Map<QName, AssociationDefinition> assocs = typeDef.getAssociations();
|
||||
assocDef = assocs.get(Repository.resolveToQName(association));
|
||||
}
|
||||
|
||||
return assocDef;
|
||||
}
|
||||
}
|
179
source/java/org/alfresco/web/bean/repository/MapNode.java
Normal file
179
source/java/org/alfresco/web/bean/repository/MapNode.java
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.web.bean.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
|
||||
/**
|
||||
* Lighweight client side representation of a node held in the repository, which
|
||||
* is modelled as a map for use in the data tables.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class MapNode extends Node implements Map<String, Object>
|
||||
{
|
||||
private static final long serialVersionUID = 4051322327734433079L;
|
||||
|
||||
private boolean propsInitialised = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param nodeRef The NodeRef this Node wrapper represents
|
||||
*/
|
||||
public MapNode(NodeRef nodeRef)
|
||||
{
|
||||
super(nodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param nodeRef The NodeRef this Node wrapper represents
|
||||
* @param nodeService The node service to use to retrieve data for this node
|
||||
* @param initProps True to immediately init the properties of the node, false to do nothing
|
||||
*/
|
||||
public MapNode(NodeRef nodeRef, NodeService nodeService, boolean initProps)
|
||||
{
|
||||
super(nodeRef);
|
||||
if (initProps == true)
|
||||
{
|
||||
getProperties();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Map implementation - allows the Node bean to be accessed using JSF expression syntax
|
||||
|
||||
/**
|
||||
* @see java.util.Map#clear()
|
||||
*/
|
||||
public void clear()
|
||||
{
|
||||
getProperties().clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#containsKey(java.lang.Object)
|
||||
*/
|
||||
public boolean containsKey(Object key)
|
||||
{
|
||||
return getProperties().containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#containsValue(java.lang.Object)
|
||||
*/
|
||||
public boolean containsValue(Object value)
|
||||
{
|
||||
return getProperties().containsKey(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#entrySet()
|
||||
*/
|
||||
public Set entrySet()
|
||||
{
|
||||
return getProperties().entrySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#get(java.lang.Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
{
|
||||
Object obj = null;
|
||||
|
||||
// there are some things that aren't available as properties
|
||||
// but from method calls, so for these handle them individually
|
||||
Map<String, Object> props = getProperties();
|
||||
if (propsInitialised == false)
|
||||
{
|
||||
// well known properties required as publically accessable map attributes
|
||||
props.put("id", this.getId());
|
||||
props.put("name", this.getName()); // TODO: perf test pulling back single prop here instead of all!
|
||||
props.put("nodeRef", this.getNodeRef());
|
||||
|
||||
propsInitialised = true;
|
||||
}
|
||||
|
||||
return props.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#isEmpty()
|
||||
*/
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return getProperties().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#keySet()
|
||||
*/
|
||||
public Set keySet()
|
||||
{
|
||||
return getProperties().keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#put(K, V)
|
||||
*/
|
||||
public Object put(String key, Object value)
|
||||
{
|
||||
return getProperties().put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#putAll(java.util.Map)
|
||||
*/
|
||||
public void putAll(Map t)
|
||||
{
|
||||
getProperties().putAll(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#remove(java.lang.Object)
|
||||
*/
|
||||
public Object remove(Object key)
|
||||
{
|
||||
return getProperties().remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#size()
|
||||
*/
|
||||
public int size()
|
||||
{
|
||||
return getProperties().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#values()
|
||||
*/
|
||||
public Collection values()
|
||||
{
|
||||
return getProperties().values();
|
||||
}
|
||||
}
|
426
source/java/org/alfresco/web/bean/repository/Node.java
Normal file
426
source/java/org/alfresco/web/bean/repository/Node.java
Normal file
@@ -0,0 +1,426 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.web.bean.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
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.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Lighweight client side representation of a node held in the repository.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class Node implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 3544390322739034169L;
|
||||
|
||||
protected static Log logger = LogFactory.getLog(Node.class);
|
||||
|
||||
protected NodeRef nodeRef;
|
||||
private String name;
|
||||
private QName type;
|
||||
private String path;
|
||||
private String id;
|
||||
private Set<QName> aspects = null;
|
||||
private Map<String, Boolean> permissions;
|
||||
protected QNameNodeMap<String, Object> properties;
|
||||
protected boolean propsRetrieved = false;
|
||||
protected ServiceRegistry services = null;
|
||||
|
||||
private boolean childAssocsRetrieved = false;
|
||||
private QNameNodeMap childAssociations;
|
||||
private Map<String, Map<String, ChildAssociationRef>> childAssociationsAdded;
|
||||
private Map<String, Map<String, ChildAssociationRef>> childAssociationsRemoved;
|
||||
|
||||
private boolean assocsRetrieved = false;
|
||||
private QNameNodeMap associations;
|
||||
private Map<String, Map<String, AssociationRef>> associationsAdded;
|
||||
private Map<String, Map<String, AssociationRef>> associationsRemoved;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param nodeRef The NodeRef this Node wrapper represents
|
||||
*/
|
||||
public Node(NodeRef nodeRef)
|
||||
{
|
||||
if (nodeRef == null)
|
||||
{
|
||||
throw new IllegalArgumentException("NodeRef must be supplied for creation of a Node.");
|
||||
}
|
||||
|
||||
this.nodeRef = nodeRef;
|
||||
this.id = nodeRef.getId();
|
||||
|
||||
this.properties = new QNameNodeMap<String, Object>(getServiceRegistry().getNamespaceService(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return All the properties known about this node.
|
||||
*/
|
||||
public Map<String, Object> getProperties()
|
||||
{
|
||||
if (this.propsRetrieved == false)
|
||||
{
|
||||
Map<QName, Serializable> props = getServiceRegistry().getNodeService().getProperties(this.nodeRef);
|
||||
|
||||
for (QName qname: props.keySet())
|
||||
{
|
||||
Serializable propValue = props.get(qname);
|
||||
this.properties.put(qname.toString(), propValue);
|
||||
}
|
||||
|
||||
this.propsRetrieved = true;
|
||||
}
|
||||
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return All the associations this node has as a Map, using the association
|
||||
* type as the key
|
||||
*/
|
||||
public final Map getAssociations()
|
||||
{
|
||||
if (this.assocsRetrieved == false)
|
||||
{
|
||||
associations = new QNameNodeMap(getServiceRegistry().getNamespaceService(), this);
|
||||
|
||||
List<AssociationRef> assocs = getServiceRegistry().getNodeService().getTargetAssocs(this.nodeRef, RegexQNamePattern.MATCH_ALL);
|
||||
|
||||
for (AssociationRef assocRef: assocs)
|
||||
{
|
||||
String assocName = assocRef.getTypeQName().toString();
|
||||
|
||||
List list = (List)this.associations.get(assocName);
|
||||
// create the list if this is first association with 'assocName'
|
||||
if (list == null)
|
||||
{
|
||||
list = new ArrayList<AssociationRef>();
|
||||
this.associations.put(assocName, list);
|
||||
}
|
||||
|
||||
// add the association to the list
|
||||
list.add(assocRef);
|
||||
}
|
||||
|
||||
this.assocsRetrieved = true;
|
||||
}
|
||||
|
||||
return this.associations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the associations added to this node in this UI session
|
||||
*
|
||||
* @return Map of Maps of AssociationRefs
|
||||
*/
|
||||
public final Map<String, Map<String, AssociationRef>> getAddedAssociations()
|
||||
{
|
||||
if (this.associationsAdded == null)
|
||||
{
|
||||
this.associationsAdded = new HashMap<String, Map<String, AssociationRef>>();
|
||||
}
|
||||
return this.associationsAdded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the associations removed from this node is this UI session
|
||||
*
|
||||
* @return Map of Maps of AssociationRefs
|
||||
*/
|
||||
public final Map<String, Map<String, AssociationRef>> getRemovedAssociations()
|
||||
{
|
||||
if (this.associationsRemoved == null)
|
||||
{
|
||||
this.associationsRemoved = new HashMap<String, Map<String, AssociationRef>>();
|
||||
}
|
||||
return this.associationsRemoved;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return All the child associations this node has as a Map, using the association
|
||||
* type as the key
|
||||
*/
|
||||
public final Map getChildAssociations()
|
||||
{
|
||||
if (this.childAssocsRetrieved == false)
|
||||
{
|
||||
this.childAssociations = new QNameNodeMap(getServiceRegistry().getNamespaceService(), this);
|
||||
|
||||
List<ChildAssociationRef> assocs = getServiceRegistry().getNodeService().getChildAssocs(this.nodeRef);
|
||||
|
||||
for (ChildAssociationRef assocRef: assocs)
|
||||
{
|
||||
String assocName = assocRef.getTypeQName().toString();
|
||||
|
||||
List list = (List)this.childAssociations.get(assocName);
|
||||
// create the list if this is first association with 'assocName'
|
||||
if (list == null)
|
||||
{
|
||||
list = new ArrayList<ChildAssociationRef>();
|
||||
this.childAssociations.put(assocName, list);
|
||||
}
|
||||
|
||||
// add the association to the list
|
||||
list.add(assocRef);
|
||||
}
|
||||
|
||||
this.childAssocsRetrieved = true;
|
||||
}
|
||||
|
||||
return this.childAssociations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the child associations added to this node in this UI session
|
||||
*
|
||||
* @return Map of Maps of ChildAssociationRefs
|
||||
*/
|
||||
public final Map<String, Map<String, ChildAssociationRef>> getAddedChildAssociations()
|
||||
{
|
||||
if (this.childAssociationsAdded == null)
|
||||
{
|
||||
this.childAssociationsAdded = new HashMap<String, Map<String, ChildAssociationRef>>();
|
||||
}
|
||||
return this.childAssociationsAdded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the child associations removed from this node is this UI session
|
||||
*
|
||||
* @return Map of Maps of ChildAssociationRefs
|
||||
*/
|
||||
public final Map<String, Map<String, ChildAssociationRef>> getRemovedChildAssociations()
|
||||
{
|
||||
if (this.childAssociationsRemoved == null)
|
||||
{
|
||||
this.childAssociationsRemoved = new HashMap<String, Map<String, ChildAssociationRef>>();
|
||||
}
|
||||
return this.childAssociationsRemoved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a property resolver for the named property.
|
||||
*
|
||||
* @param name Name of the property this resolver is for
|
||||
* @param resolver Property resolver to register
|
||||
*/
|
||||
public final void addPropertyResolver(String name, NodePropertyResolver resolver)
|
||||
{
|
||||
this.properties.addPropertyResolver(name, resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given property name is held by this node
|
||||
*
|
||||
* @param propertyName Property to test existence of
|
||||
* @return true if property exists, false otherwise
|
||||
*/
|
||||
public final boolean hasProperty(String propertyName)
|
||||
{
|
||||
return getProperties().containsKey(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the NodeRef this Node object represents
|
||||
*/
|
||||
public final NodeRef getNodeRef()
|
||||
{
|
||||
return this.nodeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the type.
|
||||
*/
|
||||
public final QName getType()
|
||||
{
|
||||
if (this.type == null)
|
||||
{
|
||||
this.type = getServiceRegistry().getNodeService().getType(this.nodeRef);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The display name for the node
|
||||
*/
|
||||
public final String getName()
|
||||
{
|
||||
if (this.name == null)
|
||||
{
|
||||
// try and get the name from the properties first
|
||||
this.name = (String)getProperties().get("cm:name");
|
||||
|
||||
// if we didn't find it as a property get the name from the association name
|
||||
if (this.name == null)
|
||||
{
|
||||
this.name = getServiceRegistry().getNodeService().getPrimaryParent(this.nodeRef).getQName().getLocalName();
|
||||
}
|
||||
}
|
||||
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The list of aspects applied to this node
|
||||
*/
|
||||
public final Set<QName> getAspects()
|
||||
{
|
||||
if (this.aspects == null)
|
||||
{
|
||||
this.aspects = getServiceRegistry().getNodeService().getAspects(this.nodeRef);
|
||||
}
|
||||
|
||||
return this.aspects;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aspect The aspect to test for
|
||||
* @return true if the node has the aspect false otherwise
|
||||
*/
|
||||
public final boolean hasAspect(QName aspect)
|
||||
{
|
||||
Set aspects = getAspects();
|
||||
return aspects.contains(aspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the current user has the specified access permission on this Node
|
||||
*
|
||||
* @param permission Permission to validate against
|
||||
*
|
||||
* @return true if the permission is applied to the node for this user, false otherwise
|
||||
*/
|
||||
public final boolean hasPermission(String permission)
|
||||
{
|
||||
Boolean valid = null;
|
||||
if (permissions != null)
|
||||
{
|
||||
valid = permissions.get(permission);
|
||||
}
|
||||
else
|
||||
{
|
||||
permissions = new HashMap<String, Boolean>(5, 1.0f);
|
||||
}
|
||||
|
||||
if (valid == null)
|
||||
{
|
||||
PermissionService service = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getPermissionService();
|
||||
valid = Boolean.valueOf(service.hasPermission(this.nodeRef, permission) == AccessStatus.ALLOWED);
|
||||
permissions.put(permission, valid);
|
||||
}
|
||||
|
||||
return valid.booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The GUID for the node
|
||||
*/
|
||||
public final String getId()
|
||||
{
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The path for the node
|
||||
*/
|
||||
public final String getPath()
|
||||
{
|
||||
if (this.path == null)
|
||||
{
|
||||
this.path = getServiceRegistry().getNodeService().getPath(this.nodeRef).toString();
|
||||
}
|
||||
|
||||
return this.path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the state of the node to force re-retrieval of the data
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
this.name = null;
|
||||
this.type = null;
|
||||
this.path = null;
|
||||
this.properties.clear();
|
||||
this.propsRetrieved = false;
|
||||
this.aspects = null;
|
||||
this.permissions = null;
|
||||
|
||||
this.associations = null;
|
||||
this.associationsAdded = null;
|
||||
this.associationsRemoved = null;
|
||||
this.assocsRetrieved = false;
|
||||
|
||||
this.childAssociations = null;
|
||||
this.childAssociationsAdded = null;
|
||||
this.childAssociationsRemoved = null;
|
||||
this.childAssocsRetrieved = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override Object.toString() to provide useful debug output
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
if (getServiceRegistry().getNodeService() != null)
|
||||
{
|
||||
if (getServiceRegistry().getNodeService().exists(nodeRef))
|
||||
{
|
||||
return "Node Type: " + getType() +
|
||||
"\nNode Properties: " + this.getProperties().toString() +
|
||||
"\nNode Aspects: " + this.getAspects().toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Node no longer exists: " + nodeRef;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
|
||||
protected ServiceRegistry getServiceRegistry()
|
||||
{
|
||||
if (this.services == null)
|
||||
{
|
||||
this.services = Repository.getServiceRegistry(FacesContext.getCurrentInstance());
|
||||
}
|
||||
return this.services;
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.web.bean.repository;
|
||||
|
||||
/**
|
||||
* Simple interface used to implement small classes capable of calculating dynamic property values
|
||||
* for Nodes at runtime. This allows bean responsible for building large lists of Nodes to
|
||||
* encapsulate the code needed to retrieve non-standard Node properties. The values are then
|
||||
* calculated on demand by the property resolver.
|
||||
*
|
||||
* When a node is reset() the standard and other props are cleared. If property resolvers are used
|
||||
* then the non-standard props will be restored automatically as well.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface NodePropertyResolver
|
||||
{
|
||||
/**
|
||||
* Get the property value for this resolver
|
||||
*
|
||||
* @param node Node this property is for
|
||||
*
|
||||
* @return property value
|
||||
*/
|
||||
public Object get(Node node);
|
||||
}
|
121
source/java/org/alfresco/web/bean/repository/QNameNodeMap.java
Normal file
121
source/java/org/alfresco/web/bean/repository/QNameNodeMap.java
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.web.bean.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.QNameMap;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* A extension of the repo QNameMap to provide custom property resolving support for Node wrappers.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class QNameNodeMap<K,V> extends QNameMap implements Map, Cloneable
|
||||
{
|
||||
private Node parent = null;
|
||||
private Map<String, NodePropertyResolver> resolvers = new HashMap<String, NodePropertyResolver>(11, 1.0f);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent Parent Node of the QNameNodeMap
|
||||
*/
|
||||
public QNameNodeMap(NamespacePrefixResolver resolver, Node parent)
|
||||
{
|
||||
super(resolver);
|
||||
if (parent == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Parent Node cannot be null!");
|
||||
}
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a property resolver for the named property.
|
||||
*
|
||||
* @param name Name of the property this resolver is for
|
||||
* @param resolver Property resolver to register
|
||||
*/
|
||||
public void addPropertyResolver(String name, NodePropertyResolver resolver)
|
||||
{
|
||||
this.resolvers.put(name, resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#containsKey(java.lang.Object)
|
||||
*/
|
||||
public boolean containsKey(Object key)
|
||||
{
|
||||
return (this.contents.containsKey(Repository.resolveToQNameString((String)key)) ||
|
||||
this.resolvers.containsKey(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#get(java.lang.Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
{
|
||||
String qnameKey = Repository.resolveToQNameString(key.toString());
|
||||
Object obj = this.contents.get(qnameKey);
|
||||
if (obj == null)
|
||||
{
|
||||
// if a property resolver exists for this property name then invoke it
|
||||
NodePropertyResolver resolver = this.resolvers.get(key.toString());
|
||||
if (resolver != null)
|
||||
{
|
||||
obj = resolver.get(this.parent);
|
||||
// cache the result
|
||||
// obviously the cache is useless if the result is null, in most cases it shouldn't be
|
||||
this.contents.put(qnameKey, obj);
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a get without using property resolvers
|
||||
*
|
||||
* @param key item key
|
||||
* @return object
|
||||
*/
|
||||
public Object getRaw(Object key)
|
||||
{
|
||||
return this.contents.get(Repository.resolveToQNameString((String)key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shallow copy the map by copying keys and values into a new QNameNodeMap
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
QNameNodeMap map = new QNameNodeMap(this.resolver, this.parent);
|
||||
map.putAll(this);
|
||||
if (this.resolvers.size() != 0)
|
||||
{
|
||||
map.resolvers = (Map)((HashMap)this.resolvers).clone();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
620
source/java/org/alfresco/web/bean/repository/Repository.java
Normal file
620
source/java/org/alfresco/web/bean/repository/Repository.java
Normal file
@@ -0,0 +1,620 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.web.bean.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.configuration.ConfigurableService;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.metadata.MetadataExtracter;
|
||||
import org.alfresco.repo.content.metadata.MetadataExtracterRegistry;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.lock.LockService;
|
||||
import org.alfresco.service.cmr.lock.LockStatus;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
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.SearchService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
import org.springframework.web.jsf.FacesContextUtils;
|
||||
|
||||
/**
|
||||
* Helper class for accessing repository objects, convert values, escape values and service utilities.
|
||||
*
|
||||
* @author gavinc
|
||||
* @author kevinr
|
||||
*/
|
||||
public final class Repository
|
||||
{
|
||||
/** I18N error messages */
|
||||
public static final String ERROR_NODEREF = "error_noderef";
|
||||
public static final String ERROR_GENERIC = "error_generic";
|
||||
public static final String ERROR_NOHOME = "error_homespace";
|
||||
public static final String ERROR_SEARCH = "error_search";
|
||||
|
||||
private static final String METADATA_EXTACTER_REGISTRY = "metadataExtracterRegistry";
|
||||
|
||||
private static Logger logger = Logger.getLogger(Repository.class);
|
||||
|
||||
/** cache of client StoreRef */
|
||||
private static StoreRef storeRef = null;
|
||||
|
||||
/** reference to Person folder */
|
||||
private static NodeRef peopleRef = null;
|
||||
|
||||
/** reference to System folder */
|
||||
private static NodeRef systemRef = null;
|
||||
|
||||
/** reference to the namespace service */
|
||||
private static NamespaceService namespaceService = null;
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
private Repository()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a store reference object
|
||||
*
|
||||
* @return A StoreRef object
|
||||
*/
|
||||
public static StoreRef getStoreRef()
|
||||
{
|
||||
return storeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a store reference object.
|
||||
* This method is used to setup the cached value by the ContextListener initialisation methods
|
||||
*
|
||||
* @return The StoreRef object
|
||||
*/
|
||||
public static StoreRef getStoreRef(ServletContext context)
|
||||
{
|
||||
storeRef = Application.getRepositoryStoreRef(context);
|
||||
|
||||
return storeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get the display name for a Node.
|
||||
* The method will attempt to use the "name" attribute, if not found it will revert to using
|
||||
* the QName.getLocalName() retrieved from the primary parent relationship.
|
||||
*
|
||||
* @param ref NodeRef
|
||||
*
|
||||
* @return display name string for the specified Node.
|
||||
*/
|
||||
public static String getNameForNode(NodeService nodeService, NodeRef ref)
|
||||
{
|
||||
String name = null;
|
||||
|
||||
// try to find a display "name" property for this node
|
||||
Object nameProp = nodeService.getProperty(ref, ContentModel.PROP_NAME);
|
||||
if (nameProp != null)
|
||||
{
|
||||
name = nameProp.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
// revert to using QName if not found
|
||||
QName qname = nodeService.getPrimaryParent(ref).getQName();
|
||||
if (qname != null)
|
||||
{
|
||||
name = qname.getLocalName();
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape a QName value so it can be used in lucene search strings
|
||||
*
|
||||
* @param qName QName to escape
|
||||
*
|
||||
* @return escaped value
|
||||
*/
|
||||
public static String escapeQName(QName qName)
|
||||
{
|
||||
String string = qName.toString();
|
||||
StringBuilder buf = new StringBuilder(string.length() + 4);
|
||||
for (int i = 0; i < string.length(); i++)
|
||||
{
|
||||
char c = string.charAt(i);
|
||||
if ((c == '{') || (c == '}') || (c == ':') || (c == '-'))
|
||||
{
|
||||
buf.append('\\');
|
||||
}
|
||||
|
||||
buf.append(c);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a Node is currently locked
|
||||
*
|
||||
* @param node The Node wrapper to test against
|
||||
* @param lockService The LockService to use
|
||||
*
|
||||
* @return whether a Node is currently locked
|
||||
*/
|
||||
public static Boolean isNodeLocked(Node node, LockService lockService)
|
||||
{
|
||||
Boolean locked = Boolean.FALSE;
|
||||
|
||||
if (node.hasAspect(ContentModel.ASPECT_LOCKABLE))
|
||||
{
|
||||
LockStatus lockStatus = lockService.getLockStatus(node.getNodeRef());
|
||||
if (lockStatus == LockStatus.LOCKED || lockStatus == LockStatus.LOCK_OWNER)
|
||||
{
|
||||
locked = Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a Node is currently locked by the current user
|
||||
*
|
||||
* @param node The Node wrapper to test against
|
||||
* @param lockService The LockService to use
|
||||
*
|
||||
* @return whether a Node is currently locked by the current user
|
||||
*/
|
||||
public static Boolean isNodeOwnerLocked(Node node, LockService lockService)
|
||||
{
|
||||
Boolean locked = Boolean.FALSE;
|
||||
|
||||
if (node.hasAspect(ContentModel.ASPECT_LOCKABLE) &&
|
||||
lockService.getLockStatus(node.getNodeRef()) == LockStatus.LOCK_OWNER)
|
||||
{
|
||||
locked = Boolean.TRUE;
|
||||
}
|
||||
|
||||
return locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a WorkingCopy Node is owned by the current User
|
||||
*
|
||||
* @param node The Node wrapper to test against
|
||||
* @param lockService The LockService to use
|
||||
*
|
||||
* @return whether a WorkingCopy Node is owned by the current User
|
||||
*/
|
||||
public static Boolean isNodeOwner(Node node, LockService lockService)
|
||||
{
|
||||
Boolean locked = Boolean.FALSE;
|
||||
|
||||
if (node.hasAspect(ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
Object obj = node.getProperties().get("workingCopyOwner");
|
||||
if (obj instanceof String)
|
||||
{
|
||||
User user = Application.getCurrentUser(FacesContext.getCurrentInstance());
|
||||
if ( ((String)obj).equals(user.getUserName()))
|
||||
{
|
||||
locked = Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the human readable form of the specified node Path. Fast version of the method that
|
||||
* simply converts QName localname components to Strings.
|
||||
*
|
||||
* @param path Path to extract readable form from, excluding the final element
|
||||
*
|
||||
* @return human readable form of the Path excluding the final element
|
||||
*/
|
||||
public static String getDisplayPath(Path path)
|
||||
{
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
|
||||
for (int i=0; i<path.size()-1; i++)
|
||||
{
|
||||
String elementString = null;
|
||||
Path.Element element = path.get(i);
|
||||
if (element instanceof Path.ChildAssocElement)
|
||||
{
|
||||
ChildAssociationRef elementRef = ((Path.ChildAssocElement)element).getRef();
|
||||
if (elementRef.getParentRef() != null)
|
||||
{
|
||||
elementString = elementRef.getQName().getLocalName();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
elementString = element.getElementString();
|
||||
}
|
||||
|
||||
if (elementString != null)
|
||||
{
|
||||
buf.append("/");
|
||||
buf.append(elementString);
|
||||
}
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a Path by converting each element into its display NAME attribute
|
||||
*
|
||||
* @param path Path to convert
|
||||
* @param separator Separator to user between path elements
|
||||
* @param prefix To prepend to the path
|
||||
*
|
||||
* @return Path converted using NAME attribute on each element
|
||||
*/
|
||||
public static String getNamePath(NodeService nodeService, Path path, NodeRef rootNode, String separator, String prefix)
|
||||
{
|
||||
StringBuilder buf = new StringBuilder(128);
|
||||
|
||||
// ignore root node check if not passed in
|
||||
boolean foundRoot = (rootNode == null);
|
||||
|
||||
buf.append(prefix);
|
||||
|
||||
// skip first element as it represents repo root '/'
|
||||
for (int i=1; i<path.size(); i++)
|
||||
{
|
||||
Path.Element element = path.get(i);
|
||||
String elementString = null;
|
||||
if (element instanceof Path.ChildAssocElement)
|
||||
{
|
||||
ChildAssociationRef elementRef = ((Path.ChildAssocElement)element).getRef();
|
||||
if (elementRef.getParentRef() != null)
|
||||
{
|
||||
// only append if we've found the root already
|
||||
if (foundRoot == true)
|
||||
{
|
||||
Object nameProp = nodeService.getProperty(elementRef.getChildRef(), ContentModel.PROP_NAME);
|
||||
if (nameProp != null)
|
||||
{
|
||||
elementString = nameProp.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
elementString = element.getElementString();
|
||||
}
|
||||
}
|
||||
|
||||
// either we've found root already or may have now
|
||||
// check after as we want to skip the root as it represents the CIFS share name
|
||||
foundRoot = (foundRoot || elementRef.getChildRef().equals(rootNode));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
elementString = element.getElementString();
|
||||
}
|
||||
|
||||
if (elementString != null)
|
||||
{
|
||||
buf.append(separator);
|
||||
buf.append(elementString);
|
||||
}
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mimetype code for the specified file name.
|
||||
* <p>
|
||||
* The file extension will be extracted from the filename and used to lookup the mimetype.
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @param filename Non-null filename to process
|
||||
*
|
||||
* @return mimetype for the specified filename - falls back to 'application/octet-stream' if not found.
|
||||
*/
|
||||
public static String getMimeTypeForFileName(FacesContext context, String filename)
|
||||
{
|
||||
// base the mimetype from the file extension
|
||||
MimetypeService mimetypeService = (MimetypeService)getServiceRegistry(context).getMimetypeService();
|
||||
|
||||
// fall back to binary mimetype if no match found
|
||||
String mimetype = MimetypeMap.MIMETYPE_BINARY;
|
||||
int extIndex = filename.lastIndexOf('.');
|
||||
if (extIndex != -1)
|
||||
{
|
||||
String ext = filename.substring(extIndex + 1).toLowerCase();
|
||||
String mt = mimetypeService.getMimetypesByExtension().get(ext);
|
||||
if (mt != null)
|
||||
{
|
||||
mimetype = mt;
|
||||
}
|
||||
}
|
||||
|
||||
return mimetype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a UserTransaction instance
|
||||
*
|
||||
* @param context FacesContext
|
||||
*
|
||||
* @return UserTransaction
|
||||
*/
|
||||
public static UserTransaction getUserTransaction(FacesContext context)
|
||||
{
|
||||
TransactionService transactionService = getServiceRegistry(context).getTransactionService();
|
||||
return transactionService.getUserTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a UserTransaction instance
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @param readonly Transaction readonly state
|
||||
*
|
||||
* @return UserTransaction
|
||||
*/
|
||||
public static UserTransaction getUserTransaction(FacesContext context, boolean readonly)
|
||||
{
|
||||
TransactionService transactionService = getServiceRegistry(context).getTransactionService();
|
||||
return transactionService.getUserTransaction(readonly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Repository Service Registry
|
||||
*
|
||||
* @param context Faces Context
|
||||
* @return the Service Registry
|
||||
*/
|
||||
public static ServiceRegistry getServiceRegistry(FacesContext context)
|
||||
{
|
||||
return (ServiceRegistry)FacesContextUtils.getRequiredWebApplicationContext(
|
||||
context).getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Repository Service Registry
|
||||
*
|
||||
* @param context Servlet Context
|
||||
* @return the Service Registry
|
||||
*/
|
||||
public static ServiceRegistry getServiceRegistry(ServletContext context)
|
||||
{
|
||||
return (ServiceRegistry)WebApplicationContextUtils.getRequiredWebApplicationContext(
|
||||
context).getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Configurable Service
|
||||
*
|
||||
* @return the configurable service
|
||||
*/
|
||||
public static ConfigurableService getConfigurableService(FacesContext context)
|
||||
{
|
||||
return (ConfigurableService)FacesContextUtils.getRequiredWebApplicationContext(context).getBean("configurableService");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Metadata Extracter Registry
|
||||
*
|
||||
* @param context Faces Context
|
||||
* @return the MetadataExtracterRegistry
|
||||
*/
|
||||
public static MetadataExtracterRegistry getMetadataExtracterRegistry(FacesContext context)
|
||||
{
|
||||
return (MetadataExtracterRegistry)FacesContextUtils.getRequiredWebApplicationContext(
|
||||
context).getBean(METADATA_EXTACTER_REGISTRY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the metadata of a "raw" piece of content into a map.
|
||||
*
|
||||
* @param context Faces Context
|
||||
* @param reader Content reader for the source content to extract from
|
||||
* @param destination Map of metadata to set metadata values into
|
||||
* @return True if an extracter was found
|
||||
*/
|
||||
public static boolean extractMetadata(FacesContext context, ContentReader reader, Map<QName, Serializable> destination)
|
||||
{
|
||||
// check that source mimetype is available
|
||||
String mimetype = reader.getMimetype();
|
||||
if (mimetype == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("The content reader mimetype must be set: " + reader);
|
||||
}
|
||||
|
||||
// look for a transformer
|
||||
MetadataExtracter extracter = getMetadataExtracterRegistry(context).getExtracter(mimetype);
|
||||
if (extracter == null)
|
||||
{
|
||||
// No metadata extracter is not a failure, but we flag it
|
||||
return false;
|
||||
}
|
||||
|
||||
// we have a transformer, so do it
|
||||
extracter.extract(reader, destination);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query a list of Person type nodes from the repo
|
||||
* It is currently assumed that all Person nodes exist below the Repository root node
|
||||
*
|
||||
* @param context Faces Context
|
||||
* @param nodeService The node service
|
||||
* @param searchService used to perform the search
|
||||
* @return List of Person node objects
|
||||
*/
|
||||
public static List<Node> getUsers(FacesContext context, NodeService nodeService, SearchService searchService)
|
||||
{
|
||||
List<Node> personNodes = null;
|
||||
|
||||
UserTransaction tx = null;
|
||||
try
|
||||
{
|
||||
tx = Repository.getUserTransaction(context, true);
|
||||
tx.begin();
|
||||
|
||||
PersonService personService = (PersonService)FacesContextUtils.getRequiredWebApplicationContext(context).getBean("personService");
|
||||
NodeRef peopleRef = personService.getPeopleContainer();
|
||||
|
||||
// TODO: better to perform an XPath search or a get for a specific child type here?
|
||||
List<ChildAssociationRef> childRefs = nodeService.getChildAssocs(peopleRef);
|
||||
personNodes = new ArrayList<Node>(childRefs.size());
|
||||
for (ChildAssociationRef ref: childRefs)
|
||||
{
|
||||
// create our Node representation from the NodeRef
|
||||
NodeRef nodeRef = ref.getChildRef();
|
||||
|
||||
if (nodeService.getType(nodeRef).equals(ContentModel.TYPE_PERSON))
|
||||
{
|
||||
// create our Node representation
|
||||
MapNode node = new MapNode(nodeRef);
|
||||
|
||||
// set data binding properties
|
||||
// this will also force initialisation of the props now during the UserTransaction
|
||||
// it is much better for performance to do this now rather than during page bind
|
||||
Map<String, Object> props = node.getProperties();
|
||||
props.put("fullName", ((String)props.get("firstName")) + ' ' + ((String)props.get("lastName")));
|
||||
NodeRef homeFolderNodeRef = (NodeRef)props.get("homeFolder");
|
||||
if (homeFolderNodeRef != null)
|
||||
{
|
||||
props.put("homeSpace", homeFolderNodeRef);
|
||||
}
|
||||
|
||||
personNodes.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
}
|
||||
catch (InvalidNodeRefException refErr)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||
context, Repository.ERROR_NODEREF), new Object[] {"root"}) );
|
||||
personNodes = Collections.<Node>emptyList();
|
||||
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||
context, Repository.ERROR_GENERIC), err.getMessage()), err );
|
||||
personNodes = Collections.<Node>emptyList();
|
||||
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
||||
}
|
||||
|
||||
return personNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a property of unknown type to a String value. A native String value will be
|
||||
* returned directly, else toString() will be executed, null is returned as null.
|
||||
*
|
||||
* @param value Property value
|
||||
*
|
||||
* @return value to String or null
|
||||
*/
|
||||
public static String safePropertyToString(Serializable value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (value instanceof String)
|
||||
{
|
||||
return (String)value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a QName representation for the given String.
|
||||
* If the String has no namespace the Alfresco namespace is added.
|
||||
* If the String has a prefix an attempt to resolve the prefix to the
|
||||
* full URI will be made.
|
||||
*
|
||||
* @param str The string to convert
|
||||
* @return A QName representation of the given string
|
||||
*/
|
||||
public static QName resolveToQName(String str)
|
||||
{
|
||||
return QName.resolveToQName(getNamespaceService(), str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string representation of a QName for the given string.
|
||||
* If the given string already has a namespace, either a URL or a prefix,
|
||||
* nothing the given string is returned. If it does not have a namespace
|
||||
* the Alfresco namespace is added.
|
||||
*
|
||||
* @param str The string to convert
|
||||
* @return A QName String representation of the given string
|
||||
*/
|
||||
public static String resolveToQNameString(String str)
|
||||
{
|
||||
return QName.resolveToQNameString(getNamespaceService(), str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the namespace service
|
||||
*
|
||||
* @return The NamespaceService
|
||||
*/
|
||||
private static NamespaceService getNamespaceService()
|
||||
{
|
||||
if (namespaceService == null)
|
||||
{
|
||||
ServiceRegistry svcReg = getServiceRegistry(FacesContext.getCurrentInstance());
|
||||
namespaceService = svcReg.getNamespaceService();
|
||||
}
|
||||
|
||||
return namespaceService;
|
||||
}
|
||||
}
|
200
source/java/org/alfresco/web/bean/repository/User.java
Normal file
200
source/java/org/alfresco/web/bean/repository/User.java
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.web.bean.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.configuration.ConfigurableService;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
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.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
|
||||
/**
|
||||
* Bean that represents the currently logged in user
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public final class User
|
||||
{
|
||||
private String homeSpaceId;
|
||||
private String userName;
|
||||
private String ticket;
|
||||
private NodeRef person;
|
||||
private String fullName = null;
|
||||
private Boolean administrator = null;
|
||||
|
||||
/** cached ref to our user preferences node */
|
||||
private NodeRef preferencesFolderRef = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param userName constructor for the user
|
||||
*/
|
||||
public User(String userName, String ticket, NodeRef person)
|
||||
{
|
||||
if (userName == null || ticket == null || person == null)
|
||||
{
|
||||
throw new IllegalArgumentException("All user details are mandatory!");
|
||||
}
|
||||
|
||||
this.userName = userName;
|
||||
this.ticket = ticket;
|
||||
this.person = person;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The user name
|
||||
*/
|
||||
public String getUserName()
|
||||
{
|
||||
return this.userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the full name of the Person this User represents
|
||||
*
|
||||
* @param service NodeService to use
|
||||
*
|
||||
* @return The full name
|
||||
*/
|
||||
public String getFullName(NodeService service)
|
||||
{
|
||||
if (this.fullName == null)
|
||||
{
|
||||
this.fullName = service.getProperty(this.person, ContentModel.PROP_FIRSTNAME) + " " +
|
||||
service.getProperty(this.person, ContentModel.PROP_LASTNAME);
|
||||
}
|
||||
|
||||
return this.fullName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Retrieves the user's home space (this may be the id of the company home space)
|
||||
*/
|
||||
public String getHomeSpaceId()
|
||||
{
|
||||
return this.homeSpaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param homeSpaceId Sets the id of the users home space
|
||||
*/
|
||||
public void setHomeSpaceId(String homeSpaceId)
|
||||
{
|
||||
this.homeSpaceId = homeSpaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the ticket.
|
||||
*/
|
||||
public String getTicket()
|
||||
{
|
||||
return this.ticket;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Returns the person NodeRef
|
||||
*/
|
||||
public NodeRef getPerson()
|
||||
{
|
||||
return this.person;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If the current user has Admin Authority
|
||||
*/
|
||||
public boolean isAdmin()
|
||||
{
|
||||
if (administrator == null)
|
||||
{
|
||||
administrator = Repository.getServiceRegistry(FacesContext.getCurrentInstance())
|
||||
.getAuthorityService().hasAdminAuthority();
|
||||
}
|
||||
|
||||
return administrator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create the node used to store user preferences.
|
||||
* Utilises the 'configurable' aspect on the Person linked to this user.
|
||||
*/
|
||||
public synchronized NodeRef getUserPreferencesRef()
|
||||
{
|
||||
if (this.preferencesFolderRef == null)
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ServiceRegistry registry = Repository.getServiceRegistry(fc);
|
||||
NodeService nodeService = registry.getNodeService();
|
||||
SearchService searchService = registry.getSearchService();
|
||||
NamespaceService namespaceService = registry.getNamespaceService();
|
||||
ConfigurableService configurableService = Repository.getConfigurableService(fc);
|
||||
|
||||
NodeRef person = Application.getCurrentUser(fc).getPerson();
|
||||
if (nodeService.hasAspect(person, ContentModel.ASPECT_CONFIGURABLE) == false)
|
||||
{
|
||||
// create the configuration folder for this Person node
|
||||
configurableService.makeConfigurable(person);
|
||||
}
|
||||
|
||||
// target of the assoc is the configurations folder ref
|
||||
NodeRef configRef = configurableService.getConfigurationFolder(person);
|
||||
if (configRef == null)
|
||||
{
|
||||
throw new IllegalStateException("Unable to find associated 'configurations' folder for node: " + person);
|
||||
}
|
||||
|
||||
String xpath = NamespaceService.APP_MODEL_PREFIX + ":" + "preferences";
|
||||
List<NodeRef> nodes = searchService.selectNodes(
|
||||
configRef,
|
||||
xpath,
|
||||
null,
|
||||
namespaceService,
|
||||
false);
|
||||
|
||||
NodeRef prefRef;
|
||||
if (nodes.size() == 1)
|
||||
{
|
||||
prefRef = nodes.get(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// create the preferences Node for this user
|
||||
ChildAssociationRef childRef = nodeService.createNode(
|
||||
configRef,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "preferences"),
|
||||
ContentModel.TYPE_CMOBJECT);
|
||||
|
||||
prefRef = childRef.getChildRef();
|
||||
}
|
||||
|
||||
this.preferencesFolderRef = prefRef;
|
||||
}
|
||||
|
||||
return this.preferencesFolderRef;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user