mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Moving to root below branch label
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2005 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version
|
||||
* 2.1 of the License, or (at your option) any later version.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.gnu.org/licenses/lgpl.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 org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
|
||||
/**
|
||||
* Abstract base class for all web service implementations, provides support for common
|
||||
* service injection
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public abstract class AbstractWebService
|
||||
{
|
||||
protected NodeService nodeService;
|
||||
protected ContentService contentService;
|
||||
protected SearchService searchService;
|
||||
protected NamespaceService namespaceService;
|
||||
|
||||
/**
|
||||
* Sets the instance of the NodeService to be used
|
||||
*
|
||||
* @param nodeService The NodeService
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ContentService instance to use
|
||||
*
|
||||
* @param contentSvc The ContentService
|
||||
*/
|
||||
public void setContentService(ContentService contentSvc)
|
||||
{
|
||||
this.contentService = contentSvc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the instance of the SearchService to be used
|
||||
*
|
||||
* @param searchService The SearchService
|
||||
*/
|
||||
public void setSearchService(SearchService searchService)
|
||||
{
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the instance of the NamespaceService to be used
|
||||
*
|
||||
* @param namespaceService The NamespaceService
|
||||
*/
|
||||
public void setNamespaceService(NamespaceService namespaceService)
|
||||
{
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
}
|
569
source/java/org/alfresco/repo/webservice/CMLUtil.java
Normal file
569
source/java/org/alfresco/repo/webservice/CMLUtil.java
Normal file
@@ -0,0 +1,569 @@
|
||||
/*
|
||||
* 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<UpdateResult> results = new ArrayList<UpdateResult>();
|
||||
|
||||
// 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<UpdateResult> 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<UpdateResult> results)
|
||||
{
|
||||
// Get the node refs
|
||||
List<NodeRef> 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<UpdateResult> results)
|
||||
{
|
||||
// Get the node refs
|
||||
List<NodeRef> 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<NodeRef> getNodeRefList(String id, Predicate predicate, ExecutionContext context)
|
||||
{
|
||||
List<NodeRef> nodeRefs = new ArrayList<NodeRef>();
|
||||
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<UpdateResult> results)
|
||||
{
|
||||
// Get the nodes and properties
|
||||
List<NodeRef> nodeRefs = getNodeRefList(update.getWhere_id(), update.getWhere(), context);
|
||||
PropertyMap props = getPropertyMap(update.getProperty());
|
||||
|
||||
for (NodeRef nodeRef : nodeRefs)
|
||||
{
|
||||
// Update the property values
|
||||
Map<QName, Serializable> 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<UpdateResult> results)
|
||||
{
|
||||
List<NodeRef> 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<UpdateResult> 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<NodeRef> 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<UpdateResult> 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<NodeRef> 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<UpdateResult> 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<NodeRef> 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<UpdateResult> results)
|
||||
{
|
||||
NodeRef parentNodeRef = getNodeRef(removeChild.getFrom_id(), removeChild.getFrom(), context);
|
||||
if (parentNodeRef != null)
|
||||
{
|
||||
List<NodeRef> 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<UpdateResult> results)
|
||||
{
|
||||
QName assocType = QName.createQName(createAssoc.getAssociation());
|
||||
if (assocType != null)
|
||||
{
|
||||
List<NodeRef> fromNodeRefs = getNodeRefList(createAssoc.getFrom_id(), createAssoc.getFrom(), context);
|
||||
List<NodeRef> 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<UpdateResult> results)
|
||||
{
|
||||
QName assocType = QName.createQName(removeAssoc.getAssociation());
|
||||
if (assocType != null)
|
||||
{
|
||||
List<NodeRef> fromNodeRefs = getNodeRefList(removeAssoc.getFrom_id(), removeAssoc.getFrom(), context);
|
||||
List<NodeRef> 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<String, NodeRef> idMap = new HashMap<String, NodeRef>();
|
||||
|
||||
public void addId(String id, NodeRef nodeRef)
|
||||
{
|
||||
this.idMap.put(id, nodeRef);
|
||||
}
|
||||
|
||||
public NodeRef getNodeRef(String id)
|
||||
{
|
||||
return this.idMap.get(id);
|
||||
}
|
||||
}
|
||||
}
|
448
source/java/org/alfresco/repo/webservice/CMLUtilTest.java
Normal file
448
source/java/org/alfresco/repo/webservice/CMLUtilTest.java
Normal file
@@ -0,0 +1,448 @@
|
||||
/*
|
||||
* 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.util.List;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
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.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.BaseSpringTest;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
|
||||
/**
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class CMLUtilTest extends BaseSpringTest
|
||||
{
|
||||
private static final ContentData CONTENT_DATA_TEXT_UTF8 = new ContentData(null, MimetypeMap.MIMETYPE_TEXT_PLAIN, 0L, "UTF-8");
|
||||
private static final ContentData CONTENT_DATA_HTML_UTF16 = new ContentData(null, MimetypeMap.MIMETYPE_HTML, 0L, "UTF-16");
|
||||
|
||||
private CMLUtil cmlUtil;
|
||||
private NodeService nodeService;
|
||||
private StoreRef testStoreRef;
|
||||
private NodeRef rootNodeRef;
|
||||
private NodeRef nodeRef;
|
||||
private NamespaceService namespaceService;
|
||||
private SearchService searchService;
|
||||
private NodeRef folderNodeRef;
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
|
||||
@Override
|
||||
protected String[] getConfigLocations()
|
||||
{
|
||||
return new String[]{"classpath:org/alfresco/repo/webservice/cml-test.xml"};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSetUpInTransaction() throws Exception
|
||||
{
|
||||
this.cmlUtil = (CMLUtil)this.applicationContext.getBean("CMLUtil");
|
||||
this.nodeService = (NodeService)this.applicationContext.getBean("nodeService");
|
||||
this.searchService = (SearchService)this.applicationContext.getBean("searchService");
|
||||
this.namespaceService = (NamespaceService)this.applicationContext.getBean("namespaceService");
|
||||
this.authenticationComponent = (AuthenticationComponent) this.applicationContext.getBean("authenticationComponent");
|
||||
|
||||
this.authenticationComponent.setSystemUserAsCurrentUser();
|
||||
|
||||
// Create the store and get the root node
|
||||
this.testStoreRef = this.nodeService.createStore(
|
||||
StoreRef.PROTOCOL_WORKSPACE, "Test_"
|
||||
+ System.currentTimeMillis());
|
||||
this.rootNodeRef = this.nodeService.getRootNode(this.testStoreRef);
|
||||
|
||||
// Create the node used for tests
|
||||
PropertyMap contentProps = new PropertyMap();
|
||||
contentProps.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT_UTF8);
|
||||
this.nodeRef = this.nodeService.createNode(
|
||||
this.rootNodeRef,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
ContentModel.TYPE_CONTENT,
|
||||
contentProps).getChildRef();
|
||||
|
||||
this.folderNodeRef = this.nodeService.createNode(
|
||||
this.rootNodeRef,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
ContentModel.TYPE_FOLDER).getChildRef();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTearDownInTransaction()
|
||||
{
|
||||
authenticationComponent.clearCurrentSecurityContext();
|
||||
super.onTearDownInTransaction();
|
||||
}
|
||||
|
||||
public void testMoreThanOneStatement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void testCreate()
|
||||
{
|
||||
CMLCreate[] creates = new CMLCreate[]{createCMLCreate(ContentModel.TYPE_CONTENT, "id1")};
|
||||
|
||||
CML cml = new CML();
|
||||
cml.setCreate(creates);
|
||||
|
||||
UpdateResult[] result = this.cmlUtil.executeCML(cml);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.length);
|
||||
|
||||
UpdateResult updateResult = result[0];
|
||||
assertEquals("create", updateResult.getStatement());
|
||||
assertNull(updateResult.getSource());
|
||||
assertNotNull(updateResult.getDestination());
|
||||
NodeRef createdNodeRef = Utils.convertToNodeRef(updateResult.getDestination(), this.nodeService, this.searchService, this.namespaceService);
|
||||
assertNotNull(createdNodeRef);
|
||||
|
||||
assertEquals(ContentModel.TYPE_CONTENT, this.nodeService.getType(createdNodeRef));
|
||||
assertEquals("name", this.nodeService.getProperty(createdNodeRef, ContentModel.PROP_NAME));
|
||||
|
||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||
}
|
||||
|
||||
public void testAddRemoveAspect()
|
||||
{
|
||||
CMLAddAspect addAspect = new CMLAddAspect();
|
||||
addAspect.setAspect(ContentModel.ASPECT_VERSIONABLE.toString());
|
||||
addAspect.setWhere(createPredicate(this.nodeRef));
|
||||
|
||||
CML cml = new CML();
|
||||
cml.setAddAspect(new CMLAddAspect[]{addAspect});
|
||||
|
||||
UpdateResult[] result = this.cmlUtil.executeCML(cml);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.length);
|
||||
|
||||
UpdateResult updateResult = result[0];
|
||||
assertEquals("addAspect", updateResult.getStatement());
|
||||
assertNotNull(updateResult.getSource());
|
||||
assertNotNull(updateResult.getDestination());
|
||||
|
||||
assertTrue(this.nodeService.hasAspect(this.nodeRef, ContentModel.ASPECT_VERSIONABLE));
|
||||
|
||||
// TODO should test with properties set as well
|
||||
|
||||
CMLRemoveAspect removeAspect = new CMLRemoveAspect();
|
||||
removeAspect.setAspect(ContentModel.ASPECT_VERSIONABLE.toString());
|
||||
removeAspect.setWhere(createPredicate(this.nodeRef));
|
||||
|
||||
CML cml2 = new CML();
|
||||
cml2.setRemoveAspect(new CMLRemoveAspect[]{removeAspect});
|
||||
|
||||
UpdateResult[] results2 = this.cmlUtil.executeCML(cml2);
|
||||
assertNotNull(results2);
|
||||
assertEquals(1, results2.length);
|
||||
|
||||
UpdateResult result2 = results2[0];
|
||||
assertEquals("removeAspect", result2.getStatement());
|
||||
assertNotNull(result2.getDestination());
|
||||
assertNotNull(result2.getSource());
|
||||
|
||||
assertFalse(this.nodeService.hasAspect(this.nodeRef, ContentModel.ASPECT_VERSIONABLE));
|
||||
|
||||
}
|
||||
|
||||
public void testUpdate()
|
||||
{
|
||||
CMLUpdate update = new CMLUpdate();
|
||||
update.setWhere(createPredicate(this.nodeRef));
|
||||
update.setProperty(new NamedValue[]
|
||||
{
|
||||
new NamedValue(ContentModel.PROP_NAME.toString(), "updatedName"),
|
||||
new NamedValue(ContentModel.PROP_CONTENT.toString(), CONTENT_DATA_HTML_UTF16.toString())
|
||||
});
|
||||
|
||||
CML cml = new CML();
|
||||
cml.setUpdate(new CMLUpdate[]{update});
|
||||
|
||||
UpdateResult[] result = this.cmlUtil.executeCML(cml);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.length);
|
||||
|
||||
UpdateResult updateResult = result[0];
|
||||
assertEquals("update", updateResult.getStatement());
|
||||
assertNotNull(updateResult.getSource());
|
||||
assertNotNull(updateResult.getDestination());
|
||||
|
||||
assertEquals("updatedName", this.nodeService.getProperty(this.nodeRef, ContentModel.PROP_NAME));
|
||||
assertEquals(CONTENT_DATA_HTML_UTF16, this.nodeService.getProperty(this.nodeRef, ContentModel.PROP_CONTENT));
|
||||
}
|
||||
|
||||
public void testDelete()
|
||||
{
|
||||
CMLDelete delete = new CMLDelete();
|
||||
delete.setWhere(createPredicate(this.nodeRef));
|
||||
|
||||
CML cml = new CML();
|
||||
cml.setDelete(new CMLDelete[]{delete});
|
||||
|
||||
UpdateResult[] result = this.cmlUtil.executeCML(cml);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.length);
|
||||
|
||||
UpdateResult updateResult = result[0];
|
||||
assertEquals("delete", updateResult.getStatement());
|
||||
assertNotNull(updateResult.getSource());
|
||||
assertNull(updateResult.getDestination());
|
||||
|
||||
// Check that the node no longer exists
|
||||
assertFalse(this.nodeService.exists(this.nodeRef));
|
||||
}
|
||||
|
||||
public void testMove()
|
||||
{
|
||||
CMLMove move = new CMLMove();
|
||||
move.setTo(createParentReference(this.folderNodeRef, ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS));
|
||||
move.setWhere(createPredicate(this.nodeRef));
|
||||
|
||||
CML cml = new CML();
|
||||
cml.setMove(new CMLMove[]{move});
|
||||
|
||||
UpdateResult[] result = this.cmlUtil.executeCML(cml);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.length);
|
||||
|
||||
UpdateResult updateResult = result[0];
|
||||
assertEquals("move", updateResult.getStatement());
|
||||
assertNotNull(updateResult.getSource());
|
||||
assertNotNull(updateResult.getDestination());
|
||||
|
||||
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(this.folderNodeRef);
|
||||
assertNotNull(assocs);
|
||||
assertEquals(1, assocs.size());
|
||||
ChildAssociationRef assoc = assocs.get(0);
|
||||
assertEquals(assoc.getChildRef(), Utils.convertToNodeRef(
|
||||
updateResult.getDestination(),
|
||||
this.nodeService,
|
||||
this.searchService,
|
||||
this.namespaceService));
|
||||
}
|
||||
|
||||
public void testCopy()
|
||||
{
|
||||
CMLCopy copy = new CMLCopy();
|
||||
copy.setTo(createParentReference(this.folderNodeRef, ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS));
|
||||
copy.setWhere(createPredicate(this.nodeRef));
|
||||
|
||||
CML cml = new CML();
|
||||
cml.setCopy(new CMLCopy[]{copy});
|
||||
|
||||
UpdateResult[] result = this.cmlUtil.executeCML(cml);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.length);
|
||||
|
||||
UpdateResult updateResult = result[0];
|
||||
assertEquals("copy", updateResult.getStatement());
|
||||
assertNotNull(updateResult.getSource());
|
||||
assertNotNull(updateResult.getDestination());
|
||||
|
||||
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(this.folderNodeRef);
|
||||
assertNotNull(assocs);
|
||||
assertEquals(1, assocs.size());
|
||||
ChildAssociationRef assoc = assocs.get(0);
|
||||
assertEquals(assoc.getChildRef(), Utils.convertToNodeRef(
|
||||
updateResult.getDestination(),
|
||||
this.nodeService,
|
||||
this.searchService,
|
||||
this.namespaceService));
|
||||
}
|
||||
|
||||
public void testAddChild()
|
||||
{
|
||||
CMLAddChild addChild = new CMLAddChild();
|
||||
addChild.setTo(createParentReference(this.folderNodeRef, ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS));
|
||||
addChild.setWhere(createPredicate(this.nodeRef));
|
||||
|
||||
CML cml = new CML();
|
||||
cml.setAddChild(new CMLAddChild[]{addChild});
|
||||
|
||||
UpdateResult[] result = this.cmlUtil.executeCML(cml);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.length);
|
||||
|
||||
UpdateResult updateResult = result[0];
|
||||
assertEquals("addChild", updateResult.getStatement());
|
||||
assertNotNull(updateResult.getSource());
|
||||
assertNotNull(updateResult.getDestination());
|
||||
|
||||
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(this.folderNodeRef);
|
||||
assertNotNull(assocs);
|
||||
assertEquals(1, assocs.size());
|
||||
ChildAssociationRef assoc = assocs.get(0);
|
||||
assertEquals(assoc.getChildRef(), Utils.convertToNodeRef(
|
||||
updateResult.getDestination(),
|
||||
this.nodeService,
|
||||
this.searchService,
|
||||
this.namespaceService));
|
||||
}
|
||||
|
||||
public void testRemoveChild()
|
||||
{
|
||||
// Add the node as a child of the folder
|
||||
this.nodeService.addChild(this.folderNodeRef, this.nodeRef, ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS);
|
||||
|
||||
CMLRemoveChild removeChild = new CMLRemoveChild();
|
||||
removeChild.setFrom(Utils.convertToReference(this.folderNodeRef));
|
||||
removeChild.setWhere(createPredicate(this.nodeRef));
|
||||
|
||||
CML cml = new CML();
|
||||
cml.setRemoveChild(new CMLRemoveChild[]{removeChild});
|
||||
|
||||
UpdateResult[] result = this.cmlUtil.executeCML(cml);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.length);
|
||||
|
||||
UpdateResult updateResult = result[0];
|
||||
assertEquals("removeChild", updateResult.getStatement());
|
||||
assertNotNull(updateResult.getSource());
|
||||
assertNull(updateResult.getDestination());
|
||||
|
||||
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(this.folderNodeRef);
|
||||
assertEquals(0, assocs.size());
|
||||
}
|
||||
|
||||
public void testCreateAssociation()
|
||||
{
|
||||
CMLCreateAssociation createAssoc = new CMLCreateAssociation();
|
||||
createAssoc.setAssociation(ContentModel.ASSOC_CONTAINS.toString());
|
||||
createAssoc.setFrom(createPredicate(this.folderNodeRef));
|
||||
createAssoc.setTo(createPredicate(this.nodeRef));
|
||||
|
||||
CML cml = new CML();
|
||||
cml.setCreateAssociation(new CMLCreateAssociation[]{createAssoc});
|
||||
|
||||
UpdateResult[] result = this.cmlUtil.executeCML(cml);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.length);
|
||||
|
||||
UpdateResult updateResult = result[0];
|
||||
assertEquals("createAssociation", updateResult.getStatement());
|
||||
assertNotNull(updateResult.getSource());
|
||||
assertNotNull(updateResult.getDestination());
|
||||
|
||||
List<AssociationRef> assocs = this.nodeService.getTargetAssocs(this.folderNodeRef, ContentModel.ASSOC_CONTAINS);
|
||||
assertNotNull(assocs);
|
||||
assertEquals(1, assocs.size());
|
||||
AssociationRef assoc = assocs.get(0);
|
||||
assertEquals(assoc.getTargetRef(), Utils.convertToNodeRef(
|
||||
updateResult.getDestination(),
|
||||
this.nodeService,
|
||||
this.searchService,
|
||||
this.namespaceService));
|
||||
}
|
||||
|
||||
public void testRemoveAssociation()
|
||||
{
|
||||
this.nodeService.createAssociation(this.folderNodeRef, this.nodeRef, ContentModel.ASSOC_CONTAINS);
|
||||
|
||||
CMLRemoveAssociation removeAssociation = new CMLRemoveAssociation();
|
||||
removeAssociation.setAssociation(ContentModel.ASSOC_CONTAINS.toString());
|
||||
removeAssociation.setFrom(createPredicate(this.folderNodeRef));
|
||||
removeAssociation.setTo(createPredicate(this.nodeRef));
|
||||
|
||||
CML cml = new CML();
|
||||
cml.setRemoveAssociation(new CMLRemoveAssociation[]{removeAssociation});
|
||||
|
||||
UpdateResult[] result = this.cmlUtil.executeCML(cml);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.length);
|
||||
|
||||
UpdateResult updateResult = result[0];
|
||||
assertEquals("removeAssociation", updateResult.getStatement());
|
||||
assertNotNull(updateResult.getSource());
|
||||
assertNotNull(updateResult.getDestination());
|
||||
|
||||
List<AssociationRef> assocs = this.nodeService.getTargetAssocs(this.folderNodeRef, ContentModel.ASSOC_CONTAINS);
|
||||
assertNotNull(assocs);
|
||||
assertEquals(0, assocs.size());
|
||||
}
|
||||
|
||||
private ParentReference createParentReference(NodeRef nodeRef, QName assocType, QName assocName)
|
||||
{
|
||||
ParentReference parentReference = new ParentReference();
|
||||
parentReference.setAssociationType(assocType.toString());
|
||||
parentReference.setChildName(assocName.toString());
|
||||
parentReference.setStore(Utils.convertToStore(nodeRef.getStoreRef()));
|
||||
parentReference.setUuid(nodeRef.getId());
|
||||
return parentReference;
|
||||
}
|
||||
|
||||
private Predicate createPredicate(NodeRef nodeRef)
|
||||
{
|
||||
Predicate predicate = new Predicate();
|
||||
predicate.setStore(Utils.convertToStore(nodeRef.getStoreRef()));
|
||||
predicate.setNodes(new Reference[]{Utils.convertToReference(nodeRef)});
|
||||
return predicate;
|
||||
}
|
||||
|
||||
private CMLCreate createCMLCreate(QName type, String id)
|
||||
{
|
||||
CMLCreate create = new CMLCreate();
|
||||
create.setId("id1");
|
||||
create.setType(ContentModel.TYPE_CONTENT.toString());
|
||||
|
||||
ParentReference parentReference = new ParentReference();
|
||||
parentReference.setAssociationType(ContentModel.ASSOC_CHILDREN.toString());
|
||||
parentReference.setChildName(ContentModel.ASSOC_CHILDREN.toString());
|
||||
parentReference.setStore(Utils.convertToStore(this.testStoreRef));
|
||||
parentReference.setUuid(this.rootNodeRef.getId());
|
||||
|
||||
create.setParent(parentReference);
|
||||
create.setProperty(getContentNamedValues());
|
||||
|
||||
return create;
|
||||
}
|
||||
|
||||
private NamedValue[] getContentNamedValues()
|
||||
{
|
||||
return new NamedValue[]
|
||||
{
|
||||
new NamedValue(ContentModel.PROP_NAME.toString(), "name"),
|
||||
new NamedValue(ContentModel.PROP_CONTENT.toString(), CONTENT_DATA_TEXT_UTF8.toString())
|
||||
};
|
||||
}
|
||||
}
|
600
source/java/org/alfresco/repo/webservice/Utils.java
Normal file
600
source/java/org/alfresco/repo/webservice/Utils.java
Normal file
@@ -0,0 +1,600 @@
|
||||
/*
|
||||
* 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.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.repo.webservice.axis.QueryConfigHandler;
|
||||
import org.alfresco.repo.webservice.types.AssociationDefinition;
|
||||
import org.alfresco.repo.webservice.types.Cardinality;
|
||||
import org.alfresco.repo.webservice.types.ClassDefinition;
|
||||
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.PropertyDefinition;
|
||||
import org.alfresco.repo.webservice.types.Query;
|
||||
import org.alfresco.repo.webservice.types.QueryLanguageEnum;
|
||||
import org.alfresco.repo.webservice.types.Reference;
|
||||
import org.alfresco.repo.webservice.types.RoleDefinition;
|
||||
import org.alfresco.repo.webservice.types.Store;
|
||||
import org.alfresco.repo.webservice.types.StoreEnum;
|
||||
import org.alfresco.repo.webservice.types.Version;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.axis.transport.http.HTTPConstants;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
/**
|
||||
* Helper class used by the web services
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class Utils
|
||||
{
|
||||
public static final String REPOSITORY_SERVICE_NAMESPACE = "http://www.alfresco.org/ws/service/repository/1.0";
|
||||
|
||||
private Utils()
|
||||
{
|
||||
// don't allow construction
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the web service Store type to a StoreRef used by the repository
|
||||
*
|
||||
* @param store
|
||||
* The Store to convert
|
||||
* @return The converted StoreRef
|
||||
*/
|
||||
public static StoreRef convertToStoreRef(Store store)
|
||||
{
|
||||
return new StoreRef(store.getScheme().getValue(), store.getAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a store reference ot a Store type
|
||||
*
|
||||
* @param ref
|
||||
* the store reference
|
||||
* @return the store
|
||||
*/
|
||||
public static Store convertToStore(StoreRef ref)
|
||||
{
|
||||
return new Store(StoreEnum.fromValue(ref.getProtocol()), ref
|
||||
.getIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given Reference web service type into a repository NodeRef
|
||||
*
|
||||
* @param ref
|
||||
* The Reference to convert
|
||||
* @return The NodeRef representation of the Reference
|
||||
*/
|
||||
public static NodeRef convertToNodeRef(Reference ref,
|
||||
NodeService nodeService, SearchService searchService,
|
||||
NamespaceService namespaceService)
|
||||
{
|
||||
return resolveToNodeRef(ref.getStore(), ref.getUuid(), ref.getPath(),
|
||||
nodeService, searchService, namespaceService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given ParentReference web service type into a repository
|
||||
* NodeRef
|
||||
*
|
||||
* @param parentRef
|
||||
* The ParentReference to convert
|
||||
* @return The NodeRef representation of the ParentReference
|
||||
*/
|
||||
public static NodeRef convertToNodeRef(ParentReference parentRef,
|
||||
NodeService nodeService, SearchService searchService,
|
||||
NamespaceService namespaceService)
|
||||
{
|
||||
// TODO: Also take into account any association information passed in
|
||||
// the ParentReference
|
||||
|
||||
return resolveToNodeRef(parentRef.getStore(), parentRef.getUuid(),
|
||||
parentRef.getPath(), nodeService, searchService,
|
||||
namespaceService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given repository NodeRef object into a web service Reference
|
||||
* type
|
||||
*
|
||||
* @param node
|
||||
* The node to create a Reference for
|
||||
* @return The Reference
|
||||
*/
|
||||
public static Reference convertToReference(NodeRef node)
|
||||
{
|
||||
Reference ref = new Reference();
|
||||
Store store = new Store(StoreEnum.fromValue(node.getStoreRef()
|
||||
.getProtocol()), node.getStoreRef().getIdentifier());
|
||||
ref.setStore(store);
|
||||
ref.setUuid(node.getId());
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given parameters to a repository NodeRef
|
||||
*
|
||||
* @param store
|
||||
* The Store to search within
|
||||
* @param uuid
|
||||
* The id of the node, or the id of the starting node if a path
|
||||
* is also present
|
||||
* @param path
|
||||
* The path to the required node, if a uuid is given the search
|
||||
* starts from that node otherwise the search will start from the
|
||||
* root node
|
||||
* @param nodeService
|
||||
* NodeService to use
|
||||
* @param searchService
|
||||
* SearchService to use
|
||||
* @param namespaceService
|
||||
* NamespaceService to use
|
||||
* @return A repository NodeRef
|
||||
*/
|
||||
public static NodeRef resolveToNodeRef(Store store, String uuid,
|
||||
String path, NodeService nodeService, SearchService searchService,
|
||||
NamespaceService namespaceService)
|
||||
{
|
||||
if (store == null)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"A Store must be supplied to resolve to a NodeRef");
|
||||
}
|
||||
|
||||
NodeRef nodeRef = null;
|
||||
|
||||
// find out where we are starting from, either the root or the node
|
||||
// represented by the uuid
|
||||
NodeRef rootNodeRef = null;
|
||||
if (uuid == null)
|
||||
{
|
||||
rootNodeRef = nodeService.getRootNode(convertToStoreRef(store));
|
||||
} else
|
||||
{
|
||||
rootNodeRef = new NodeRef(convertToStoreRef(store), uuid);
|
||||
}
|
||||
|
||||
// see if we have a path to further define the node being requested
|
||||
if (path != null)
|
||||
{
|
||||
List<NodeRef> nodes = searchService.selectNodes(rootNodeRef, path,
|
||||
null, namespaceService, false);
|
||||
|
||||
// make sure we only have one result
|
||||
if (nodes.size() != 1)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(
|
||||
"Failed to resolve to a single NodeRef with parameters (store=");
|
||||
builder.append(store.getScheme().getValue()).append(":")
|
||||
.append(store.getAddress());
|
||||
builder.append(" uuid=").append(uuid);
|
||||
builder.append(" path=").append(path).append("), found ");
|
||||
builder.append(nodes.size()).append(" nodes.");
|
||||
throw new IllegalStateException(builder.toString());
|
||||
}
|
||||
|
||||
nodeRef = nodes.get(0);
|
||||
} else
|
||||
{
|
||||
// if there is no path just use whatever the rootNodeRef currently
|
||||
// is
|
||||
nodeRef = rootNodeRef;
|
||||
}
|
||||
|
||||
return nodeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given predicate into a list of NodeRefs that can be acted
|
||||
* upon
|
||||
*
|
||||
* @param predicate
|
||||
* The predicate passed from the client
|
||||
* @param nodeService
|
||||
* NodeService to use
|
||||
* @param searchService
|
||||
* SearchService to use
|
||||
* @param namespaceService
|
||||
* NamespaceService to use
|
||||
* @return A List of NodeRef objects
|
||||
*/
|
||||
public static List<NodeRef> resolvePredicate(Predicate predicate,
|
||||
NodeService nodeService, SearchService searchService,
|
||||
NamespaceService namespaceService)
|
||||
{
|
||||
List<NodeRef> nodeRefs = null;
|
||||
|
||||
if (predicate.getNodes() != null)
|
||||
{
|
||||
Reference[] nodes = predicate.getNodes();
|
||||
nodeRefs = new ArrayList<NodeRef>(nodes.length);
|
||||
|
||||
for (int x = 0; x < nodes.length; x++)
|
||||
{
|
||||
nodeRefs.add(convertToNodeRef(nodes[x], nodeService,
|
||||
searchService, namespaceService));
|
||||
}
|
||||
}
|
||||
else if (predicate.getQuery() != null)
|
||||
{
|
||||
// make sure a query is present
|
||||
Query query = predicate.getQuery();
|
||||
|
||||
if (query == null)
|
||||
{
|
||||
throw new IllegalStateException(
|
||||
"Either a set of nodes or a query must be supplied in a Predicate.");
|
||||
}
|
||||
|
||||
// make sure a Store has been supplied too
|
||||
if (predicate.getStore() == null)
|
||||
{
|
||||
throw new IllegalStateException(
|
||||
"A Store has to be supplied to in order to execute a query.");
|
||||
}
|
||||
|
||||
QueryLanguageEnum langEnum = query.getLanguage();
|
||||
|
||||
if (langEnum.equals(QueryLanguageEnum.cql)
|
||||
|| langEnum.equals(QueryLanguageEnum.xpath))
|
||||
{
|
||||
throw new IllegalArgumentException("Only '"
|
||||
+ QueryLanguageEnum.lucene.getValue()
|
||||
+ "' queries are currently supported!");
|
||||
}
|
||||
|
||||
// execute the query
|
||||
ResultSet searchResults = null;
|
||||
try
|
||||
{
|
||||
searchResults = searchService.query(Utils
|
||||
.convertToStoreRef(predicate.getStore()), langEnum
|
||||
.getValue(), query.getStatement());
|
||||
// get hold of all the NodeRef's from the results
|
||||
nodeRefs = searchResults.getNodeRefs();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (searchResults != null)
|
||||
{
|
||||
searchResults.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (predicate.getStore() != null)
|
||||
{
|
||||
// Since only the store was supplied interpret this to mean the predicate should be resolved to the
|
||||
// stores root node
|
||||
Store store = predicate.getStore();
|
||||
NodeRef rootNode = nodeService.getRootNode(Utils.convertToStoreRef(store));
|
||||
|
||||
nodeRefs = new ArrayList<NodeRef>();
|
||||
nodeRefs.add(rootNode);
|
||||
}
|
||||
|
||||
return nodeRefs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current Spring WebApplicationContext object
|
||||
*
|
||||
* @param msgContext
|
||||
* SOAP message context
|
||||
* @return The Spring WebApplicationContext
|
||||
*/
|
||||
public static WebApplicationContext getSpringContext(
|
||||
MessageContext msgContext)
|
||||
{
|
||||
// get hold of the web application context via the message context
|
||||
HttpServletRequest req = (HttpServletRequest) msgContext
|
||||
.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
|
||||
ServletContext servletCtx = req.getSession().getServletContext();
|
||||
return WebApplicationContextUtils
|
||||
.getRequiredWebApplicationContext(servletCtx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a UserTransaction that can be used within a service call
|
||||
*
|
||||
* @param msgContext
|
||||
* SOAP message context
|
||||
* @return a UserTransaction
|
||||
*/
|
||||
public static UserTransaction getUserTransaction(MessageContext msgContext)
|
||||
{
|
||||
// get the service regsistry
|
||||
ServiceRegistry svcReg = (ServiceRegistry) getSpringContext(msgContext)
|
||||
.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
|
||||
TransactionService transactionService = svcReg.getTransactionService();
|
||||
return transactionService.getUserTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the <code>fetchSize</code> from the
|
||||
* QueryConfiguration SOAP header (if present)
|
||||
*
|
||||
* @param msgContext
|
||||
* The SOAP MessageContext
|
||||
* @return The current batch size or -1 if the header is not present
|
||||
*/
|
||||
public static int getBatchSize(MessageContext msgContext)
|
||||
{
|
||||
int batchSize = -1;
|
||||
|
||||
Integer batchConfigSize = (Integer) MessageContext.getCurrentContext()
|
||||
.getProperty(QueryConfigHandler.ALF_FETCH_SIZE);
|
||||
if (batchConfigSize != null)
|
||||
{
|
||||
batchSize = batchConfigSize.intValue();
|
||||
}
|
||||
|
||||
return batchSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a repository version object into a web service version object.
|
||||
*
|
||||
* @param version
|
||||
* the repository version object
|
||||
* @return the web service version object
|
||||
*/
|
||||
public static Version convertToVersion(
|
||||
org.alfresco.service.cmr.version.Version version)
|
||||
{
|
||||
Version webServiceVersion = new Version();
|
||||
|
||||
// Set the basic properties
|
||||
webServiceVersion.setId(Utils.convertToReference(version
|
||||
.getFrozenStateNodeRef()));
|
||||
webServiceVersion.setCreator(version.getCreator());
|
||||
webServiceVersion.setLabel(version.getVersionLabel());
|
||||
|
||||
// Set the created date
|
||||
Date createdDate = version.getCreatedDate();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(createdDate);
|
||||
webServiceVersion.setCreated(calendar);
|
||||
|
||||
// Set the falg to indicate whether the version was mojor or minor
|
||||
boolean isMajor = false;
|
||||
VersionType versionType = version.getVersionType();
|
||||
if (versionType != null
|
||||
&& versionType.equals(VersionType.MAJOR) == true)
|
||||
{
|
||||
isMajor = true;
|
||||
}
|
||||
webServiceVersion.setMajor(isMajor);
|
||||
|
||||
// Set the commetary values
|
||||
Map<String, Serializable> versionProps = version.getVersionProperties();
|
||||
NamedValue[] namedValues = new NamedValue[versionProps.size()];
|
||||
int iIndex = 0;
|
||||
for (Map.Entry<String, Serializable> entry : versionProps.entrySet())
|
||||
{
|
||||
String value = null;
|
||||
try
|
||||
{
|
||||
value = DefaultTypeConverter.INSTANCE.convert(String.class, entry.getValue());
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
value = entry.getValue().toString();
|
||||
}
|
||||
namedValues[iIndex] = new NamedValue(entry.getKey(), value);
|
||||
iIndex++;
|
||||
}
|
||||
webServiceVersion.setCommentaries(namedValues);
|
||||
|
||||
return webServiceVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ClassDefinition web service type object for the given
|
||||
* repository ClassDefinition
|
||||
*
|
||||
* @param ddClassDef The repository ClassDefinition to generate
|
||||
* @return The web service ClassDefinition representation
|
||||
*/
|
||||
public static ClassDefinition setupClassDefObject(org.alfresco.service.cmr.dictionary.ClassDefinition ddClassDef)
|
||||
{
|
||||
ClassDefinition classDef = new ClassDefinition();
|
||||
classDef.setName(ddClassDef.getName().toString());
|
||||
classDef.setIsAspect(ddClassDef.isAspect());
|
||||
|
||||
if (ddClassDef.getTitle() != null)
|
||||
{
|
||||
classDef.setTitle(ddClassDef.getTitle());
|
||||
}
|
||||
if (ddClassDef.getDescription() != null)
|
||||
{
|
||||
classDef.setDescription(ddClassDef.getDescription());
|
||||
}
|
||||
if (ddClassDef.getParentName() != null)
|
||||
{
|
||||
classDef.setSuperClass(ddClassDef.getParentName().toString());
|
||||
}
|
||||
|
||||
// represent the properties
|
||||
Map<QName, org.alfresco.service.cmr.dictionary.PropertyDefinition> props = ddClassDef.getProperties();
|
||||
if (props != null)
|
||||
{
|
||||
PropertyDefinition[] propDefs = new PropertyDefinition[props.size()];
|
||||
int pos = 0;
|
||||
for (org.alfresco.service.cmr.dictionary.PropertyDefinition ddPropDef : props.values())
|
||||
{
|
||||
PropertyDefinition propDef = new PropertyDefinition();
|
||||
propDef.setName(ddPropDef.getName().toString());
|
||||
propDef.setDataType(ddPropDef.getDataType().getName().toString());
|
||||
propDef.setMandatory(ddPropDef.isMandatory());
|
||||
propDef.setReadOnly(ddPropDef.isProtected());
|
||||
if (ddPropDef.getDefaultValue() != null)
|
||||
{
|
||||
propDef.setDefaultValue(ddPropDef.getDefaultValue());
|
||||
}
|
||||
if (ddPropDef.getTitle() != null)
|
||||
{
|
||||
propDef.setTitle(ddPropDef.getTitle());
|
||||
}
|
||||
if (ddPropDef.getDescription() != null)
|
||||
{
|
||||
propDef.setDescription(ddPropDef.getDescription());
|
||||
}
|
||||
|
||||
// add it to the array
|
||||
propDefs[pos] = propDef;
|
||||
pos++;
|
||||
}
|
||||
|
||||
// add properties to the overall ClassDefinition
|
||||
classDef.setProperties(propDefs);
|
||||
}
|
||||
|
||||
// TODO need to get the child associations as well !!
|
||||
|
||||
// represent the associations
|
||||
Map<QName, org.alfresco.service.cmr.dictionary.AssociationDefinition> assocs = ddClassDef.getAssociations();
|
||||
if (assocs != null)
|
||||
{
|
||||
AssociationDefinition[] assocDefs = new AssociationDefinition[assocs.size()];
|
||||
int pos = 0;
|
||||
for (org.alfresco.service.cmr.dictionary.AssociationDefinition ddAssocDef : assocs.values())
|
||||
{
|
||||
AssociationDefinition assocDef = new AssociationDefinition();
|
||||
assocDef.setName(ddAssocDef.getName().toString());
|
||||
assocDef.setIsChild(ddAssocDef.isChild());
|
||||
if (ddAssocDef.getTitle() != null)
|
||||
{
|
||||
assocDef.setTitle(ddAssocDef.getTitle());
|
||||
}
|
||||
if (ddAssocDef.getDescription() != null)
|
||||
{
|
||||
assocDef.setDescription(ddAssocDef.getDescription());
|
||||
}
|
||||
|
||||
RoleDefinition sourceRole = new RoleDefinition();
|
||||
if (ddAssocDef.getSourceRoleName() != null)
|
||||
{
|
||||
sourceRole.setName(ddAssocDef.getSourceRoleName().toString());
|
||||
}
|
||||
sourceRole.setCardinality(setupSourceCardinalityObject(ddAssocDef));
|
||||
assocDef.setSourceRole(sourceRole);
|
||||
|
||||
RoleDefinition targetRole = new RoleDefinition();
|
||||
if (ddAssocDef.getTargetRoleName() != null)
|
||||
{
|
||||
targetRole.setName(ddAssocDef.getTargetRoleName().toString());
|
||||
}
|
||||
targetRole.setCardinality(setupTargetCardinalityObject(ddAssocDef));;
|
||||
assocDef.setTargetRole(targetRole);
|
||||
assocDef.setTargetClass(ddAssocDef.getTargetClass().getName().toString());
|
||||
|
||||
assocDefs[pos] = assocDef;
|
||||
pos++;
|
||||
}
|
||||
|
||||
classDef.setAssociations(assocDefs);
|
||||
}
|
||||
|
||||
return classDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a web service Cardinality type for the source from the given repository AssociationDefinition
|
||||
*
|
||||
* @param ddAssocDef The AssociationDefinition to get the cardinality from
|
||||
* @return The Cardinality
|
||||
*/
|
||||
private static Cardinality setupSourceCardinalityObject(org.alfresco.service.cmr.dictionary.AssociationDefinition ddAssocDef)
|
||||
{
|
||||
if (ddAssocDef.isSourceMandatory() == false && ddAssocDef.isSourceMany() == false)
|
||||
{
|
||||
// 0..1
|
||||
return Cardinality.value1;
|
||||
}
|
||||
else if (ddAssocDef.isSourceMandatory() && ddAssocDef.isSourceMany() == false)
|
||||
{
|
||||
// 1
|
||||
return Cardinality.value2;
|
||||
}
|
||||
else if (ddAssocDef.isSourceMandatory() && ddAssocDef.isSourceMany())
|
||||
{
|
||||
// 1..*
|
||||
return Cardinality.value4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// *
|
||||
return Cardinality.value3;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a web service Cardinality type for the target from the given repository AssociationDefinition
|
||||
*
|
||||
* @param ddAssocDef The AssociationDefinition to get the cardinality from
|
||||
* @return The Cardinality
|
||||
*/
|
||||
private static Cardinality setupTargetCardinalityObject(org.alfresco.service.cmr.dictionary.AssociationDefinition ddAssocDef)
|
||||
{
|
||||
if (ddAssocDef.isTargetMandatory() == false && ddAssocDef.isTargetMany() == false)
|
||||
{
|
||||
// 0..1
|
||||
return Cardinality.value1;
|
||||
}
|
||||
else if (ddAssocDef.isTargetMandatory() && ddAssocDef.isTargetMany() == false)
|
||||
{
|
||||
// 1
|
||||
return Cardinality.value2;
|
||||
}
|
||||
else if (ddAssocDef.isTargetMandatory() && ddAssocDef.isTargetMany())
|
||||
{
|
||||
// 1..*
|
||||
return Cardinality.value4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// *
|
||||
return Cardinality.value3;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
import org.alfresco.example.webservice.TicketHolder;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Web service implementation of the AuthenticationService. The WSDL for this
|
||||
* service can be accessed from
|
||||
* http://localhost:8080/alfresco/wsdl/authentication-service.wsdl
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class AuthenticationWebService implements AuthenticationServiceSoapPort
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(AuthenticationWebService.class);
|
||||
|
||||
private AuthenticationService authenticationService;
|
||||
|
||||
/**
|
||||
* Sets the AuthenticationService instance to use
|
||||
*
|
||||
* @param authenticationSvc
|
||||
* The AuthenticationService
|
||||
*/
|
||||
public void setAuthenticationService(AuthenticationService authenticationSvc)
|
||||
{
|
||||
this.authenticationService = authenticationSvc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authentication.AuthenticationServiceSoapPort#startSession(java.lang.String,
|
||||
* java.lang.String)
|
||||
*/
|
||||
public AuthenticationResult startSession(String username, String password)
|
||||
throws RemoteException, AuthenticationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
this.authenticationService.authenticate(username, password.toCharArray());
|
||||
String ticket = this.authenticationService.getCurrentTicket();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Issued ticket '" + ticket + "' for '" + username + "'");
|
||||
}
|
||||
|
||||
return new AuthenticationResult(username, ticket);
|
||||
}
|
||||
catch (AuthenticationException ae)
|
||||
{
|
||||
throw new AuthenticationFault(100, ae.getMessage());
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new AuthenticationFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authentication.AuthenticationServiceSoapPort#endSession()
|
||||
*/
|
||||
public void endSession() throws RemoteException, AuthenticationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
String ticket = TicketHolder.ticket;
|
||||
if (ticket != null)
|
||||
{
|
||||
this.authenticationService.invalidateTicket(ticket);
|
||||
this.authenticationService.clearCurrentSecurityContext();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Session ended for ticket '" + ticket + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new AuthenticationFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,804 @@
|
||||
/*
|
||||
* 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.authoring;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transaction.TransactionUtil;
|
||||
import org.alfresco.repo.webservice.AbstractWebService;
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.types.ContentFormat;
|
||||
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.repo.webservice.types.VersionHistory;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.lock.LockService;
|
||||
import org.alfresco.service.cmr.lock.LockType;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Web service implementation of the AuthoringService. The WSDL for this service
|
||||
* can be accessed from
|
||||
* http://localhost:8080/alfresco/wsdl/authoring-service.wsdl
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class AuthoringWebService extends AbstractWebService implements
|
||||
AuthoringServiceSoapPort
|
||||
{
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static Log logger = LogFactory.getLog(AuthoringWebService.class);
|
||||
|
||||
/**
|
||||
* The check in check out service
|
||||
*/
|
||||
private CheckOutCheckInService cociService;
|
||||
|
||||
/**
|
||||
* The lock service
|
||||
*/
|
||||
private LockService lockService;
|
||||
|
||||
/**
|
||||
* The version service
|
||||
*/
|
||||
private VersionService versionService;
|
||||
|
||||
/**
|
||||
* The transaction service
|
||||
*/
|
||||
private TransactionService transactionService;
|
||||
|
||||
/**
|
||||
* Sets the CheckInCheckOutService to use
|
||||
*
|
||||
* @param cociService
|
||||
* The CheckInCheckOutService
|
||||
*/
|
||||
public void setCheckOutCheckinService(CheckOutCheckInService cociService)
|
||||
{
|
||||
this.cociService = cociService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the LockService to use
|
||||
*
|
||||
* @param lockService the lock service
|
||||
*/
|
||||
public void setLockService(LockService lockService)
|
||||
{
|
||||
this.lockService = lockService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the version service
|
||||
*
|
||||
* @param versionService the version service
|
||||
*/
|
||||
public void setVersionService(VersionService versionService)
|
||||
{
|
||||
this.versionService = versionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transaction service
|
||||
*
|
||||
* @param transactionService
|
||||
* the transaction service
|
||||
*/
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authoring.AuthoringServiceSoapPort#checkout(org.alfresco.repo.webservice.types.Predicate,
|
||||
* org.alfresco.repo.webservice.types.ParentReference)
|
||||
*/
|
||||
public CheckoutResult checkout(final Predicate items, final ParentReference destination) throws RemoteException,
|
||||
AuthoringFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<CheckoutResult>()
|
||||
{
|
||||
public CheckoutResult doWork()
|
||||
{
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(items,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService);
|
||||
CheckoutResult checkoutResult = new CheckoutResult();
|
||||
Reference[] originals = new Reference[nodes.size()];
|
||||
Reference[] workingCopies = new Reference[nodes.size()];
|
||||
|
||||
// get a repository NodeRef for the destination (if
|
||||
// there is one)
|
||||
NodeRef destinationRef = null;
|
||||
if (destination != null)
|
||||
{
|
||||
destinationRef = Utils.convertToNodeRef(
|
||||
destination,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService);
|
||||
}
|
||||
|
||||
for (int x = 0; x < nodes.size(); x++)
|
||||
{
|
||||
// get the current node
|
||||
NodeRef original = nodes.get(x);
|
||||
|
||||
// call the appropriate service method depending on
|
||||
// whether a destination has been provided
|
||||
NodeRef workingCopy = null;
|
||||
if (destinationRef != null)
|
||||
{
|
||||
workingCopy = AuthoringWebService.this.cociService
|
||||
.checkout(
|
||||
original,
|
||||
destinationRef,
|
||||
QName.createQName(destination.getAssociationType()),
|
||||
QName.createQName(destination.getChildName()));
|
||||
} else
|
||||
{
|
||||
workingCopy = AuthoringWebService.this.cociService
|
||||
.checkout(original);
|
||||
}
|
||||
|
||||
// store the results
|
||||
originals[x] = Utils.convertToReference(original);
|
||||
workingCopies[x] = Utils.convertToReference(workingCopy);
|
||||
}
|
||||
|
||||
// setup the result object
|
||||
checkoutResult.setOriginals(originals);
|
||||
checkoutResult.setWorkingCopies(workingCopies);
|
||||
|
||||
return checkoutResult;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new AuthoringFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authoring.AuthoringServiceSoapPort#checkin(org.alfresco.repo.webservice.types.Predicate,
|
||||
* org.alfresco.repo.webservice.types.NamedValue[], boolean)
|
||||
*/
|
||||
public CheckinResult checkin(final Predicate items,
|
||||
final NamedValue[] comments, final boolean keepCheckedOut)
|
||||
throws RemoteException, AuthoringFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<CheckinResult>()
|
||||
{
|
||||
public CheckinResult doWork()
|
||||
{
|
||||
// Get the passed nodes
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(
|
||||
items,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService);
|
||||
|
||||
// Map the comments into the expected map
|
||||
Map<String, Serializable> mapComments = new HashMap<String, Serializable>(comments.length);
|
||||
for (NamedValue value : comments)
|
||||
{
|
||||
mapComments.put(value.getName(), value.getValue());
|
||||
}
|
||||
|
||||
Reference[] checkedIn = new Reference[nodes.size()];
|
||||
List<Reference> listWorkingCopies = new ArrayList<Reference>(nodes.size());
|
||||
int iIndex = 0;
|
||||
|
||||
// Execute checkin for each node
|
||||
// TODO should be able to do this as a batch so that all the nodes are versioned together
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
// Checkin the node
|
||||
NodeRef checkedInNode = AuthoringWebService.this.cociService.checkin(node, mapComments, null, keepCheckedOut);
|
||||
|
||||
// Add the results to the array
|
||||
checkedIn[iIndex] = Utils.convertToReference(checkedInNode);
|
||||
|
||||
// Only return the working copies if the node is keep checked out otherwise the working copies have been deleted
|
||||
if (keepCheckedOut == true)
|
||||
{
|
||||
listWorkingCopies.add(Utils.convertToReference(node));
|
||||
}
|
||||
iIndex++;
|
||||
}
|
||||
|
||||
// Sort out the working copy list
|
||||
Reference[] workingCopies = listWorkingCopies.toArray(new Reference[listWorkingCopies.size()]);
|
||||
if (workingCopies == null)
|
||||
{
|
||||
workingCopies = new Reference[0];
|
||||
}
|
||||
|
||||
// Create the result object
|
||||
CheckinResult result = new CheckinResult();
|
||||
result.setCheckedIn(checkedIn);
|
||||
result.setWorkingCopies(workingCopies);
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new AuthoringFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authoring.AuthoringServiceSoapPort#checkinExternal(org.alfresco.repo.webservice.types.Reference, org.alfresco.repo.webservice.types.NamedValue[], boolean, org.alfresco.repo.webservice.types.ContentFormat, byte[])
|
||||
*/
|
||||
public Reference checkinExternal(final Reference node, final NamedValue[] comments, final boolean keepCheckedOut, final ContentFormat format, final byte[] content)
|
||||
throws RemoteException, AuthoringFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<Reference>()
|
||||
{
|
||||
public Reference doWork()
|
||||
{
|
||||
// Get the passed nodes
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(
|
||||
node,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService);
|
||||
|
||||
// Write the content to the server
|
||||
// TODO: Need to get the property QName into this method
|
||||
ContentWriter contentWriter = AuthoringWebService.this.contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, false);
|
||||
if (contentWriter == null)
|
||||
{
|
||||
throw new RuntimeException("Unable to write external content before checkin.");
|
||||
}
|
||||
InputStream is = new ByteArrayInputStream(content);
|
||||
contentWriter.setEncoding(format.getEncoding());
|
||||
contentWriter.setMimetype(format.getMimetype());
|
||||
contentWriter.putContent(is);
|
||||
String contentUrl = contentWriter.getContentUrl();
|
||||
|
||||
// Get the version properties map
|
||||
Map<String, Serializable> versionProperties = new HashMap<String, Serializable>(comments.length);
|
||||
for (NamedValue namedValue : comments)
|
||||
{
|
||||
versionProperties.put(namedValue.getName(), namedValue.getValue());
|
||||
}
|
||||
|
||||
// CheckIn the content
|
||||
NodeRef origNodeRef = AuthoringWebService.this.cociService.checkin(
|
||||
nodeRef,
|
||||
versionProperties,
|
||||
contentUrl,
|
||||
keepCheckedOut);
|
||||
// Return the orig node ref
|
||||
return Utils.convertToReference(origNodeRef);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new AuthoringFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authoring.AuthoringServiceSoapPort#cancelCheckout(org.alfresco.repo.webservice.types.Predicate)
|
||||
*/
|
||||
public CancelCheckoutResult cancelCheckout(final Predicate items)
|
||||
throws RemoteException, AuthoringFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<CancelCheckoutResult>()
|
||||
{
|
||||
public CancelCheckoutResult doWork()
|
||||
{
|
||||
// Get the passed nodes
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(
|
||||
items,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService);
|
||||
|
||||
// Create the arrays to hold results
|
||||
Reference[] origNodes = new Reference[nodes.size()];
|
||||
Reference[] workingCopies = new Reference[nodes.size()];
|
||||
int iIndex = 0;
|
||||
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
// Cancel the checkout
|
||||
NodeRef origNode = AuthoringWebService.this.cociService.cancelCheckout(node);
|
||||
|
||||
// Set the value in the arrays
|
||||
origNodes[iIndex] = Utils.convertToReference(origNode);
|
||||
workingCopies[iIndex] = Utils.convertToReference(node);
|
||||
iIndex ++;
|
||||
}
|
||||
|
||||
CancelCheckoutResult result = new CancelCheckoutResult();
|
||||
result.setOriginals(origNodes);
|
||||
result.setWorkingCopies(workingCopies);
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new AuthoringFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authoring.AuthoringServiceSoapPort#lock(org.alfresco.repo.webservice.types.Predicate,
|
||||
* boolean, org.alfresco.repo.webservice.authoring.LockTypeEnum)
|
||||
*/
|
||||
public Reference[] lock(final Predicate items, final boolean lockChildren, final LockTypeEnum lockType)
|
||||
throws RemoteException, AuthoringFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<Reference[]>()
|
||||
{
|
||||
public Reference[] doWork()
|
||||
{
|
||||
// Get the passed nodes
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(
|
||||
items,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService);
|
||||
|
||||
// Gather together the results
|
||||
Reference[] result = new Reference[nodes.size()];
|
||||
int iIndex = 0;
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
LockType convertedLockType = convertToLockType(lockType);
|
||||
AuthoringWebService.this.lockService.lock(node, convertedLockType, 0, lockChildren);
|
||||
result[iIndex] = Utils.convertToReference(node);
|
||||
iIndex++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new AuthoringFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from the web service lock type to the Lock type enum value used by the service interface
|
||||
*
|
||||
* @param lockTypeEnum web service lock type value
|
||||
* @return lock type enum value used by the service interface
|
||||
*/
|
||||
private LockType convertToLockType(LockTypeEnum lockTypeEnum)
|
||||
{
|
||||
LockType lockType = null;
|
||||
if (lockTypeEnum.equals(LockTypeEnum.write) == true)
|
||||
{
|
||||
lockType = LockType.WRITE_LOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
lockType = LockType.READ_ONLY_LOCK;
|
||||
}
|
||||
return lockType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authoring.AuthoringServiceSoapPort#unlock(org.alfresco.repo.webservice.types.Predicate,
|
||||
* boolean)
|
||||
*/
|
||||
public Reference[] unlock(final Predicate items, final boolean unlockChildren)
|
||||
throws RemoteException, AuthoringFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<Reference[]>()
|
||||
{
|
||||
public Reference[] doWork()
|
||||
{
|
||||
// Get the passed nodes
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(
|
||||
items,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService);
|
||||
|
||||
// Gather together the results
|
||||
Reference[] result = new Reference[nodes.size()];
|
||||
int iIndex = 0;
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
AuthoringWebService.this.lockService.unlock(node, unlockChildren);
|
||||
|
||||
result[iIndex] = Utils.convertToReference(node);
|
||||
iIndex++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new AuthoringFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authoring.AuthoringServiceSoapPort#getLockStatus(org.alfresco.repo.webservice.types.Predicate)
|
||||
*/
|
||||
public LockStatus[] getLockStatus(final Predicate items)
|
||||
throws RemoteException, AuthoringFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<LockStatus[]>()
|
||||
{
|
||||
public LockStatus[] doWork()
|
||||
{
|
||||
// Get the passed nodes
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(
|
||||
items,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService);
|
||||
|
||||
// Gather together the results
|
||||
LockStatus[] result = new LockStatus[nodes.size()];
|
||||
int iIndex = 0;
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
// Get the lock owner
|
||||
String lockOwner = (String)AuthoringWebService.this.nodeService.getProperty(node, ContentModel.PROP_LOCK_OWNER);
|
||||
|
||||
// Get the lock type
|
||||
LockTypeEnum lockTypeEnum = convertFromLockType(AuthoringWebService.this.lockService.getLockType(node));
|
||||
|
||||
LockStatus lockStatus = new LockStatus();
|
||||
lockStatus.setLockOwner(lockOwner);
|
||||
lockStatus.setLockType(lockTypeEnum);
|
||||
lockStatus.setNode(Utils.convertToReference(node));
|
||||
|
||||
result[iIndex] = lockStatus;
|
||||
iIndex++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
e.printStackTrace();
|
||||
throw new AuthoringFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private LockTypeEnum convertFromLockType(LockType lockType)
|
||||
{
|
||||
LockTypeEnum result = null;
|
||||
if (lockType != null)
|
||||
{
|
||||
switch (lockType)
|
||||
{
|
||||
case WRITE_LOCK:
|
||||
result = LockTypeEnum.write;
|
||||
break;
|
||||
case READ_ONLY_LOCK:
|
||||
result = LockTypeEnum.read;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authoring.AuthoringServiceSoapPort#createVersion(org.alfresco.repo.webservice.types.Predicate,
|
||||
* org.alfresco.repo.webservice.types.NamedValue[], boolean)
|
||||
*/
|
||||
public VersionResult createVersion(final Predicate items, final NamedValue[] comments, final boolean versionChildren)
|
||||
throws RemoteException, AuthoringFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<VersionResult>()
|
||||
{
|
||||
public VersionResult doWork()
|
||||
{
|
||||
// Get the passed nodes
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(
|
||||
items,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService);
|
||||
|
||||
// Map the comments into the expected map
|
||||
Map<String, Serializable> mapComments = new HashMap<String, Serializable>(comments.length);
|
||||
for (NamedValue value : comments)
|
||||
{
|
||||
mapComments.put(value.getName(), value.getValue());
|
||||
}
|
||||
|
||||
List<Reference> versionedReferences = new ArrayList<Reference>(nodes.size());
|
||||
List<org.alfresco.repo.webservice.types.Version> webServiceVersions = new ArrayList<org.alfresco.repo.webservice.types.Version>(nodes.size());
|
||||
|
||||
// Version each node
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
Collection<Version> versions = AuthoringWebService.this.versionService.createVersion(node, mapComments, versionChildren);
|
||||
for (Version version : versions)
|
||||
{
|
||||
versionedReferences.add(Utils.convertToReference(version.getVersionedNodeRef()));
|
||||
webServiceVersions.add(Utils.convertToVersion(version));
|
||||
}
|
||||
}
|
||||
|
||||
VersionResult result = new VersionResult();
|
||||
result.setNodes(versionedReferences.toArray(new Reference[versionedReferences.size()]));
|
||||
result.setVersions(webServiceVersions.toArray(new org.alfresco.repo.webservice.types.Version[webServiceVersions.size()]));
|
||||
return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
throw new AuthoringFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authoring.AuthoringServiceSoapPort#getVersionHistory(org.alfresco.repo.webservice.types.Reference)
|
||||
*/
|
||||
public VersionHistory getVersionHistory(final Reference node)
|
||||
throws RemoteException, AuthoringFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<VersionHistory>()
|
||||
{
|
||||
public VersionHistory doWork()
|
||||
{
|
||||
org.alfresco.service.cmr.version.VersionHistory versionHistory =
|
||||
AuthoringWebService.this.versionService.getVersionHistory(
|
||||
Utils.convertToNodeRef(
|
||||
node,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService));
|
||||
|
||||
VersionHistory webServiceVersionHistory = new VersionHistory();
|
||||
if (versionHistory != null)
|
||||
{
|
||||
Collection<Version> versions = versionHistory.getAllVersions();
|
||||
org.alfresco.repo.webservice.types.Version[] webServiceVersions = new org.alfresco.repo.webservice.types.Version[versions.size()];
|
||||
int iIndex = 0;
|
||||
for (Version version : versions)
|
||||
{
|
||||
webServiceVersions[iIndex] = Utils.convertToVersion(version);
|
||||
iIndex ++;
|
||||
}
|
||||
webServiceVersionHistory.setVersions(webServiceVersions);
|
||||
}
|
||||
|
||||
return webServiceVersionHistory;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new AuthoringFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authoring.AuthoringServiceSoapPort#revertVersion(org.alfresco.repo.webservice.types.Reference,
|
||||
* java.lang.String)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void revertVersion(final Reference node, final String versionLabel)
|
||||
throws RemoteException, AuthoringFault
|
||||
{
|
||||
try
|
||||
{
|
||||
TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork()
|
||||
{
|
||||
public Object doWork()
|
||||
{
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(
|
||||
node,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService);
|
||||
|
||||
org.alfresco.service.cmr.version.VersionHistory versionHistory = AuthoringWebService.this.versionService.getVersionHistory(nodeRef);
|
||||
if (versionHistory != null)
|
||||
{
|
||||
Version version = versionHistory.getVersion(versionLabel);
|
||||
if (version != null)
|
||||
{
|
||||
AuthoringWebService.this.versionService.revert(nodeRef, version);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException("The node could not be reverted because the version label is invalid.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException("A unversioned node cannot be reverted.");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new AuthoringFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authoring.AuthoringServiceSoapPort#deleteAllVersions(org.alfresco.repo.webservice.types.Reference)
|
||||
*/
|
||||
public VersionHistory deleteAllVersions(final Reference node)
|
||||
throws RemoteException, AuthoringFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<VersionHistory>()
|
||||
{
|
||||
public VersionHistory doWork()
|
||||
{
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(
|
||||
node,
|
||||
AuthoringWebService.this.nodeService,
|
||||
AuthoringWebService.this.searchService,
|
||||
AuthoringWebService.this.namespaceService);
|
||||
|
||||
AuthoringWebService.this.versionService.deleteVersionHistory(nodeRef);
|
||||
|
||||
return new VersionHistory();
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new AuthoringFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.axis;
|
||||
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.types.QueryConfiguration;
|
||||
import org.apache.axis.AxisFault;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.axis.description.OperationDesc;
|
||||
import org.apache.axis.handlers.BasicHandler;
|
||||
import org.apache.axis.message.SOAPEnvelope;
|
||||
import org.apache.axis.message.SOAPHeaderElement;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Axis handler to extract the fetchSize parameter from the QueryConfiguration SOAP header.
|
||||
* The value of fetchSize is then placed in the MessageContext with a property name of
|
||||
* ALF_FETCH_SIZE
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class QueryConfigHandler extends BasicHandler
|
||||
{
|
||||
public static final String ALF_FETCH_SIZE = "ALF_FETCH_SIZE";
|
||||
|
||||
private static final long serialVersionUID = 6467938074555362971L;
|
||||
private static Log logger = LogFactory.getLog(QueryConfigHandler.class);
|
||||
|
||||
/**
|
||||
* @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
|
||||
*/
|
||||
public void invoke(MessageContext msgContext) throws AxisFault
|
||||
{
|
||||
try
|
||||
{
|
||||
// determine the method we are calling
|
||||
String opName = "Unknown method";
|
||||
OperationDesc op = msgContext.getOperation();
|
||||
if (op != null)
|
||||
{
|
||||
opName = op.getName();
|
||||
}
|
||||
|
||||
// try and find the appropriate header and extract info from it
|
||||
SOAPEnvelope env = msgContext.getRequestMessage().getSOAPEnvelope();
|
||||
SOAPHeaderElement header = env.getHeaderByName(Utils.REPOSITORY_SERVICE_NAMESPACE, "QueryHeader");
|
||||
if (header != null)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found QueryHeader for call to " + opName);
|
||||
|
||||
QueryConfiguration queryCfg = (QueryConfiguration)header.getObjectValue(QueryConfiguration.class);
|
||||
if (queryCfg != null)
|
||||
{
|
||||
int fetchSize = queryCfg.getFetchSize();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Fetch size for query = " + fetchSize);
|
||||
|
||||
msgContext.setProperty(ALF_FETCH_SIZE, new Integer(fetchSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Failed to find QueryConfiguration within QueryHeader");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("QueryHeader was not found for call to " + opName);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Failed to determine fetch size", e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.axis;
|
||||
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.apache.axis.AxisFault;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.axis.handlers.soap.SOAPService;
|
||||
import org.apache.axis.providers.java.RPCProvider;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
/**
|
||||
* A custom Axis RPC Provider that retrieves services via Spring
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class SpringBeanRPCProvider extends RPCProvider
|
||||
{
|
||||
private static final long serialVersionUID = 2173234269124176995L;
|
||||
private static final String OPTION_NAME = "springBean";
|
||||
private WebApplicationContext webAppCtx;
|
||||
|
||||
/**
|
||||
* Retrieves the class of the bean represented by the given name
|
||||
*
|
||||
* @see org.apache.axis.providers.java.JavaProvider#getServiceClass(java.lang.String, org.apache.axis.handlers.soap.SOAPService, org.apache.axis.MessageContext)
|
||||
*/
|
||||
@Override
|
||||
protected Class getServiceClass(String beanName, SOAPService service, MessageContext msgCtx) throws AxisFault
|
||||
{
|
||||
Class clazz = null;
|
||||
|
||||
Object bean = getBean(msgCtx, beanName);
|
||||
if (bean != null)
|
||||
{
|
||||
clazz = bean.getClass();
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.axis.providers.java.JavaProvider#getServiceClassNameOptionName()
|
||||
*/
|
||||
@Override
|
||||
protected String getServiceClassNameOptionName()
|
||||
{
|
||||
return OPTION_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the bean with the given name from the current spring context
|
||||
*
|
||||
* @see org.apache.axis.providers.java.JavaProvider#makeNewServiceObject(org.apache.axis.MessageContext, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected Object makeNewServiceObject(MessageContext msgCtx, String beanName) throws Exception
|
||||
{
|
||||
return getBean(msgCtx, beanName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the bean with the given name from the current spring context
|
||||
*
|
||||
* @param msgCtx Axis MessageContext
|
||||
* @param beanName Name of the bean to lookup
|
||||
* @return The instance of the bean
|
||||
*/
|
||||
private Object getBean(MessageContext msgCtx, String beanName) throws AxisFault
|
||||
{
|
||||
return getWebAppContext(msgCtx).getBean(beanName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Spring context from the web application
|
||||
*
|
||||
* @param msgCtx Axis MessageContext
|
||||
* @return The Spring web app context
|
||||
*/
|
||||
private WebApplicationContext getWebAppContext(MessageContext msgCtx) throws AxisFault
|
||||
{
|
||||
if (this.webAppCtx == null && msgCtx != null)
|
||||
{
|
||||
this.webAppCtx = Utils.getSpringContext(msgCtx);
|
||||
}
|
||||
|
||||
if (this.webAppCtx == null)
|
||||
{
|
||||
throw new AxisFault("Failed to retrieve the Spring web application context");
|
||||
}
|
||||
|
||||
return this.webAppCtx;
|
||||
}
|
||||
}
|
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.axis;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.repo.webservice.authentication.AuthenticationFault;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.ws.security.WSPasswordCallback;
|
||||
|
||||
/**
|
||||
* CallbackHandler that verifies the given ticket in the password element of the UsernameToken
|
||||
* header is still a valid ticket
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class TicketCallbackHandler implements CallbackHandler
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(TicketCallbackHandler.class);
|
||||
|
||||
private AuthenticationService authenticationService;
|
||||
|
||||
/**
|
||||
* Sets the AuthenticationService instance to use
|
||||
*
|
||||
* @param authenticationService The AuthenticationService
|
||||
*/
|
||||
public void setAuthenticationService(AuthenticationService authenticationService)
|
||||
{
|
||||
this.authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
|
||||
*/
|
||||
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
|
||||
{
|
||||
for (int i = 0; i < callbacks.length; i++)
|
||||
{
|
||||
if (callbacks[i] instanceof WSPasswordCallback)
|
||||
{
|
||||
WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
|
||||
String ticket = pc.getPassword();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Verifying ticket for: " + pc.getIdentifer());
|
||||
logger.debug("Ticket: " + ticket);
|
||||
}
|
||||
|
||||
// ensure the ticket is valid
|
||||
try
|
||||
{
|
||||
this.authenticationService.validate(ticket);
|
||||
}
|
||||
catch (AuthenticationException ae)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Ticket validation failed: " + ae.getMessage());
|
||||
|
||||
// NOTE: Throwing AuthenticationFault just gets consumed and the ws-security handler
|
||||
// reports a missing password; we would need to modify the WSS4J code to let
|
||||
// the exception bubble up so for now just let the default message get thrown
|
||||
throw new AuthenticationFault(701, "Authentication failed due to an invalid ticket");
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Ticket validated successfully");
|
||||
|
||||
// if all is well set the password to return as the given ticket
|
||||
pc.setPassword(pc.getPassword());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.axis;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.axis.AxisFault;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.axis.handlers.BasicHandler;
|
||||
import org.apache.axis.transport.http.HTTPConstants;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.ws.security.handler.WSHandlerConstants;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
/**
|
||||
* Axis handler that retrieves the TicketCallbackHandler instance from
|
||||
* a Spring context. The authentication service is injected by Spring
|
||||
* so that when it gets called by the WSS4J handler it can verify the
|
||||
* ticket passed to the service.
|
||||
* The callback handler is then added to the MessageContext under the standard
|
||||
* WsHandlerConstants.PW_CALLBACK_REF property.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class TicketCallbackSpringHandler extends BasicHandler
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(TicketCallbackSpringHandler.class);
|
||||
private static final String BEAN_NAME = "ticketCallbackHandler";
|
||||
private static final long serialVersionUID = -135125831180499667L;
|
||||
|
||||
/**
|
||||
* @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
|
||||
*/
|
||||
public void invoke(MessageContext msgContext) throws AxisFault
|
||||
{
|
||||
// get hold of the Spring context and retrieve the AuthenticationService
|
||||
HttpServletRequest req = (HttpServletRequest)msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
|
||||
ServletContext servletCtx = req.getSession().getServletContext();
|
||||
WebApplicationContext webAppCtx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletCtx);
|
||||
TicketCallbackHandler callback = (TicketCallbackHandler)webAppCtx.getBean(BEAN_NAME);
|
||||
|
||||
// store the callback in the context where the WS-Security handler can pick it up from
|
||||
msgContext.setProperty(WSHandlerConstants.PW_CALLBACK_REF, callback);
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.axis;
|
||||
|
||||
import org.apache.axis.EngineConfiguration;
|
||||
import org.apache.axis.Handler;
|
||||
import org.apache.axis.deployment.wsdd.WSDDProvider;
|
||||
import org.apache.axis.deployment.wsdd.WSDDService;
|
||||
|
||||
/**
|
||||
* Provider class loaded by Axis, used to identify and
|
||||
* create an instance of our SpringRPC provider which in
|
||||
* turn loads service endpoints from Spring configured beans
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.axis.SpringBeanRPCProvider
|
||||
* @author gavinc
|
||||
*/
|
||||
public class WSDDSpringBeanRPCProvider extends WSDDProvider
|
||||
{
|
||||
private static final String PROVIDER_NAME = "SpringRPC";
|
||||
|
||||
/**
|
||||
* @see org.apache.axis.deployment.wsdd.WSDDProvider#newProviderInstance(org.apache.axis.deployment.wsdd.WSDDService, org.apache.axis.EngineConfiguration)
|
||||
*/
|
||||
@Override
|
||||
public Handler newProviderInstance(WSDDService service, EngineConfiguration registry)
|
||||
throws Exception
|
||||
{
|
||||
return new SpringBeanRPCProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.axis.deployment.wsdd.WSDDProvider#getName()
|
||||
*/
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return PROVIDER_NAME;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,454 @@
|
||||
/*
|
||||
* 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.classification;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transaction.TransactionUtil;
|
||||
import org.alfresco.repo.webservice.AbstractWebService;
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.types.Category;
|
||||
import org.alfresco.repo.webservice.types.ClassDefinition;
|
||||
import org.alfresco.repo.webservice.types.Classification;
|
||||
import org.alfresco.repo.webservice.types.Predicate;
|
||||
import org.alfresco.repo.webservice.types.Reference;
|
||||
import org.alfresco.repo.webservice.types.Store;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Web service implementation of the ClassificationService. The WSDL for this
|
||||
* service can be accessed from
|
||||
* http://localhost:8080/alfresco/wsdl/classification-service.wsdl
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class ClassificationWebService extends AbstractWebService implements
|
||||
ClassificationServiceSoapPort
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(ClassificationWebService.class);
|
||||
|
||||
/**
|
||||
* The category service
|
||||
*/
|
||||
private CategoryService categoryService;
|
||||
|
||||
/**
|
||||
* The dictionary service
|
||||
*/
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
/**
|
||||
* The transaction service
|
||||
*/
|
||||
private TransactionService transactionService;
|
||||
|
||||
/**
|
||||
* Set the category service
|
||||
*
|
||||
* @param categoryService the category service
|
||||
*/
|
||||
public void setCategoryService(CategoryService categoryService)
|
||||
{
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transaction service
|
||||
*
|
||||
* @param transactionService the transaction service
|
||||
*/
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dictionary service
|
||||
*
|
||||
* @param dictionaryService the dictionary service
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.classification.ClassificationServiceSoapPort#getClassifications()
|
||||
*/
|
||||
public Classification[] getClassifications(final Store store) throws RemoteException,
|
||||
ClassificationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<Classification[]>()
|
||||
{
|
||||
public Classification[] doWork()
|
||||
{
|
||||
List<Classification> classifications = new ArrayList<Classification>();
|
||||
|
||||
Collection<QName> categoryAspects = ClassificationWebService.this.categoryService.getClassificationAspects();
|
||||
for (QName aspect : categoryAspects)
|
||||
{
|
||||
// Get the title of the cateogry
|
||||
String title = null;
|
||||
org.alfresco.service.cmr.dictionary.ClassDefinition aspectDefinition = ClassificationWebService.this.dictionaryService.getClass(aspect);
|
||||
if (aspectDefinition != null)
|
||||
{
|
||||
title = aspectDefinition.getTitle();
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Category aspect found: " + title + " (" + aspect.toString() + ")");
|
||||
}
|
||||
|
||||
Collection<ChildAssociationRef> assocs = ClassificationWebService.this.categoryService.getCategories(
|
||||
Utils.convertToStoreRef(store),
|
||||
aspect,
|
||||
CategoryService.Depth.IMMEDIATE);
|
||||
for (ChildAssociationRef assoc : assocs)
|
||||
{
|
||||
NodeRef categoryNodeRef = assoc.getChildRef();
|
||||
|
||||
Classification classification = new Classification();
|
||||
classification.setClassification(aspect.toString());
|
||||
classification.setTitle(title);
|
||||
// TODO set the description
|
||||
classification.setRootCategory(convertToCategory(categoryNodeRef));
|
||||
|
||||
classifications.add(classification);
|
||||
}
|
||||
}
|
||||
|
||||
return classifications.toArray(new Classification[classifications.size()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new ClassificationFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Category convertToCategory(NodeRef nodeRef)
|
||||
{
|
||||
String title = (String)this.nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Category: " + title + "(" + nodeRef.toString() + ")");
|
||||
}
|
||||
|
||||
Category category = new Category();
|
||||
category.setId(Utils.convertToReference(nodeRef));
|
||||
category.setTitle(title);
|
||||
// TODO need to set the description
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.classification.ClassificationServiceSoapPort#getChildCategories(org.alfresco.repo.webservice.types.Reference)
|
||||
*/
|
||||
public Category[] getChildCategories(final Reference parentCategory)
|
||||
throws RemoteException, ClassificationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<Category[]>()
|
||||
{
|
||||
public Category[] doWork()
|
||||
{
|
||||
NodeRef parentNodeRef = Utils.convertToNodeRef(
|
||||
parentCategory,
|
||||
ClassificationWebService.this.nodeService,
|
||||
ClassificationWebService.this.searchService,
|
||||
ClassificationWebService.this.namespaceService);
|
||||
|
||||
Collection<ChildAssociationRef> assocs = ClassificationWebService.this.categoryService.getChildren(
|
||||
parentNodeRef,
|
||||
CategoryService.Mode.SUB_CATEGORIES,
|
||||
CategoryService.Depth.IMMEDIATE);
|
||||
|
||||
List<Category> categories = new ArrayList<Category>(assocs.size());
|
||||
|
||||
for (ChildAssociationRef assoc : assocs)
|
||||
{
|
||||
NodeRef categoryNodeRef = assoc.getChildRef();
|
||||
categories.add(convertToCategory(categoryNodeRef));
|
||||
}
|
||||
|
||||
return categories.toArray(new Category[categories.size()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new ClassificationFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.classification.ClassificationServiceSoapPort#getCategories(org.alfresco.repo.webservice.types.Predicate)
|
||||
*/
|
||||
public CategoriesResult[] getCategories(final Predicate items)
|
||||
throws RemoteException, ClassificationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<CategoriesResult[]>()
|
||||
{
|
||||
public CategoriesResult[] doWork()
|
||||
{
|
||||
List<CategoriesResult> result = new ArrayList<CategoriesResult>();
|
||||
|
||||
List<NodeRef> nodeRefs = Utils.resolvePredicate(
|
||||
items,
|
||||
ClassificationWebService.this.nodeService,
|
||||
ClassificationWebService.this.searchService,
|
||||
ClassificationWebService.this.namespaceService);
|
||||
|
||||
for (NodeRef nodeRef : nodeRefs)
|
||||
{
|
||||
List<AppliedCategory> appliedCategories = new ArrayList<AppliedCategory>();
|
||||
|
||||
Set<QName> apsects = ClassificationWebService.this.nodeService.getAspects(nodeRef);
|
||||
for (QName aspect : apsects)
|
||||
{
|
||||
if (ClassificationWebService.this.dictionaryService.isSubClass(aspect, ContentModel.ASPECT_CLASSIFIABLE) == true)
|
||||
{
|
||||
QName categoryPropertyName = getPropertyName(aspect);
|
||||
|
||||
if (categoryPropertyName != null)
|
||||
{
|
||||
// Get the category value
|
||||
Collection<NodeRef> categoryNodeRefs = DefaultTypeConverter.INSTANCE.getCollection(
|
||||
NodeRef.class,
|
||||
ClassificationWebService.this.nodeService.getProperty(nodeRef, categoryPropertyName));
|
||||
|
||||
Reference[] categoryReferences = new Reference[categoryNodeRefs.size()];
|
||||
int iIndex = 0;
|
||||
for (NodeRef categoryNodeRef : categoryNodeRefs)
|
||||
{
|
||||
categoryReferences[iIndex] = Utils.convertToReference(categoryNodeRef);
|
||||
iIndex ++;
|
||||
}
|
||||
|
||||
|
||||
// Create the applied category object
|
||||
AppliedCategory appliedCategory = new AppliedCategory();
|
||||
appliedCategory.setClassification(aspect.toString());
|
||||
appliedCategory.setCategories(categoryReferences);
|
||||
|
||||
appliedCategories.add(appliedCategory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the category result object
|
||||
CategoriesResult categoryResult = new CategoriesResult();
|
||||
categoryResult.setNode(Utils.convertToReference(nodeRef));
|
||||
categoryResult.setCategories(appliedCategories.toArray(new AppliedCategory[appliedCategories.size()]));
|
||||
|
||||
result.add(categoryResult);
|
||||
}
|
||||
|
||||
return result.toArray(new CategoriesResult[result.size()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new ClassificationFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the category property qname for a classifiable apsect
|
||||
*
|
||||
* @param aspect the aspect qname
|
||||
* @return the property qname, null if none found
|
||||
*/
|
||||
private QName getPropertyName(QName aspect)
|
||||
{
|
||||
QName categoryPropertyName = null;
|
||||
|
||||
// Need to get category property
|
||||
org.alfresco.service.cmr.dictionary.ClassDefinition classDefinition = ClassificationWebService.this.dictionaryService.getClass(aspect);
|
||||
for (PropertyDefinition propertyDefintion : classDefinition.getProperties().values())
|
||||
{
|
||||
if (DataTypeDefinition.CATEGORY.equals(propertyDefintion.getDataType().getName()) == true)
|
||||
{
|
||||
// We have found the category property (assume there is only one)
|
||||
categoryPropertyName = propertyDefintion.getName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return categoryPropertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.classification.ClassificationServiceSoapPort#setCategories(org.alfresco.repo.webservice.types.Predicate,
|
||||
* org.alfresco.repo.webservice.classification.AppliedCategory[])
|
||||
*/
|
||||
public CategoriesResult[] setCategories(final Predicate items, final AppliedCategory[] categories)
|
||||
throws RemoteException, ClassificationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<CategoriesResult[]>()
|
||||
{
|
||||
public CategoriesResult[] doWork()
|
||||
{
|
||||
List<CategoriesResult> result = new ArrayList<CategoriesResult>();
|
||||
|
||||
List<NodeRef> nodeRefs = Utils.resolvePredicate(
|
||||
items,
|
||||
ClassificationWebService.this.nodeService,
|
||||
ClassificationWebService.this.searchService,
|
||||
ClassificationWebService.this.namespaceService);
|
||||
|
||||
for (NodeRef nodeRef : nodeRefs)
|
||||
{
|
||||
List<AppliedCategory> appliedCategories = new ArrayList<AppliedCategory>();
|
||||
|
||||
for (AppliedCategory category : categories)
|
||||
{
|
||||
QName aspect = QName.createQName(category.getClassification());
|
||||
QName propertyName = getPropertyName(aspect);
|
||||
if (propertyName != null)
|
||||
{
|
||||
// First check that the aspect has been applied to the node
|
||||
if (ClassificationWebService.this.nodeService.hasAspect(nodeRef, aspect) == false)
|
||||
{
|
||||
ClassificationWebService.this.nodeService.addAspect(nodeRef, aspect, null);
|
||||
}
|
||||
|
||||
ArrayList<NodeRef> categoryNodeRefs = new ArrayList<NodeRef>(category.getCategories().length);
|
||||
for (Reference categoryReference : category.getCategories())
|
||||
{
|
||||
categoryNodeRefs.add(Utils.convertToNodeRef(
|
||||
categoryReference,
|
||||
ClassificationWebService.this.nodeService,
|
||||
ClassificationWebService.this.searchService,
|
||||
ClassificationWebService.this.namespaceService));
|
||||
}
|
||||
|
||||
ClassificationWebService.this.nodeService.setProperty(nodeRef, propertyName, categoryNodeRefs);
|
||||
|
||||
// Create the applied category object
|
||||
AppliedCategory appliedCategory = new AppliedCategory();
|
||||
appliedCategory.setClassification(category.getClassification());
|
||||
appliedCategory.setCategories(category.getCategories());
|
||||
|
||||
appliedCategories.add(appliedCategory);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create the category result object
|
||||
CategoriesResult categoryResult = new CategoriesResult();
|
||||
categoryResult.setNode(Utils.convertToReference(nodeRef));
|
||||
categoryResult.setCategories(appliedCategories.toArray(new AppliedCategory[appliedCategories.size()]));
|
||||
|
||||
result.add(categoryResult);
|
||||
}
|
||||
|
||||
return result.toArray(new CategoriesResult[result.size()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new ClassificationFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.classification.ClassificationServiceSoapPort#describeClassification(org.alfresco.repo.webservice.types.Reference)
|
||||
*/
|
||||
public ClassDefinition describeClassification(final String classification)
|
||||
throws RemoteException, ClassificationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
return TransactionUtil.executeInUserTransaction(
|
||||
this.transactionService,
|
||||
new TransactionUtil.TransactionWork<ClassDefinition>()
|
||||
{
|
||||
public ClassDefinition doWork()
|
||||
{
|
||||
org.alfresco.service.cmr.dictionary.ClassDefinition classDefinition = ClassificationWebService.this.dictionaryService.getClass(QName.createQName(classification));
|
||||
return Utils.setupClassDefObject(classDefinition);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new ClassificationFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
9
source/java/org/alfresco/repo/webservice/cml-test.xml
Normal file
9
source/java/org/alfresco/repo/webservice/cml-test.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||
|
||||
<beans>
|
||||
|
||||
<import resource="classpath:alfresco/application-context.xml" />
|
||||
<import resource="classpath:web-services-application-context.xml" />
|
||||
|
||||
</beans>
|
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* 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.content;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.rmi.RemoteException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.webservice.AbstractWebService;
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.types.ContentFormat;
|
||||
import org.alfresco.repo.webservice.types.Predicate;
|
||||
import org.alfresco.repo.webservice.types.Reference;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.axis.transport.http.HTTPConstants;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Web service implementation of the ContentService. The WSDL for this service
|
||||
* can be accessed from http://localhost:8080/alfresco/wsdl/content-service.wsdl
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class ContentWebService extends AbstractWebService implements
|
||||
ContentServiceSoapPort
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(ContentWebService.class);
|
||||
|
||||
private static final String BROWSER_URL = "{0}://{1}{2}/download/direct/{3}/{4}/{5}/{6}";
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.content.ContentServiceSoapPort#read(org.alfresco.repo.webservice.types.Reference)
|
||||
*/
|
||||
public Content[] read(Predicate items, String property)
|
||||
throws RemoteException, ContentFault
|
||||
{
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
|
||||
tx.begin();
|
||||
|
||||
// resolve the predicates
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(items, this.nodeService, this.searchService, this.namespaceService);
|
||||
List<Content> results = new ArrayList<Content>(nodes.size());
|
||||
for (NodeRef nodeRef : nodes)
|
||||
{
|
||||
// Add content to the result
|
||||
results.add(createContent(nodeRef, property));
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
|
||||
return results.toArray(new Content[results.size()]);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new ContentFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the content object
|
||||
*
|
||||
* @param nodeRef the node reference
|
||||
* @param property the content property
|
||||
* @return the content object
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
private Content createContent(NodeRef nodeRef, String property)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
Content content = null;
|
||||
|
||||
// Lets have a look and see if this node has any content on this node
|
||||
ContentReader contentReader = this.contentService.getReader(nodeRef, QName.createQName(property));
|
||||
|
||||
if (contentReader != null)
|
||||
{
|
||||
// Work out what the server, port and context path are
|
||||
HttpServletRequest req = (HttpServletRequest)MessageContext.getCurrentContext().getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
|
||||
|
||||
String address = req.getLocalName();
|
||||
if (req.getLocalPort() != 80)
|
||||
{
|
||||
address = address + ":" + req.getLocalPort();
|
||||
}
|
||||
|
||||
// Get the file name
|
||||
String filename = (String)this.nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||
|
||||
// format the URL that can be used to download the content
|
||||
String downloadUrl = MessageFormat.format(BROWSER_URL,
|
||||
new Object[] { req.getScheme(), address,
|
||||
req.getContextPath(),
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId(),
|
||||
URLEncoder.encode(filename, "UTF-8") });
|
||||
|
||||
// Create the content object
|
||||
ContentFormat format = new ContentFormat(contentReader.getMimetype(), contentReader.getEncoding());
|
||||
content = new Content(Utils.convertToReference(nodeRef), property, contentReader.getSize(), format, downloadUrl);
|
||||
|
||||
// Debug
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Content: " + nodeRef.getId() + " name="
|
||||
+ filename + " encoding="
|
||||
+ content.getFormat().getEncoding() + " mimetype="
|
||||
+ content.getFormat().getMimetype() + " size="
|
||||
+ content.getLength() + " downloadURL="
|
||||
+ content.getUrl());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create an empty content object
|
||||
content = new Content(Utils.convertToReference(nodeRef), property, 0, null, null);
|
||||
|
||||
// Debug
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("No content found: " + nodeRef.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.content.ContentServiceSoapPort#write(org.alfresco.repo.webservice.types.Reference,
|
||||
* byte[])
|
||||
*/
|
||||
public Content write(Reference node, String property, byte[] content, ContentFormat format)
|
||||
throws RemoteException, ContentFault
|
||||
{
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
|
||||
tx.begin();
|
||||
|
||||
// create a NodeRef from the parent reference
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(node, this.nodeService,
|
||||
this.searchService, this.namespaceService);
|
||||
|
||||
// Get the content writer
|
||||
ContentWriter writer = this.contentService.getWriter(nodeRef, QName.createQName(property), true);
|
||||
|
||||
// Set the content format details (if they have been specified)
|
||||
if (format != null)
|
||||
{
|
||||
writer.setEncoding(format.getEncoding());
|
||||
writer.setMimetype(format.getMimetype());
|
||||
}
|
||||
|
||||
// Write the content
|
||||
writer.putContent(new String(content));
|
||||
|
||||
// Debug
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Updated content for node with id: " + nodeRef.getId());
|
||||
}
|
||||
|
||||
// Commit the transaction
|
||||
tx.commit();
|
||||
|
||||
// Return the content object
|
||||
return createContent(nodeRef, property);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// Rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new ContentFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.content.ContentServiceSoapPort#clear(org.alfresco.repo.webservice.types.Predicate,
|
||||
* java.lang.String)
|
||||
*/
|
||||
public Content[] clear(Predicate items, String property)
|
||||
throws RemoteException, ContentFault
|
||||
{
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
|
||||
tx.begin();
|
||||
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(items, this.nodeService,this.searchService, this.namespaceService);
|
||||
Content[] contents = new Content[nodes.size()];
|
||||
|
||||
// delete each node in the predicate
|
||||
for (int x = 0; x < nodes.size(); x++)
|
||||
{
|
||||
NodeRef nodeRef = nodes.get(x);
|
||||
|
||||
// Clear the content
|
||||
this.nodeService.setProperty(nodeRef, QName.createQName(property), null);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Cleared content node with id: " + nodeRef.getId());
|
||||
}
|
||||
|
||||
contents[x] = createContent(nodeRef, property);
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
|
||||
return contents;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new ContentFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.repository;
|
||||
|
||||
import org.alfresco.util.GUID;
|
||||
|
||||
/**
|
||||
* Abstract implementation of a QuerySession providing support
|
||||
* for automatic id generation and provides support for
|
||||
* paging through query results.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public abstract class AbstractQuerySession implements QuerySession
|
||||
{
|
||||
protected int batchSize;
|
||||
protected int position = 0;
|
||||
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Common constructor that initialises the session's id and batch size
|
||||
*
|
||||
* @param batchSize The batch size this session will use
|
||||
*/
|
||||
public AbstractQuerySession(int batchSize)
|
||||
{
|
||||
this.id = GUID.generate();
|
||||
this.batchSize = batchSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.QuerySession#getId()
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the index of the last row to retrieve.
|
||||
*
|
||||
* @param totalRowCount The total number of rows in the results
|
||||
* @return The index of the last row to return
|
||||
*/
|
||||
protected int calculateLastRowIndex(int totalRowCount)
|
||||
{
|
||||
int lastRowIndex = totalRowCount;
|
||||
|
||||
// set the last row index if there are more results available
|
||||
// than the batch size
|
||||
if ((this.batchSize != -1) && ((this.position + this.batchSize) < totalRowCount))
|
||||
{
|
||||
lastRowIndex = this.position + this.batchSize;
|
||||
}
|
||||
|
||||
return lastRowIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the value of the next position.
|
||||
* If the end of the result set is reached the position is set to -1
|
||||
*
|
||||
* @param totalRowCount The total number of rows in the results
|
||||
* @param queryResult The QueryResult object being returned to the client,
|
||||
* if there are no more results the id is removed from the QueryResult instance
|
||||
*/
|
||||
protected void updatePosition(int totalRowCount, QueryResult queryResult)
|
||||
{
|
||||
this.position += this.batchSize;
|
||||
if (this.position >= totalRowCount)
|
||||
{
|
||||
// signify that there are no more results
|
||||
this.position = -1;
|
||||
queryResult.setQuerySession(null);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.types.NamedValue;
|
||||
import org.alfresco.repo.webservice.types.Reference;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRow;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRowNode;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
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.service.namespace.RegexQNamePattern;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Implementation of a QuerySession that stores the results from a query for
|
||||
* associations
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class AssociatedQuerySession extends AbstractQuerySession
|
||||
{
|
||||
private static final long serialVersionUID = 6488008047324436124L;
|
||||
|
||||
private transient static Log logger = LogFactory
|
||||
.getLog(AssociatedQuerySession.class);
|
||||
|
||||
private Reference node;
|
||||
|
||||
/**
|
||||
* Constructs a AssociatedQuerySession
|
||||
*
|
||||
* @param batchSize
|
||||
* The batch size to use for this session
|
||||
* @param node
|
||||
* The node to retrieve the associations
|
||||
*/
|
||||
public AssociatedQuerySession(int batchSize, Reference node)
|
||||
{
|
||||
super(batchSize);
|
||||
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.QuerySession#getNextResultsBatch(org.alfresco.service.cmr.search.SearchService,
|
||||
* org.alfresco.service.cmr.repository.NodeService,
|
||||
* org.alfresco.service.namespace.NamespaceService)
|
||||
*/
|
||||
public QueryResult getNextResultsBatch(SearchService searchService,
|
||||
NodeService nodeService, NamespaceService namespaceService)
|
||||
{
|
||||
QueryResult queryResult = null;
|
||||
|
||||
if (this.position != -1)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Before getNextResultsBatch: " + toString());
|
||||
|
||||
// create the node ref and get the children from the repository
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(this.node, nodeService,
|
||||
searchService, namespaceService);
|
||||
List<AssociationRef> assocs = nodeService.getTargetAssocs(nodeRef,
|
||||
RegexQNamePattern.MATCH_ALL);
|
||||
|
||||
int totalRows = assocs.size();
|
||||
int lastRow = calculateLastRowIndex(totalRows);
|
||||
int currentBatchSize = lastRow - this.position;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Total rows = " + totalRows
|
||||
+ ", current batch size = " + currentBatchSize);
|
||||
|
||||
org.alfresco.repo.webservice.types.ResultSet batchResults = new org.alfresco.repo.webservice.types.ResultSet();
|
||||
org.alfresco.repo.webservice.types.ResultSetRow[] rows = new org.alfresco.repo.webservice.types.ResultSetRow[currentBatchSize];
|
||||
|
||||
int arrPos = 0;
|
||||
for (int x = this.position; x < lastRow; x++)
|
||||
{
|
||||
AssociationRef assoc = assocs.get(x);
|
||||
NodeRef childNodeRef = assoc.getTargetRef();
|
||||
ResultSetRowNode rowNode = new ResultSetRowNode(childNodeRef
|
||||
.getId(), nodeService.getType(childNodeRef).toString(),
|
||||
null);
|
||||
|
||||
// create columns for all the properties of the node
|
||||
// get the data for the row and build up the columns structure
|
||||
Map<QName, Serializable> props = nodeService
|
||||
.getProperties(childNodeRef);
|
||||
NamedValue[] columns = new NamedValue[props.size()];
|
||||
int col = 0;
|
||||
for (QName propName : props.keySet())
|
||||
{
|
||||
String value = null;
|
||||
Serializable valueObj = props.get(propName);
|
||||
if (valueObj != null)
|
||||
{
|
||||
value = valueObj.toString();
|
||||
}
|
||||
columns[col] = new NamedValue(propName.toString(), value);
|
||||
col++;
|
||||
}
|
||||
|
||||
ResultSetRow row = new ResultSetRow();
|
||||
row.setRowIndex(x);
|
||||
row.setNode(rowNode);
|
||||
row.setColumns(columns);
|
||||
|
||||
// add the row to the overall results
|
||||
rows[arrPos] = row;
|
||||
arrPos++;
|
||||
}
|
||||
|
||||
// add the rows to the result set and set the total row count
|
||||
batchResults.setRows(rows);
|
||||
batchResults.setTotalRowCount(totalRows);
|
||||
|
||||
queryResult = new QueryResult(getId(), batchResults);
|
||||
|
||||
// move the position on
|
||||
updatePosition(totalRows, queryResult);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("After getNextResultsBatch: " + toString());
|
||||
}
|
||||
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(super.toString());
|
||||
builder.append(" (id=").append(getId());
|
||||
builder.append(" batchSize=").append(this.batchSize);
|
||||
builder.append(" position=").append(this.position);
|
||||
builder.append(" node-id=").append(this.node.getUuid()).append(")");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.types.NamedValue;
|
||||
import org.alfresco.repo.webservice.types.Reference;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRow;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRowNode;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Implementation of a QuerySession that stores the results from a query for children
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class ChildrenQuerySession extends AbstractQuerySession
|
||||
{
|
||||
private static final long serialVersionUID = -5347036309571057074L;
|
||||
|
||||
private transient static Log logger = LogFactory.getLog(ChildrenQuerySession.class);
|
||||
|
||||
private Reference node;
|
||||
|
||||
/**
|
||||
* Constructs a ChildrenQuerySession
|
||||
*
|
||||
* @param batchSize The batch size to use for this session
|
||||
* @param node The node to retrieve the parents
|
||||
*/
|
||||
public ChildrenQuerySession(int batchSize, Reference node)
|
||||
{
|
||||
super(batchSize);
|
||||
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.QuerySession#getNextResultsBatch(org.alfresco.service.cmr.search.SearchService, org.alfresco.service.cmr.repository.NodeService, org.alfresco.service.namespace.NamespaceService)
|
||||
*/
|
||||
public QueryResult getNextResultsBatch(SearchService searchService, NodeService nodeService, NamespaceService namespaceService)
|
||||
{
|
||||
QueryResult queryResult = null;
|
||||
|
||||
if (this.position != -1)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Before getNextResultsBatch: " + toString());
|
||||
|
||||
// create the node ref and get the children from the repository
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(this.node, nodeService, searchService, namespaceService);
|
||||
List<ChildAssociationRef> kids = nodeService.getChildAssocs(nodeRef);
|
||||
|
||||
int totalRows = kids.size();
|
||||
int lastRow = calculateLastRowIndex(totalRows);
|
||||
int currentBatchSize = lastRow - this.position;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Total rows = " + totalRows + ", current batch size = " + currentBatchSize);
|
||||
|
||||
org.alfresco.repo.webservice.types.ResultSet batchResults = new org.alfresco.repo.webservice.types.ResultSet();
|
||||
org.alfresco.repo.webservice.types.ResultSetRow[] rows = new org.alfresco.repo.webservice.types.ResultSetRow[currentBatchSize];
|
||||
|
||||
int arrPos = 0;
|
||||
for (int x = this.position; x < lastRow; x++)
|
||||
{
|
||||
ChildAssociationRef assoc = kids.get(x);
|
||||
NodeRef childNodeRef = assoc.getChildRef();
|
||||
ResultSetRowNode rowNode = new ResultSetRowNode(childNodeRef.getId(), nodeService.getType(childNodeRef).toString(), null);
|
||||
|
||||
// create columns for all the properties of the node
|
||||
// get the data for the row and build up the columns structure
|
||||
Map<QName, Serializable> props = nodeService.getProperties(childNodeRef);
|
||||
NamedValue[] columns = new NamedValue[props.size()];
|
||||
int col = 0;
|
||||
for (QName propName : props.keySet())
|
||||
{
|
||||
String value = null;
|
||||
Serializable valueObj = props.get(propName);
|
||||
if (valueObj != null)
|
||||
{
|
||||
value = valueObj.toString();
|
||||
}
|
||||
columns[col] = new NamedValue(propName.toString(), value);
|
||||
col++;
|
||||
}
|
||||
|
||||
ResultSetRow row = new ResultSetRow();
|
||||
row.setRowIndex(x);
|
||||
row.setNode(rowNode);
|
||||
row.setColumns(columns);
|
||||
|
||||
// add the row to the overall results
|
||||
rows[arrPos] = row;
|
||||
arrPos++;
|
||||
}
|
||||
|
||||
// add the rows to the result set and set the total row count
|
||||
batchResults.setRows(rows);
|
||||
batchResults.setTotalRowCount(totalRows);
|
||||
|
||||
queryResult = new QueryResult(getId(), batchResults);
|
||||
|
||||
// move the position on
|
||||
updatePosition(totalRows, queryResult);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("After getNextResultsBatch: " + toString());
|
||||
}
|
||||
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(super.toString());
|
||||
builder.append(" (id=").append(getId());
|
||||
builder.append(" batchSize=").append(this.batchSize);
|
||||
builder.append(" position=").append(this.position);
|
||||
builder.append(" node-id=").append(this.node.getUuid()).append(")");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.types.NamedValue;
|
||||
import org.alfresco.repo.webservice.types.Reference;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRow;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRowNode;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Implementation of a QuerySession that stores the results from a query for parents
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class ParentsQuerySession extends AbstractQuerySession
|
||||
{
|
||||
private static final long serialVersionUID = 2539375863409175463L;
|
||||
|
||||
private transient static Log logger = LogFactory.getLog(ParentsQuerySession.class);
|
||||
|
||||
private Reference node;
|
||||
|
||||
/**
|
||||
* Constructs a ParentsQuerySession
|
||||
*
|
||||
* @param batchSize The batch size to use for this session
|
||||
* @param node The node to retrieve the parents
|
||||
*/
|
||||
public ParentsQuerySession(int batchSize, Reference node)
|
||||
{
|
||||
super(batchSize);
|
||||
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.QuerySession#getNextResultsBatch(org.alfresco.service.cmr.search.SearchService, org.alfresco.service.cmr.repository.NodeService, org.alfresco.service.namespace.NamespaceService)
|
||||
*/
|
||||
public QueryResult getNextResultsBatch(SearchService searchService, NodeService nodeService, NamespaceService namespaceService)
|
||||
{
|
||||
QueryResult queryResult = null;
|
||||
|
||||
if (this.position != -1)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Before getNextResultsBatch: " + toString());
|
||||
|
||||
// create the node ref and get the children from the repository
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(this.node, nodeService, searchService, namespaceService);
|
||||
List<ChildAssociationRef> parents = nodeService.getParentAssocs(nodeRef);
|
||||
|
||||
int totalRows = parents.size();
|
||||
int lastRow = calculateLastRowIndex(totalRows);
|
||||
int currentBatchSize = lastRow - this.position;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Total rows = " + totalRows + ", current batch size = " + currentBatchSize);
|
||||
|
||||
org.alfresco.repo.webservice.types.ResultSet batchResults = new org.alfresco.repo.webservice.types.ResultSet();
|
||||
org.alfresco.repo.webservice.types.ResultSetRow[] rows = new org.alfresco.repo.webservice.types.ResultSetRow[currentBatchSize];
|
||||
|
||||
int arrPos = 0;
|
||||
for (int x = this.position; x < lastRow; x++)
|
||||
{
|
||||
ChildAssociationRef assoc = parents.get(x);
|
||||
NodeRef parentNodeRef = assoc.getParentRef();
|
||||
ResultSetRowNode rowNode = new ResultSetRowNode(parentNodeRef.getId(), nodeService.getType(parentNodeRef).toString(), null);
|
||||
|
||||
// create columns for all the properties of the node
|
||||
// get the data for the row and build up the columns structure
|
||||
Map<QName, Serializable> props = nodeService.getProperties(parentNodeRef);
|
||||
NamedValue[] columns = new NamedValue[props.size()];
|
||||
int col = 0;
|
||||
for (QName propName : props.keySet())
|
||||
{
|
||||
String value = null;
|
||||
Serializable valueObj = props.get(propName);
|
||||
if (valueObj != null)
|
||||
{
|
||||
value = valueObj.toString();
|
||||
}
|
||||
columns[col] = new NamedValue(propName.toString(), value);
|
||||
col++;
|
||||
}
|
||||
|
||||
ResultSetRow row = new ResultSetRow();
|
||||
row.setRowIndex(x);
|
||||
row.setNode(rowNode);
|
||||
row.setColumns(columns);
|
||||
|
||||
// add the row to the overall results
|
||||
rows[arrPos] = row;
|
||||
arrPos++;
|
||||
}
|
||||
|
||||
// add the rows to the result set and set the total row count
|
||||
batchResults.setRows(rows);
|
||||
batchResults.setTotalRowCount(totalRows);
|
||||
|
||||
queryResult = new QueryResult(getId(), batchResults);
|
||||
|
||||
// move the position on
|
||||
updatePosition(totalRows, queryResult);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("After getNextResultsBatch: " + toString());
|
||||
}
|
||||
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(super.toString());
|
||||
builder.append(" (id=").append(getId());
|
||||
builder.append(" batchSize=").append(this.batchSize);
|
||||
builder.append(" position=").append(this.position);
|
||||
builder.append(" node-id=").append(this.node.getUuid()).append(")");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
|
||||
/**
|
||||
* Interface definition for a QuerySession.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public interface QuerySession extends Serializable
|
||||
{
|
||||
/**
|
||||
* Retrieves the id this query session can be identified as
|
||||
*
|
||||
* @return Id of this query session
|
||||
*/
|
||||
public String getId();
|
||||
|
||||
/**
|
||||
* Returns a QueryResult object representing the next batch of results.
|
||||
* QueryResult will contain a maximum of items as determined by the
|
||||
* <code>fetchSize</code> element of the QueryConfiguration SOAP header.
|
||||
*
|
||||
* When the last batch of results is being returned the querySession of
|
||||
* QueryResult will be null.
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.repository.QuerySession#getId()
|
||||
* @param searchService The SearchService to use for gathering the results
|
||||
* @param nodeService The NodeService to use for gathering the results
|
||||
* @param namespaceService The NamespaceService to use
|
||||
* @return QueryResult containing the next batch of results or null if there
|
||||
* are no more results
|
||||
*/
|
||||
public QueryResult getNextResultsBatch(SearchService searchService, NodeService nodeService,
|
||||
NamespaceService namespaceService);
|
||||
}
|
@@ -0,0 +1,681 @@
|
||||
/*
|
||||
* 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.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.alfresco.repo.webservice.AbstractWebService;
|
||||
import org.alfresco.repo.webservice.CMLUtil;
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.types.CML;
|
||||
import org.alfresco.repo.webservice.types.ClassDefinition;
|
||||
import org.alfresco.repo.webservice.types.NamedValue;
|
||||
import org.alfresco.repo.webservice.types.Node;
|
||||
import org.alfresco.repo.webservice.types.NodeDefinition;
|
||||
import org.alfresco.repo.webservice.types.Predicate;
|
||||
import org.alfresco.repo.webservice.types.Query;
|
||||
import org.alfresco.repo.webservice.types.QueryLanguageEnum;
|
||||
import org.alfresco.repo.webservice.types.Reference;
|
||||
import org.alfresco.repo.webservice.types.Store;
|
||||
import org.alfresco.repo.webservice.types.StoreEnum;
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Web service implementation of the RepositoryService. The WSDL for this
|
||||
* service can be accessed from
|
||||
* http://localhost:8080/alfresco/wsdl/repository-service.wsdl
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class RepositoryWebService extends AbstractWebService implements
|
||||
RepositoryServiceSoapPort
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(RepositoryWebService.class);
|
||||
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
private CMLUtil cmlUtil;
|
||||
|
||||
private SimpleCache<String, QuerySession> querySessionCache;
|
||||
|
||||
/**
|
||||
* Sets the instance of the DictionaryService to be used
|
||||
*
|
||||
* @param dictionaryService
|
||||
* The DictionaryService
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the CML Util
|
||||
*
|
||||
* @param cmlUtil CML util object
|
||||
*/
|
||||
public void setCmlUtil(CMLUtil cmlUtil)
|
||||
{
|
||||
this.cmlUtil = cmlUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the instance of the SimpleCache to be used
|
||||
*
|
||||
* @param querySessionCache
|
||||
* The SimpleCache
|
||||
*/
|
||||
public void setQuerySessionCache(
|
||||
SimpleCache<String, QuerySession> querySessionCache)
|
||||
{
|
||||
this.querySessionCache = querySessionCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#getStores()
|
||||
*/
|
||||
public Store[] getStores() throws RemoteException, RepositoryFault
|
||||
{
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
|
||||
tx.begin();
|
||||
|
||||
List<StoreRef> stores = this.nodeService.getStores();
|
||||
Store[] returnStores = new Store[stores.size()];
|
||||
for (int x = 0; x < stores.size(); x++)
|
||||
{
|
||||
StoreRef storeRef = stores.get(x);
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Store protocol :" + storeRef.getProtocol());
|
||||
}
|
||||
|
||||
StoreEnum storeEnum = StoreEnum.fromString(storeRef
|
||||
.getProtocol());
|
||||
Store store = new Store(storeEnum, storeRef.getIdentifier());
|
||||
returnStores[x] = store;
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
|
||||
return returnStores;
|
||||
} catch (Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new RepositoryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#query(org.alfresco.repo.webservice.types.Store,
|
||||
* org.alfresco.repo.webservice.types.Query, boolean)
|
||||
*/
|
||||
public QueryResult query(Store store, Query query, boolean includeMetaData)
|
||||
throws RemoteException, RepositoryFault
|
||||
{
|
||||
QueryLanguageEnum langEnum = query.getLanguage();
|
||||
|
||||
if (langEnum.equals(QueryLanguageEnum.cql)
|
||||
|| langEnum.equals(QueryLanguageEnum.xpath))
|
||||
{
|
||||
throw new RepositoryFault(110, "Only '"
|
||||
+ QueryLanguageEnum.lucene.getValue()
|
||||
+ "' queries are currently supported!");
|
||||
}
|
||||
|
||||
UserTransaction tx = null;
|
||||
MessageContext msgContext = MessageContext.getCurrentContext();
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(msgContext);
|
||||
tx.begin();
|
||||
|
||||
// setup a query session and get the first batch of results
|
||||
QuerySession querySession = new ResultSetQuerySession(Utils
|
||||
.getBatchSize(msgContext), store, query, includeMetaData);
|
||||
QueryResult queryResult = querySession
|
||||
.getNextResultsBatch(this.searchService, this.nodeService,
|
||||
this.namespaceService);
|
||||
|
||||
// add the session to the cache if there are more results to come
|
||||
if (queryResult.getQuerySession() != null)
|
||||
{
|
||||
// this.querySessionCache.putQuerySession(querySession);
|
||||
this.querySessionCache.put(queryResult.getQuerySession(),
|
||||
querySession);
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
|
||||
return queryResult;
|
||||
} catch (Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
throw new RepositoryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#queryChildren(org.alfresco.repo.webservice.types.Reference)
|
||||
*/
|
||||
public QueryResult queryChildren(Reference node) throws RemoteException,
|
||||
RepositoryFault
|
||||
{
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
|
||||
tx.begin();
|
||||
|
||||
// setup a query session and get the first batch of results
|
||||
QuerySession querySession = new ChildrenQuerySession(Utils
|
||||
.getBatchSize(MessageContext.getCurrentContext()), node);
|
||||
QueryResult queryResult = querySession
|
||||
.getNextResultsBatch(this.searchService, this.nodeService,
|
||||
this.namespaceService);
|
||||
|
||||
// add the session to the cache if there are more results to come
|
||||
if (queryResult.getQuerySession() != null)
|
||||
{
|
||||
// this.querySessionCache.putQuerySession(querySession);
|
||||
this.querySessionCache.put(queryResult.getQuerySession(),
|
||||
querySession);
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
|
||||
return queryResult;
|
||||
} catch (Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new RepositoryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#queryParents(org.alfresco.repo.webservice.types.Reference)
|
||||
*/
|
||||
public QueryResult queryParents(Reference node) throws RemoteException,
|
||||
RepositoryFault
|
||||
{
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
|
||||
tx.begin();
|
||||
|
||||
// setup a query session and get the first batch of results
|
||||
QuerySession querySession = new ParentsQuerySession(Utils
|
||||
.getBatchSize(MessageContext.getCurrentContext()), node);
|
||||
QueryResult queryResult = querySession
|
||||
.getNextResultsBatch(this.searchService, this.nodeService,
|
||||
this.namespaceService);
|
||||
|
||||
// add the session to the cache if there are more results to come
|
||||
if (queryResult.getQuerySession() != null)
|
||||
{
|
||||
// this.querySessionCache.putQuerySession(querySession);
|
||||
this.querySessionCache.put(queryResult.getQuerySession(),
|
||||
querySession);
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
|
||||
return queryResult;
|
||||
} catch (Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new RepositoryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#queryAssociated(org.alfresco.repo.webservice.types.Reference,
|
||||
* org.alfresco.repo.webservice.repository.Association[])
|
||||
*/
|
||||
public QueryResult queryAssociated(Reference node, Association[] association)
|
||||
throws RemoteException, RepositoryFault
|
||||
{
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
|
||||
tx.begin();
|
||||
|
||||
// setup a query session and get the first batch of results
|
||||
QuerySession querySession = new AssociatedQuerySession(Utils.getBatchSize(MessageContext.getCurrentContext()), node);
|
||||
QueryResult queryResult = querySession
|
||||
.getNextResultsBatch(this.searchService, this.nodeService,
|
||||
this.namespaceService);
|
||||
|
||||
// add the session to the cache if there are more results to come
|
||||
if (queryResult.getQuerySession() != null)
|
||||
{
|
||||
// this.querySessionCache.putQuerySession(querySession);
|
||||
this.querySessionCache.put(queryResult.getQuerySession(),
|
||||
querySession);
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
|
||||
return queryResult;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new RepositoryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#fetchMore(java.lang.String)
|
||||
*/
|
||||
public QueryResult fetchMore(String querySession) throws RemoteException,
|
||||
RepositoryFault
|
||||
{
|
||||
QueryResult queryResult = null;
|
||||
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
|
||||
tx.begin();
|
||||
|
||||
// try and get the QuerySession with the given id from the cache
|
||||
QuerySession session = this.querySessionCache.get(querySession);
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Invalid querySession id requested: "
|
||||
+ querySession);
|
||||
|
||||
throw new RepositoryFault(4, "querySession with id '"
|
||||
+ querySession + "' is invalid");
|
||||
}
|
||||
|
||||
// get the next batch of results
|
||||
queryResult = session.getNextResultsBatch(this.searchService,
|
||||
this.nodeService, this.namespaceService);
|
||||
|
||||
// remove the QuerySession from the cache if there are no more
|
||||
// results to come
|
||||
if (queryResult.getQuerySession() == null)
|
||||
{
|
||||
this.querySessionCache.remove(querySession);
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
|
||||
return queryResult;
|
||||
} catch (Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
if (e instanceof RepositoryFault)
|
||||
{
|
||||
throw (RepositoryFault) e;
|
||||
} else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new RepositoryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#update(org.alfresco.repo.webservice.types.CML)
|
||||
*/
|
||||
public UpdateResult[] update(CML statements) throws RemoteException,
|
||||
RepositoryFault
|
||||
{
|
||||
UpdateResult[] result = null;
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
|
||||
tx.begin();
|
||||
|
||||
result = this.cmlUtil.executeCML(statements);
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new RepositoryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#describe(org.alfresco.repo.webservice.types.Predicate)
|
||||
*/
|
||||
public NodeDefinition[] describe(Predicate items) throws RemoteException,
|
||||
RepositoryFault
|
||||
{
|
||||
NodeDefinition[] nodeDefs = null;
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
|
||||
tx.begin();
|
||||
|
||||
List<NodeRef> nodes = Utils
|
||||
.resolvePredicate(items, this.nodeService,
|
||||
this.searchService, this.namespaceService);
|
||||
nodeDefs = new NodeDefinition[nodes.size()];
|
||||
|
||||
for (int x = 0; x < nodes.size(); x++)
|
||||
{
|
||||
nodeDefs[x] = setupNodeDefObject(nodes.get(x));
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
|
||||
return nodeDefs;
|
||||
} catch (Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new RepositoryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a NodeDefinition web service type object for the given
|
||||
* repository NodeRef instance
|
||||
*
|
||||
* @param nodeRef The NodeRef to generate the NodeDefinition for
|
||||
* @return The NodeDefinition representation of nodeRef
|
||||
*/
|
||||
private NodeDefinition setupNodeDefObject(NodeRef nodeRef)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Building NodeDefinition for node: " + nodeRef);
|
||||
|
||||
TypeDefinition ddTypeDef = this.dictionaryService
|
||||
.getType(this.nodeService.getType(nodeRef));
|
||||
|
||||
// create the web service ClassDefinition type from the data dictionary TypeDefinition
|
||||
ClassDefinition typeDef = Utils.setupClassDefObject(ddTypeDef);
|
||||
|
||||
// create the web service ClassDefinition types to represent the aspects
|
||||
ClassDefinition[] aspectDefs = null;
|
||||
List<AspectDefinition> aspects = ddTypeDef.getDefaultAspects();
|
||||
if (aspects != null)
|
||||
{
|
||||
aspectDefs = new ClassDefinition[aspects.size()];
|
||||
int pos = 0;
|
||||
for (AspectDefinition ddAspectDef : aspects)
|
||||
{
|
||||
aspectDefs[pos] = Utils.setupClassDefObject(ddAspectDef);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return new NodeDefinition(typeDef, aspectDefs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nodes associatiated with the predicate provided. Usefull when the store and ids of the required
|
||||
* nodes are known.
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#get(org.alfresco.repo.webservice.types.Predicate)
|
||||
*/
|
||||
public Node[] get(Predicate where) throws RemoteException, RepositoryFault
|
||||
{
|
||||
Node[] nodes = null;
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
|
||||
tx.begin();
|
||||
|
||||
// Resolve the predicate to a list of node references
|
||||
List<NodeRef> nodeRefs = Utils.resolvePredicate(where, this.nodeService, this.searchService, this.namespaceService);
|
||||
nodes = new Node[nodeRefs.size()];
|
||||
int index = 0;
|
||||
for (NodeRef nodeRef : nodeRefs)
|
||||
{
|
||||
// Get the nodes reference
|
||||
Reference reference = Utils.convertToReference(nodeRef);
|
||||
|
||||
// Get the nodes type
|
||||
String type = this.nodeService.getType(nodeRef).toString();
|
||||
|
||||
// Get the nodes aspects
|
||||
Set<QName> aspectQNames = this.nodeService.getAspects(nodeRef);
|
||||
String[] aspects = new String[aspectQNames.size()];
|
||||
int aspectIndex = 0;
|
||||
for (QName aspectQName : aspectQNames)
|
||||
{
|
||||
aspects[aspectIndex] = aspectQName.toString();
|
||||
aspectIndex++;
|
||||
}
|
||||
|
||||
// Get the nodes properties
|
||||
Map<QName, Serializable> propertyMap = this.nodeService.getProperties(nodeRef);
|
||||
NamedValue[] properties = new NamedValue[propertyMap.size()];
|
||||
int propertyIndex = 0;
|
||||
for (Map.Entry<QName, Serializable> entry : propertyMap.entrySet())
|
||||
{
|
||||
String value = null;
|
||||
try
|
||||
{
|
||||
value = DefaultTypeConverter.INSTANCE.convert(String.class, entry.getValue());
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
value = entry.getValue().toString();
|
||||
}
|
||||
properties[propertyIndex] = new NamedValue(entry.getKey().toString(), value);
|
||||
propertyIndex++;
|
||||
}
|
||||
|
||||
// Create the node and add to the array
|
||||
Node node = new Node(reference, type, aspects, properties);
|
||||
nodes[index] = node;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new RepositoryFault(0, e.getMessage());
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
}
|
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.types.NamedValue;
|
||||
import org.alfresco.repo.webservice.types.Query;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRowNode;
|
||||
import org.alfresco.repo.webservice.types.Store;
|
||||
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.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Implementation of a QuerySession that retrieves results from a repository ResultSet
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class ResultSetQuerySession extends AbstractQuerySession
|
||||
{
|
||||
private static final long serialVersionUID = -9154514445963635138L;
|
||||
|
||||
private transient static Log logger = LogFactory.getLog(ResultSetQuerySession.class);
|
||||
|
||||
private Store store;
|
||||
private Query query;
|
||||
private boolean includeMetaData;
|
||||
|
||||
/**
|
||||
* Constructs a ResultSetQuerySession
|
||||
*
|
||||
* @param batchSize The batch size to use for this session
|
||||
* @param store The repository store to query against
|
||||
* @param query The query to execute
|
||||
* @param includeMetaData Whether to include metadata in the query results
|
||||
*/
|
||||
public ResultSetQuerySession(int batchSize, Store store, Query query, boolean includeMetaData)
|
||||
{
|
||||
super(batchSize);
|
||||
|
||||
this.store = store;
|
||||
this.query = query;
|
||||
this.includeMetaData = includeMetaData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.repository.QuerySession#getNextResultsBatch(org.alfresco.service.cmr.search.SearchService, org.alfresco.service.cmr.repository.NodeService, org.alfresco.service.namespace.NamespaceService)
|
||||
*/
|
||||
public QueryResult getNextResultsBatch(SearchService searchService, NodeService nodeService, NamespaceService namespaceService)
|
||||
{
|
||||
QueryResult queryResult = null;
|
||||
|
||||
if (this.position != -1)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Before getNextResultsBatch: " + toString());
|
||||
|
||||
// handle the special search string of * meaning, get everything
|
||||
String statement = query.getStatement();
|
||||
if (statement.equals("*"))
|
||||
{
|
||||
statement = "ISNODE:*";
|
||||
}
|
||||
ResultSet searchResults = null;
|
||||
try
|
||||
{
|
||||
searchResults = searchService.query(Utils.convertToStoreRef(this.store),
|
||||
this.query.getLanguage().getValue(), statement);
|
||||
|
||||
int totalRows = searchResults.length();
|
||||
int lastRow = calculateLastRowIndex(totalRows);
|
||||
int currentBatchSize = lastRow - this.position;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Total rows = " + totalRows + ", current batch size = " + currentBatchSize);
|
||||
|
||||
org.alfresco.repo.webservice.types.ResultSet batchResults = new org.alfresco.repo.webservice.types.ResultSet();
|
||||
org.alfresco.repo.webservice.types.ResultSetRow[] rows = new org.alfresco.repo.webservice.types.ResultSetRow[currentBatchSize];
|
||||
|
||||
int arrPos = 0;
|
||||
for (int x = this.position; x < lastRow; x++)
|
||||
{
|
||||
ResultSetRow origRow = searchResults.getRow(x);
|
||||
NodeRef nodeRef = origRow.getNodeRef();
|
||||
ResultSetRowNode rowNode = new ResultSetRowNode(nodeRef.getId(), nodeService.getType(nodeRef).toString(), null);
|
||||
|
||||
// get the data for the row and build up the columns structure
|
||||
Map<Path, Serializable> values = origRow.getValues();
|
||||
NamedValue[] columns = new NamedValue[values.size()];
|
||||
int col = 0;
|
||||
for (Path path : values.keySet())
|
||||
{
|
||||
String value = null;
|
||||
Serializable valueObj = values.get(path);
|
||||
if (valueObj != null)
|
||||
{
|
||||
value = valueObj.toString();
|
||||
}
|
||||
|
||||
// Get the attribute QName from the result path
|
||||
String attributeName = path.last().toString();
|
||||
if (attributeName.startsWith("@") == true)
|
||||
{
|
||||
attributeName = attributeName.substring(1);
|
||||
}
|
||||
|
||||
columns[col] = new NamedValue(attributeName, value);
|
||||
col++;
|
||||
}
|
||||
|
||||
|
||||
org.alfresco.repo.webservice.types.ResultSetRow row = new org.alfresco.repo.webservice.types.ResultSetRow();
|
||||
row.setColumns(columns);
|
||||
row.setScore(origRow.getScore());
|
||||
row.setRowIndex(x);
|
||||
row.setNode(rowNode);
|
||||
|
||||
// add the row to the overall results
|
||||
rows[arrPos] = row;
|
||||
arrPos++;
|
||||
}
|
||||
|
||||
// TODO: build up the meta data data structure if we've been asked to
|
||||
|
||||
// add the rows to the result set and set the total row count
|
||||
batchResults.setRows(rows);
|
||||
batchResults.setTotalRowCount(totalRows);
|
||||
|
||||
queryResult = new QueryResult(getId(), batchResults);
|
||||
|
||||
// move the position on
|
||||
updatePosition(totalRows, queryResult);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("After getNextResultsBatch: " + toString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (searchResults != null)
|
||||
{
|
||||
searchResults.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(super.toString());
|
||||
builder.append(" (id=").append(getId());
|
||||
builder.append(" batchSize=").append(this.batchSize);
|
||||
builder.append(" position=").append(this.position);
|
||||
builder.append(" store=").append(this.store.getScheme().getValue()).append(":").append(this.store.getAddress());
|
||||
builder.append(" language=").append(this.query.getLanguage().getValue());
|
||||
builder.append(" statement=").append(this.query.getStatement());
|
||||
builder.append(")");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user