mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-02 17:35:18 +00:00
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2818 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
1239 lines
50 KiB
Java
1239 lines
50 KiB
Java
/*
|
|
* 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.jcr.item;
|
|
|
|
import java.io.InputStream;
|
|
import java.io.Serializable;
|
|
import java.util.ArrayList;
|
|
import java.util.Calendar;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import javax.jcr.AccessDeniedException;
|
|
import javax.jcr.InvalidItemStateException;
|
|
import javax.jcr.Item;
|
|
import javax.jcr.ItemExistsException;
|
|
import javax.jcr.ItemNotFoundException;
|
|
import javax.jcr.ItemVisitor;
|
|
import javax.jcr.MergeException;
|
|
import javax.jcr.NoSuchWorkspaceException;
|
|
import javax.jcr.Node;
|
|
import javax.jcr.NodeIterator;
|
|
import javax.jcr.PathNotFoundException;
|
|
import javax.jcr.Property;
|
|
import javax.jcr.PropertyIterator;
|
|
import javax.jcr.RepositoryException;
|
|
import javax.jcr.UnsupportedRepositoryOperationException;
|
|
import javax.jcr.Value;
|
|
import javax.jcr.ValueFormatException;
|
|
import javax.jcr.lock.Lock;
|
|
import javax.jcr.lock.LockException;
|
|
import javax.jcr.nodetype.ConstraintViolationException;
|
|
import javax.jcr.nodetype.NoSuchNodeTypeException;
|
|
import javax.jcr.nodetype.NodeDefinition;
|
|
import javax.jcr.nodetype.NodeType;
|
|
import javax.jcr.version.Version;
|
|
import javax.jcr.version.VersionException;
|
|
import javax.jcr.version.VersionHistory;
|
|
|
|
import org.alfresco.error.AlfrescoRuntimeException;
|
|
import org.alfresco.jcr.api.JCRNodeRef;
|
|
import org.alfresco.jcr.dictionary.ClassMap;
|
|
import org.alfresco.jcr.dictionary.NodeDefinitionImpl;
|
|
import org.alfresco.jcr.dictionary.NodeTypeImpl;
|
|
import org.alfresco.jcr.item.property.PropertyResolver;
|
|
import org.alfresco.jcr.session.SessionImpl;
|
|
import org.alfresco.jcr.util.JCRProxyFactory;
|
|
import org.alfresco.jcr.version.VersionHistoryImpl;
|
|
import org.alfresco.jcr.version.VersionImpl;
|
|
import org.alfresco.model.ContentModel;
|
|
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
|
import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
|
|
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
|
import org.alfresco.service.cmr.lock.LockService;
|
|
import org.alfresco.service.cmr.lock.LockStatus;
|
|
import org.alfresco.service.cmr.lock.LockType;
|
|
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.Path.Element;
|
|
import org.alfresco.service.cmr.search.SearchService;
|
|
import org.alfresco.service.cmr.version.VersionService;
|
|
import org.alfresco.service.namespace.QName;
|
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
|
import org.alfresco.util.ParameterCheck;
|
|
|
|
|
|
/**
|
|
* Alfresco Implementation of a JCR Node
|
|
*
|
|
* @author David Caruana
|
|
*/
|
|
public class NodeImpl extends ItemImpl implements Node
|
|
{
|
|
/** Node Reference to wrap */
|
|
private NodeRef nodeRef;
|
|
|
|
/** Proxy */
|
|
private Node proxy = null;
|
|
|
|
|
|
/**
|
|
* Construct
|
|
*
|
|
* @param context session context
|
|
* @param nodeRef node reference to wrap
|
|
*/
|
|
public NodeImpl(SessionImpl context, NodeRef nodeRef)
|
|
{
|
|
super(context);
|
|
this.nodeRef = nodeRef;
|
|
}
|
|
|
|
/**
|
|
* Get Node Proxy
|
|
*
|
|
* @param nodeImpl
|
|
* @return
|
|
*/
|
|
@Override
|
|
public Node getProxy()
|
|
{
|
|
if (proxy == null)
|
|
{
|
|
proxy = (Node)JCRProxyFactory.create(this, Node.class, session);
|
|
}
|
|
return proxy;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#addNode(java.lang.String)
|
|
*/
|
|
public Node addNode(String relPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException
|
|
{
|
|
return addNode(relPath, null);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#addNode(java.lang.String, java.lang.String)
|
|
*/
|
|
public Node addNode(String relPath, String primaryNodeTypeName) throws ItemExistsException, PathNotFoundException, NoSuchNodeTypeException, LockException, VersionException, ConstraintViolationException, RepositoryException
|
|
{
|
|
ParameterCheck.mandatoryString("relPath", relPath);
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
DictionaryService dictionaryService = session.getRepositoryImpl().getServiceRegistry().getDictionaryService();
|
|
|
|
// Determine parent node reference and new node name
|
|
Path path = new JCRPath(session.getNamespaceResolver(), relPath).getPath();
|
|
QName nodeName = null;
|
|
NodeRef parentRef = null;
|
|
if (path.size() == 1)
|
|
{
|
|
parentRef = nodeRef;
|
|
nodeName = ((JCRPath.SimpleElement)path.get(0)).getQName();
|
|
}
|
|
else
|
|
{
|
|
Path parentPath = path.subPath(path.size() -2);
|
|
parentRef = ItemResolver.getNodeRef(session, nodeRef, parentPath.toPrefixString(session.getNamespaceResolver()));
|
|
if (parentRef == null)
|
|
{
|
|
throw new PathNotFoundException("Path '" + relPath + "' does not exist from node " + nodeRef);
|
|
}
|
|
nodeName = ((JCRPath.SimpleElement)path.get(path.size() -1)).getQName();
|
|
}
|
|
|
|
// Check for invalid node name
|
|
// TODO: Replace with proper name validation
|
|
if (nodeName.getLocalName().indexOf('[') != -1 || nodeName.getLocalName().indexOf(']') != -1)
|
|
{
|
|
throw new RepositoryException("Node name '" + nodeName + "' is invalid");
|
|
}
|
|
|
|
// Determine child association to add node under
|
|
ChildAssociationDefinition childAssocDef = null;
|
|
QName nodeType = null;
|
|
if (primaryNodeTypeName == null || primaryNodeTypeName.length() == 0)
|
|
{
|
|
childAssocDef = getDefaultChildAssocDefForParent(nodeService, dictionaryService, parentRef);
|
|
nodeType = childAssocDef.getTargetClass().getName();
|
|
}
|
|
else
|
|
{
|
|
nodeType = QName.createQName(primaryNodeTypeName, session.getNamespaceResolver());
|
|
childAssocDef = getNodeTypeChildAssocDefForParent(nodeService, dictionaryService, parentRef, nodeType);
|
|
}
|
|
|
|
// Create node
|
|
// Note: Integrity exception will be thrown when the node is saved
|
|
ChildAssociationRef childRef = nodeService.createNode(parentRef, childAssocDef.getName(), nodeName, nodeType);
|
|
NodeImpl nodeImpl = new NodeImpl(session, childRef.getChildRef());
|
|
return nodeImpl.getProxy();
|
|
}
|
|
|
|
/**
|
|
* Get the default child association definition for the specified node
|
|
*
|
|
* @param nodeService node service
|
|
* @param dictionaryService dictionary service
|
|
* @param nodeRef node reference
|
|
* @return child association definition
|
|
*/
|
|
private ChildAssociationDefinition getDefaultChildAssocDefForParent(NodeService nodeService, DictionaryService dictionaryService, NodeRef nodeRef)
|
|
{
|
|
QName type = nodeService.getType(nodeRef);
|
|
Set<QName> aspects = nodeService.getAspects(nodeRef);
|
|
ClassDefinition classDef = dictionaryService.getAnonymousType(type, aspects);
|
|
Map<QName, ChildAssociationDefinition> childAssocs = classDef.getChildAssociations();
|
|
if (childAssocs.size() != 1)
|
|
{
|
|
throw new AlfrescoRuntimeException("Cannot determine node type for child within parent " + nodeRef);
|
|
}
|
|
ChildAssociationDefinition childAssocDef = childAssocs.values().iterator().next();
|
|
return childAssocDef;
|
|
}
|
|
|
|
/**
|
|
* Get the child association definition whose target matches the specified node type for the specified node
|
|
*
|
|
* @param nodeService node service
|
|
* @param dictionaryService dictionary service
|
|
* @param nodeRef node reference
|
|
* @param nodeType node type to find child association definition for
|
|
* @return child association definition
|
|
*/
|
|
private ChildAssociationDefinition getNodeTypeChildAssocDefForParent(NodeService nodeService, DictionaryService dictionaryService, NodeRef nodeRef, QName nodeType)
|
|
{
|
|
ChildAssociationDefinition nodeTypeChildAssocDef = null;
|
|
QName type = nodeService.getType(nodeRef);
|
|
Set<QName> aspects = nodeService.getAspects(nodeRef);
|
|
ClassDefinition classDef = dictionaryService.getAnonymousType(type, aspects);
|
|
Map<QName, ChildAssociationDefinition> childAssocs = classDef.getChildAssociations();
|
|
for (ChildAssociationDefinition childAssocDef : childAssocs.values())
|
|
{
|
|
QName targetClass = childAssocDef.getTargetClass().getName();
|
|
if (dictionaryService.isSubClass(nodeType, targetClass))
|
|
{
|
|
if (nodeTypeChildAssocDef != null)
|
|
{
|
|
throw new AlfrescoRuntimeException("Cannot determine child association for node type '" + nodeType + " within parent " + nodeRef);
|
|
}
|
|
nodeTypeChildAssocDef = childAssocDef;
|
|
}
|
|
}
|
|
if (nodeTypeChildAssocDef == null)
|
|
{
|
|
throw new AlfrescoRuntimeException("Cannot determine child association for node type '" + nodeType + " within parent " + nodeRef);
|
|
}
|
|
return nodeTypeChildAssocDef;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Item#remove()
|
|
*/
|
|
public void remove() throws VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
|
|
// Note: remove the primary child association, therefore forcing a delete of the node (including any secondary child
|
|
// associations)
|
|
ChildAssociationRef assocRef = nodeService.getPrimaryParent(nodeRef);
|
|
NodeRef parentRef = assocRef.getParentRef();
|
|
if (parentRef == null)
|
|
{
|
|
throw new ConstraintViolationException("Cannot remove the root node");
|
|
}
|
|
nodeService.removeChild(parentRef, nodeRef);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#orderBefore(java.lang.String, java.lang.String)
|
|
*/
|
|
public void orderBefore(String srcChildRelPath, String destChildRelPath) throws UnsupportedRepositoryOperationException, VersionException, ConstraintViolationException, ItemNotFoundException, LockException, RepositoryException
|
|
{
|
|
throw new UnsupportedRepositoryOperationException();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, javax.jcr.Value)
|
|
*/
|
|
public Property setProperty(String name, Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(value, -1);
|
|
return (value == null ) ? null : property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, javax.jcr.Value, int)
|
|
*/
|
|
public Property setProperty(String name, Value value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(value, type);
|
|
return (value == null ) ? null : property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, javax.jcr.Value[])
|
|
*/
|
|
public Property setProperty(String name, Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(values, -1);
|
|
return (values == null ) ? null : property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, javax.jcr.Value[], int)
|
|
*/
|
|
public Property setProperty(String name, Value[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(values, type);
|
|
return (values == null ) ? null : property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, java.lang.String[])
|
|
*/
|
|
public Property setProperty(String name, String[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(values, -1);
|
|
return (values == null ) ? null : property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, java.lang.String[], int)
|
|
*/
|
|
public Property setProperty(String name, String[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(values, type);
|
|
return (values == null ) ? null : property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, java.lang.String)
|
|
*/
|
|
public Property setProperty(String name, String value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(value, -1);
|
|
return (value == null ) ? null : property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, java.lang.String, int)
|
|
*/
|
|
public Property setProperty(String name, String value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(value, type);
|
|
return (value == null ) ? null : property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, java.io.InputStream)
|
|
*/
|
|
public Property setProperty(String name, InputStream value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(value, -1);
|
|
return (value == null ) ? null : property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, boolean)
|
|
*/
|
|
public Property setProperty(String name, boolean value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(value, -1);
|
|
return property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, double)
|
|
*/
|
|
public Property setProperty(String name, double value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(value, -1);
|
|
return property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, long)
|
|
*/
|
|
public Property setProperty(String name, long value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue(value, -1);
|
|
return property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, java.util.Calendar)
|
|
*/
|
|
public Property setProperty(String name, Calendar value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue((value == null) ? null : value.getTime(), -1);
|
|
return (value == null ) ? null : property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#setProperty(java.lang.String, javax.jcr.Node)
|
|
*/
|
|
public Property setProperty(String name, Node value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
|
|
{
|
|
QName propertyName = QName.createQName(name, session.getNamespaceResolver());
|
|
PropertyImpl property = new PropertyImpl(this, propertyName);
|
|
property.setPropertyValue((value == null) ? null : JCRNodeRef.getNodeRef(value), -1);
|
|
return (value == null ) ? null : property;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getNode(java.lang.String)
|
|
*/
|
|
public Node getNode(String relPath) throws PathNotFoundException, RepositoryException
|
|
{
|
|
NodeImpl nodeImpl = ItemResolver.findNode(session, nodeRef, relPath);
|
|
return nodeImpl.getProxy();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getNodes()
|
|
*/
|
|
public NodeIterator getNodes() throws RepositoryException
|
|
{
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
List<ChildAssociationRef> childAssocs = nodeService.getChildAssocs(nodeRef);
|
|
NodeIterator iterator = new ChildAssocNodeIteratorImpl(session, childAssocs);
|
|
return iterator;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getNodes(java.lang.String)
|
|
*/
|
|
public NodeIterator getNodes(String namePattern) throws RepositoryException
|
|
{
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
JCRPatternMatch match = new JCRPatternMatch(namePattern, session.getNamespaceResolver());
|
|
List<ChildAssociationRef> childAssocs = nodeService.getChildAssocs(nodeRef, RegexQNamePattern.MATCH_ALL, match);
|
|
NodeIterator iterator = new ChildAssocNodeIteratorImpl(session, childAssocs);
|
|
return iterator;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getProperty(java.lang.String)
|
|
*/
|
|
public Property getProperty(String relPath) throws PathNotFoundException, RepositoryException
|
|
{
|
|
JCRPath jcrPath = new JCRPath(session.getNamespaceResolver(), relPath);
|
|
Path path = jcrPath.getPath();
|
|
if (path.size() == 1)
|
|
{
|
|
QName propertyName = ((JCRPath.SimpleElement)path.get(0)).getQName();
|
|
return PropertyResolver.createProperty(this, propertyName).getProxy();
|
|
}
|
|
|
|
ItemImpl itemImpl = ItemResolver.findItem(session, nodeRef, relPath);
|
|
if (itemImpl == null || !(itemImpl instanceof PropertyImpl))
|
|
{
|
|
throw new PathNotFoundException("Property path " + relPath + " not found from node " + nodeRef);
|
|
}
|
|
return ((PropertyImpl)itemImpl).getProxy();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getProperties()
|
|
*/
|
|
public PropertyIterator getProperties() throws RepositoryException
|
|
{
|
|
List<PropertyImpl> properties = PropertyResolver.createProperties(this, null);
|
|
PropertyIterator iterator = new PropertyListIterator(properties);
|
|
return iterator;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getProperties(java.lang.String)
|
|
*/
|
|
public PropertyIterator getProperties(String namePattern) throws RepositoryException
|
|
{
|
|
JCRPatternMatch match = new JCRPatternMatch(namePattern, session.getNamespaceResolver());
|
|
List<PropertyImpl> properties = PropertyResolver.createProperties(this, match);
|
|
PropertyIterator iterator = new PropertyListIterator(properties);
|
|
return iterator;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getPrimaryItem()
|
|
*/
|
|
public Item getPrimaryItem() throws ItemNotFoundException, RepositoryException
|
|
{
|
|
// Note: Alfresco does not support the notion of primary item
|
|
throw new ItemNotFoundException();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getUUID()
|
|
*/
|
|
public String getUUID() throws UnsupportedRepositoryOperationException, RepositoryException
|
|
{
|
|
return nodeRef.getId();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getIndex()
|
|
*/
|
|
public int getIndex() throws RepositoryException
|
|
{
|
|
int index = 1;
|
|
String name = getName();
|
|
if (name != null)
|
|
{
|
|
// TODO: Look at more efficient approach
|
|
SearchService searchService = session.getRepositoryImpl().getServiceRegistry().getSearchService();
|
|
List<NodeRef> siblings = searchService.selectNodes(nodeRef, "../" + name, null, session.getNamespaceResolver(), false);
|
|
for (NodeRef sibling : siblings)
|
|
{
|
|
if (sibling.equals(nodeRef))
|
|
{
|
|
break;
|
|
}
|
|
index++;
|
|
}
|
|
}
|
|
return index;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getReferences()
|
|
*/
|
|
public PropertyIterator getReferences() throws RepositoryException
|
|
{
|
|
// Note: Lookup for references not supported for now
|
|
return new PropertyListIterator(new ArrayList<PropertyImpl>());
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#hasNode(java.lang.String)
|
|
*/
|
|
public boolean hasNode(String relPath) throws RepositoryException
|
|
{
|
|
return ItemResolver.nodeExists(session, nodeRef, relPath);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#hasProperty(java.lang.String)
|
|
*/
|
|
public boolean hasProperty(String relPath) throws RepositoryException
|
|
{
|
|
JCRPath jcrPath = new JCRPath(session.getNamespaceResolver(), relPath);
|
|
Path path = jcrPath.getPath();
|
|
if (path.size() == 1)
|
|
{
|
|
QName propertyName = ((JCRPath.SimpleElement)path.get(0)).getQName();
|
|
return PropertyResolver.hasProperty(this, propertyName);
|
|
}
|
|
|
|
return ItemResolver.itemExists(session, nodeRef, relPath);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#hasNodes()
|
|
*/
|
|
public boolean hasNodes() throws RepositoryException
|
|
{
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
List<ChildAssociationRef> childAssocs = nodeService.getChildAssocs(nodeRef);
|
|
return childAssocs.size() > 0;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#hasProperties()
|
|
*/
|
|
public boolean hasProperties() throws RepositoryException
|
|
{
|
|
// Note: nt:base has a mandatory primaryType property for which we don't have security access control
|
|
return true;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getPrimaryNodeType()
|
|
*/
|
|
public NodeType getPrimaryNodeType() throws RepositoryException
|
|
{
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
QName type = nodeService.getType(nodeRef);
|
|
return session.getTypeManager().getNodeTypeImpl(type);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getMixinNodeTypes()
|
|
*/
|
|
public NodeType[] getMixinNodeTypes() throws RepositoryException
|
|
{
|
|
// Add aspects defined by node
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
Set<QName> aspects = nodeService.getAspects(nodeRef);
|
|
NodeType[] nodeTypes = new NodeType[aspects.size() + 1];
|
|
int i = 0;
|
|
for (QName aspect : aspects)
|
|
{
|
|
nodeTypes[i++] = session.getTypeManager().getNodeTypeImpl(aspect);
|
|
QName mixin = ClassMap.convertClassToType(aspect);
|
|
if (mixin != null)
|
|
{
|
|
nodeTypes[i++] = session.getTypeManager().getNodeTypeImpl(mixin);
|
|
}
|
|
}
|
|
|
|
return nodeTypes;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#isNodeType(java.lang.String)
|
|
*/
|
|
public boolean isNodeType(String nodeTypeName) throws RepositoryException
|
|
{
|
|
QName nodeType = QName.createQName(nodeTypeName, session.getNamespaceResolver());
|
|
|
|
// is it one of standard types
|
|
if (nodeType.equals(NodeTypeImpl.MIX_REFERENCEABLE) || nodeType.equals(NodeTypeImpl.NT_BASE))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// map JCR mixins to Alfresco mixins
|
|
QName nodeClass = ClassMap.convertTypeToClass(nodeType);
|
|
if (nodeClass == null)
|
|
{
|
|
nodeClass = nodeType;
|
|
}
|
|
|
|
// determine via class hierarchy
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
DictionaryService dictionaryService = session.getRepositoryImpl().getServiceRegistry().getDictionaryService();
|
|
|
|
// first, check the type
|
|
QName type = nodeService.getType(nodeRef);
|
|
if (dictionaryService.isSubClass(nodeClass, type))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// second, check the aspects
|
|
Set<QName> aspects = nodeService.getAspects(nodeRef);
|
|
for (QName aspect : aspects)
|
|
{
|
|
if (dictionaryService.isSubClass(nodeClass, aspect))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// no, its definitely not of the specified type
|
|
return false;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#addMixin(java.lang.String)
|
|
*/
|
|
public void addMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException
|
|
{
|
|
// map JCR mixins to Alfresco mixins
|
|
QName mixin = QName.createQName(mixinName, session.getNamespaceResolver());
|
|
QName aspect = ClassMap.convertTypeToClass(mixin);
|
|
if (aspect == null)
|
|
{
|
|
aspect = mixin;
|
|
}
|
|
|
|
// retrieve aspect definition
|
|
DictionaryService dictionaryService = session.getRepositoryImpl().getServiceRegistry().getDictionaryService();
|
|
AspectDefinition aspectDef = dictionaryService.getAspect(aspect);
|
|
if (aspectDef == null)
|
|
{
|
|
throw new NoSuchNodeTypeException("Unknown mixin name '" + mixinName + "'");
|
|
}
|
|
|
|
// apply aspect
|
|
ClassMap.AddMixin addMixin = ClassMap.getAddMixin(aspect);
|
|
Map<QName, Serializable> initialProperties = addMixin.preAddMixin(session, nodeRef);
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
nodeService.addAspect(nodeRef, aspect, initialProperties);
|
|
addMixin.postAddMixin(session, nodeRef);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#removeMixin(java.lang.String)
|
|
*/
|
|
public void removeMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException
|
|
{
|
|
// map JCR mixins to Alfresco mixins
|
|
QName mixin = QName.createQName(mixinName, session.getNamespaceResolver());
|
|
QName aspect = ClassMap.convertTypeToClass(mixin);
|
|
if (aspect == null)
|
|
{
|
|
aspect = mixin;
|
|
}
|
|
|
|
// retrieve aspect definition
|
|
DictionaryService dictionaryService = session.getRepositoryImpl().getServiceRegistry().getDictionaryService();
|
|
AspectDefinition aspectDef = dictionaryService.getAspect(aspect);
|
|
if (aspectDef == null)
|
|
{
|
|
throw new NoSuchNodeTypeException("Unknown mixin name '" + mixinName + "'");
|
|
}
|
|
|
|
// check the node actually has the mixin
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
Set<QName> nodeAspects = nodeService.getAspects(nodeRef);
|
|
if (!nodeAspects.contains(aspect))
|
|
{
|
|
throw new NoSuchNodeTypeException("Node " + nodeRef.getId() + " does not have the mixin " + mixin);
|
|
}
|
|
|
|
// remove aspect
|
|
ClassMap.RemoveMixin removeMixin = ClassMap.getRemoveMixin(aspect);
|
|
removeMixin.preRemoveMixin(session, nodeRef);
|
|
nodeService.removeAspect(nodeRef, aspect);
|
|
removeMixin.postRemoveMixin(session, nodeRef);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#canAddMixin(java.lang.String)
|
|
*/
|
|
public boolean canAddMixin(String mixinName) throws NoSuchNodeTypeException, RepositoryException
|
|
{
|
|
// map JCR mixins to Alfresco mixins
|
|
QName mixin = QName.createQName(mixinName, session.getNamespaceResolver());
|
|
QName aspect = ClassMap.convertTypeToClass(mixin);
|
|
if (aspect == null)
|
|
{
|
|
aspect = mixin;
|
|
}
|
|
|
|
// retrieve aspect definition
|
|
DictionaryService dictionaryService = session.getRepositoryImpl().getServiceRegistry().getDictionaryService();
|
|
AspectDefinition aspectDef = dictionaryService.getAspect(aspect);
|
|
if (aspectDef == null)
|
|
{
|
|
throw new NoSuchNodeTypeException("Unknown mixin name '" + mixinName + "'");
|
|
}
|
|
|
|
// TODO: check for write permission
|
|
|
|
// check for locked node
|
|
LockService lockService = session.getRepositoryImpl().getServiceRegistry().getLockService();
|
|
LockStatus lockStatus = lockService.getLockStatus(nodeRef);
|
|
if (lockStatus == LockStatus.LOCKED)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// mixin addition is allowed
|
|
return true;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getDefinition()
|
|
*/
|
|
public NodeDefinition getDefinition() throws RepositoryException
|
|
{
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
DictionaryService dictionaryService = session.getRepositoryImpl().getServiceRegistry().getDictionaryService();
|
|
ChildAssociationRef childAssocRef = nodeService.getPrimaryParent(this.nodeRef);
|
|
ChildAssociationDefinition childAssocDef = (ChildAssociationDefinition)dictionaryService.getAssociation(childAssocRef.getTypeQName());
|
|
NodeDefinition nodeDef = new NodeDefinitionImpl(session.getTypeManager(), childAssocDef);
|
|
return nodeDef;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#checkin()
|
|
*/
|
|
public Version checkin() throws VersionException, UnsupportedRepositoryOperationException, InvalidItemStateException, LockException, RepositoryException
|
|
{
|
|
// check this node is versionable
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE))
|
|
{
|
|
throw new UnsupportedRepositoryOperationException("Node " + nodeRef + " is not versionable");
|
|
}
|
|
|
|
Version version = null;
|
|
if (!isCheckedOut())
|
|
{
|
|
// return current version
|
|
version = getBaseVersion();
|
|
}
|
|
else
|
|
{
|
|
// create a new version snapshot
|
|
VersionService versionService = session.getRepositoryImpl().getServiceRegistry().getVersionService();
|
|
org.alfresco.service.cmr.version.Version versionNode = versionService.createVersion(nodeRef, null);
|
|
org.alfresco.service.cmr.version.VersionHistory versionHistory = versionService.getVersionHistory(nodeRef);
|
|
version = new VersionImpl(new VersionHistoryImpl(session, versionHistory), versionNode).getProxy();
|
|
|
|
// set to 'read only'
|
|
LockService lockService = session.getRepositoryImpl().getServiceRegistry().getLockService();
|
|
lockService.lock(nodeRef, LockType.READ_ONLY_LOCK);
|
|
}
|
|
|
|
return version;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#checkout()
|
|
*/
|
|
public void checkout() throws UnsupportedRepositoryOperationException, LockException, RepositoryException
|
|
{
|
|
// check this node is versionable
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE))
|
|
{
|
|
throw new UnsupportedRepositoryOperationException("Node " + nodeRef + " is not versionable");
|
|
}
|
|
|
|
// remove 'read only' lock
|
|
if (!isCheckedOut())
|
|
{
|
|
LockService lockService = session.getRepositoryImpl().getServiceRegistry().getLockService();
|
|
lockService.unlock(nodeRef);
|
|
}
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#doneMerge(javax.jcr.version.Version)
|
|
*/
|
|
public void doneMerge(Version version) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException
|
|
{
|
|
throw new UnsupportedRepositoryOperationException();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#cancelMerge(javax.jcr.version.Version)
|
|
*/
|
|
public void cancelMerge(Version version) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException
|
|
{
|
|
throw new UnsupportedRepositoryOperationException();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#update(java.lang.String)
|
|
*/
|
|
public void update(String srcWorkspaceName) throws NoSuchWorkspaceException, AccessDeniedException, LockException, InvalidItemStateException, RepositoryException
|
|
{
|
|
throw new UnsupportedRepositoryOperationException();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#merge(java.lang.String, boolean)
|
|
*/
|
|
public NodeIterator merge(String srcWorkspace, boolean bestEffort) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException
|
|
{
|
|
throw new UnsupportedRepositoryOperationException();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getCorrespondingNodePath(java.lang.String)
|
|
*/
|
|
public String getCorrespondingNodePath(String workspaceName) throws ItemNotFoundException, NoSuchWorkspaceException, AccessDeniedException, RepositoryException
|
|
{
|
|
throw new UnsupportedRepositoryOperationException();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#isCheckedOut()
|
|
*/
|
|
public boolean isCheckedOut() throws RepositoryException
|
|
{
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE))
|
|
{
|
|
// it's not versionable, therefore it's checked-out and writable
|
|
// TODO: Do not yet take into consideration versionable ancestor
|
|
return true;
|
|
}
|
|
|
|
// it's versionable, use the lock to determine if it's checked-out
|
|
LockService lockService = session.getRepositoryImpl().getServiceRegistry().getLockService();
|
|
LockType lockType = lockService.getLockType(nodeRef);
|
|
if (lockType == null)
|
|
{
|
|
// it's not locked at all
|
|
return true;
|
|
}
|
|
|
|
// it's only checked-in when a read-only locked
|
|
return (lockType.equals(LockType.READ_ONLY_LOCK)) ? false : true;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#restore(java.lang.String, boolean)
|
|
*/
|
|
public void restore(String versionName, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException
|
|
{
|
|
// check this node is versionable
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE))
|
|
{
|
|
throw new UnsupportedRepositoryOperationException("Node " + nodeRef + " is not versionable");
|
|
}
|
|
|
|
// retrieve version for label
|
|
VersionService versionService = session.getRepositoryImpl().getServiceRegistry().getVersionService();
|
|
org.alfresco.service.cmr.version.VersionHistory versionHistory = versionService.getVersionHistory(nodeRef);
|
|
org.alfresco.service.cmr.version.Version version = versionHistory.getVersion(versionName);
|
|
if (version == null)
|
|
{
|
|
throw new VersionException("Version name " + versionName + " does not exist in the version history of node " + nodeRef);
|
|
}
|
|
|
|
// unlock if necessary
|
|
LockService lockService = session.getRepositoryImpl().getServiceRegistry().getLockService();
|
|
LockType lockType = lockService.getLockType(nodeRef);
|
|
if (lockType != null)
|
|
{
|
|
lockService.unlock(nodeRef);
|
|
}
|
|
|
|
// revert to version
|
|
versionService.revert(nodeRef, version);
|
|
lockService.lock(nodeRef, LockType.READ_ONLY_LOCK);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#restore(javax.jcr.version.Version, boolean)
|
|
*/
|
|
public void restore(Version version, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, RepositoryException
|
|
{
|
|
restore(version.getName(), removeExisting);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#restore(javax.jcr.version.Version, java.lang.String, boolean)
|
|
*/
|
|
public void restore(Version version, String relPath, boolean removeExisting) throws PathNotFoundException, ItemExistsException, VersionException, ConstraintViolationException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException
|
|
{
|
|
throw new UnsupportedRepositoryOperationException();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#restoreByLabel(java.lang.String, boolean)
|
|
*/
|
|
public void restoreByLabel(String versionLabel, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException
|
|
{
|
|
throw new UnsupportedRepositoryOperationException();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getVersionHistory()
|
|
*/
|
|
public VersionHistory getVersionHistory() throws UnsupportedRepositoryOperationException, RepositoryException
|
|
{
|
|
// check this node is versionable
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE))
|
|
{
|
|
throw new UnsupportedRepositoryOperationException("Node " + nodeRef + " is not versionable");
|
|
}
|
|
|
|
// construct version history
|
|
VersionService versionService = session.getRepositoryImpl().getServiceRegistry().getVersionService();
|
|
org.alfresco.service.cmr.version.VersionHistory versionHistory = versionService.getVersionHistory(nodeRef);
|
|
return new VersionHistoryImpl(session, versionHistory).getProxy();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getBaseVersion()
|
|
*/
|
|
public Version getBaseVersion() throws UnsupportedRepositoryOperationException, RepositoryException
|
|
{
|
|
// check this node is versionable
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE))
|
|
{
|
|
throw new UnsupportedRepositoryOperationException("Node " + nodeRef + " is not versionable");
|
|
}
|
|
|
|
// construct version
|
|
VersionService versionService = session.getRepositoryImpl().getServiceRegistry().getVersionService();
|
|
org.alfresco.service.cmr.version.VersionHistory versionHistory = versionService.getVersionHistory(nodeRef);
|
|
org.alfresco.service.cmr.version.Version version = versionService.getCurrentVersion(nodeRef);
|
|
return new VersionImpl(new VersionHistoryImpl(session, versionHistory), version).getProxy();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#lock(boolean, boolean)
|
|
*/
|
|
public Lock lock(boolean isDeep, boolean isSessionScoped) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException
|
|
{
|
|
// note: alfresco does not yet support session scoped locks
|
|
if (isSessionScoped)
|
|
{
|
|
throw new UnsupportedRepositoryOperationException("Session scope locking is not supported.");
|
|
}
|
|
|
|
// check this node is lockable
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE))
|
|
{
|
|
throw new LockException("Node " + nodeRef + " does is not lockable.");
|
|
}
|
|
|
|
// lock the node
|
|
LockService lockService = session.getRepositoryImpl().getServiceRegistry().getLockService();
|
|
lockService.lock(nodeRef, LockType.WRITE_LOCK, 0, isDeep);
|
|
|
|
// return lock
|
|
return new LockImpl(this).getProxy();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#getLock()
|
|
*/
|
|
public Lock getLock() throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, RepositoryException
|
|
{
|
|
// check this node is lockable
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE))
|
|
{
|
|
throw new LockException("Node " + nodeRef + " does is not lockable.");
|
|
}
|
|
|
|
// return lock
|
|
return new LockImpl(this).getProxy();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#unlock()
|
|
*/
|
|
public void unlock() throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException
|
|
{
|
|
// check this node is lockable
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE))
|
|
{
|
|
throw new LockException("Node " + nodeRef + " does is not lockable.");
|
|
}
|
|
|
|
// unlock
|
|
LockService lockService = session.getRepositoryImpl().getServiceRegistry().getLockService();
|
|
lockService.unlock(nodeRef, true);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#holdsLock()
|
|
*/
|
|
public boolean holdsLock() throws RepositoryException
|
|
{
|
|
// note: for now, alfresco doesn't distinguish between lock holder and locked
|
|
return isLocked();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Node#isLocked()
|
|
*/
|
|
public boolean isLocked() throws RepositoryException
|
|
{
|
|
LockService lockService = session.getRepositoryImpl().getServiceRegistry().getLockService();
|
|
LockStatus lockStatus = lockService.getLockStatus(getNodeRef());
|
|
return lockStatus.equals(LockStatus.LOCK_OWNER) || lockStatus.equals(LockStatus.LOCKED);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Item#getName()
|
|
*/
|
|
public String getName() throws RepositoryException
|
|
{
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(nodeRef);
|
|
QName childName = parentAssoc.getQName();
|
|
return (childName == null) ? "" : childName.toPrefixString(session.getNamespaceResolver());
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Item#isNode()
|
|
*/
|
|
public boolean isNode()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Item#getParent()
|
|
*/
|
|
public Node getParent() throws ItemNotFoundException, AccessDeniedException, RepositoryException
|
|
{
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(nodeRef);
|
|
if (parentAssoc == null || parentAssoc.getParentRef() == null)
|
|
{
|
|
// TODO: Distinguish between ItemNotFound and AccessDenied
|
|
throw new ItemNotFoundException("Parent of node " + nodeRef + " does not exist.");
|
|
}
|
|
NodeImpl nodeImpl = new NodeImpl(session, parentAssoc.getParentRef());
|
|
return nodeImpl.getProxy();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Item#getPath()
|
|
*/
|
|
public String getPath() throws RepositoryException
|
|
{
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
SearchService searchService = session.getRepositoryImpl().getServiceRegistry().getSearchService();
|
|
Path path = nodeService.getPath(nodeRef);
|
|
|
|
// Add indexes for same name siblings
|
|
// TODO: Look at more efficient approach
|
|
for (int i = path.size() - 1; i >= 0; i--)
|
|
{
|
|
Path.Element pathElement = path.get(i);
|
|
if (i > 0 && pathElement instanceof Path.ChildAssocElement)
|
|
{
|
|
int index = 1;
|
|
String searchPath = path.subPath(i).toPrefixString(session.getNamespaceResolver());
|
|
List<NodeRef> siblings = searchService.selectNodes(nodeRef, searchPath, null, session.getNamespaceResolver(), false);
|
|
if (siblings.size() > 1)
|
|
{
|
|
ChildAssociationRef childAssoc = ((Path.ChildAssocElement)pathElement).getRef();
|
|
NodeRef childRef = childAssoc.getChildRef();
|
|
for (NodeRef sibling : siblings)
|
|
{
|
|
if (sibling.equals(childRef))
|
|
{
|
|
childAssoc.setNthSibling(index);
|
|
break;
|
|
}
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return path.toPrefixString(session.getNamespaceResolver());
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Item#getDepth()
|
|
*/
|
|
public int getDepth() throws RepositoryException
|
|
{
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
Path path = nodeService.getPath(nodeRef);
|
|
// Note: Root is at depth 0
|
|
return path.size() -1;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Item#getAncestor(int)
|
|
*/
|
|
public Item getAncestor(int depth) throws ItemNotFoundException, AccessDeniedException, RepositoryException
|
|
{
|
|
// Retrieve primary parent path for node
|
|
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
|
|
Path path = nodeService.getPath(nodeRef);
|
|
if (depth < 0 || depth > (path.size() - 1))
|
|
{
|
|
throw new ItemNotFoundException("Ancestor at depth " + depth + " not found for node " + nodeRef);
|
|
}
|
|
|
|
// Extract path element at requested depth
|
|
Element element = path.get(depth);
|
|
if (!(element instanceof Path.ChildAssocElement))
|
|
{
|
|
throw new RepositoryException("Path element at depth " + depth + " is not a node");
|
|
}
|
|
Path.ChildAssocElement childAssocElement = (Path.ChildAssocElement)element;
|
|
|
|
// Create node
|
|
NodeRef ancestorNodeRef = childAssocElement.getRef().getChildRef();
|
|
NodeImpl nodeImpl = new NodeImpl(session, ancestorNodeRef);
|
|
return nodeImpl.getProxy();
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Item#isSame(javax.jcr.Item)
|
|
*/
|
|
public boolean isSame(Item otherItem) throws RepositoryException
|
|
{
|
|
return getProxy().equals(otherItem);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see javax.jcr.Item#accept(javax.jcr.ItemVisitor)
|
|
*/
|
|
public void accept(ItemVisitor visitor) throws RepositoryException
|
|
{
|
|
visitor.visit(getProxy());
|
|
}
|
|
|
|
/**
|
|
* Gets the Alfresco Node Reference
|
|
*
|
|
* @return the node reference
|
|
*/
|
|
public NodeRef getNodeRef()
|
|
{
|
|
return nodeRef;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj)
|
|
{
|
|
if (obj == this)
|
|
{
|
|
return true;
|
|
}
|
|
if (!(obj instanceof NodeImpl))
|
|
{
|
|
return false;
|
|
}
|
|
NodeImpl other = (NodeImpl)obj;
|
|
return this.nodeRef.equals(other.nodeRef);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode()
|
|
{
|
|
return nodeRef.hashCode();
|
|
}
|
|
|
|
}
|