Java tutorial
/* * Copyright (C) 2005-2010 Alfresco Software Limited. * * This file is part of Alfresco * * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Alfresco is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */ package org.alfresco.module.phpIntegration.lib; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.alfresco.model.ContentModel; import org.alfresco.module.phpIntegration.PHPProcessor; import org.alfresco.module.phpIntegration.PHPProcessorException; import org.alfresco.repo.jscript.ScriptNode; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.CopyService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.TemplateService; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.version.VersionService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.EqualsHelper; import org.alfresco.util.GUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.caucho.quercus.annotation.Optional; import com.caucho.quercus.env.Env; import com.caucho.quercus.env.NullValue; import com.caucho.quercus.env.Value; /** * Repository node implementation class. * * @author Roy Wetherall */ public class Node implements ScriptObject { /** Logger **/ private static Log logger = LogFactory.getLog(Node.class); /** Script object name */ private static final String SCRIPT_OBJECT_NAME = "Node"; /** New node id delimiter */ private static final String NEW_NODE_DELIM = "new_"; /** Node service */ protected NodeService nodeService; /** Version service */ protected VersionService versionService; /** Template service */ protected TemplateService templateService; /** Session object */ protected Session session; /** Node id */ private String id; /** Node type */ private String type; /** Node store */ private Store store; /** List of nodes aspects (removed and added)*/ private List<String> aspects; private List<String> addedAspects; private List<String> removedAspects; /** Indicates if the properties have been modified */ private boolean arePropertiesDirty = false; private Map<String, Object> properties; private List<ChildAssociation> children; private List<ChildAssociation> addedChildren; private List<ChildAssociation> removedChildren; private List<ChildAssociation> parents; private ChildAssociation primaryParent; private List<Association> associations; private List<Association> addedAssociations; private List<Association> removedAssociations; /** * @see org.alfresco.module.phpIntegration.lib.ScriptObject#getScriptObjectName() */ public String getScriptObjectName() { return SCRIPT_OBJECT_NAME; } /** * Constructor * * @param session the session * @param nodeRef the node reference */ public Node(Session session, NodeRef nodeRef) { // Call the constructor this(session, session.getStoreFromString(nodeRef.getStoreRef().toString()), nodeRef.getId()); } /** * Constructor * * @param session the session * @param store the store * @param id the node id */ public Node(Session session, Store store, String id) { // Call the constructor this(session, store, id, null); } /** * Constructor * * @param session the session * @param store the store * @param id the node id * @param type the node type */ public Node(Session session, Store store, String id, String type) { // Set the attribute details this.session = session; this.store = store; this.id = id; if (type != null) { this.type = type; } // Set the node service this.nodeService = session.getServiceRegistry().getNodeService(); this.versionService = session.getServiceRegistry().getVersionService(); this.templateService = session.getServiceRegistry().getTemplateService(); // Add the node to the session this.session.addNode(this); } /** * Get the node reference that this node represents * * @return the node reference */ public NodeRef getNodeRef() { NodeRef nodeRef = null; if (isNewNode() == false) { nodeRef = new NodeRef(this.store.getStoreRef(), this.id); } return nodeRef; } /** * Get the nodes session * * @return the session */ public Session getSession() { return this.session; } /** * Get the nodes store * * @return the Store */ public Store getStore() { return this.store; } /** * Gets the id of the node * * @return the id of the node */ public String getId() { return this.id; } /** * Gets the type of the node * * @return the node type */ public String getType() { return this.session.doSessionWork(new SessionWork<String>() { public String doWork() { if (Node.this.type == null) { Node.this.type = Node.this.nodeService.getType(getNodeRef()).toString(); } return Node.this.type; } }); } /** * Indicates whether the node is newly created. True if it is yet to be saved, false otherwise. * * @return boolean True if it is a new node, false otherwise. */ public boolean isNewNode() { return this.id.startsWith(NEW_NODE_DELIM); } /** * Get the map of property names and values * * @return a map of property names and values */ public Map<String, Object> getProperties() { // Make sure the properties are populated populateProperties(); // Return the properties return new HashMap<String, Object>(this.properties); } /** * Get the value of a property * * @param propertyName the property name * @return Object the value of the property */ public Object getProperty(String propertyName) { // Get the property value from the property map propertyName = this.session.getNamespaceMap().getFullName(propertyName); Map<String, Object> properties = getProperties(); return properties.get(propertyName); } /** * Set the value of a property * * @param propertyName the property name * @param value the value of the property */ public void setProperty(String propertyName, Object value) { // Get the full name of the property propertyName = this.session.getNamespaceMap().getFullName(propertyName); // Make sure the properties are populated populateProperties(); // Set the value of the property this.properties.put(propertyName, value); this.arePropertiesDirty = true; } /** * Sets the property values for the node * * @param properties a map of property names and values */ public void setProperties(Map<String, Object> properties) { if (logger.isDebugEnabled() == true) { logger.debug("Setting properties on node " + this.getId()); } // Set the property values this.properties = new HashMap<String, Object>(properties); this.arePropertiesDirty = true; } /** * Sets the values of the properties found in the array provided * * @param properties a map of property values */ public void setPropertyValues(Map<String, Object> properties) { // Make sure the properties are populated populateProperties(); // Overwrite/set the properties with the passed property values for (Map.Entry<String, Object> entry : properties.entrySet()) { String fullName = this.session.getNamespaceMap().getFullName(entry.getKey()); this.properties.put(fullName, entry.getValue()); } this.arePropertiesDirty = true; } /** * Call back used to indicate that a content property has been modified directly. */ /*package*/ void contentUpdated() { this.arePropertiesDirty = true; } /** * Gets a list of the node's aspects * * @return List<String> a list of the node aspects */ public List<String> getAspects() { // Check that the aspects have been populated populateAspects(); return this.aspects; } /** * Indicates whether an node has the specified aspect or not. * * @param aspect the aspect type (short names accepted) * @return boolean true if the node has the aspect, false otherwise */ public boolean hasAspect(String aspect) { // Check that the aspects have been populated populateAspects(); // Map aspect name to full name aspect = this.session.getNamespaceMap().getFullName(aspect); // Check to see if the aspect is in the list return this.aspects.contains(aspect); } /** * Adds an aspect to the node * * @param aspect the aspect * @param properties the properties of the aspect */ public void addAspect(String aspect, Map<String, Object> properties) { // Check that the aspects have been populated populateAspects(); // Map aspect name to full name aspect = this.session.getNamespaceMap().getFullName(aspect); // Add the aspect if (this.aspects.contains(aspect) == false) { // Deal with re-added aspects if (this.removedAspects.contains(aspect) == true) { this.removedAspects.remove(aspect); } else { this.addedAspects.add(aspect); } this.aspects.add(aspect); } // Add the properties if (properties != null) { setPropertyValues(properties); } } /** * Removes as aspect from the node. * * @param aspect the aspect */ public void removeAspect(String aspect) { // Check that the aspects have been populated populateAspects(); // Map the aspect name to the correct full name aspect = this.session.getNamespaceMap().getFullName(aspect); // Remove the aspect if (this.aspects.contains(aspect) == true) { if (this.addedAspects.contains(aspect) == true) { this.addedAspects.remove(aspect); } else { this.removedAspects.add(aspect); } this.aspects.remove(aspect); } } /** * Get the child associations of this node * * @return List<ChildAssociation> a list of child associations */ public List<ChildAssociation> getChildren() { // Check the children have been populated populateChildren(); return this.children; } /** * Get the parent associations of this node * * @return List<ChildAssociation> a list of parent assocations */ public List<ChildAssociation> getParents() { // Check that the parents have been populated populateParents(); return this.parents; } /** * Get the primary parent of this node * * @return the primary parent node */ public Node getPrimaryParent() { // Check that the parents have been populated populateParents(); // Return the primary parent of this node return this.primaryParent.getParent(); } /** * Get the associations eminating from this node * * @return List<Association> a list of associations */ public List<Association> getAssociations() { // Check that associations have been populated populateAssociations(); return this.associations; } /** * Updates the content on a content property * * @param property the content property name * @param mimetype the content mimetype * @param encoding the content encoding * @param content the content * @return ContentData the contetn data */ public org.alfresco.module.phpIntegration.lib.ContentData updateContent(String property, String mimetype, String encoding, String content) { // Make sure the properties are populated populateProperties(); // Convert to full name property = this.session.getNamespaceMap().getFullName(property); // Create the content data object org.alfresco.module.phpIntegration.lib.ContentData contentData = new org.alfresco.module.phpIntegration.lib.ContentData( this, property, mimetype, encoding); if (content != null) { contentData.setContent(content); } // Assign to property this.properties.put(property, contentData); return contentData; } /** * Create a new child node * * @param type the type of the node * @param associationType the association type * @param associationName the association name * @return Node the newly create node */ public Node createChild(final String origType, final String origAssociationType, final String origAssociationName) { return this.session.doSessionWork(new SessionWork<Node>() { public Node doWork() { // Convert to full names String type = Node.this.session.getNamespaceMap().getFullName(origType); String associationType = Node.this.session.getNamespaceMap().getFullName(origAssociationType); String associationName = Node.this.session.getNamespaceMap().getFullName(origAssociationName); // Check the children have been populates populateChildren(); // Create the new node String id = NEW_NODE_DELIM + GUID.generate(); // Use the node factory to create the node of the correct type Node newNode = Node.this.session.getNodeFactory().createNode(Node.this.session, getStore(), id, type); // Create the child association object ChildAssociation childAssociation = new ChildAssociation(Node.this, newNode, associationType, associationName, true, 0); // Set the parent array of the node node newNode.parents = new ArrayList<ChildAssociation>(5); newNode.primaryParent = childAssociation; newNode.parents.add(childAssociation); // Add as a child of the parent node Node.this.children.add(childAssociation); Node.this.addedChildren.add(childAssociation); return newNode; } }); } /** * Add a new child to the node. Creates a non-primary child association. * * @param node the child node * @param associationType the association type * @param associationName the association name */ public void addChild(Node node, String associationType, String associationName) { // Convert to full names associationType = this.session.getNamespaceMap().getFullName(associationType); associationName = this.session.getNamespaceMap().getFullName(associationName); // Check that the children have been populated populateChildren(); // Check the parents of the child node have been populated node.populateParents(); // Create the child association ChildAssociation childAssociation = new ChildAssociation(this, node, associationType, associationName, false, 0); // Add to the parent list of the child node node.parents.add(childAssociation); // Add to the child lists of the parent node this.children.add(childAssociation); if (this.removedChildren.contains(childAssociation) == true) { this.removedChildren.remove(childAssociation); } else { this.addedChildren.add(childAssociation); } } /** * Removes a non-primary child association from the node. * * @param childAssociation the child association to remove. */ public void removeChild(ChildAssociation childAssociation) { if (childAssociation.getIsPrimary() == false) { // Check that the children have been populated populateChildren(); if (this.children.contains(childAssociation) == true) { // Check the parents of the child have been populated childAssociation.getChild().populateParents(); // Adjust lists accordingly this.children.remove(childAssociation); childAssociation.getChild().parents.remove(childAssociation); if (this.addedChildren.contains(childAssociation) == true) { this.addedChildren.remove(childAssociation); } else { this.removedChildren.add(childAssociation); } } else { if (logger.isDebugEnabled() == true) { logger.debug("The child association being delete is not present of the node."); } } } else { throw new PHPProcessorException("Cannot remove a primary child association."); } } /** * Adds an association from one node to another. * * @param toNode the destination node * @param associationType the assocation type */ public void addAssociation(Node toNode, String associationType) { // Convert to full name associationType = this.session.getNamespaceMap().getFullName(associationType); // Populate the associations for this node populateAssociations(); // Create the association Association association = new Association(this, toNode, associationType); // Adjust lists accordingly if (removedAssociations.contains(association) == true) { this.removedAssociations.remove(association); } else { this.addedAssociations.add(association); } this.associations.add(association); } /** * Remove an association * * @param association the association */ public void removeAssociation(Association association) { // Populate the associations for this node populateAssociations(); // Adjust lists accordingly if (addedAssociations.contains(association) == true) { this.addedAssociations.remove(association); } else { this.removedAssociations.add(association); } this.associations.remove(association); } /** * Copies the node and optionally all its children, to another destination * * @param destination the destination node * @param associationType the association type * @param associationName the association name * @param copyChildren indicates whether the children of the node should be copied or not * @return Node the newly created copy of the origional node */ public Node copy(final Node destination, final String associationType, final String associationName, final boolean copyChildren) { return this.session.doSessionWork(new SessionWork<Node>() { public Node doWork() { // Get the full names of the association type and name String associationTypeFull = Node.this.session.getNamespaceMap().getFullName(associationType); String associationNameFull = Node.this.session.getNamespaceMap().getFullName(associationName); // Check that the destination node is not an unsaved node if (destination.isDirty() == true) { throw new PHPProcessorException("Can not copy node (" + toString() + ") since there are outstanding modifications that require saving on the destination node (" + destination.toString() + ")"); } // Check whether there are any outstanding changes if (isDirty() == true) { throw new PHPProcessorException("Can not copy node (" + toString() + ") since there are outstanding modifications that require saving"); } // Copy the node CopyService copyService = Node.this.session.getServiceRegistry().getCopyService(); NodeRef nodeRef = copyService.copyAndRename(getNodeRef(), destination.getNodeRef(), QName.createQName(associationTypeFull), QName.createQName(associationNameFull), copyChildren); // To ensure information is up to date, clean the destination node destination.cleanNode(); // Return the newly created node return Node.this.session.getNodeFromString(nodeRef.toString()); } }); } /** * Moves the node from its current primary parent into another. * * @param destination the destination node * @param associationType the assocation type * @param assocationName the association name */ public void move(final Node destination, final String associationType, final String associationName) { this.session.doSessionWork(new SessionWork<Object>() { public Object doWork() { // Get the full names of the assoc type and name String fullAssociationType = Node.this.session.getNamespaceMap().getFullName(associationType); String fullAssociationName = Node.this.session.getNamespaceMap().getFullName(associationName); // Check the current primary parent for modifications Node currentParent = getPrimaryParent(); if (currentParent.isDirty() == true) { throw new PHPProcessorException("Can not move node (" + toString() + ") since there are outstanding modifications that require saving on the current parent node (" + currentParent.toString() + ")"); } // Check that the destination node is not an unsaved node if (destination.isDirty() == true) { throw new PHPProcessorException("Can not move node (" + toString() + ") since there are outstanding modifications that require saving on the destination node (" + destination.toString() + ")"); } // Check whether there are any outstanding changes if (isDirty() == true) { throw new PHPProcessorException("Can not move node (" + toString() + ") since there are outstanding modifications that require saving"); } // Do the move Node.this.nodeService.moveNode(getNodeRef(), destination.getNodeRef(), QName.createQName(fullAssociationType), QName.createQName(fullAssociationName)); // Clean all 3 nodes involved in the mode to ensure no data is out of date currentParent.cleanNode(); destination.cleanNode(); cleanNode(); return null; } }); } /** * Determines whether the current user has specified permissions on the node * * @param permission the permission string * @return boolean true if the user has the permission, false otherwise */ public boolean hasPermission(String permission) { boolean allowed = false; if (permission != null && permission.length() != 0) { if (this.isNewNode() == true) { // Since this is a new node then this user must have created it allowed = true; } else { AccessStatus status = this.session.getServiceRegistry().getPermissionService() .hasPermission(getNodeRef(), permission); allowed = (AccessStatus.ALLOWED == status); } } return allowed; } /** * Indicates whether this node is a sub type of the another type. * * @param subTypeOf is this node a sub type of this type. * @return boolean true if it is, false otherwise */ public boolean isSubTypeOf(String subTypeOf) { return this.session.getDataDictionary().isSubTypeOf(getType(), subTypeOf); } public Version createVersion(@Optional("") final String description, @Optional("false") final boolean major) { // TODO .. figure out how we deep version? // We can only create a version if there are no outstanding changes for this node if (this.isDirty() == true) { throw new PHPProcessorException( "You must save any outstanding modifications before a new version can be created."); } return this.session.doSessionWork(new SessionWork<Version>() { public Version doWork() { // TODO implement major flag ... // - send version type correctly // - set major flag on Version return value creation // Create the new version Map<String, Serializable> versionProperties = new HashMap<String, Serializable>(1); versionProperties.put(org.alfresco.service.cmr.version.Version.PROP_DESCRIPTION, description); org.alfresco.service.cmr.version.Version repoVersion = Node.this.versionService .createVersion(Node.this.getNodeRef(), versionProperties); // Clean the node after the version has been created cleanNode(); // Create the version return Version.createVersion(Node.this.session, repoVersion); } }); } /** * Dynamic implementation of get properties * * @param name the name of the property * @return Value the value of the property */ public Value __getField(Env env, Value name) { Value result = null; String fullName = this.session.getNamespaceMap().getFullName(name.toString()); if (fullName.equals(name) == false) { // Make sure the properties are populated populateProperties(); Object value = this.properties.get(fullName); if (value != null) { result = PHPProcessor.convertToValue(env, this.session, value); } else { result = NullValue.NULL; } } return result; } /** * Dynamic implemenatation of set properties * * @param name the name of the property * @param value the value of the property */ public void __setField(String name, String value) { String fullName = this.session.getNamespaceMap().getFullName(name.toString()); if (fullName.equals(name) == false) { // Make sure the properties are populated populateProperties(); if (logger.isDebugEnabled() == true) { logger.debug("Setting field on node " + this.getId() + " (name=" + fullName + "; value:" + value.toString() + ")"); } // Set the property value this.properties.put(fullName, value); this.arePropertiesDirty = true; } } /** * PHP toString implementation * * @return the node string representation */ public String __toString() { return this.toString(); } /** * @see java.lang.Object#toString() */ @Override public String toString() { return this.store.getScheme() + "://" + this.store.getAddress() + "/" + this.id; } /*package*/ void prepareSave() { // Handle the creation of a new node if (isNewNode() == true) { // Get the primary parent if (this.primaryParent == null) { throw new PHPProcessorException( "Unable to save new node since no valid primary parent has been found."); } // Create the new node ChildAssociationRef childAssocRef = this.nodeService.createNode( this.primaryParent.getParent().getNodeRef(), QName.createQName(this.primaryParent.getType()), QName.createQName(this.primaryParent.getName()), QName.createQName(this.type)); // Set the id of the new node this.id = childAssocRef.getChildRef().getId(); } } /** * Called when the node is saved. Inspects the node and persists any changes as appropriate. */ /*package*/ void onSave() { // Get the node reference NodeRef nodeRef = getNodeRef(); if (this.arePropertiesDirty == true) { // Log details if (logger.isDebugEnabled() == true) { logger.debug("Saving property updates made to node " + this.getId()); } // List of pending content properties to process List<org.alfresco.module.phpIntegration.lib.ContentData> pendingContentProperties = new ArrayList<org.alfresco.module.phpIntegration.lib.ContentData>( 1); // Update the properties Map<QName, Serializable> currentProperties = this.nodeService.getProperties(nodeRef); for (Map.Entry<String, Object> entry : this.properties.entrySet()) { if (entry.getValue() instanceof org.alfresco.module.phpIntegration.lib.ContentData) { // Save the content property org.alfresco.module.phpIntegration.lib.ContentData contentData = (org.alfresco.module.phpIntegration.lib.ContentData) entry .getValue(); pendingContentProperties.add(contentData); } else { Serializable propValue = null; // Get the property definition so we can do the correct conversion QName propertyName = QName.createQName(entry.getKey()); DictionaryService dictionaryService = this.session.getServiceRegistry().getDictionaryService(); PropertyDefinition propDefintion = dictionaryService.getProperty(propertyName); if (propDefintion == null) { // TODO summert here! propValue = (Serializable) entry.getValue(); } else { propValue = (Serializable) DefaultTypeConverter.INSTANCE .convert(propDefintion.getDataType(), entry.getValue()); } // Set the property value in the temp map if (propValue == null || propValue.equals(currentProperties.get(propertyName)) == false) { currentProperties.put(propertyName, propValue); } } } // Set the values of the updated properties this.nodeService.setProperties(nodeRef, currentProperties); // Sort out any pending content properties for (org.alfresco.module.phpIntegration.lib.ContentData contentData : pendingContentProperties) { contentData.onSave(); } } // Update the aspects if (this.addedAspects != null && this.addedAspects.size() != 0) { for (String aspect : this.addedAspects) { this.nodeService.addAspect(nodeRef, QName.createQName(aspect), null); } } if (this.removedAspects != null && this.removedAspects.size() != 0) { for (String aspect : this.removedAspects) { this.nodeService.removeAspect(nodeRef, QName.createQName(aspect)); } } // Update the child associations if (this.addedChildren != null && this.addedChildren.size() != 0) { for (ChildAssociation addedChildAssociation : this.addedChildren) { if (addedChildAssociation.getIsPrimary() == false) { this.nodeService.addChild(nodeRef, addedChildAssociation.getChild().getNodeRef(), QName.createQName(addedChildAssociation.getType()), QName.createQName(addedChildAssociation.getName())); } } } if (this.removedChildren != null && this.removedChildren.size() != 0) { for (ChildAssociation removedChildAssociation : this.removedChildren) { this.nodeService.removeChild(nodeRef, removedChildAssociation.getChild().getNodeRef()); } } // Update the associations if (this.addedAssociations != null && this.addedAssociations.size() != 0) { for (Association addedAssociation : this.addedAssociations) { this.nodeService.createAssociation(nodeRef, addedAssociation.getTo().getNodeRef(), QName.createQName(addedAssociation.getType())); } } if (this.removedAssociations != null && this.removedAssociations.size() != 0) { for (Association removedAssociation : this.removedAssociations) { this.nodeService.removeAssociation(nodeRef, removedAssociation.getTo().getNodeRef(), QName.createQName(removedAssociation.getType())); } } // Refresh the state of the node cleanNode(); } /** * Cleans the nodes cached data and restores it to its initial state */ protected void cleanNode() { if (logger.isDebugEnabled() == true) { logger.debug("Cleaning node " + getId()); } this.properties = null; this.arePropertiesDirty = false; this.aspects = null; this.addedAspects = null; this.removedAspects = null; this.children = null; this.addedChildren = null; this.removedChildren = null; this.parents = null; this.primaryParent = null; this.associations = null; this.addedAssociations = null; this.removedAssociations = null; } private boolean isDirty() { if (logger.isDebugEnabled() == true) { logger.debug("Calling isDrity() for " + getId() + " (isNewNode = " + isNewNode() + "; arePropertiesDirty = " + this.arePropertiesDirty + ")"); } if (isNewNode() == false && this.arePropertiesDirty == false && (this.addedAspects == null || this.addedAspects.size() == 0) && (this.removedAspects == null || this.removedAspects.size() == 0) && (this.addedChildren == null || this.addedChildren.size() == 0) && (this.removedChildren == null || this.removedChildren.size() == 0) && (this.addedAssociations == null || this.addedAssociations.size() == 0) && (this.removedAssociations == null || this.removedAssociations.size() == 0)) { return false; } else { return true; } } /** * Populates the properties of the node */ private void populateProperties() { this.session.doSessionWork(new SessionWork<Object>() { public Object doWork() { if (Node.this.properties == null) { if (logger.isDebugEnabled() == true) { logger.debug("Populating properties for node " + Node.this.getId()); } if (isNewNode() == false) { Map<QName, Serializable> properties = Node.this.nodeService.getProperties(getNodeRef()); Node.this.properties = new HashMap<String, Object>(properties.size()); for (Map.Entry<QName, Serializable> entry : properties.entrySet()) { if (entry.getValue() instanceof ContentData) { if (logger.isDebugEnabled() == true) { logger.debug(" - Found content property " + entry.getKey()); } ContentData value = (ContentData) entry.getValue(); org.alfresco.module.phpIntegration.lib.ContentData contentData = new org.alfresco.module.phpIntegration.lib.ContentData( Node.this, entry.getKey().toString(), value.getMimetype(), value.getEncoding(), value.getSize()); Node.this.properties.put(entry.getKey().toString(), contentData); } else { String value = DefaultTypeConverter.INSTANCE.convert(String.class, entry.getValue()); Node.this.properties.put(entry.getKey().toString(), value); } } } else { Node.this.properties = new HashMap<String, Object>(10); } Node.this.arePropertiesDirty = false; } return null; } }); } /** * Get the list of aspects for this node. * * @return List<String> list containing aspects */ private void populateAspects() { this.session.doSessionWork(new SessionWork<Object>() { public Object doWork() { if (Node.this.aspects == null) { if (isNewNode() == false) { // Populate the aspect list from the node service Set<QName> aspects = Node.this.nodeService.getAspects(getNodeRef()); Node.this.aspects = new ArrayList<String>(aspects.size()); for (QName aspect : aspects) { Node.this.aspects.add(aspect.toString()); } } else { Node.this.aspects = new ArrayList<String>(5); } // Create the list's used to monitor added and deleted aspects Node.this.addedAspects = new ArrayList<String>(); Node.this.removedAspects = new ArrayList<String>(); } return null; } }); } /** * Populates the child information for this node */ private void populateChildren() { this.session.doSessionWork(new SessionWork<Object>() { public Object doWork() { if (Node.this.children == null) { if (isNewNode() == false) { List<ChildAssociationRef> assocs = Node.this.nodeService.getChildAssocs(getNodeRef()); Node.this.children = new ArrayList<ChildAssociation>(assocs.size()); for (ChildAssociationRef assoc : assocs) { Node.this.children.add(new ChildAssociation( Node.this.session.getNodeFromString(assoc.getParentRef().toString()), Node.this.session.getNodeFromString(assoc.getChildRef().toString()), assoc.getTypeQName().toString(), assoc.getQName().toString(), assoc.isPrimary(), assoc.getNthSibling())); } } else { Node.this.children = new ArrayList<ChildAssociation>(10); } // Create the added and removed lists Node.this.addedChildren = new ArrayList<ChildAssociation>(5); Node.this.removedChildren = new ArrayList<ChildAssociation>(5); } return null; } }); } /** * Populates the parent information for this node */ private void populateParents() { this.session.doSessionWork(new SessionWork<Object>() { public Object doWork() { if (Node.this.parents == null) { if (isNewNode() == false) { List<ChildAssociationRef> parents = Node.this.nodeService.getParentAssocs(getNodeRef()); Node.this.parents = new ArrayList<ChildAssociation>(parents.size()); for (ChildAssociationRef assoc : parents) { ChildAssociation childAssociation = new ChildAssociation( Node.this.session.getNodeFromString(assoc.getParentRef().toString()), Node.this.session.getNodeFromString(assoc.getChildRef().toString()), assoc.getTypeQName().toString(), assoc.getQName().toString(), assoc.isPrimary(), assoc.getNthSibling()); Node.this.parents.add(childAssociation); // Set the primary parent when we come across it if (assoc.isPrimary() == true) { Node.this.primaryParent = childAssociation; } } } else { Node.this.parents = new ArrayList<ChildAssociation>(5); } } return null; } }); } /** * Populates the association information for this node */ private void populateAssociations() { this.session.doSessionWork(new SessionWork<Object>() { public Object doWork() { if (Node.this.associations == null) { if (isNewNode() == false) { List<AssociationRef> associations = Node.this.nodeService.getTargetAssocs(getNodeRef(), RegexQNamePattern.MATCH_ALL); Node.this.associations = new ArrayList<Association>(associations.size()); for (AssociationRef association : associations) { Node.this.associations.add(new Association( Node.this.session.getNodeFromString(association.getSourceRef().toString()), Node.this.session.getNodeFromString(association.getTargetRef().toString()), association.getTypeQName().toString())); } } else { Node.this.associations = new ArrayList<Association>(5); } // Create the added and removes association lists Node.this.addedAssociations = new ArrayList<Association>(5); Node.this.removedAssociations = new ArrayList<Association>(5); } return null; } }); } @SuppressWarnings("unused") private void dumpProperties(String message) { if (logger.isDebugEnabled() == true) { logger.debug("Current property values (" + message + ") ..."); for (Map.Entry<String, Object> entry : this.properties.entrySet()) { logger.debug(" - " + entry.getKey() + ":" + entry.getValue()); } } } /** * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Node)) { return false; } Node other = (Node) o; return (EqualsHelper.nullSafeEquals(this.id, other.id) && EqualsHelper.nullSafeEquals(this.store, other.store)); } /** * @see java.lang.Object#hashCode() */ public int hashCode() { return id.hashCode(); } /** * * @param template * @return */ public String processTemplate(ScriptNode template) { return processTemplate(template.getContent(), null, null); } /** * * @param template * @param args * @return */ public String processTemplate(ScriptNode template, Map<String, Object> args) { return processTemplate(template.getContent(), null, args); } /** * * @param template * @return */ public String processTemplate(String template) { return processTemplate(template, null, null); } /** * * @param template * @param args * @return */ public String processTemplate(String template, Map<String, Object> args) { return processTemplate(template, null, args); } /** * * @param template * @param templateRef * @param args * @return */ private String processTemplate(String template, NodeRef templateRef, Map<String, Object> args) { NodeRef person = null; NodeRef companyHome = null; NodeRef userHome = null; Map<String, Object> model = templateService.buildDefaultModel(person, companyHome, userHome, templateRef, null); // add the current node as either the document/space as appropriate DictionaryService dd = this.getSession().getServiceRegistry().getDictionaryService(); boolean isDocument = Boolean .valueOf(dd.isSubClass(QName.createQName(getType()), ContentModel.TYPE_CONTENT)); if (isDocument == true) { model.put("document", getNodeRef()); model.put("space", getPrimaryParent()); } else { model.put("space", getNodeRef()); } // add the supplied args to the 'args' root object if (args != null) { // TODO the values may need converting to the correct types ... // add the args to the model as the 'args' root object model.put("args", args); } // execute template return templateService.processTemplateString(null, template, model); } }