diff --git a/source/java/org/alfresco/repo/jscript/Node.java b/source/java/org/alfresco/repo/jscript/Node.java index 0ae23a4708..9e26f3a787 100644 --- a/source/java/org/alfresco/repo/jscript/Node.java +++ b/source/java/org/alfresco/repo/jscript/Node.java @@ -31,6 +31,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.dictionary.InvalidAspectException; import org.alfresco.service.cmr.lock.LockStatus; import org.alfresco.service.cmr.model.FileExistsException; import org.alfresco.service.cmr.model.FileInfo; @@ -51,6 +52,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.mozilla.javascript.NativeArray; import org.mozilla.javascript.ScriptableObject; +import org.mozilla.javascript.Wrapper; import org.springframework.util.StringUtils; /** @@ -87,8 +89,7 @@ public final class Node implements Serializable private String path; private String id; private Set aspects = null; - private ScriptableQNameMap properties; - private boolean propsRetrieved = false; + private ScriptableQNameMap properties = null; private ServiceRegistry services = null; private NodeService nodeService = null; private Boolean isDocument = null; @@ -356,7 +357,7 @@ public final class Node implements Serializable */ public Map getProperties() { - if (this.propsRetrieved == false) + if (this.properties == null) { // this Map implements the Scriptable interface for native JS syntax property access this.properties = new ScriptableQNameMap(this.services.getNamespaceService()); @@ -379,8 +380,6 @@ public final class Node implements Serializable } this.properties.put(qname.toString(), propValue); } - - this.propsRetrieved = true; } return this.properties; @@ -449,7 +448,7 @@ public final class Node implements Serializable } /** - * @param aspect The aspect name to test for + * @param aspect The aspect name to test for (full qualified or short-name form) * * @return true if the node has the aspect false otherwise */ @@ -462,7 +461,7 @@ public final class Node implements Serializable if (aspect.startsWith(NAMESPACE_BEGIN)) { - return aspects.contains((QName.createQName(aspect))); + return aspects.contains((createQName(aspect))); } else { @@ -787,7 +786,12 @@ public final class Node implements Serializable // convert back to ContentData value = ((ScriptContentData)value).contentData; } - props.put(QName.createQName(key), value); + else if (value instanceof Wrapper) + { + // unwrap a Java object from a JavaScript wrapper + value = (Serializable)((Wrapper)value).unwrap(); + } + props.put(createQName(key), value); } this.nodeService.setProperties(this.nodeRef, props); } @@ -883,7 +887,7 @@ public final class Node implements Serializable this.nodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.ALFRESCO_URI, QName.createValidLocalName(name)), - QName.createQName(type), + createQName(type), props); node = new Node(childAssocRef.getChildRef(), this.services, this.imageResolver); } @@ -992,6 +996,83 @@ public final class Node implements Serializable return success; } + /** + * Add an aspect to the Node. + * + * @param type Type name of the aspect to add + * @param props Object (generally an assocative array) providing the named properties + * for the aspect - any mandatory properties for the aspect must be provided! + * + * @return true if the aspect was added successfully, false if an error occured. + */ + public boolean addAspect(String type, Object properties) + { + boolean success = false; + + if (type != null && type.length() != 0) + { + try + { + Map aspectProps = null; + if (properties instanceof ScriptableObject) + { + ScriptableObject props = (ScriptableObject)properties; + // we need to get all the keys to the properties provided + // and convert them to a Map of QName to Serializable objects + Object[] propIds = props.getIds(); + aspectProps = new HashMap(propIds.length); + for (int i=0; i