Kevin Roast d03bc33acb . Moved avm specific types from ContentModel (cm) into WCMModel (wcm)
. Updated appropriate AVM and client classes to use new types
. Updated application types to derive from wcm types
NOTE: You will need a new database - this is NOT backward compatible with current websites!

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@4022 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2006-10-04 16:39:26 +00:00

1582 lines
62 KiB
Java

/*
* Copyright (C) 2006 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.repo.avm;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMModel;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.node.AbstractNodeServiceImpl;
import org.alfresco.service.cmr.avm.AVMException;
import org.alfresco.service.cmr.avm.AVMExistsException;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMNotFoundException;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.InvalidAspectException;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.AssociationExistsException;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.CyclicChildRelationshipException;
import org.alfresco.service.cmr.repository.InvalidChildAssociationRefException;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.InvalidStoreRefException;
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.StoreExistsException;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.QNamePattern;
import org.alfresco.util.Pair;
import org.apache.log4j.Logger;
/**
* NodeService implementing facade over AVMService.
* @author britt
*/
public class AVMNodeService extends AbstractNodeServiceImpl implements NodeService
{
private static Logger fgLogger = Logger.getLogger(AVMNodeService.class);
/**
* Reference to AVMService.
*/
private AVMService fAVMService;
/**
* Set the AVMService. For Spring.
* @param service The AVMService instance.
*/
public void setAvmService(AVMService service)
{
fAVMService = service;
}
/**
* Default constructor.
*/
public AVMNodeService()
{
}
/**
* Gets a list of all available node store references
*
* @return Returns a list of store references
*/
public List<StoreRef> getStores()
{
// For AVM stores we fake up StoreRefs.
List<AVMStoreDescriptor> stores = fAVMService.getAVMStores();
List<StoreRef> result = new ArrayList<StoreRef>();
for (AVMStoreDescriptor desc : stores)
{
String name = desc.getName();
result.add(new StoreRef(StoreRef.PROTOCOL_AVM, name));
}
return result;
}
/**
* Create a new AVM store.
* @param protocol the implementation protocol
* @param identifier the protocol-specific identifier
* @return Returns a reference to the store
* @throws StoreExistsException
*/
public StoreRef createStore(String protocol, String identifier) throws StoreExistsException
{
StoreRef result = new StoreRef(StoreRef.PROTOCOL_AVM, identifier);
// invokeBeforeCreateStore(ContentModel.TYPE_STOREROOT, result);
try
{
fAVMService.createAVMStore(identifier);
NodeRef rootRef = getRootNode(result);
addAspect(rootRef, ContentModel.ASPECT_ROOT,
Collections.<QName, Serializable>emptyMap());
// invokeOnCreateStore(rootRef);
return result;
}
catch (AVMExistsException e)
{
throw new StoreExistsException("AVMStore exists", result);
}
}
/**
* Does the indicated store exist?
* @param storeRef a reference to the store to look for
* @return Returns true if the store exists, otherwise false
*/
public boolean exists(StoreRef storeRef)
{
return fAVMService.getAVMStore(storeRef.getIdentifier()) != null;
}
/**
* @param nodeRef a reference to the node to look for
* @return Returns true if the node exists, otherwise false
*/
public boolean exists(NodeRef nodeRef)
{
Pair<Integer, String> avmInfo = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmInfo.getFirst();
String avmPath = avmInfo.getSecond();
return fAVMService.lookup(version, avmPath) != null;
}
/**
* Gets the ID of the last transaction that caused the node to change. This includes
* deletions, so it is possible that the node being referenced no longer exists.
* If the node never existed, then null is returned.
*
* @param nodeRef a reference to a current or previously existing node
* @return Returns the status of the node, or null if the node never existed
*/
public NodeRef.Status getNodeStatus(NodeRef nodeRef)
{
// TODO Need to find out if this is important and if so
// need to capture Transaction IDs.
return new NodeRef.Status("Unknown", !exists(nodeRef));
}
/**
* @param storeRef a reference to an existing store
* @return Returns a reference to the root node of the store
* @throws InvalidStoreRefException if the store could not be found
*/
public NodeRef getRootNode(StoreRef storeRef) throws InvalidStoreRefException
{
String storeName = storeRef.getIdentifier();
if (fAVMService.getAVMStore(storeName) != null)
{
return AVMNodeConverter.ToNodeRef(-1, storeName + ":/");
}
else
{
throw new InvalidStoreRefException("Not Found.", storeRef);
}
}
/**
* @see #createNode(NodeRef, QName, QName, QName, Map)
*/
public ChildAssociationRef createNode(
NodeRef parentRef,
QName assocTypeQName,
QName assocQName,
QName nodeTypeQName)
throws InvalidNodeRefException, InvalidTypeException
{
return createNode(parentRef,
assocTypeQName,
assocQName,
nodeTypeQName,
new HashMap<QName, Serializable>());
}
/**
* Creates a new, non-abstract, real node as a primary child of the given parent node.
*
* @param parentRef the parent node
* @param assocTypeQName the type of the association to create. This is used
* for verification against the data dictionary.
* @param assocQName the qualified name of the association
* @param nodeTypeQName a reference to the node type
* @param properties optional map of properties to keyed by their qualified names
* @return Returns a reference to the newly created child association
* @throws InvalidNodeRefException if the parent reference is invalid
* @throws InvalidTypeException if the node type reference is not recognised
*
* @see org.alfresco.service.cmr.dictionary.DictionaryService
*/
public ChildAssociationRef createNode(
NodeRef parentRef,
QName assocTypeQName,
QName assocQName,
QName nodeTypeQName,
Map<QName, Serializable> properties)
throws InvalidNodeRefException, InvalidTypeException
{
// AVM stores only allow simple child associations.
if (!assocTypeQName.equals(ContentModel.ASSOC_CONTAINS))
{
throw new InvalidTypeException(assocTypeQName);
}
String nodeName = assocQName.getLocalName();
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef);
int version = avmVersionPath.getFirst();
if (version >= 0)
{
throw new InvalidNodeRefException("Read only store.", parentRef);
}
String avmPath = avmVersionPath.getSecond();
// Invoke policy behavior.
// invokeBeforeUpdateNode(parentRef);
// invokeBeforeCreateNode(parentRef, assocTypeQName, assocQName, nodeTypeQName);
// Look up the type definition in the dictionary.
TypeDefinition nodeTypeDef = dictionaryService.getType(nodeTypeQName);
// Do the creates for supported types, or error out.
try
{
if (nodeTypeQName.equals(WCMModel.TYPE_AVM_PLAIN_FOLDER) ||
nodeTypeQName.equals(ContentModel.TYPE_FOLDER))
{
fAVMService.createDirectory(avmPath, nodeName);
}
else if (nodeTypeQName.equals(WCMModel.TYPE_AVM_PLAIN_CONTENT) ||
nodeTypeQName.equals(ContentModel.TYPE_CONTENT))
{
fAVMService.createFile(avmPath, nodeName);
}
else if (nodeTypeQName.equals(WCMModel.TYPE_AVM_LAYERED_CONTENT))
{
NodeRef indirection = (NodeRef)properties.get(WCMModel.PROP_AVM_FILE_INDIRECTION);
if (indirection == null)
{
throw new InvalidTypeException("No Indirection Property", nodeTypeQName);
}
Pair<Integer, String> indVersionPath = AVMNodeConverter.ToAVMVersionPath(indirection);
fAVMService.createLayeredFile(indVersionPath.getSecond(), avmPath, nodeName);
}
else if (nodeTypeQName.equals(WCMModel.TYPE_AVM_LAYERED_FOLDER))
{
NodeRef indirection = (NodeRef)properties.get(WCMModel.PROP_AVM_DIR_INDIRECTION);
if (indirection == null)
{
throw new InvalidTypeException("No Indirection Property.", nodeTypeQName);
}
Pair<Integer, String> indVersionPath = AVMNodeConverter.ToAVMVersionPath(indirection);
fAVMService.createLayeredDirectory(indVersionPath.getSecond(), avmPath, nodeName);
}
else
{
throw new InvalidTypeException("Invalid node type for AVM.", nodeTypeQName);
}
addDefaultPropertyValues(nodeTypeDef, properties);
addDefaultAspects(nodeTypeDef, avmPath, properties);
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException("Not Found.", parentRef);
}
catch (AVMExistsException e)
{
throw new InvalidNodeRefException("Child " + nodeName + " exists", parentRef);
}
String newAVMPath = AVMNodeConverter.ExtendAVMPath(avmPath, nodeName);
NodeRef childRef = AVMNodeConverter.ToNodeRef(-1, newAVMPath);
addDefaultPropertyValues(nodeTypeDef, properties);
addDefaultAspects(nodeTypeDef, newAVMPath, properties);
Map<QName, PropertyValue> props = new HashMap<QName, PropertyValue>();
for (QName qname : properties.keySet())
{
if (isBuiltInProperty(qname))
{
continue;
}
props.put(qname, new PropertyValue(null, properties.get(qname)));
}
fAVMService.setNodeProperties(newAVMPath, props);
ChildAssociationRef ref =
new ChildAssociationRef(assocTypeQName,
parentRef,
assocQName,
childRef,
true,
-1);
// invokeOnCreateNode(ref);
// invokeOnUpdateNode(parentRef);
// if (properties.size() != 0)
// {
// invokeOnUpdateProperties(childRef, new HashMap<QName, Serializable>(), properties);
// }
return ref;
}
/**
* Moves the primary location of the given node.
* <p>
* This involves changing the node's primary parent and possibly the name of the
* association referencing it.
* <p>
* If the new parent is in a different store from the original, then the entire
* node hierarchy is moved to the new store. Inter-store associations are not
* affected.
*
* @param nodeToMoveRef the node to move
* @param newParentRef the new parent of the moved node
* @param assocTypeQName the type of the association to create. This is used
* for verification against the data dictionary.
* @param assocQName the qualified name of the new child association
* @return Returns a reference to the newly created child association
* @throws InvalidNodeRefException if either the parent node or move node reference is invalid
* @throws CyclicChildRelationshipException if the child partakes in a cyclic relationship after the add
*
* @see #getPrimaryParent(NodeRef)
*/
public ChildAssociationRef moveNode(
NodeRef nodeToMoveRef,
NodeRef newParentRef,
QName assocTypeQName,
QName assocQName)
throws InvalidNodeRefException
{
// AVM stores only allow simple child associations.
if (!assocTypeQName.equals(ContentModel.ASSOC_CONTAINS))
{
throw new InvalidTypeException(assocTypeQName);
}
// Extract the parts from the source.
Pair<Integer, String> src = AVMNodeConverter.ToAVMVersionPath(nodeToMoveRef);
int srcVersion = src.getFirst();
if (srcVersion >= 0)
{
throw new InvalidNodeRefException("Read Only Store.", nodeToMoveRef);
}
String srcPath = src.getSecond();
String [] splitSrc = null;
try
{
splitSrc = AVMNodeConverter.SplitBase(srcPath);
}
catch (AVMException e)
{
throw new InvalidNodeRefException("Invalid src path.", nodeToMoveRef);
}
String srcParent = splitSrc[0];
if (srcParent == null)
{
throw new InvalidNodeRefException("Cannot rename root node.", nodeToMoveRef);
}
String srcName = splitSrc[1];
// Extract and setup the parts of the destination.
Pair<Integer, String> dst = AVMNodeConverter.ToAVMVersionPath(newParentRef);
if (dst.getFirst() >= 0)
{
throw new InvalidNodeRefException("Read Only Store.", newParentRef);
}
String dstParent = dst.getSecond();
String dstName = assocQName.getLocalName();
// TODO Invoke policy behavior. Not quite sure how to translate this.
// NodeRef oldParentRef = AVMNodeConverter.ToNodeRef(-1, srcParent);
// ChildAssociationRef oldAssocRef =
// new ChildAssociationRef(assocTypeQName,
// oldParentRef,
// QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, srcName),
// nodeToMoveRef,
// true,
// -1);
// invokeBeforeDeleteChildAssociation(oldAssocRef);
String dstPath = AVMNodeConverter.ExtendAVMPath(dstParent, dstName);
NodeRef newChildRef = AVMNodeConverter.ToNodeRef(-1, dstPath);
// invokeBeforeCreateChildAssociation(newParentRef, newChildRef, assocTypeQName, assocQName);
// invokeBeforeUpdateNode(oldParentRef);
// invokeBeforeUpdateNode(newParentRef);
// Actually perform the rename and return a pseudo
// ChildAssociationRef.
try
{
fAVMService.rename(srcParent, srcName, dstParent, dstName);
ChildAssociationRef newAssocRef =
new ChildAssociationRef(assocTypeQName,
newParentRef,
assocQName,
newChildRef,
true,
-1);
// invokeOnCreateChildAssociation(newAssocRef);
// invokeOnDeleteChildAssociation(oldAssocRef);
// invokeOnUpdateNode(oldParentRef);
// invokeOnUpdateNode(newParentRef);
return newAssocRef;
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException("Non existent node.", nodeToMoveRef);
}
catch (AVMExistsException e)
{
throw new InvalidNodeRefException("Target already exists.", newParentRef);
}
catch (AVMException e)
{
throw new InvalidNodeRefException("Illegal move.", nodeToMoveRef);
}
}
/**
* Set the ordering index of the child association. This affects the ordering of
* of the return values of methods that return a set of children or child
* associations.
*
* @param childAssocRef the child association that must be moved in the order
* @param index an arbitrary index that will affect the return order
*
* @see #getChildAssocs(NodeRef)
* @see #getChildAssocs(NodeRef, QNamePattern, QNamePattern)
* @see ChildAssociationRef#getNthSibling()
*/
public void setChildAssociationIndex(
ChildAssociationRef childAssocRef,
int index)
throws InvalidChildAssociationRefException
{
// TODO We'll keep this a no-op unless there's a
// compelling reason to implement this capability
// for the AVM repository.
}
/**
* @param nodeRef
* @return Returns the type name
* @throws InvalidNodeRefException if the node could not be found
*
* @see org.alfresco.service.cmr.dictionary.DictionaryService
*/
public QName getType(NodeRef nodeRef) throws InvalidNodeRefException
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
AVMNodeDescriptor desc = fAVMService.lookup(avmVersionPath.getFirst(),
avmVersionPath.getSecond());
if (desc == null)
{
throw new InvalidNodeRefException("Not Found.", nodeRef);
}
if (desc.isPlainDirectory())
{
return WCMModel.TYPE_AVM_PLAIN_FOLDER;
}
else if (desc.isPlainFile())
{
return WCMModel.TYPE_AVM_PLAIN_CONTENT;
}
else if (desc.isLayeredDirectory())
{
return WCMModel.TYPE_AVM_LAYERED_FOLDER;
}
else
{
return WCMModel.TYPE_AVM_LAYERED_CONTENT;
}
}
/**
* Re-sets the type of the node. Can be called in order specialise a node to a sub-type.
*
* This should be used with caution since calling it changes the type of the node and thus
* implies a different set of aspects, properties and associations. It is the calling codes
* responsibility to ensure that the node is in a approriate state after changing the type.
*
* @param nodeRef the node reference
* @param typeQName the type QName
*
* @since 1.1
*/
public void setType(NodeRef nodeRef, QName typeQName) throws InvalidNodeRefException
{
throw new UnsupportedOperationException("AVM Types are immutable.");
}
/**
* Applies an aspect to the given node. After this method has been called,
* the node with have all the aspect-related properties present
*
* @param nodeRef
* @param aspectTypeQName the aspect to apply to the node
* @param aspectProperties a minimum of the mandatory properties required for
* the aspect
* @throws InvalidNodeRefException
* @throws InvalidAspectException if the class reference is not to a valid aspect
*
* @see org.alfresco.service.cmr.dictionary.DictionaryService#getAspect(QName)
* @see org.alfresco.service.cmr.dictionary.ClassDefinition#getProperties()
*/
public void addAspect(
NodeRef nodeRef,
QName aspectTypeQName,
Map<QName, Serializable> aspectProperties)
throws InvalidNodeRefException, InvalidAspectException
{
// Check that the aspect exists.
AspectDefinition aspectDef = this.dictionaryService.getAspect(aspectTypeQName);
if (aspectDef == null)
{
throw new InvalidAspectException("The aspect is invalid: " + aspectTypeQName,
aspectTypeQName);
}
// Invoke policy behaviors.
// invokeBeforeUpdateNode(nodeRef);
// invokeBeforeAddAspect(nodeRef, aspectTypeQName);
// Crack the nodeRef.
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmVersionPath.getFirst();
if (version >= 0)
{
throw new InvalidNodeRefException("Read Only node.", nodeRef);
}
String avmPath = avmVersionPath.getSecond();
// Accumulate properties.
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
// Add the supplied properties.
if (aspectProperties != null)
{
properties.putAll(aspectProperties);
}
// Now set any unspecified default properties for the aspect.
addDefaultPropertyValues(aspectDef, properties);
// Now add any cascading aspects.
addDefaultAspects(aspectDef, avmPath, properties);
// Set the property values on the AVM Node.
if (properties.size() != 0)
{
Map<QName, PropertyValue> props = new HashMap<QName, PropertyValue>();
for (Map.Entry<QName, Serializable> entry : properties.entrySet())
{
if (!isBuiltInProperty(entry.getKey()))
{
props.put(entry.getKey(), new PropertyValue(null, entry.getValue()));
}
}
if (props.size() != 0)
{
fAVMService.setNodeProperties(avmPath, props);
}
}
if (isBuiltinAspect(aspectTypeQName))
{
// No more work to do in this case.
return;
}
try
{
fAVMService.addAspect(avmPath, aspectTypeQName);
// Invoke policy behaviors.
// invokeOnUpdateNode(nodeRef);
// invokeOnAddAspect(nodeRef, aspectTypeQName);
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException(nodeRef);
}
}
/**
* Add any aspects that are mandatory for the ClassDefinition.
* @param classDef The ClassDefinition.
* @param path The path to the AVMNode.
* @param properties The in/out map of accumulated properties.
*/
private void addDefaultAspects(ClassDefinition classDef, String path,
Map<QName, Serializable> properties)
{
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, path);
// Get mandatory aspects.
List<AspectDefinition> defaultAspectDefs = classDef.getDefaultAspects();
// add all the aspects (and there dependent aspects recursively).
for (AspectDefinition def : defaultAspectDefs)
{
// invokeBeforeAddAspect(nodeRef, def.getName());
addAspect(nodeRef, def.getName(), Collections.<QName, Serializable>emptyMap());
addDefaultPropertyValues(def, properties);
// invokeOnAddAspect(nodeRef, def.getName());
// recurse
addDefaultAspects(def, path, properties);
}
}
/**
* Remove an aspect and all related properties from a node
*
* @param nodeRef
* @param aspectTypeQName the type of aspect to remove
* @throws InvalidNodeRefException if the node could not be found
* @throws InvalidAspectException if the the aspect is unknown or if the
* aspect is mandatory for the <b>class</b> of the <b>node</b>
*/
public void removeAspect(NodeRef nodeRef, QName aspectTypeQName)
throws InvalidNodeRefException, InvalidAspectException
{
// Invoke policy behaviors.
// invokeBeforeUpdateNode(nodeRef);
// invokeBeforeRemoveAspect(nodeRef, aspectTypeQName);
AspectDefinition def = dictionaryService.getAspect(aspectTypeQName);
if (def == null)
{
throw new InvalidAspectException(aspectTypeQName);
}
if (isBuiltinAspect(aspectTypeQName))
{
// TODO shouldn't we be throwing some kind of exception here.
return;
}
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmVersionPath.getFirst();
if (version >= 0)
{
throw new InvalidNodeRefException("Read Only Node.", nodeRef);
}
String path = avmVersionPath.getSecond();
try
{
if (fAVMService.hasAspect(-1, path, aspectTypeQName))
{
fAVMService.removeAspect(path, aspectTypeQName);
Map<QName, PropertyDefinition> propDefs = def.getProperties();
for (QName propertyName : propDefs.keySet())
{
fAVMService.deleteNodeProperty(path, propertyName);
}
}
// Invoke policy behaviors.
// invokeOnUpdateNode(nodeRef);
// invokeOnRemoveAspect(nodeRef, aspectTypeQName);
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException(nodeRef);
}
}
/**
* Determines if a given aspect is present on a node. Aspects may only be
* removed if they are <b>NOT</b> mandatory.
*
* @param nodeRef
* @param aspectTypeQName
* @return Returns true if the aspect has been applied to the given node,
* otherwise false
* @throws InvalidNodeRefException if the node could not be found
* @throws InvalidAspectException if the aspect reference is invalid
*/
public boolean hasAspect(NodeRef nodeRef, QName aspectTypeQName)
throws InvalidNodeRefException, InvalidAspectException
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmVersionPath.getFirst();
String path = avmVersionPath.getSecond();
if (isBuiltinAspect(aspectTypeQName))
{
return true;
}
try
{
return fAVMService.hasAspect(version, path, aspectTypeQName);
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException(nodeRef);
}
}
private static QName [] fgBuiltinAspects = new QName[] { ContentModel.ASPECT_AUDITABLE,
ContentModel.ASPECT_REFERENCEABLE };
private boolean isBuiltinAspect(QName aspectQName)
{
for (QName builtin : fgBuiltinAspects)
{
if (builtin.equals(aspectQName))
{
return true;
}
}
return false;
}
/**
* @param nodeRef
* @return Returns a set of all aspects applied to the node, including mandatory
* aspects
* @throws InvalidNodeRefException if the node could not be found
*/
public Set<QName> getAspects(NodeRef nodeRef) throws InvalidNodeRefException
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmVersionPath.getFirst();
String path = avmVersionPath.getSecond();
Set<QName> result = new HashSet<QName>();
// Add the builtin ones.
for (QName name : fgBuiltinAspects)
{
result.add(name);
}
try
{
List<QName> aspects = fAVMService.getAspects(version, path);
for (QName name : aspects)
{
result.add(name);
}
return result;
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException(nodeRef);
}
}
/**
* Deletes the given node.
* <p>
* All associations (both children and regular node associations)
* will be deleted, and where the given node is the primary parent,
* the children will also be cascade deleted.
*
* @param nodeRef reference to a node within a store
* @throws InvalidNodeRefException if the reference given is invalid
*/
public void deleteNode(NodeRef nodeRef) throws InvalidNodeRefException
{
// Invoke policy behaviors.
// invokeBeforeDeleteNode(nodeRef);
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
if (avmVersionPath.getFirst() != -1)
{
throw new InvalidNodeRefException("Read only store.", nodeRef);
}
String [] avmPathBase = AVMNodeConverter.SplitBase(avmVersionPath.getSecond());
if (avmPathBase[0] == null)
{
throw new InvalidNodeRefException("Cannot delete root node.", nodeRef);
}
try
{
// QName nodeTypeQName = getType(nodeRef);
// Set<QName> aspects = getAspects(nodeRef);
fAVMService.removeNode(avmPathBase[0], avmPathBase[1]);
// ChildAssociationRef childAssocRef =
// new ChildAssociationRef(ContentModel.ASSOC_CHILDREN,
// AVMNodeConverter.ToNodeRef(-1, avmPathBase[0]),
// QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
// avmPathBase[1]),
// nodeRef);
// invokeOnDeleteNode(childAssocRef, nodeTypeQName, aspects, false);
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException("Not Found.", nodeRef);
}
}
/**
* Makes a parent-child association between the given nodes. Both nodes must belong to the same store.
* <p>
*
* @param parentRef
* @param childRef
* @param assocTypeQName the qualified name of the association type as defined in the datadictionary
* @param qname the qualified name of the association
* @return Returns a reference to the newly created child association
* @throws InvalidNodeRefException if the parent or child nodes could not be found
* @throws CyclicChildRelationshipException if the child partakes in a cyclic relationship after the add
*/
public ChildAssociationRef addChild(
NodeRef parentRef,
NodeRef childRef,
QName assocTypeQName,
QName qname) throws InvalidNodeRefException
{
Pair<Integer, String> childVersionPath = AVMNodeConverter.ToAVMVersionPath(childRef);
AVMNodeDescriptor child = fAVMService.lookup(childVersionPath.getFirst(),
childVersionPath.getSecond());
if (child == null)
{
throw new InvalidNodeRefException("Not Found.", childRef);
}
Pair<Integer, String> parentVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef);
if (parentVersionPath.getFirst() >= 0)
{
throw new InvalidNodeRefException("Read Only.", parentRef);
}
try
{
fAVMService.link(parentVersionPath.getSecond(), qname.getLocalName(), child);
ChildAssociationRef newChild =
new ChildAssociationRef(assocTypeQName, parentRef, qname,
AVMNodeConverter.ToNodeRef(-1,
AVMNodeConverter.ExtendAVMPath(parentVersionPath.getSecond(), qname.getLocalName())));
return newChild;
}
catch (AVMException e)
{
throw new InvalidNodeRefException("Could not link.", childRef);
}
}
/**
* Severs all parent-child relationships between two nodes.
* <p>
* The child node will be cascade deleted if one of the associations was the
* primary association, i.e. the one with which the child node was created.
*
* @param parentRef the parent end of the association
* @param childRef the child end of the association
* @throws InvalidNodeRefException if the parent or child nodes could not be found
*/
public void removeChild(NodeRef parentRef, NodeRef childRef) throws InvalidNodeRefException
{
Pair<Integer, String> parentVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef);
if (parentVersionPath.getFirst() >= 0)
{
throw new InvalidNodeRefException("Read only store.", parentRef);
}
Pair<Integer, String> childVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef);
if (childVersionPath.getFirst() >= 0)
{
throw new InvalidNodeRefException("Read only store.", childRef);
}
String parentPath = parentVersionPath.getSecond();
String childPath = childVersionPath.getSecond();
String [] childPathBase = AVMNodeConverter.SplitBase(childPath);
if (childPathBase[0] == null || !childPathBase[0].equals(parentPath))
{
throw new InvalidNodeRefException("Not a child.", childRef);
}
try
{
// ChildAssociationRef assocRef =
// new ChildAssociationRef(ContentModel.ASSOC_CHILDREN,
// AVMNodeConverter.ToNodeRef(-1, parentPath),
// QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
// childPathBase[1]),
// AVMNodeConverter.ToNodeRef(-1, childPath));
// invokeBeforeDeleteChildAssociation(assocRef);
fAVMService.removeNode(childPathBase[0], childPathBase[1]);
// invokeOnDeleteChildAssociation(assocRef);
// invokeOnUpdateNode(AVMNodeConverter.ToNodeRef(-1, parentPath));
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException("Not found.", childRef);
}
}
/**
* @param nodeRef
* @return Returns all properties keyed by their qualified name
* @throws InvalidNodeRefException if the node could not be found
*/
public Map<QName, Serializable> getProperties(NodeRef nodeRef) throws InvalidNodeRefException
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
Map<QName, PropertyValue> props = null;
AVMNodeDescriptor desc = fAVMService.lookup(avmVersionPath.getFirst(),
avmVersionPath.getSecond());
try
{
props = fAVMService.getNodeProperties(avmVersionPath.getFirst(),
avmVersionPath.getSecond());
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException("Not Found.", nodeRef);
}
Map<QName, Serializable> result = new HashMap<QName, Serializable>();
for (QName qName : props.keySet())
{
PropertyValue value = props.get(qName);
PropertyDefinition def = dictionaryService.getProperty(qName);
result.put(qName, makeSerializableValue(def, value));
}
// Now spoof properties that are built in.
result.put(ContentModel.PROP_CREATED, new Date(desc.getCreateDate()));
result.put(ContentModel.PROP_CREATOR, desc.getCreator());
result.put(ContentModel.PROP_MODIFIED, new Date(desc.getModDate()));
result.put(ContentModel.PROP_MODIFIER, desc.getLastModifier());
result.put(ContentModel.PROP_OWNER, desc.getOwner());
result.put(ContentModel.PROP_NAME, desc.getName());
result.put(ContentModel.PROP_NODE_UUID, "UNKNOWN");
result.put(ContentModel.PROP_NODE_DBID, new Long(desc.getId()));
result.put(ContentModel.PROP_STORE_PROTOCOL, "avm");
result.put(ContentModel.PROP_STORE_IDENTIFIER, nodeRef.getStoreRef().getIdentifier());
if (desc.isLayeredDirectory())
{
result.put(WCMModel.PROP_AVM_DIR_INDIRECTION,
AVMNodeConverter.ToNodeRef(-1, desc.getIndirection()));
}
if (desc.isLayeredFile())
{
result.put(WCMModel.PROP_AVM_FILE_INDIRECTION,
AVMNodeConverter.ToNodeRef(-1, desc.getIndirection()));
}
if (desc.isFile())
{
try
{
ContentData contentData = fAVMService.getContentDataForRead(avmVersionPath.getFirst(),
avmVersionPath.getSecond());
result.put(ContentModel.PROP_CONTENT, contentData);
}
catch (AVMException e)
{
// TODO For now ignore.
}
}
return result;
}
/**
* @param nodeRef
* @param qname the qualified name of the property
* @return Returns the value of the property, or null if not yet set
* @throws InvalidNodeRefException if the node could not be found
*/
public Serializable getProperty(NodeRef nodeRef, QName qname) throws InvalidNodeRefException
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
if (isBuiltInProperty(qname))
{
return getBuiltInProperty(avmVersionPath, qname, nodeRef);
}
try
{
PropertyValue value = fAVMService.getNodeProperty(avmVersionPath.getFirst(),
avmVersionPath.getSecond(),
qname);
if (value == null)
{
return null;
}
PropertyDefinition def = this.dictionaryService.getProperty(qname);
return makeSerializableValue(def, value);
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException("Not Found.", nodeRef);
}
}
/**
* A Helper to spoof built in properties.
* @param avmVersionPath The broken out version and path from a NodeRef.
* @param qName The name of the property to retrieve.
* @param nodeRef The original NodeRef (for error reporting).
* @return The property value.
*/
private Serializable getBuiltInProperty(Pair<Integer, String> avmVersionPath,
QName qName,
NodeRef nodeRef)
{
if (qName.equals(ContentModel.PROP_CONTENT))
{
try
{
ContentData contentData =
fAVMService.getContentDataForRead(avmVersionPath.getFirst(),
avmVersionPath.getSecond());
return contentData;
}
catch (AVMException e)
{
// TODO This seems very wrong. Do something better
// sooner rather than later.
return null;
}
}
AVMNodeDescriptor desc = fAVMService.lookup(avmVersionPath.getFirst(),
avmVersionPath.getSecond());
if (desc == null)
{
throw new InvalidNodeRefException("Not Found.", nodeRef);
}
if (qName.equals(ContentModel.PROP_CREATED))
{
return new Date(desc.getCreateDate());
}
else if (qName.equals(ContentModel.PROP_CREATOR))
{
return desc.getCreator();
}
else if (qName.equals(ContentModel.PROP_MODIFIED))
{
return new Date(desc.getModDate());
}
else if (qName.equals(ContentModel.PROP_MODIFIER))
{
return desc.getLastModifier();
}
else if (qName.equals(ContentModel.PROP_OWNER))
{
return desc.getOwner();
}
else if (qName.equals(ContentModel.PROP_NAME))
{
return desc.getName();
}
else if (qName.equals(ContentModel.PROP_NODE_UUID))
{
return "UNKNOWN";
}
else if (qName.equals(ContentModel.PROP_NODE_DBID))
{
return new Long(desc.getId());
}
else if (qName.equals(ContentModel.PROP_STORE_PROTOCOL))
{
return "avm";
}
else if (qName.equals(ContentModel.PROP_STORE_IDENTIFIER))
{
return nodeRef.getStoreRef().getIdentifier();
}
else if (qName.equals(WCMModel.PROP_AVM_DIR_INDIRECTION))
{
if (desc.isLayeredDirectory())
{
return AVMNodeConverter.ToNodeRef(-1, desc.getIndirection());
}
return null;
}
else if (qName.equals(WCMModel.PROP_AVM_FILE_INDIRECTION))
{
if (desc.isLayeredFile())
{
return AVMNodeConverter.ToNodeRef(-1, desc.getIndirection());
}
return null;
}
else
{
fgLogger.error("Invalid Built In Property: " + qName);
return null;
}
}
/**
* Set the values of all properties to be an <code>Serializable</code> instances.
* The properties given must still fulfill the requirements of the class and
* aspects relevant to the node.
* <p>
* <b>NOTE:</b> Null values <u>are</u> allowed.
*
* @param nodeRef
* @param properties all the properties of the node keyed by their qualified names
* @throws InvalidNodeRefException if the node could not be found
*/
public void setProperties(NodeRef nodeRef, Map<QName, Serializable> properties) throws InvalidNodeRefException
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
if (avmVersionPath.getFirst() >= 0)
{
throw new InvalidNodeRefException("Read only store.", nodeRef);
}
// TODO Not sure this try block is necessary.
try
{
// Invoke policy behaviors.
// invokeBeforeUpdateNode(nodeRef);
// Map<QName, Serializable> oldProps = getProperties(nodeRef);
fAVMService.deleteNodeProperties(avmVersionPath.getSecond());
Map<QName, PropertyValue> values = new HashMap<QName, PropertyValue>();
for (QName qName : properties.keySet())
{
// For AVM nodes is in place.
if (isBuiltInProperty(qName))
{
if (qName.equals(ContentModel.PROP_CONTENT))
{
AVMNodeDescriptor desc = fAVMService.lookup(-1, avmVersionPath.getSecond());
if (desc == null)
{
throw new InvalidNodeRefException("Not Found.", nodeRef);
}
if (desc.isPlainFile())
{
fAVMService.setContentData(avmVersionPath.getSecond(),
(ContentData)properties.get(qName));
}
}
}
values.put(qName, new PropertyValue(null, properties.get(qName)));
}
fAVMService.setNodeProperties(avmVersionPath.getSecond(), values);
// Invoke policy behaviors.
// invokeOnUpdateNode(nodeRef);
// invokeOnUpdateProperties(nodeRef, oldProps, properties);
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException("Not Found.", nodeRef);
}
}
static QName [] fgBuiltinProperties = new QName []
{
ContentModel.PROP_CREATED,
ContentModel.PROP_CREATOR,
ContentModel.PROP_MODIFIED,
ContentModel.PROP_MODIFIER,
ContentModel.PROP_OWNER,
ContentModel.PROP_CONTENT,
ContentModel.PROP_NAME,
ContentModel.PROP_NODE_UUID,
ContentModel.PROP_NODE_DBID,
ContentModel.PROP_STORE_PROTOCOL,
ContentModel.PROP_STORE_IDENTIFIER,
WCMModel.PROP_AVM_FILE_INDIRECTION,
WCMModel.PROP_AVM_DIR_INDIRECTION
};
/**
* Helper to distinguish built-in from generic properties.
* @param qName The name of the property to check.
* @return Whether <code>qName</code> is a built-in propety.
*/
private boolean isBuiltInProperty(QName qName)
{
for (QName name : fgBuiltinProperties)
{
if (name.equals(qName))
{
return true;
}
}
return false;
}
/**
* Sets the value of a property to be any <code>Serializable</code> instance.
* To remove a property value, use {@link #getProperties(NodeRef)}, remove the
* value and call {@link #setProperties(NodeRef, Map)}.
* <p>
* <b>NOTE:</b> Null values <u>are</u> allowed.
*
* @param nodeRef
* @param qname the fully qualified name of the property
* @param propertyValue the value of the property - never null
* @throws InvalidNodeRefException if the node could not be found
*/
public void setProperty(NodeRef nodeRef, QName qname, Serializable value) throws InvalidNodeRefException
{
// Invoke policy behaviors.
// invokeBeforeUpdateNode(nodeRef);
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
if (avmVersionPath.getFirst() >= 0)
{
throw new InvalidNodeRefException("Read only store.", nodeRef);
}
if (isBuiltInProperty(qname))
{
if (qname.equals(ContentModel.PROP_CONTENT))
{
try
{
fAVMService.setContentData(avmVersionPath.getSecond(), (ContentData)value);
}
catch (ClassCastException e)
{
throw new AVMException("Invalid ContentData.");
}
}
return;
}
try
{
// Map<QName, Serializable> propsBefore = getProperties(nodeRef);
fAVMService.setNodeProperty(avmVersionPath.getSecond(), qname, new PropertyValue(null, value));
// Map<QName, Serializable> propsAfter = getProperties(nodeRef);
// Invoke policy behaviors.
// invokeOnUpdateNode(nodeRef);
// invokeOnUpdateProperties(nodeRef, propsBefore, propsAfter);
}
catch (AVMNotFoundException e)
{
throw new InvalidNodeRefException("Not Found.", nodeRef);
}
}
/**
* @param nodeRef the child node
* @return Returns a list of all parent-child associations that exist where the given
* node is the child
* @throws InvalidNodeRefException if the node could not be found
*
* @see #getParentAssocs(NodeRef, QNamePattern, QNamePattern)
*/
public List<ChildAssociationRef> getParentAssocs(NodeRef nodeRef) throws InvalidNodeRefException
{
// TODO OK, for now we'll simply return the single parent that corresponds
// to the path stuffed in the NodeRef.
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
String path = avmVersionPath.getSecond();
List<ChildAssociationRef> result = new ArrayList<ChildAssociationRef>();
String [] splitPath = AVMNodeConverter.SplitBase(path);
if (splitPath[0] == null)
{
return result;
}
result.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS,
AVMNodeConverter.ToNodeRef(avmVersionPath.getFirst(),
splitPath[0]),
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
splitPath[1]),
nodeRef,
true,
-1));
return result;
}
/**
* Gets all parent associations where the pattern of the association qualified
* name is a match
* <p>
* The resultant list is ordered by (a) explicit index and (b) association creation time.
*
* @param nodeRef the child node
* @param typeQNamePattern the pattern that the type qualified name of the association must match
* @param qnamePattern the pattern that the qnames of the assocs must match
* @return Returns a list of all parent-child associations that exist where the given
* node is the child
* @throws InvalidNodeRefException if the node could not be found
*
* @see ChildAssociationRef#getNthSibling()
* @see #setChildAssociationIndex(ChildAssociationRef, int)
* @see QName
* @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL
*/
public List<ChildAssociationRef> getParentAssocs(NodeRef nodeRef, QNamePattern typeQNamePattern, QNamePattern qnamePattern)
throws InvalidNodeRefException
{
if (!typeQNamePattern.isMatch(ContentModel.ASSOC_CONTAINS))
{
return new ArrayList<ChildAssociationRef>();
}
List<ChildAssociationRef> result = getParentAssocs(nodeRef);
if (result.size() == 0)
{
return result;
}
if (qnamePattern.isMatch(result.get(0).getQName()))
{
return result;
}
return new ArrayList<ChildAssociationRef>();
}
/**
* Get all child associations of the given node.
* <p>
* The resultant list is ordered by (a) explicit index and (b) association creation time.
*
* @param nodeRef the parent node - usually a <b>container</b>
* @return Returns a collection of <code>ChildAssocRef</code> instances. If the
* node is not a <b>container</b> then the result will be empty.
* @throws InvalidNodeRefException if the node could not be found
*
* @see #getChildAssocs(NodeRef, QNamePattern, QNamePattern)
* @see #setChildAssociationIndex(ChildAssociationRef, int)
* @see ChildAssociationRef#getNthSibling()
*/
public List<ChildAssociationRef> getChildAssocs(NodeRef nodeRef) throws InvalidNodeRefException
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmVersionPath.getFirst();
String path = avmVersionPath.getSecond();
List<ChildAssociationRef> result = new ArrayList<ChildAssociationRef>();
SortedMap<String, AVMNodeDescriptor> children = null;
try
{
children =
fAVMService.getDirectoryListing(version,
path);
}
catch (AVMNotFoundException e)
{
return result;
}
for (String name : children.keySet())
{
result.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS,
nodeRef,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
name),
AVMNodeConverter.ToNodeRef(
version,
AVMNodeConverter.ExtendAVMPath(path, name)),
true,
-1));
}
return result;
}
/**
* Gets all child associations where the pattern of the association qualified
* name is a match.
*
* @param nodeRef the parent node - usually a <b>container</b>
* @param typeQNamePattern the pattern that the type qualified name of the association must match
* @param qnamePattern the pattern that the qnames of the assocs must match
* @return Returns a list of <code>ChildAssocRef</code> instances. If the
* node is not a <b>container</b> then the result will be empty.
* @throws InvalidNodeRefException if the node could not be found
*
* @see QName
* @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL
*/
public List<ChildAssociationRef> getChildAssocs(
NodeRef nodeRef,
QNamePattern typeQNamePattern,
QNamePattern qnamePattern)
throws InvalidNodeRefException
{
List<ChildAssociationRef> result = new ArrayList<ChildAssociationRef>();
if (!typeQNamePattern.isMatch(ContentModel.ASSOC_CONTAINS))
{
return result;
}
List<ChildAssociationRef> all = getChildAssocs(nodeRef);
for (ChildAssociationRef child : all)
{
if (!qnamePattern.isMatch(child.getQName()))
{
continue;
}
result.add(child);
}
return result;
}
/**
* Get a child NodeRef by name.
* @param nodeRef The parent node.
* @param assocTypeQName The type of the Child Association.
* @param childName The name of the child to get.
*/
public NodeRef getChildByName(NodeRef nodeRef, QName assocTypeQName, String childName)
{
if (!assocTypeQName.equals(ContentModel.ASSOC_CONTAINS))
{
return null;
}
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
try
{
AVMNodeDescriptor child = fAVMService.lookup(avmVersionPath.getFirst(),
avmVersionPath.getSecond());
if (child == null)
{
return null;
}
return AVMNodeConverter.ToNodeRef(avmVersionPath.getFirst(),
child.getPath());
}
catch (AVMException e)
{
return null;
}
}
/**
* Fetches the primary parent-child relationship.
* <p>
* For a root node, the parent node reference will be null.
*
* @param nodeRef
* @return Returns the primary parent-child association of the node
* @throws InvalidNodeRefException if the node could not be found
*/
public ChildAssociationRef getPrimaryParent(NodeRef nodeRef) throws InvalidNodeRefException
{
List<ChildAssociationRef> parents = getParentAssocs(nodeRef);
if (parents.size() == 0)
{
return new ChildAssociationRef(null, null, null, nodeRef);
}
return parents.get(0);
}
/**
*
* @param sourceRef a reference to a <b>real</b> node
* @param targetRef a reference to a node
* @param assocTypeQName the qualified name of the association type
* @return Returns a reference to the new association
* @throws InvalidNodeRefException if either of the nodes could not be found
* @throws AssociationExistsException
*/
public AssociationRef createAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName)
throws InvalidNodeRefException, AssociationExistsException
{
throw new UnsupportedOperationException("AVM does not support arbitrary associations.");
}
/**
*
* @param sourceRef the associaton source node
* @param targetRef the association target node
* @param assocTypeQName the qualified name of the association type
* @throws InvalidNodeRefException if either of the nodes could not be found
*/
public void removeAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName)
throws InvalidNodeRefException
{
throw new UnsupportedOperationException("AVM does not support arbitrary associations.");
}
/**
* Fetches all associations <i>from</i> the given source where the associations'
* qualified names match the pattern provided.
*
* @param sourceRef the association source
* @param qnamePattern the association qname pattern to match against
* @return Returns a list of <code>NodeAssocRef</code> instances for which the
* given node is a source
* @throws InvalidNodeRefException if the source node could not be found
*
* @see QName
* @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL
*/
public List<AssociationRef> getTargetAssocs(NodeRef sourceRef, QNamePattern qnamePattern)
throws InvalidNodeRefException
{
return new ArrayList<AssociationRef>();
}
/**
* Fetches all associations <i>to</i> the given target where the associations'
* qualified names match the pattern provided.
*
* @param targetRef the association target
* @param qnamePattern the association qname pattern to match against
* @return Returns a list of <code>NodeAssocRef</code> instances for which the
* given node is a target
* @throws InvalidNodeRefException
*
* @see QName
* @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL
*/
public List<AssociationRef> getSourceAssocs(NodeRef targetRef, QNamePattern qnamePattern)
throws InvalidNodeRefException
{
return new ArrayList<AssociationRef>();
}
/**
* The root node has an entry in the path(s) returned. For this reason, there
* will always be <b>at least one</b> path element in the returned path(s).
* The first element will have a null parent reference and qname.
*
* @param nodeRef
* @return Returns the path to the node along the primary node path
* @throws InvalidNodeRefException if the node could not be found
*
* @see #getPaths(NodeRef, boolean)
*/
public Path getPath(NodeRef nodeRef) throws InvalidNodeRefException
{
// TODO Review later. This may be wrong.
Path path = new Path();
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmVersionPath.getFirst();
String currPath = avmVersionPath.getSecond();
while (!currPath.endsWith("/"))
{
String [] splitPath = AVMNodeConverter.SplitBase(currPath);
String parentPath = splitPath[0];
String name = splitPath[1];
ChildAssociationRef caRef =
new ChildAssociationRef(ContentModel.ASSOC_CONTAINS,
AVMNodeConverter.ToNodeRef(version, parentPath),
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
name),
AVMNodeConverter.ToNodeRef(version, currPath),
true,
-1);
path.prepend(new Path.ChildAssocElement(caRef));
currPath = parentPath;
}
ChildAssociationRef caRef = new ChildAssociationRef(null, null, null,
AVMNodeConverter.ToNodeRef(version,
currPath));
path.prepend(new Path.ChildAssocElement(caRef));
return path;
}
/**
* The root node has an entry in the path(s) returned. For this reason, there
* will always be <b>at least one</b> path element in the returned path(s).
* The first element will have a null parent reference and qname.
*
* @param nodeRef
* @param primaryOnly true if only the primary path must be retrieved. If true, the
* result will have exactly one entry.
* @return Returns a List of all possible paths to the given node
* @throws InvalidNodeRefException if the node could not be found
*/
public List<Path> getPaths(NodeRef nodeRef, boolean primaryOnly) throws InvalidNodeRefException
{
List<Path> result = new ArrayList<Path>();
result.add(getPath(nodeRef));
return result;
}
/**
* Get the node where archived items will have gone when deleted from the given store.
*
* @param storeRef the store that items were deleted from
* @return Returns the archive node parent
*/
public NodeRef getStoreArchiveNode(StoreRef storeRef)
{
throw new UnsupportedOperationException("AVM does not support this operation.");
}
/**
* Restore an individual node (along with its sub-tree nodes) to the target location.
* The archived node must have the {@link org.alfresco.model.ContentModel#ASPECT_ARCHIVED archived aspect}
* set against it.
*
* @param archivedNodeRef the archived node
* @param destinationParentNodeRef the parent to move the node into
* or <tt>null</tt> to use the original
* @param assocTypeQName the primary association type name to use in the new location
* or <tt>null</tt> to use the original
* @param assocQName the primary association name to use in the new location
* or <tt>null</tt> to use the original
* @return Returns the reference to the newly created node
*/
public NodeRef restoreNode(
NodeRef archivedNodeRef,
NodeRef destinationParentNodeRef,
QName assocTypeQName,
QName assocQName)
{
throw new UnsupportedOperationException("AVM does not support this operation.");
}
}