/* * 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.repo.webservice; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.alfresco.repo.webservice.repository.UpdateResult; import org.alfresco.repo.webservice.types.CML; import org.alfresco.repo.webservice.types.CMLAddAspect; import org.alfresco.repo.webservice.types.CMLAddChild; import org.alfresco.repo.webservice.types.CMLCopy; import org.alfresco.repo.webservice.types.CMLCreate; import org.alfresco.repo.webservice.types.CMLCreateAssociation; import org.alfresco.repo.webservice.types.CMLDelete; import org.alfresco.repo.webservice.types.CMLMove; import org.alfresco.repo.webservice.types.CMLRemoveAspect; import org.alfresco.repo.webservice.types.CMLRemoveAssociation; import org.alfresco.repo.webservice.types.CMLRemoveChild; import org.alfresco.repo.webservice.types.CMLUpdate; import org.alfresco.repo.webservice.types.NamedValue; import org.alfresco.repo.webservice.types.ParentReference; import org.alfresco.repo.webservice.types.Predicate; import org.alfresco.repo.webservice.types.Reference; 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.search.SearchService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.util.PropertyMap; /** * @author Roy Wetherall */ public class CMLUtil { private static final String CREATE = "create"; private static final String ADD_ASPECT = "addAspect"; private static final String REMOVE_ASPECT = "removeAspect"; private static final String UPDATE = "update"; private static final String DELETE = "delete"; private static final String MOVE = "move"; private static final String COPY = "copy"; private static final String ADD_CHILD = "addChild"; private static final String REMOVE_CHILD = "removeChild"; private static final String CREATE_ASSOCIATION = "createAssociation"; private static final String REMOVE_ASSOCIATION = "removeAssociation"; private NodeService nodeService; private SearchService searchService; private NamespaceService namespaceService; private CopyService copyService; public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } public void setSearchService(SearchService searchService) { this.searchService = searchService; } public void setNamespaceService(NamespaceService namespaceService) { this.namespaceService = namespaceService; } public void setCopyService(CopyService copyService) { this.copyService = copyService; } /** * Execute a cml update query. * * @param cml the cml objects * @return the update result */ public UpdateResult[] executeCML(CML cml) { ExecutionContext context = new ExecutionContext(); List results = new ArrayList(); // Execute creates CMLCreate[] creates = cml.getCreate(); if (creates != null) { for (CMLCreate create : creates) { executeCMLCreate(create, context, results); } } // Exceute add aspect CMLAddAspect[] addAspects = cml.getAddAspect(); if (addAspects != null) { for (CMLAddAspect addAspect : addAspects) { executeCMLAddAspect(addAspect, context, results); } } // Execeute remove aspect CMLRemoveAspect[] removeAspects = cml.getRemoveAspect(); if (removeAspects != null) { for (CMLRemoveAspect removeAspect : removeAspects) { executeCMLRemoveAspect(removeAspect, context, results); } } // Execute update CMLUpdate[] updates = cml.getUpdate(); if (updates != null) { for (CMLUpdate update : updates) { executeCMLUpdate(update, context, results); } } // Execute delete CMLDelete[] deletes = cml.getDelete(); if (deletes != null) { for (CMLDelete delete : deletes) { executeCMLDelete(delete, context, results); } } // Execute move CMLMove[] moves = cml.getMove(); if (moves != null) { for (CMLMove move : moves) { executeCMLMove(move, context, results); } } // Execute copy CMLCopy[] copies = cml.getCopy(); if (copies != null) { for (CMLCopy copy : copies) { executeCMLCopy(copy, context, results); } } // Execute addChild CMLAddChild[] addChildren = cml.getAddChild(); if (addChildren != null) { for (CMLAddChild addChild : addChildren) { executeCMLAddChild(addChild, context, results); } } // Execute removeChild CMLRemoveChild[] removeChildren = cml.getRemoveChild(); if (removeChildren != null) { for (CMLRemoveChild removeChild : removeChildren) { executeCMLRemoveChild(removeChild, context, results); } } // Execute createAssociation CMLCreateAssociation[] createAssocs = cml.getCreateAssociation(); if (createAssocs != null) { for (CMLCreateAssociation createAssoc : createAssocs) { executeCMLCreateAssociation(createAssoc, context, results); } } // Execute removeAssociation CMLRemoveAssociation[] removeAssocs = cml.getRemoveAssociation(); if (removeAssocs != null) { for (CMLRemoveAssociation removeAssoc : removeAssocs) { executeCMLRemoveAssociation(removeAssoc, context, results); } } return results.toArray(new UpdateResult[results.size()]); } /** * * @param create * @param result */ private void executeCMLCreate(CMLCreate create, ExecutionContext context, List results) { // Get the detail of the parent ParentReference parentReference = create.getParent(); NodeRef parentNodeRef = Utils.convertToNodeRef( parentReference, this.nodeService, this.searchService, this.namespaceService); QName assocTypeQName = QName.createQName(parentReference.getAssociationType()); QName assocQName = QName.createQName(parentReference.getChildName()); // Get the type of the node to create QName nodeTypeQName = QName.createQName(create.getType()); // Get the properties PropertyMap properties = getPropertyMap(create.getProperty()); // Create the new node NodeRef nodeRef = this.nodeService.createNode(parentNodeRef, assocTypeQName, assocQName, nodeTypeQName, properties).getChildRef(); // Store the node ref in the execution context (if appropraite) String id = create.getId(); if (id != null && id.length() != 0) { context.addId(id, nodeRef); } results.add(createResult(CREATE, null, nodeRef)); } private PropertyMap getPropertyMap(NamedValue[] namedValues) { PropertyMap properties = new PropertyMap(); if (namedValues != null) { for (NamedValue value : namedValues) { QName qname = QName.createQName(value.getName()); properties.put(qname, value.getValue()); } } return properties; } private UpdateResult createResult(String cmd, NodeRef sourceNodeRef, NodeRef destinationNodeRef) { UpdateResult result = new UpdateResult(); result.setStatement(cmd); if (sourceNodeRef != null) { result.setSource(Utils.convertToReference(sourceNodeRef)); } if (destinationNodeRef != null) { result.setDestination(Utils.convertToReference(destinationNodeRef)); } // Sort out the count ??? return result; } /** * * @param addAspect * @param result */ private void executeCMLAddAspect(CMLAddAspect addAspect, ExecutionContext context, List results) { // Get the node refs List nodeRefs = getNodeRefList(addAspect.getWhere_id(), addAspect.getWhere(), context); // Get the aspect name and the properties QName aspectQName = QName.createQName(addAspect.getAspect()); PropertyMap properties = getPropertyMap(addAspect.getProperty()); for (NodeRef nodeRef : nodeRefs) { // Add the aspect this.nodeService.addAspect(nodeRef, aspectQName, properties); // Create the result results.add(createResult(ADD_ASPECT, nodeRef, nodeRef)); } } private void executeCMLRemoveAspect(CMLRemoveAspect removeAspect, ExecutionContext context, List results) { // Get the node refs List nodeRefs = getNodeRefList(removeAspect.getWhere_id(), removeAspect.getWhere(), context); // Get the aspect name QName aspectQName = QName.createQName(removeAspect.getAspect()); for (NodeRef nodeRef : nodeRefs) { // Add the aspect this.nodeService.removeAspect(nodeRef, aspectQName); // Create the result results.add(createResult(REMOVE_ASPECT, nodeRef, nodeRef)); } } private List getNodeRefList(String id, Predicate predicate, ExecutionContext context) { List nodeRefs = new ArrayList(); if (id != null && id.length() != 0) { NodeRef localNodeRef = context.getNodeRef(id); if (localNodeRef != null) { nodeRefs.add(localNodeRef); } } else { nodeRefs = Utils.resolvePredicate(predicate, this.nodeService, this.searchService, this.namespaceService); } return nodeRefs; } private void executeCMLUpdate(CMLUpdate update, ExecutionContext context, List results) { // Get the nodes and properties List nodeRefs = getNodeRefList(update.getWhere_id(), update.getWhere(), context); PropertyMap props = getPropertyMap(update.getProperty()); for (NodeRef nodeRef : nodeRefs) { // Update the property values Map currentProps = this.nodeService.getProperties(nodeRef); currentProps.putAll(props); this.nodeService.setProperties(nodeRef, currentProps); // Get the result results.add(createResult(UPDATE, nodeRef, nodeRef)); } } private void executeCMLDelete(CMLDelete delete, ExecutionContext context, List results) { List nodeRefs = Utils.resolvePredicate(delete.getWhere(), this.nodeService, this.searchService, this.namespaceService); for (NodeRef nodeRef : nodeRefs) { // Delete the node this.nodeService.deleteNode(nodeRef); // Create the result results.add(createResult(DELETE, nodeRef, null)); } } private void executeCMLMove(CMLMove move, ExecutionContext context, List results) { NodeRef destinationNodeRef = getNodeRef(move.getTo_id(), move.getTo(), context); if (destinationNodeRef != null) { QName assocType = null; QName assocName = null; if (move.getTo_id() != null) { assocType = QName.createQName(move.getAssociationType()); assocName = QName.createQName(move.getChildName()); } else { assocType = QName.createQName(move.getTo().getAssociationType()); assocName = QName.createQName(move.getTo().getChildName()); } List nodesToMove = getNodeRefList(move.getWhere_id(), move.getWhere(), context); for (NodeRef nodeToMove : nodesToMove) { NodeRef newNodeRef = this.nodeService.moveNode(nodeToMove, destinationNodeRef, assocType, assocName).getChildRef(); // Create the result results.add(createResult(MOVE, nodeToMove, newNodeRef)); } } } private NodeRef getNodeRef(String id, ParentReference parentReference, ExecutionContext context) { NodeRef nodeRef = null; if (id != null && id.length() != 0) { nodeRef = context.getNodeRef(id); } else { nodeRef = Utils.convertToNodeRef(parentReference, this.nodeService, this.searchService, this.namespaceService); } return nodeRef; } private NodeRef getNodeRef(String id, Reference reference, ExecutionContext context) { NodeRef nodeRef = null; if (id != null && id.length() != 0) { nodeRef = context.getNodeRef(id); } else { nodeRef = Utils.convertToNodeRef(reference, this.nodeService, this.searchService, this.namespaceService); } return nodeRef; } private void executeCMLCopy(CMLCopy copy, ExecutionContext context, List results) { NodeRef destinationNodeRef = getNodeRef(copy.getTo_id(), copy.getTo(), context); if (destinationNodeRef != null) { QName assocType = null; QName assocName = null; if (copy.getTo_id() != null) { assocType = QName.createQName(copy.getAssociationType()); assocName = QName.createQName(copy.getChildName()); } else { assocType = QName.createQName(copy.getTo().getAssociationType()); assocName = QName.createQName(copy.getTo().getChildName()); } boolean copyChildren = false; Boolean value = copy.getChildren(); if (value != null) { copyChildren = value.booleanValue(); } List nodesToCopy = getNodeRefList(copy.getWhere_id(), copy.getWhere(), context); for (NodeRef nodeToCopy : nodesToCopy) { NodeRef newNodeRef = this.copyService.copy(nodeToCopy, destinationNodeRef, assocType, assocName, copyChildren); // Create the result results.add(createResult(COPY, nodeToCopy, newNodeRef)); } } } private void executeCMLAddChild(CMLAddChild addChild, ExecutionContext context, List results) { NodeRef nodeRef = getNodeRef(addChild.getTo_id(), addChild.getTo(), context); if (nodeRef != null) { QName assocType = null; QName assocName = null; if (addChild.getTo_id() != null) { assocType = QName.createQName(addChild.getAssociationType()); assocName = QName.createQName(addChild.getChildName()); } else { assocType = QName.createQName(addChild.getTo().getAssociationType()); assocName = QName.createQName(addChild.getTo().getChildName()); } List whereNodeRefs = getNodeRefList(addChild.getWhere_id(), addChild.getWhere(), context); for (NodeRef whereNodeRef : whereNodeRefs) { this.nodeService.addChild(nodeRef, whereNodeRef, assocType, assocName); // Create the result results.add(createResult(ADD_CHILD, nodeRef, whereNodeRef)); } } } private void executeCMLRemoveChild(CMLRemoveChild removeChild, ExecutionContext context, List results) { NodeRef parentNodeRef = getNodeRef(removeChild.getFrom_id(), removeChild.getFrom(), context); if (parentNodeRef != null) { List childNodeRefs = getNodeRefList(removeChild.getWhere_id(), removeChild.getWhere(), context); for (NodeRef childNodeRef : childNodeRefs) { this.nodeService.removeChild(parentNodeRef, childNodeRef); // Create the result results.add(createResult(REMOVE_CHILD, parentNodeRef, null)); } } } private void executeCMLCreateAssociation(CMLCreateAssociation createAssoc, ExecutionContext context, List results) { QName assocType = QName.createQName(createAssoc.getAssociation()); if (assocType != null) { List fromNodeRefs = getNodeRefList(createAssoc.getFrom_id(), createAssoc.getFrom(), context); List toNodeRefs = getNodeRefList(createAssoc.getTo_id(), createAssoc.getTo(), context); for (NodeRef fromNodeRef : fromNodeRefs) { for (NodeRef toNodeRef : toNodeRefs) { this.nodeService.createAssociation(fromNodeRef, toNodeRef, assocType); // Create the result results.add(createResult(CREATE_ASSOCIATION, fromNodeRef, toNodeRef)); } } } } private void executeCMLRemoveAssociation(CMLRemoveAssociation removeAssoc, ExecutionContext context, List results) { QName assocType = QName.createQName(removeAssoc.getAssociation()); if (assocType != null) { List fromNodeRefs = getNodeRefList(removeAssoc.getFrom_id(), removeAssoc.getFrom(), context); List toNodeRefs = getNodeRefList(removeAssoc.getTo_id(), removeAssoc.getTo(), context); for (NodeRef fromNodeRef : fromNodeRefs) { for (NodeRef toNodeRef : toNodeRefs) { this.nodeService.removeAssociation(fromNodeRef, toNodeRef, assocType); // Create the result results.add(createResult(REMOVE_ASSOCIATION, fromNodeRef, toNodeRef)); } } } } private class ExecutionContext { private Map idMap = new HashMap(); public void addId(String id, NodeRef nodeRef) { this.idMap.put(id, nodeRef); } public NodeRef getNodeRef(String id) { return this.idMap.get(id); } } }