mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-21 18:09:20 +00:00
Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (5.0/Cloud)
76305: Merged EOL2 (5.0.0.EOL2) to HEAD-BUG-FIX (5.0/Cloud) 76026: ACE-2012 EOL Original SOAP API (CML) - removed. Based on BRANCHES/DEV/EOL:r73833,73932 and CMIS EOL removal merge. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@77579 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.webservice.types.ResultSetRowNode;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Abstract implementation of a QuerySession providing support for automatic id generation
|
||||
* and provides support for paging through query results.
|
||||
* <p>
|
||||
* Before executing, all the services need to be set.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public abstract class AbstractQuery<RESULTSET> implements ServerQuery<RESULTSET>
|
||||
{
|
||||
public AbstractQuery()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method only if the query can limit the results without a post-query cut-off.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public RESULTSET execute(ServiceRegistry serviceRegistry, long maxResults)
|
||||
{
|
||||
return execute(serviceRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a result set row node object for the provided node reference
|
||||
*
|
||||
* @param nodeRef
|
||||
* the node reference
|
||||
* @param nodeService
|
||||
* the node service
|
||||
* @return
|
||||
* the result set row node
|
||||
*/
|
||||
protected ResultSetRowNode createResultSetRowNode(NodeRef nodeRef, NodeService nodeService)
|
||||
{
|
||||
// Get the type
|
||||
String type = nodeService.getType(nodeRef).toString();
|
||||
|
||||
// Get the aspects applied to the node
|
||||
Set<QName> aspects = nodeService.getAspects(nodeRef);
|
||||
String[] aspectNames = new String[aspects.size()];
|
||||
int index = 0;
|
||||
for (QName aspect : aspects)
|
||||
{
|
||||
aspectNames[index] = aspect.toString();
|
||||
index++;
|
||||
}
|
||||
|
||||
// Create and return the result set row node
|
||||
return new ResultSetRowNode(nodeRef.getId(), type, aspectNames);
|
||||
}
|
||||
}
|
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* An abstract implementation of the query session that keeps track of the paging data.
|
||||
* It provides support for paging of results of <code>Serializable[]</code> instances.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 2.1
|
||||
*/
|
||||
public abstract class AbstractQuerySession<RESULTSET, RESULTSETROW> implements QuerySession<RESULTSET>
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(AbstractQuerySession.class);
|
||||
|
||||
private String id;
|
||||
private long maxResults;
|
||||
private long batchSize;
|
||||
private ServerQuery<RESULTSET> query;
|
||||
/** a transient cache of the query results */
|
||||
private transient RESULTSET cachedResults;
|
||||
|
||||
/**
|
||||
* A pointer to the first row to be returned. When the last result is returned, the
|
||||
* position will be out of range of the current results by 1.
|
||||
*/
|
||||
private long position;
|
||||
/**
|
||||
* Keep track of whether the position has previously passed the end of a set of results.
|
||||
*/
|
||||
private boolean expectMoreResults;
|
||||
|
||||
/**
|
||||
* Common constructor that initialises the session's id and batch size
|
||||
*
|
||||
* @param maxResults
|
||||
* the maximum number of results to retrieve for the query. This is not the page
|
||||
* size, which is normally significantly smaller.
|
||||
* @param batchSize
|
||||
* the batch size this session will use
|
||||
* @param query
|
||||
* the query that generates the results
|
||||
*/
|
||||
public AbstractQuerySession(long maxResults, long batchSize, ServerQuery<RESULTSET> query)
|
||||
{
|
||||
this.id = GUID.generate();
|
||||
this.batchSize = batchSize;
|
||||
this.maxResults = maxResults;
|
||||
this.query = query;
|
||||
this.position = 0;
|
||||
this.expectMoreResults = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public ServerQuery<RESULTSET> getQuery()
|
||||
{
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the results. This may be a cached value or may be
|
||||
* freshly retrieved from the query object.
|
||||
*
|
||||
* @param serviceRegistry the
|
||||
* @return the query results, new or cached
|
||||
*/
|
||||
protected RESULTSET getQueryResults(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
if (cachedResults != null)
|
||||
{
|
||||
return cachedResults;
|
||||
}
|
||||
// Get the results and cache them
|
||||
cachedResults = query.execute(serviceRegistry, maxResults);
|
||||
// Done
|
||||
return cachedResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean haveMoreResults()
|
||||
{
|
||||
return expectMoreResults;
|
||||
}
|
||||
|
||||
protected abstract RESULTSETROW[] makeArray(int size);
|
||||
|
||||
/**
|
||||
* Helper method to page through the results. The task of retrieving, unwrapping and
|
||||
* rewrapping the array of results (rows) is left up to the derived implementations.
|
||||
*/
|
||||
protected final RESULTSETROW[] getNextResults(RESULTSETROW[] allResults)
|
||||
{
|
||||
/*
|
||||
* This class can't manipulate the query to get the results because each
|
||||
* query implementation's results (the array of rows) is contained within
|
||||
* a different type of object. This method helps
|
||||
*/
|
||||
|
||||
long allResultsSize = allResults.length;
|
||||
|
||||
RESULTSETROW[] batchedResults = null;
|
||||
if (position >= allResultsSize)
|
||||
{
|
||||
// We are already past the last result
|
||||
batchedResults = makeArray(0);
|
||||
// Position is after last
|
||||
position = allResultsSize;
|
||||
}
|
||||
else if (position == 0 && batchSize >= allResultsSize)
|
||||
{
|
||||
// We can give back the original results
|
||||
batchedResults = allResults;
|
||||
// Position is after last
|
||||
position = allResultsSize;
|
||||
}
|
||||
else if ((position + batchSize) >= allResultsSize)
|
||||
{
|
||||
// There isn't an excess of rows remaining, so copy to the last one
|
||||
long rowCopyCount = allResultsSize - position; //ETWOONE-396 second part
|
||||
batchedResults = makeArray((int)rowCopyCount);
|
||||
System.arraycopy(allResults, (int)position, batchedResults, 0, (int)rowCopyCount);
|
||||
// Position is after last
|
||||
position = allResultsSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// There are an excess of rows remaining
|
||||
batchedResults = makeArray((int)batchSize);
|
||||
System.arraycopy(allResults, (int)position, batchedResults, 0, (int)batchSize);
|
||||
// Position increases by the batch size
|
||||
position += batchSize;
|
||||
}
|
||||
// Keep track of whether we expect more results
|
||||
if (position >= allResultsSize)
|
||||
{
|
||||
expectMoreResults = false;
|
||||
}
|
||||
// Done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\n" +
|
||||
"Fetched next set of results: \n" +
|
||||
" Total results count: " + allResultsSize + "\n" +
|
||||
" Batch size: " + batchedResults.length + "\n" +
|
||||
" New Position: " + position);
|
||||
}
|
||||
return batchedResults;
|
||||
}
|
||||
}
|
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice;
|
||||
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
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 ServiceRegistry serviceRegistry;
|
||||
protected DictionaryService dictionaryService;
|
||||
protected NodeService nodeService;
|
||||
protected ContentService contentService;
|
||||
protected SearchService searchService;
|
||||
protected NamespaceService namespaceService;
|
||||
|
||||
protected SimpleCache<String, QuerySession> querySessionCache;
|
||||
|
||||
public void setServiceRegistry(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the instance of the DictionaryService to be used
|
||||
*
|
||||
* @param dictionaryService
|
||||
* The DictionaryService
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cache to use for storing the the query session's paging information by query session ID.
|
||||
*
|
||||
* @param querySessionCache the cache. Cluster replication should be via serialization of
|
||||
* the cache values.
|
||||
*/
|
||||
public void setQuerySessionCache(SimpleCache<String, QuerySession> querySessionCache)
|
||||
{
|
||||
this.querySessionCache = querySessionCache;
|
||||
}
|
||||
}
|
@@ -1,714 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
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.CMLWriteContent;
|
||||
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.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
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;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class CMLUtil
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(CMLUtil.class);
|
||||
|
||||
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 static final String WRITE_CONTENT = "writeContent";
|
||||
|
||||
private NodeService nodeService;
|
||||
private SearchService searchService;
|
||||
private NamespaceService namespaceService;
|
||||
private CopyService copyService;
|
||||
private DictionaryService dictionaryService;
|
||||
private ContentService contentService;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
public void setContentService(ContentService contentService)
|
||||
{
|
||||
this.contentService = contentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
CMLWriteContent[] writes = cml.getWriteContent();
|
||||
if (writes != null)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug(writes.length + " write content statements ready for execution.");
|
||||
}
|
||||
|
||||
for (CMLWriteContent write : writes)
|
||||
{
|
||||
executeCMLWriteContent(write, 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)
|
||||
{
|
||||
NodeRef parentNodeRef = null;
|
||||
QName assocTypeQName = null;
|
||||
QName assocQName = null;
|
||||
|
||||
// Get the detail of the parent
|
||||
ParentReference parentReference = create.getParent();
|
||||
if (parentReference != null)
|
||||
{
|
||||
parentNodeRef = Utils.convertToNodeRef(
|
||||
parentReference,
|
||||
this.nodeService,
|
||||
this.searchService,
|
||||
this.namespaceService);
|
||||
assocTypeQName = QName.createQName(parentReference.getAssociationType());
|
||||
assocQName = QName.createQName(parentReference.getChildName());
|
||||
}
|
||||
else
|
||||
{
|
||||
String parentId = create.getParent_id();
|
||||
if (parentId != null)
|
||||
{
|
||||
parentNodeRef = context.idMap.get(parentId);
|
||||
}
|
||||
assocTypeQName = QName.createQName(create.getAssociationType());
|
||||
assocQName = QName.createQName(create.getChildName());
|
||||
}
|
||||
|
||||
if (parentNodeRef == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("No parent details have been specified for the node being created.");
|
||||
}
|
||||
|
||||
// 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, id, null, nodeRef));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a property map from the named value array that can be used when setting properties
|
||||
*
|
||||
* @param namedValues a array of named value properties
|
||||
* @return a property map of vlaues
|
||||
*/
|
||||
private PropertyMap getPropertyMap(NamedValue[] namedValues)
|
||||
{
|
||||
PropertyMap properties = new PropertyMap();
|
||||
if (namedValues != null)
|
||||
{
|
||||
for (NamedValue value : namedValues)
|
||||
{
|
||||
QName qname = QName.createQName(value.getName());
|
||||
Serializable propValue = Utils.getValueFromNamedValue(this.dictionaryService, qname, value);
|
||||
properties.put(qname, propValue);
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private UpdateResult createResult(String cmd, String sourceId, NodeRef sourceNodeRef, NodeRef destinationNodeRef)
|
||||
{
|
||||
UpdateResult result = new UpdateResult();
|
||||
result.setStatement(cmd);
|
||||
if (sourceId != null)
|
||||
{
|
||||
result.setSourceId(sourceId);
|
||||
}
|
||||
if (sourceNodeRef != null)
|
||||
{
|
||||
result.setSource(Utils.convertToReference(this.nodeService, this.namespaceService, sourceNodeRef));
|
||||
}
|
||||
if (destinationNodeRef != null)
|
||||
{
|
||||
result.setDestination(Utils.convertToReference(this.nodeService, this.namespaceService, 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, null, 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, null, nodeRef, nodeRef));
|
||||
}
|
||||
}
|
||||
|
||||
private List<NodeRef> getNodeRefList(String id, Predicate predicate, ExecutionContext context)
|
||||
{
|
||||
boolean bResolved = false;
|
||||
List<NodeRef> nodeRefs = new ArrayList<NodeRef>();
|
||||
if (id != null && id.length() != 0)
|
||||
{
|
||||
NodeRef localNodeRef = context.getNodeRef(id);
|
||||
if (localNodeRef != null)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Local node ref has been resolved for id = " + id);
|
||||
}
|
||||
|
||||
nodeRefs.add(localNodeRef);
|
||||
bResolved = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bResolved == false)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Trying to resolve predicate for where statement");
|
||||
if (predicate.getNodes() == null)
|
||||
{
|
||||
logger.debug("!! Predicate has no nodes !!");
|
||||
}
|
||||
}
|
||||
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, null, nodeRef, nodeRef));
|
||||
}
|
||||
}
|
||||
|
||||
private void executeCMLWriteContent(CMLWriteContent write, ExecutionContext context, List<UpdateResult> results)
|
||||
{
|
||||
// Get the nodes and content property
|
||||
List<NodeRef> nodeRefs = getNodeRefList(write.getWhere_id(), write.getWhere(), context);
|
||||
QName property = QName.createQName(write.getProperty());
|
||||
ContentFormat format = write.getFormat();
|
||||
byte[] content = write.getContent();
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
if (nodeRefs != null)
|
||||
{
|
||||
logger.debug("Write content: " + nodeRefs.size() + " nodes found for execution");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.debug("No nodes found to write content to!");
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeRefs != null)
|
||||
{
|
||||
for (NodeRef nodeRef : nodeRefs)
|
||||
{
|
||||
//Get the content writer
|
||||
ContentWriter writer = this.contentService.getWriter(nodeRef, 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
|
||||
InputStream is = new ByteArrayInputStream(content);
|
||||
writer.putContent(is);
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Write content: content written on node " + nodeRef.toString() + " with format " + format.getMimetype() + "|" + format.getEncoding());
|
||||
}
|
||||
|
||||
results.add(createResult(WRITE_CONTENT, null, 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, null, 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, null, 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.copyAndRename(nodeToCopy, destinationNodeRef, assocType, assocName, copyChildren);
|
||||
|
||||
// Create the result
|
||||
results.add(createResult(COPY, null, 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, null, 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, null, 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, null, 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, null, fromNodeRef, toNodeRef));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ExecutionContext
|
||||
{
|
||||
private Map<String, NodeRef> idMap = new HashMap<String, NodeRef>();
|
||||
private Map<NodeRef, String> nodeRefMap = new HashMap<NodeRef, String>();
|
||||
|
||||
public void addId(String id, NodeRef nodeRef)
|
||||
{
|
||||
this.idMap.put(id, nodeRef);
|
||||
this.nodeRefMap.put(nodeRef, id);
|
||||
}
|
||||
|
||||
public NodeRef getNodeRef(String id)
|
||||
{
|
||||
return this.idMap.get(id);
|
||||
}
|
||||
|
||||
public String getId(NodeRef nodeRef)
|
||||
{
|
||||
return this.nodeRefMap.get(nodeRef);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* An interface for objects that track the query and its results. The only commonality between
|
||||
* the different types of results used in the WebServices return values is that they are
|
||||
* Serializable.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface QuerySession<RESULTSET> extends Serializable
|
||||
{
|
||||
/**
|
||||
* Retrieves the id this query session can be identified as
|
||||
*
|
||||
* @return Id of this query session
|
||||
*/
|
||||
public String getId();
|
||||
|
||||
/**
|
||||
* Check if the session is expecting more results. This will be <tt>false</tt> if the
|
||||
* cursor previously passed the end of a given set of results.
|
||||
*/
|
||||
public boolean haveMoreResults();
|
||||
|
||||
/**
|
||||
* Get the next batch of results from the full set of available results. If there are no results
|
||||
* available, then this session must go and fetch them. It is up to the implementation to provide
|
||||
* a means for this to occur.
|
||||
*
|
||||
* @param serviceRegistry
|
||||
* the services to perform a query
|
||||
* @param allResults
|
||||
* All available results. It may be necessary to requery to get the results.
|
||||
* @return
|
||||
* Returns the next batch of results based on the maximum fetch size. If there are no
|
||||
* more results, the resultset will be empty.
|
||||
*/
|
||||
public RESULTSET getNextResults(ServiceRegistry serviceRegistry);
|
||||
}
|
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* Interface definition for a QuerySession.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public interface ServerQuery<RESULTSET> extends Serializable
|
||||
{
|
||||
/** System column namess */
|
||||
public static String SYS_COL_ASSOC_TYPE = "associationType";
|
||||
public static String SYS_COL_ASSOC_NAME = "associationName";
|
||||
public static String SYS_COL_IS_PRIMARY = "isPrimary";
|
||||
public static String SYS_COL_NTH_SIBLING = "nthSibling";
|
||||
|
||||
/**
|
||||
* Executes the query and returns the <b>full query results</b>.
|
||||
*
|
||||
* @param
|
||||
* The services to help make the query
|
||||
* @return
|
||||
* The full set of query results.
|
||||
* The results must be empty if there are no results.
|
||||
*/
|
||||
public RESULTSET execute(ServiceRegistry serviceRegistry);
|
||||
|
||||
/**
|
||||
* Executes the query and return all results up to given maximum number.
|
||||
* Note that this is not the same as the page size, but rather is a total
|
||||
* upper limit to the number of results that can viewed.
|
||||
*
|
||||
* @param
|
||||
* The services to help make the query
|
||||
* @param maxResults
|
||||
* the total number of results to retrieve
|
||||
* @return
|
||||
* The full set of query results up to the maximum given.
|
||||
* The results must be empty if there are no results.
|
||||
*/
|
||||
public RESULTSET execute(ServiceRegistry serviceRegistry, long maxResults);
|
||||
}
|
@@ -1,866 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.transaction.UserTransaction;
|
||||
import javax.xml.rpc.server.ServletEndpointContext;
|
||||
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
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.Reference;
|
||||
import org.alfresco.repo.webservice.types.RoleDefinition;
|
||||
import org.alfresco.repo.webservice.types.Store;
|
||||
import org.alfresco.repo.webservice.types.Version;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
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.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
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
|
||||
{
|
||||
/** Default batch size for query results - 1000 */
|
||||
public static final int DEFAULT_BATCH_SIZE = 1000;
|
||||
public static final String REPOSITORY_SERVICE_NAMESPACE = "http://www.alfresco.org/ws/service/repository/1.0";
|
||||
|
||||
/** Get the logger for this class */
|
||||
private static Log logger = LogFactory.getLog(Utils.class);
|
||||
|
||||
private Utils()
|
||||
{
|
||||
// don't allow construction
|
||||
}
|
||||
|
||||
/** Query language names */
|
||||
public static final String QUERY_LANG_LUCENE = "lucene";
|
||||
public static final String QUERY_LANG_XPATH = "xpath";
|
||||
public static final String QUERY_LANG_CQL = "cql";
|
||||
|
||||
|
||||
/**
|
||||
* Utility method to convert from a string representation of a property value into the correct object representation.
|
||||
*
|
||||
* @param dictionaryService the dictionary service
|
||||
* @param propertyName the qname of the property in question
|
||||
* @param propertyValue the property vlaue as a string
|
||||
* @return the object value of the property
|
||||
*/
|
||||
public static Serializable getValueFromNamedValue(DictionaryService dictionaryService, QName propertyName, NamedValue namedValue)
|
||||
{
|
||||
Serializable result = null;
|
||||
if (namedValue != null)
|
||||
{
|
||||
org.alfresco.service.cmr.dictionary.PropertyDefinition propDef = dictionaryService.getProperty(propertyName);
|
||||
if (propDef == null)
|
||||
{
|
||||
if (namedValue.getIsMultiValue() == false)
|
||||
{
|
||||
result = namedValue.getValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
String[] values = namedValue.getValues();
|
||||
|
||||
if (values != null)
|
||||
{
|
||||
Collection<Serializable> collection = new ArrayList<Serializable>(values.length);
|
||||
for (String value : values)
|
||||
{
|
||||
collection.add(value);
|
||||
}
|
||||
result = (Serializable)collection;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DataTypeDefinition propertyType = propDef.getDataType();
|
||||
if (propertyType != null)
|
||||
{
|
||||
if (namedValue.getIsMultiValue() == false)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Converting single-valued property '" + propertyName.toString() + "' with value " + namedValue.getValue());
|
||||
}
|
||||
|
||||
result = (Serializable)DefaultTypeConverter.INSTANCE.convert(propertyType, namedValue.getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
String[] values = namedValue.getValues();
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Converting multi-valued property '" + propertyName.toString() + "' with values " + Arrays.toString(values));
|
||||
}
|
||||
|
||||
if (values != null)
|
||||
{
|
||||
Collection<Serializable> collection = new ArrayList<Serializable>(values.length);
|
||||
for (String value : values)
|
||||
{
|
||||
collection.add((Serializable)DefaultTypeConverter.INSTANCE.convert(propertyType, value));
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("The collection for the multi-value property has been generated '" + collection.toString());
|
||||
}
|
||||
|
||||
result = (Serializable)collection;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("No property definition was found for property '" + propertyName.toString() + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a named value object from the property name and value informaiton
|
||||
*
|
||||
* @param dictionaryService the dictionary service
|
||||
* @param propertyName the property qname
|
||||
* @param propertyValue the property value
|
||||
* @return the namedValue object
|
||||
*/
|
||||
public static NamedValue createNamedValue(DictionaryService dictionaryService, QName propertyName, Serializable propertyValue)
|
||||
{
|
||||
NamedValue namedValue = new NamedValue();
|
||||
namedValue.setName(propertyName.toString());
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Creating named value for property '" + propertyName + "' with value '" + propertyValue + "'");
|
||||
}
|
||||
|
||||
if (propertyValue != null)
|
||||
{
|
||||
org.alfresco.service.cmr.dictionary.PropertyDefinition propDef = dictionaryService.getProperty(propertyName);
|
||||
if (propDef != null)
|
||||
{
|
||||
if (propDef.isMultiValued() == true)
|
||||
{
|
||||
namedValue.setIsMultiValue(true);
|
||||
if (propertyValue instanceof Collection)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Converting multivalue for property '" + propertyName + "'");
|
||||
}
|
||||
|
||||
Collection<Serializable> collection = (Collection<Serializable>)propertyValue;
|
||||
String[] values = new String[collection.size()];
|
||||
int count = 0;
|
||||
for (Serializable value : collection)
|
||||
{
|
||||
values[count] = DefaultTypeConverter.INSTANCE.convert(String.class, value);
|
||||
count ++;
|
||||
}
|
||||
namedValue.setValues(values);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Converting single value for property '" + propertyName + "'");
|
||||
}
|
||||
|
||||
namedValue.setIsMultiValue(false);
|
||||
namedValue.setValue(DefaultTypeConverter.INSTANCE.convert(String.class, propertyValue));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("No property definition found for property '" + propertyName + "'");
|
||||
}
|
||||
|
||||
namedValue.setIsMultiValue(false);
|
||||
namedValue.setValue(propertyValue.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return namedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(), 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(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(NodeService nodeService, NamespaceService namespaceService, NodeRef node)
|
||||
{
|
||||
Reference ref = new Reference();
|
||||
Store store = new Store(node.getStoreRef().getProtocol(), node.getStoreRef().getIdentifier());
|
||||
ref.setStore(store);
|
||||
ref.setUuid(node.getId());
|
||||
|
||||
// Need to check if node still exists (e.g., after a delete operation) so getPath()
|
||||
// doesn't fail
|
||||
if(nodeService.exists(node) == true)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("setting path for reference to: " + nodeService.getPath(node).toPrefixString(namespaceService));
|
||||
}
|
||||
|
||||
// so clients can get the path too
|
||||
ref.setPath(nodeService.getPath(node).toPrefixString(namespaceService));
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given parameters to a repository NodeRef
|
||||
*
|
||||
* @param store
|
||||
* The Store to search within
|
||||
* @param uuid
|
||||
* The id of the required node.c
|
||||
* @param path
|
||||
* The path to the required node. If a uuid is given the uuid is used
|
||||
+ * to find the node. Otherwise, the path is used.
|
||||
* @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;
|
||||
|
||||
// If uuid is null, then use the path to find the node
|
||||
if (uuid == null || uuid.length() == 0)
|
||||
{
|
||||
if (path != null && path.length() != 0)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Resolving path: " + path);
|
||||
}
|
||||
|
||||
NodeRef rootNodeRef = nodeService.getRootNode(convertToStoreRef(store));
|
||||
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()).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
|
||||
{
|
||||
throw new IllegalArgumentException("A uuid or a path must be supplied to resolve to a NodeRef");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else // use the uuid
|
||||
{
|
||||
nodeRef = new NodeRef(convertToStoreRef(store), uuid);
|
||||
}
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
String language = query.getLanguage();
|
||||
if (language.equals(QUERY_LANG_LUCENE) != true)
|
||||
{
|
||||
throw new IllegalArgumentException("Only '"
|
||||
+ QUERY_LANG_LUCENE
|
||||
+ "' queries are currently supported!");
|
||||
}
|
||||
|
||||
// execute the query
|
||||
ResultSet searchResults = null;
|
||||
try
|
||||
{
|
||||
searchResults = searchService.query(Utils
|
||||
.convertToStoreRef(predicate.getStore()), language, 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
|
||||
*
|
||||
* @deprecated Use {@link #getRetryingTransactionHelper(MessageContext)}
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the executer to wrap transactional callbacks in for better transaction behaviour.
|
||||
*
|
||||
* @param msgContext
|
||||
* SOAP message context
|
||||
* @return
|
||||
* a transactional, retrying, callback executer
|
||||
*/
|
||||
public static RetryingTransactionHelper getRetryingTransactionHelper(MessageContext msgContext)
|
||||
{
|
||||
// get the service regsistry
|
||||
ServiceRegistry svcReg = (ServiceRegistry) getSpringContext(msgContext)
|
||||
.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
|
||||
TransactionService transactionService = svcReg.getTransactionService();
|
||||
return transactionService.getRetryingTransactionHelper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current http session id
|
||||
*
|
||||
* @return the current http session id, null if none found
|
||||
*/
|
||||
public static String getSessionId()
|
||||
{
|
||||
HttpSession session = getSession();
|
||||
return ((session != null) ? (session.getId()) : (null));
|
||||
}
|
||||
|
||||
private static HttpSession getSession()
|
||||
{
|
||||
HttpSession result = null;
|
||||
|
||||
ServletEndpointContext endpointContext = (ServletEndpointContext) MessageContext.getCurrentContext().getProperty("servletEndpointContext");
|
||||
if (endpointContext != null)
|
||||
{
|
||||
result = endpointContext.getHttpSession();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates the current http session
|
||||
*/
|
||||
public static void invalidateSession()
|
||||
{
|
||||
HttpSession session = getSession();
|
||||
if (session != null)
|
||||
{
|
||||
session.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = DEFAULT_BATCH_SIZE;
|
||||
|
||||
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(
|
||||
NodeService nodeService,
|
||||
NamespaceService namespaceService,
|
||||
org.alfresco.service.cmr.version.Version version)
|
||||
{
|
||||
Version webServiceVersion = new Version();
|
||||
|
||||
// Set the basic properties
|
||||
webServiceVersion.setId(Utils.convertToReference(nodeService, namespaceService, 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(), false, value, null);
|
||||
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(DictionaryService dictionaryService, org.alfresco.service.cmr.dictionary.ClassDefinition ddClassDef)
|
||||
{
|
||||
ClassDefinition classDef = new ClassDefinition();
|
||||
classDef.setName(ddClassDef.getName().toString());
|
||||
classDef.setIsAspect(ddClassDef.isAspect());
|
||||
|
||||
if (ddClassDef.getTitle(dictionaryService) != null)
|
||||
{
|
||||
classDef.setTitle(ddClassDef.getTitle(dictionaryService));
|
||||
}
|
||||
if (ddClassDef.getDescription(dictionaryService) != null)
|
||||
{
|
||||
classDef.setDescription(ddClassDef.getDescription(dictionaryService));
|
||||
}
|
||||
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 = setupPropertyDefObject(dictionaryService, ddPropDef);
|
||||
propDefs[pos] = propDef;
|
||||
pos++;
|
||||
}
|
||||
|
||||
// add properties to the overall ClassDefinition
|
||||
classDef.setProperties(propDefs);
|
||||
}
|
||||
|
||||
// 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 = setupAssociationDefObject(dictionaryService, ddAssocDef);
|
||||
assocDefs[pos] = assocDef;
|
||||
pos++;
|
||||
}
|
||||
|
||||
classDef.setAssociations(assocDefs);
|
||||
}
|
||||
|
||||
return classDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PropertyDefinition web service type object for the given
|
||||
* repository PropertyDefinition
|
||||
*
|
||||
* @param ddPropertyDef The repository PropertyDefinition to generate
|
||||
* @return The web service PropertyDefinition representation
|
||||
*/
|
||||
public static PropertyDefinition setupPropertyDefObject(DictionaryService dictionaryService, org.alfresco.service.cmr.dictionary.PropertyDefinition ddPropDef)
|
||||
{
|
||||
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(dictionaryService) != null)
|
||||
{
|
||||
propDef.setTitle(ddPropDef.getTitle(dictionaryService));
|
||||
}
|
||||
if (ddPropDef.getDescription(dictionaryService) != null)
|
||||
{
|
||||
propDef.setDescription(ddPropDef.getDescription(dictionaryService));
|
||||
}
|
||||
return propDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an AssociationDefinition web service type object for the given
|
||||
* repository AssociationDefinition
|
||||
*
|
||||
* @param ddAssociationDef The repository AssociationDefinition to generate
|
||||
* @return The web service AssociationDefinition representation
|
||||
*/
|
||||
public static AssociationDefinition setupAssociationDefObject(DictionaryService dictionaryService, org.alfresco.service.cmr.dictionary.AssociationDefinition ddAssocDef)
|
||||
{
|
||||
AssociationDefinition assocDef = new AssociationDefinition();
|
||||
assocDef.setName(ddAssocDef.getName().toString());
|
||||
assocDef.setIsChild(ddAssocDef.isChild());
|
||||
if (ddAssocDef.getTitle(dictionaryService) != null)
|
||||
{
|
||||
assocDef.setTitle(ddAssocDef.getTitle(dictionaryService));
|
||||
}
|
||||
if (ddAssocDef.getDescription(dictionaryService) != null)
|
||||
{
|
||||
assocDef.setDescription(ddAssocDef.getDescription(dictionaryService));
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
return assocDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,795 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.accesscontrol;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.transaction.TransactionServiceImpl;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.repo.webservice.AbstractWebService;
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.action.ActionFault;
|
||||
import org.alfresco.repo.webservice.types.Predicate;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.AccessPermission;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
import org.alfresco.service.cmr.security.OwnableService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class AccessControlWebService extends AbstractWebService implements AccessControlServiceSoapPort
|
||||
{
|
||||
/** Log */
|
||||
private static Log logger = LogFactory.getLog(AccessControlWebService.class);
|
||||
|
||||
/** Transaction service */
|
||||
private TransactionServiceImpl transactionService = null;
|
||||
|
||||
/** Permission service */
|
||||
private PermissionService permissionService = null;
|
||||
|
||||
/** Ownable service */
|
||||
private OwnableService ownableService = null;
|
||||
|
||||
/** Authority service */
|
||||
private AuthorityService authorityService;
|
||||
|
||||
/**
|
||||
* Set the transaction service
|
||||
*
|
||||
* @param transactionService the transaction service
|
||||
*/
|
||||
public void setTransactionService(TransactionServiceImpl transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the permissions service
|
||||
*
|
||||
* @param permissionService the permissions service
|
||||
*/
|
||||
public void setPermissionService(PermissionService permissionService)
|
||||
{
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ownable service
|
||||
*
|
||||
* @param ownableService the ownable service
|
||||
*/
|
||||
public void setOwnableService(OwnableService ownableService)
|
||||
{
|
||||
this.ownableService = ownableService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authentication service
|
||||
*
|
||||
* @param authorityService the authentication service
|
||||
*/
|
||||
public void setAuthorityService(AuthorityService authorityService)
|
||||
{
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#getACLs(org.alfresco.repo.webservice.types.Predicate, org.alfresco.repo.webservice.accesscontrol.ACE)
|
||||
*/
|
||||
public ACL[] getACLs(final Predicate predicate, final ACE filter) throws RemoteException, AccessControlFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<ACL[]> callback = new RetryingTransactionCallback<ACL[]>()
|
||||
{
|
||||
public ACL[] execute() throws Exception
|
||||
{
|
||||
return getACLsImpl(predicate, filter);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ACL's for the predicate, filtered if appropraite.
|
||||
*
|
||||
* @param predicate the predicate
|
||||
* @param filter the fileter (optional)
|
||||
* @return an array of ACL's
|
||||
*/
|
||||
private ACL[] getACLsImpl(Predicate predicate, ACE filter)
|
||||
{
|
||||
// Resolve the nodes
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(predicate, this.nodeService, this.searchService, this.namespaceService);
|
||||
ACL[] acls = new ACL[nodes.size()];
|
||||
|
||||
int index = 0;
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
// Create ACL of node
|
||||
ACL acl = getACLFromNodeRef(node, filter);
|
||||
|
||||
// Add the acl to the results
|
||||
acls[index] = acl;
|
||||
index++;
|
||||
}
|
||||
|
||||
return acls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a node reference, creates the relating ACL
|
||||
*
|
||||
* @param node the node reference
|
||||
* @return the ACL
|
||||
*/
|
||||
private ACL getACLFromNodeRef(NodeRef node, ACE filter)
|
||||
{
|
||||
// Create the acl
|
||||
ACL acl = new ACL();
|
||||
acl.setReference(Utils.convertToReference(this.nodeService, this.namespaceService, node));
|
||||
|
||||
// Set the inhertied value
|
||||
boolean inheritPermission = this.permissionService.getInheritParentPermissions(node);
|
||||
acl.setInheritPermissions(inheritPermission);
|
||||
|
||||
// Get the access permissions
|
||||
Set<AccessPermission> accessPermissions = this.permissionService.getAllSetPermissions(node);
|
||||
ACE[] aces = new ACE[accessPermissions.size()];
|
||||
|
||||
// Marshal the permissions into ACE's
|
||||
int count = 0;
|
||||
for (AccessPermission permission : accessPermissions)
|
||||
{
|
||||
// TODO need to filter the results accordingly using ACE filter
|
||||
|
||||
// Create the ace
|
||||
org.alfresco.repo.webservice.accesscontrol.AccessStatus accessStatus = org.alfresco.repo.webservice.accesscontrol.AccessStatus.declined;
|
||||
if (AccessStatus.ALLOWED.equals(permission.getAccessStatus()) == true)
|
||||
{
|
||||
accessStatus = org.alfresco.repo.webservice.accesscontrol.AccessStatus.acepted;
|
||||
}
|
||||
|
||||
ACE ace = new ACE(permission.getAuthority(),
|
||||
permission.getPermission(),
|
||||
accessStatus);
|
||||
|
||||
// Add ace to array
|
||||
aces[count] = ace;
|
||||
count ++;
|
||||
}
|
||||
acl.setAces(aces);
|
||||
return acl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#addACEs(org.alfresco.repo.webservice.types.Predicate, org.alfresco.repo.webservice.accesscontrol.ACE[])
|
||||
*/
|
||||
public ACL[] addACEs(final Predicate predicate, final ACE[] aces) throws RemoteException, AccessControlFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<ACL[]> callback = new RetryingTransactionCallback<ACL[]>()
|
||||
{
|
||||
public ACL[] execute() throws Exception
|
||||
{
|
||||
return addACEsImpl(predicate, aces);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ACE to a collection of nodes
|
||||
*
|
||||
* @param predicate the predicate
|
||||
* @param aces the ACE's to add
|
||||
* @return the ACL's of the modified node
|
||||
*/
|
||||
private ACL[] addACEsImpl(Predicate predicate, ACE[] aces)
|
||||
{
|
||||
// Resolce the predicate
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(predicate, this.nodeService, this.searchService, this.namespaceService);
|
||||
ACL[] acls = new ACL[nodes.size()];
|
||||
|
||||
int count = 0;
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
// Add the permissions for each ace
|
||||
for (ACE ace : aces)
|
||||
{
|
||||
// Add the permissions associated with the ace
|
||||
boolean allow = false;
|
||||
if (ace.getAccessStatus().equals(org.alfresco.repo.webservice.accesscontrol.AccessStatus.acepted) == true)
|
||||
{
|
||||
allow = true;
|
||||
}
|
||||
this.permissionService.setPermission(node, ace.getAuthority(), ace.getPermission(), allow);
|
||||
}
|
||||
|
||||
// Add the ACL for this node to the returned array
|
||||
acls[count] = getACLFromNodeRef(node, null);
|
||||
count++;
|
||||
}
|
||||
|
||||
return acls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#removeACEs(org.alfresco.repo.webservice.types.Predicate, org.alfresco.repo.webservice.accesscontrol.ACE[])
|
||||
*/
|
||||
public ACL[] removeACEs(final Predicate predicate, final ACE[] aces) throws RemoteException, AccessControlFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<ACL[]> callback = new RetryingTransactionCallback<ACL[]>()
|
||||
{
|
||||
public ACL[] execute() throws Exception
|
||||
{
|
||||
return removeACEsImpl(predicate, aces);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove specified ACE's from the nodes. Removes all permissions if no ACE's specified.
|
||||
*
|
||||
* @param predicate the predicate
|
||||
* @param aces the ACE's to remove
|
||||
* @return the modified ACL's
|
||||
*/
|
||||
private ACL[] removeACEsImpl(Predicate predicate, ACE[] aces)
|
||||
{
|
||||
// Resolce the predicate
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(predicate, this.nodeService, this.searchService, this.namespaceService);
|
||||
ACL[] acls = new ACL[nodes.size()];
|
||||
|
||||
int count = 0;
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
if (aces == null)
|
||||
{
|
||||
// Delete all the permissions
|
||||
this.permissionService.deletePermissions(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete the permissions for each ACE
|
||||
for (ACE ace : aces)
|
||||
{
|
||||
this.permissionService.deletePermission(node, ace.getAuthority(), ace.getPermission());
|
||||
}
|
||||
}
|
||||
|
||||
// Add the ACL for this node to the returned array
|
||||
acls[count] = getACLFromNodeRef(node, null);
|
||||
count++;
|
||||
}
|
||||
|
||||
return acls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#getPermissions(org.alfresco.repo.webservice.types.Predicate)
|
||||
*/
|
||||
public GetPermissionsResult[] getPermissions(final Predicate predicate) throws RemoteException, AccessControlFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<GetPermissionsResult[]> callback = new RetryingTransactionCallback<GetPermissionsResult[]>()
|
||||
{
|
||||
public GetPermissionsResult[] execute() throws Exception
|
||||
{
|
||||
return getPermissionsImpl(predicate);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permissions
|
||||
*
|
||||
* @param predicate the predicate
|
||||
* @return the permissions available
|
||||
*/
|
||||
private GetPermissionsResult[] getPermissionsImpl(Predicate predicate)
|
||||
{
|
||||
// Resolve the predicate
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(predicate, this.nodeService, this.searchService, this.namespaceService);
|
||||
GetPermissionsResult[] results = new GetPermissionsResult[nodes.size()];
|
||||
|
||||
int count = 0;
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
// Get the permissions
|
||||
Set<String> permissions = this.permissionService.getSettablePermissions(node);
|
||||
|
||||
// Create the permissions result object
|
||||
GetPermissionsResult result = new GetPermissionsResult();
|
||||
result.setReference(Utils.convertToReference(this.nodeService, this.namespaceService, node));
|
||||
result.setPermissions((String[])permissions.toArray(new String[permissions.size()]));
|
||||
|
||||
// Add result to array
|
||||
results[count] = result;
|
||||
count ++;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#getClassPermissions(java.lang.String[])
|
||||
*/
|
||||
public GetClassPermissionsResult[] getClassPermissions(final String[] classNames) throws RemoteException, AccessControlFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<GetClassPermissionsResult[]> callback = new RetryingTransactionCallback<GetClassPermissionsResult[]>()
|
||||
{
|
||||
public GetClassPermissionsResult[] execute() throws Exception
|
||||
{
|
||||
return getClassPermissionsImpl(classNames);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permissions based on type
|
||||
*
|
||||
* @param classNames the class names
|
||||
* @return the permission results
|
||||
*/
|
||||
private GetClassPermissionsResult[] getClassPermissionsImpl(String[] classNames)
|
||||
{
|
||||
// Resolve the predicate
|
||||
GetClassPermissionsResult[] results = new GetClassPermissionsResult[classNames.length];
|
||||
|
||||
int count = 0;
|
||||
for (String className : classNames)
|
||||
{
|
||||
// Get the permissions
|
||||
Set<String> permissions = this.permissionService.getSettablePermissions(QName.createQName(className));
|
||||
|
||||
// Create the permissions result object
|
||||
GetClassPermissionsResult result = new GetClassPermissionsResult();
|
||||
result.setClassName(className);
|
||||
result.setPermissions((String[])permissions.toArray(new String[permissions.size()]));
|
||||
|
||||
// Add result to array
|
||||
results[count] = result;
|
||||
count ++;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#hasPermissions(org.alfresco.repo.webservice.types.Predicate, java.lang.String[])
|
||||
*/
|
||||
public HasPermissionsResult[] hasPermissions(final Predicate predicate, final String[] permissions) throws RemoteException, AccessControlFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<HasPermissionsResult[]> callback = new RetryingTransactionCallback<HasPermissionsResult[]>()
|
||||
{
|
||||
public HasPermissionsResult[] execute() throws Exception
|
||||
{
|
||||
return hasPermissionsImpl(predicate, permissions);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a set of node has a given set of permissions.
|
||||
*
|
||||
* @param predicate the predicate
|
||||
* @param permissions the permissions
|
||||
* @return the permissions result
|
||||
*/
|
||||
private HasPermissionsResult[] hasPermissionsImpl(Predicate predicate, String[] permissions)
|
||||
{
|
||||
// Resolve the predicate
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(predicate, this.nodeService, this.searchService, this.namespaceService);
|
||||
List<HasPermissionsResult> results = new ArrayList<HasPermissionsResult>(20);
|
||||
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
for (String permission : permissions)
|
||||
{
|
||||
// Detemine whether the node has the permissions
|
||||
AccessStatus accessStatus = this.permissionService.hasPermission(node, permission);
|
||||
org.alfresco.repo.webservice.accesscontrol.AccessStatus accessState = org.alfresco.repo.webservice.accesscontrol.AccessStatus.declined;
|
||||
if (AccessStatus.ALLOWED.equals(accessStatus) == true)
|
||||
{
|
||||
accessState = org.alfresco.repo.webservice.accesscontrol.AccessStatus.acepted;
|
||||
}
|
||||
|
||||
// Add to the results list
|
||||
results.add(new HasPermissionsResult(Utils.convertToReference(this.nodeService, this.namespaceService, node), permission, accessState));
|
||||
}
|
||||
}
|
||||
|
||||
return (HasPermissionsResult[])results.toArray(new HasPermissionsResult[results.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#setInheritPermission(org.alfresco.repo.webservice.types.Predicate, boolean)
|
||||
*/
|
||||
public ACL[] setInheritPermission(final Predicate predicate, final boolean inheritPermission) throws RemoteException, AccessControlFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<ACL[]> callback = new RetryingTransactionCallback<ACL[]>()
|
||||
{
|
||||
public ACL[] execute() throws Exception
|
||||
{
|
||||
return setInheritPermissionImpl(predicate, inheritPermission);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the inherit permissions flag
|
||||
*
|
||||
* @param predicate the predicate
|
||||
* @param inheritPermission indicates whether the permissions are inherited or not
|
||||
* @return the updated acl's
|
||||
*/
|
||||
private ACL[] setInheritPermissionImpl(Predicate predicate, boolean inheritPermission)
|
||||
{
|
||||
// Resolve the predicate
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(predicate, this.nodeService, this.searchService, this.namespaceService);
|
||||
ACL[] acls = new ACL[nodes.size()];
|
||||
|
||||
int count = 0;
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
// Set the inherited permission value
|
||||
this.permissionService.setInheritParentPermissions(node, inheritPermission);
|
||||
|
||||
// Add the ACL of the modified node to the result
|
||||
acls[count] = getACLFromNodeRef(node, null);
|
||||
count ++;
|
||||
}
|
||||
|
||||
return acls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#getOwners(org.alfresco.repo.webservice.types.Predicate)
|
||||
*/
|
||||
public OwnerResult[] getOwners(final Predicate predicate) throws RemoteException, AccessControlFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<OwnerResult[]> callback = new RetryingTransactionCallback<OwnerResult[]>()
|
||||
{
|
||||
public OwnerResult[] execute() throws Exception
|
||||
{
|
||||
return getOwnersImpl(predicate);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the owners of the nodes
|
||||
*
|
||||
* @param predicate the predicate
|
||||
* @return the owner details
|
||||
*/
|
||||
private OwnerResult[] getOwnersImpl(Predicate predicate)
|
||||
{
|
||||
// Convert predicate
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(predicate, this.nodeService, this.searchService, this.namespaceService);
|
||||
OwnerResult[] result = new OwnerResult[nodes.size()];
|
||||
|
||||
int count = 0;
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
// Get the current owner of the node
|
||||
String owner = this.ownableService.getOwner(node);
|
||||
|
||||
// Marshal into result
|
||||
result[count] = new OwnerResult(Utils.convertToReference(this.nodeService, this.namespaceService, node), owner);
|
||||
count ++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#setOwners(org.alfresco.repo.webservice.types.Predicate, java.lang.String)
|
||||
*/
|
||||
public OwnerResult[] setOwners(final Predicate predicate, final String owner) throws RemoteException, AccessControlFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<OwnerResult[]> callback = new RetryingTransactionCallback<OwnerResult[]>()
|
||||
{
|
||||
public OwnerResult[] execute() throws Exception
|
||||
{
|
||||
return setOwnersImpl(predicate, owner);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the owner of a nodes
|
||||
*
|
||||
* @param predicate the predicate
|
||||
* @param owner the owner
|
||||
* @return the owner results updated
|
||||
*/
|
||||
private OwnerResult[] setOwnersImpl(Predicate predicate, String owner)
|
||||
{
|
||||
// Convert predicate
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(predicate, this.nodeService, this.searchService, this.namespaceService);
|
||||
OwnerResult[] result = new OwnerResult[nodes.size()];
|
||||
|
||||
int count = 0;
|
||||
for (NodeRef node : nodes)
|
||||
{
|
||||
// Set the owner of the node
|
||||
this.ownableService.setOwner(node, owner);
|
||||
|
||||
// Marshal into result
|
||||
result[count] = new OwnerResult(Utils.convertToReference(this.nodeService, this.namespaceService, node), owner);
|
||||
count ++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an existing authority as a child of another authority.
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#addChildAuthorities(java.lang.String, java.lang.String[])
|
||||
*/
|
||||
public String[] addChildAuthorities(String parentAuthority, String[] authorities)
|
||||
throws RemoteException, AccessControlFault
|
||||
{
|
||||
String[] result = new String[authorities.length];
|
||||
int index = 0;
|
||||
for (String authority : authorities)
|
||||
{
|
||||
this.authorityService.addAuthority(parentAuthority, authority);
|
||||
result[index] = authority;
|
||||
index++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new authority under a given parent authority. If no parent authority is provided then the new authority is
|
||||
* created at the root.
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#createAuthorities(java.lang.String, org.alfresco.repo.webservice.accesscontrol.NewAuthority[])
|
||||
*/
|
||||
public String[] createAuthorities(String parentAuthority, NewAuthority[] newAuthorites)
|
||||
throws RemoteException, AccessControlFault
|
||||
{
|
||||
String[] result = new String[newAuthorites.length];
|
||||
int index = 0;
|
||||
for (NewAuthority newAuthority : newAuthorites)
|
||||
{
|
||||
AuthorityType authorityType = AuthorityType.valueOf(newAuthority.getAuthorityType());
|
||||
String authority = this.authorityService.createAuthority(authorityType, newAuthority.getName());
|
||||
if (parentAuthority != null)
|
||||
{
|
||||
this.authorityService.addAuthority(parentAuthority, authority);
|
||||
}
|
||||
result[index] = authority;
|
||||
index++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete existing authority
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#deleteAuthorities(java.lang.String[])
|
||||
*/
|
||||
public void deleteAuthorities(String[] authorities)
|
||||
throws RemoteException, AccessControlFault
|
||||
{
|
||||
for (String authority : authorities)
|
||||
{
|
||||
this.authorityService.deleteAuthority(authority);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all authorities that match the filter
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#getAllAuthorities(org.alfresco.repo.webservice.accesscontrol.AuthorityFilter)
|
||||
*/
|
||||
public String[] getAllAuthorities(AuthorityFilter filter)
|
||||
throws RemoteException, AccessControlFault
|
||||
{
|
||||
List<String> result = new ArrayList<String>(10);
|
||||
|
||||
AuthorityType authorityType = AuthorityType.valueOf(filter.getAuthorityType());
|
||||
if (filter.isRootOnly() == true)
|
||||
{
|
||||
result.addAll(this.authorityService.getAllRootAuthorities(authorityType));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.addAll(this.authorityService.getAllAuthorities(authorityType));
|
||||
}
|
||||
|
||||
return (String[])result.toArray(new String[result.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the authorities that the current user belongs to
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#getAuthorities()
|
||||
*/
|
||||
public String[] getAuthorities()
|
||||
throws RemoteException, AccessControlFault
|
||||
{
|
||||
Set<String> result = this.authorityService.getAuthorities();
|
||||
return (String[])result.toArray(new String[result.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the child authorities of a given authority, taking into account a filter
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#getChildAuthorities(java.lang.String, org.alfresco.repo.webservice.accesscontrol.SiblingAuthorityFilter)
|
||||
*/
|
||||
public String[] getChildAuthorities(String authority, SiblingAuthorityFilter filter)
|
||||
throws RemoteException, AccessControlFault
|
||||
{
|
||||
AuthorityType authorityType = AuthorityType.valueOf(filter.getAuthorityType());
|
||||
Set<String> result = this.authorityService.getContainedAuthorities(authorityType, authority, filter.isImmediate());
|
||||
return (String[])result.toArray(new String[result.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the parent authorities of a given authority, taking into account a filter
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#getParentAuthorities(java.lang.String, org.alfresco.repo.webservice.accesscontrol.SiblingAuthorityFilter)
|
||||
*/
|
||||
public String[] getParentAuthorities(String authority, SiblingAuthorityFilter filter)
|
||||
throws RemoteException, AccessControlFault
|
||||
{
|
||||
AuthorityType authorityType = AuthorityType.valueOf(filter.getAuthorityType());
|
||||
Set<String> result = this.authorityService.getContainingAuthorities(authorityType, authority, filter.isImmediate());
|
||||
return (String[])result.toArray(new String[result.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a child authority
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.accesscontrol.AccessControlServiceSoapPort#removeChildAuthorities(java.lang.String, java.lang.String[])
|
||||
*/
|
||||
public void removeChildAuthorities(String parentAuthority, String[] authorities)
|
||||
throws RemoteException, AccessControlFault
|
||||
{
|
||||
for (String authority : authorities)
|
||||
{
|
||||
this.authorityService.removeAuthority(parentAuthority, authority);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -1,600 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.administration;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.rmi.RemoteException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.repo.webservice.AbstractWebService;
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.action.ActionFault;
|
||||
import org.alfresco.repo.webservice.repository.RepositoryFault;
|
||||
import org.alfresco.repo.webservice.types.NamedValue;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class AdministrationWebService extends AbstractWebService implements
|
||||
AdministrationServiceSoapPort
|
||||
{
|
||||
/** Log */
|
||||
private static Log logger = LogFactory.getLog(AdministrationWebService.class);
|
||||
|
||||
/** The person service */
|
||||
private PersonService personService = null;
|
||||
|
||||
/**
|
||||
* Indicates whether the user administration methods should manage the authentication
|
||||
* details, or just the person details.
|
||||
*
|
||||
* Set this to true if an 3rd party authentication implementation has been pluged into
|
||||
* the repository that manages authentication details.
|
||||
*/
|
||||
private boolean manageAuthenticationDetails = true;
|
||||
|
||||
/** The authentication service */
|
||||
private MutableAuthenticationService authenticationService = null;
|
||||
|
||||
private AuthorityService authorityService;
|
||||
|
||||
/** The transaction service */
|
||||
private TransactionService transactionService = null;
|
||||
|
||||
/** A set of ignored properties */
|
||||
private static Set<QName> ignoredProperties = new HashSet<QName>(3);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public AdministrationWebService()
|
||||
{
|
||||
// Set properties to ignore
|
||||
AdministrationWebService.ignoredProperties.add(ContentModel.PROP_STORE_PROTOCOL);
|
||||
AdministrationWebService.ignoredProperties.add(ContentModel.PROP_STORE_IDENTIFIER);
|
||||
AdministrationWebService.ignoredProperties.add(ContentModel.PROP_NODE_UUID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the flag that indicates whether this service should manage user authentication details as
|
||||
* well as person details.
|
||||
*
|
||||
* @param manageAuthenticationDetails true if authentication details are managed, false otherwise
|
||||
*/
|
||||
public void setManageAuthenticationDetails(boolean manageAuthenticationDetails)
|
||||
{
|
||||
this.manageAuthenticationDetails = manageAuthenticationDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transaction service
|
||||
*
|
||||
* @param transactionService the transaction service
|
||||
*/
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the person service
|
||||
*
|
||||
* @param personService sets the person service
|
||||
*/
|
||||
public void setPersonService(PersonService personService)
|
||||
{
|
||||
this.personService = personService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authentication service
|
||||
*
|
||||
* @param authenticationService the authentication service
|
||||
*/
|
||||
public void setAuthenticationService(MutableAuthenticationService authenticationService)
|
||||
{
|
||||
this.authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authority service used to determine admin rights.
|
||||
*
|
||||
* @param authorityService the service implementation
|
||||
*/
|
||||
public void setAuthorityService(AuthorityService authorityService)
|
||||
{
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#queryUsers(org.alfresco.repo.webservice.administration.UserFilter)
|
||||
*/
|
||||
public UserQueryResults queryUsers(final UserFilter filter)
|
||||
throws RemoteException, AdministrationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<UserQueryResults> callback = new RetryingTransactionCallback<UserQueryResults>()
|
||||
{
|
||||
public UserQueryResults execute() throws Exception
|
||||
{
|
||||
return queryUsersImpl(filter);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query users, batch by set size
|
||||
*
|
||||
* @param filter used to filter results
|
||||
* @return user query results, optionally batched
|
||||
*/
|
||||
private UserQueryResults queryUsersImpl(UserFilter filter)
|
||||
{
|
||||
MessageContext msgContext = MessageContext.getCurrentContext();
|
||||
|
||||
// Create the query
|
||||
UserQuery query = new UserQuery(filter);
|
||||
|
||||
// Create a user query session
|
||||
UserQuerySession userQuerySession = new UserQuerySession(Long.MAX_VALUE, Utils.getBatchSize(msgContext), query);
|
||||
|
||||
// Get the next batch of results
|
||||
UserQueryResults userQueryResults = userQuerySession.getNextResults(serviceRegistry);
|
||||
|
||||
String querySessionId = userQuerySession.getId();
|
||||
// add the session to the cache if there are more results to come
|
||||
boolean haveMoreResults = userQuerySession.haveMoreResults();
|
||||
if (haveMoreResults)
|
||||
{
|
||||
querySessionCache.put(querySessionId, userQuerySession);
|
||||
}
|
||||
|
||||
// Construct the return value
|
||||
// TODO: http://issues.alfresco.com/browse/AR-1689
|
||||
// This looks odd, but I've chosen to be specific about when the ID is set on the return
|
||||
// results and when it isn't.
|
||||
UserQueryResults result = new UserQueryResults(
|
||||
haveMoreResults ? querySessionId : null,
|
||||
userQueryResults.getUserDetails());
|
||||
|
||||
// Done
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#fetchMoreUsers(java.lang.String)
|
||||
*/
|
||||
public UserQueryResults fetchMoreUsers(final String querySession)
|
||||
throws RemoteException, AdministrationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<UserQueryResults> callback = new RetryingTransactionCallback<UserQueryResults>()
|
||||
{
|
||||
public UserQueryResults execute() throws Exception
|
||||
{
|
||||
return fetchMoreUsersImpl(querySession);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param querySessionId
|
||||
* @return
|
||||
*/
|
||||
private UserQueryResults fetchMoreUsersImpl(String querySessionId) throws RepositoryFault
|
||||
{
|
||||
UserQuerySession session = null;
|
||||
try
|
||||
{
|
||||
session = (UserQuerySession) querySessionCache.get(querySessionId);
|
||||
}
|
||||
catch (ClassCastException e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Query session was not generated by the AdministrationWebService: " + querySessionId);
|
||||
}
|
||||
throw new RepositoryFault(
|
||||
4,
|
||||
"querySession with id '" + querySessionId + "' is invalid");
|
||||
}
|
||||
|
||||
UserQueryResults queryResult = null;
|
||||
if (session != null)
|
||||
{
|
||||
queryResult = session.getNextResults(serviceRegistry);
|
||||
if (!session.haveMoreResults())
|
||||
{
|
||||
this.querySessionCache.remove(querySessionId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update the cache instance so that it can trigger replication as required
|
||||
querySessionCache.put(querySessionId, session);
|
||||
}
|
||||
}
|
||||
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#getUser(java.lang.String)
|
||||
*/
|
||||
public UserDetails getUser(final String userName) throws RemoteException, AdministrationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<UserDetails> callback = new RetryingTransactionCallback<UserDetails>()
|
||||
{
|
||||
public UserDetails execute() throws Exception
|
||||
{
|
||||
return getUserImpl(userName);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user details
|
||||
*
|
||||
* @param userName the user name
|
||||
* @return the user details object
|
||||
* @throws RemoteException
|
||||
* @throws AdministrationFault
|
||||
*/
|
||||
private UserDetails getUserImpl(String userName)
|
||||
{
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
UserDetails userDetails = null;
|
||||
|
||||
if (this.personService.personExists(userName) == true)
|
||||
{
|
||||
NodeRef nodeRef = this.personService.getPerson(userName);
|
||||
userDetails = createUserDetails(nodeService, userName, nodeRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Throw an exception to indicate that the user does not exist
|
||||
throw new AlfrescoRuntimeException(MessageFormat.format("The user with name {0} does not exist.", new Object[]{userName}));
|
||||
}
|
||||
|
||||
return userDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a valid person node reference will create a user details object
|
||||
*
|
||||
* @param nodeRef the node reference
|
||||
* @return the user details object populated with the appropriate property values
|
||||
*/
|
||||
/* package */ static UserDetails createUserDetails(NodeService nodeService, String userName, NodeRef nodeRef)
|
||||
{
|
||||
// Create the user details object
|
||||
UserDetails userDetails = new UserDetails();
|
||||
|
||||
// Set the user name
|
||||
userDetails.setUserName(userName);
|
||||
|
||||
// Set the various property values
|
||||
Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
|
||||
List<NamedValue> namedValues = new ArrayList<NamedValue>(properties.size());
|
||||
for (Map.Entry<QName, Serializable> entry : properties.entrySet())
|
||||
{
|
||||
if (AdministrationWebService.ignoredProperties.contains(entry.getKey()) == false)
|
||||
{
|
||||
String value = null;
|
||||
try
|
||||
{
|
||||
value = DefaultTypeConverter.INSTANCE.convert(String.class, entry.getValue());
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
value = entry.getValue().toString();
|
||||
}
|
||||
NamedValue namedValue = new NamedValue();
|
||||
namedValue.setName(entry.getKey().toString());
|
||||
namedValue.setIsMultiValue(false);
|
||||
namedValue.setValue(value);
|
||||
namedValues.add(namedValue);
|
||||
}
|
||||
}
|
||||
userDetails.setProperties((NamedValue[])namedValues.toArray(new NamedValue[namedValues.size()]));
|
||||
|
||||
return userDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#createUsers(org.alfresco.repo.webservice.administration.NewUserDetails[])
|
||||
*/
|
||||
public UserDetails[] createUsers(final NewUserDetails[] newUsers) throws RemoteException, AdministrationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<UserDetails[]> callback = new RetryingTransactionCallback<UserDetails[]>()
|
||||
{
|
||||
public UserDetails[] execute() throws Exception
|
||||
{
|
||||
return createUsersImpl(newUsers);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the new users
|
||||
*
|
||||
* @param newUsers the new users detail
|
||||
* @return the details of the created users
|
||||
* @throws RemoteException
|
||||
* @throws AdministrationFault
|
||||
*/
|
||||
private UserDetails[] createUsersImpl(NewUserDetails[] newUsers)
|
||||
{
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
UserDetails[] userDetails = new UserDetails[newUsers.length];
|
||||
|
||||
int index = 0;
|
||||
for (NewUserDetails newUser : newUsers)
|
||||
{
|
||||
if (this.manageAuthenticationDetails == true)
|
||||
{
|
||||
// Create a new authentication
|
||||
this.authenticationService.createAuthentication(newUser.getUserName(), newUser.getPassword().toCharArray());
|
||||
}
|
||||
|
||||
// Create a new person
|
||||
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(7);
|
||||
properties.put(ContentModel.PROP_USERNAME, newUser.getUserName());
|
||||
for (NamedValue namedValue : newUser.getProperties())
|
||||
{
|
||||
properties.put(QName.createQName(namedValue.getName()), namedValue.getValue());
|
||||
}
|
||||
NodeRef personNodeRef = this.personService.createPerson(properties);
|
||||
|
||||
// Add the details to the result
|
||||
userDetails[index] = createUserDetails(nodeService, newUser.getUserName(), personNodeRef);
|
||||
index++;
|
||||
}
|
||||
|
||||
return userDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#updateUsers(org.alfresco.repo.webservice.administration.UserDetails[])
|
||||
*/
|
||||
public UserDetails[] updateUsers(final UserDetails[] users) throws RemoteException, AdministrationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<UserDetails[]> callback = new RetryingTransactionCallback<UserDetails[]>()
|
||||
{
|
||||
public UserDetails[] execute() throws Exception
|
||||
{
|
||||
return updateUsersImpl(users);
|
||||
}
|
||||
};
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the users details
|
||||
*
|
||||
* @param users the user details to update
|
||||
* @return the updated user details
|
||||
*/
|
||||
private UserDetails[] updateUsersImpl(UserDetails[] users)
|
||||
{
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
UserDetails[] userDetails = new UserDetails[users.length];
|
||||
|
||||
int index = 0;
|
||||
for (UserDetails user : users)
|
||||
{
|
||||
// Build the property map
|
||||
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(7);
|
||||
properties.put(ContentModel.PROP_USERNAME, user.getUserName());
|
||||
for (NamedValue namedValue : user.getProperties())
|
||||
{
|
||||
properties.put(QName.createQName(namedValue.getName()), namedValue.getValue());
|
||||
}
|
||||
|
||||
// Update the properties of the person
|
||||
this.personService.setPersonProperties(user.getUserName(), properties);
|
||||
|
||||
// Add the details to the result
|
||||
NodeRef nodeRef = this.personService.getPerson(user.getUserName());
|
||||
userDetails[index] = createUserDetails(nodeService, user.getUserName(), nodeRef);
|
||||
index++;
|
||||
}
|
||||
|
||||
return userDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#changePassword(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void changePassword(final String userName, final String oldPassword, final String newPassword) throws RemoteException, AdministrationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<Object> callback = new RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute() throws Exception
|
||||
{
|
||||
changePasswordImpl(userName, oldPassword, newPassword);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the current password of the user
|
||||
*
|
||||
* @param userName the user name
|
||||
* @param oldPassword the old (current) password
|
||||
* @param newPassword the new password
|
||||
*/
|
||||
private void changePasswordImpl(String userName, String oldPassword, String newPassword)
|
||||
{
|
||||
if (this.manageAuthenticationDetails == true)
|
||||
{
|
||||
// Update the authentication details
|
||||
if (this.authorityService.hasAdminAuthority() == true)
|
||||
{
|
||||
this.authenticationService.setAuthentication(userName, newPassword.toCharArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
this.authenticationService.updateAuthentication(userName, oldPassword.toCharArray(), newPassword.toCharArray());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException("Web service has been configured so that user authenticaiton details are not managed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#deleteUsers(java.lang.String[])
|
||||
*/
|
||||
public void deleteUsers(final String[] userNames) throws RemoteException,
|
||||
AdministrationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<Object> callback = new RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute() throws Exception
|
||||
{
|
||||
deleteUsersImpl(userNames);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", exception);
|
||||
}
|
||||
|
||||
throw new ActionFault(0, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete users
|
||||
*
|
||||
* @param userNames the names of the users to delete
|
||||
*/
|
||||
private void deleteUsersImpl(String[] userNames)
|
||||
{
|
||||
for (String userName : userNames)
|
||||
{
|
||||
this.personService.deletePerson(userName);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.administration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.webservice.AbstractQuery;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
|
||||
/**
|
||||
* A query to retrieve normal node associations.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 2.1
|
||||
*/
|
||||
public class UserQuery extends AbstractQuery<UserQueryResults>
|
||||
{
|
||||
private static final long serialVersionUID = -672399618512462040L;
|
||||
|
||||
private UserFilter userFilter;
|
||||
|
||||
/**
|
||||
* @param userFilter
|
||||
* The user filter
|
||||
*/
|
||||
public UserQuery(UserFilter userFilter)
|
||||
{
|
||||
this.userFilter = userFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
sb.append("AssociationQuery")
|
||||
.append("[ userFilter=").append(userFilter.getUserName())
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public UserQueryResults execute(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
PersonService personService = serviceRegistry.getPersonService();
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
|
||||
Set<NodeRef> nodeRefs = personService.getAllPeople();
|
||||
|
||||
// Filter the results
|
||||
List<NodeRef> filteredNodeRefs = null;
|
||||
if (userFilter != null && userFilter.getUserName() != null && userFilter.getUserName().length() != 0)
|
||||
{
|
||||
String userNameFilter = userFilter.getUserName();
|
||||
|
||||
filteredNodeRefs = new ArrayList<NodeRef>(nodeRefs.size());
|
||||
for (NodeRef nodeRef : nodeRefs)
|
||||
{
|
||||
String userName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME);
|
||||
if (userName.matches(userNameFilter) == true)
|
||||
{
|
||||
filteredNodeRefs.add(nodeRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
filteredNodeRefs = new ArrayList<NodeRef>(nodeRefs);
|
||||
}
|
||||
|
||||
UserDetails[] results = new UserDetails[filteredNodeRefs.size()];
|
||||
int index = 0;
|
||||
for (NodeRef nodeRef : filteredNodeRefs)
|
||||
{
|
||||
String userName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME);
|
||||
results[index] = AdministrationWebService.createUserDetails(nodeService, userName, nodeRef);
|
||||
index++;
|
||||
}
|
||||
|
||||
UserQueryResults queryResults = new UserQueryResults(null, results);
|
||||
|
||||
// Done
|
||||
return queryResults;
|
||||
}
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.administration;
|
||||
|
||||
import org.alfresco.repo.webservice.AbstractQuerySession;
|
||||
import org.alfresco.repo.webservice.ServerQuery;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* A session for managing user-related queries.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 2.1
|
||||
*/
|
||||
public class UserQuerySession extends AbstractQuerySession<UserQueryResults, UserDetails>
|
||||
{
|
||||
private static final long serialVersionUID = 1823253197962982642L;
|
||||
|
||||
public UserQuerySession(long maxResults, long batchSize, ServerQuery<UserQueryResults> query)
|
||||
{
|
||||
super(maxResults, batchSize, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UserDetails[] makeArray(int size)
|
||||
{
|
||||
return new UserDetails[size];
|
||||
}
|
||||
|
||||
public UserQueryResults getNextResults(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
UserQueryResults queryResults = getQueryResults(serviceRegistry);
|
||||
UserDetails[] allRows = queryResults.getUserDetails();
|
||||
UserDetails[] batchedRows = getNextResults(allRows);
|
||||
// Build the user query results
|
||||
UserQueryResults batchedResults = new UserQueryResults();
|
||||
// batchedResults.setQuerySession(getId()); TODO: http://issues.alfresco.com/browse/AR-1689
|
||||
|
||||
batchedResults.setUserDetails(batchedRows);
|
||||
// Done
|
||||
return batchedResults;
|
||||
}
|
||||
}
|
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.authentication;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.apache.axis.MessageContext;
|
||||
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;
|
||||
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
|
||||
/**
|
||||
* Sets the AuthenticationService instance to use
|
||||
*
|
||||
* @param authenticationSvc
|
||||
* The AuthenticationService
|
||||
*/
|
||||
public void setAuthenticationService(AuthenticationService authenticationSvc)
|
||||
{
|
||||
this.authenticationService = authenticationSvc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authentication component
|
||||
*
|
||||
* @param authenticationComponent
|
||||
*/
|
||||
public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
|
||||
{
|
||||
this.authenticationComponent = authenticationComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authentication.AuthenticationServiceSoapPort#startSession(java.lang.String,
|
||||
* java.lang.String)
|
||||
*/
|
||||
public AuthenticationResult startSession(final String username, final String password)
|
||||
throws RemoteException, AuthenticationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<AuthenticationResult> callback = new RetryingTransactionCallback<AuthenticationResult>()
|
||||
{
|
||||
public AuthenticationResult execute() throws Throwable
|
||||
{
|
||||
authenticationService.authenticate(username, password.toCharArray());
|
||||
String ticket = authenticationService.getCurrentTicket();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Issued ticket '" + ticket + "' for '" + username + "'");
|
||||
}
|
||||
|
||||
return new AuthenticationResult(username, ticket, Utils.getSessionId());
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback);
|
||||
}
|
||||
catch (AuthenticationException ae)
|
||||
{
|
||||
ae.printStackTrace();
|
||||
throw new AuthenticationFault(100, ae.getMessage());
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
throw new AuthenticationFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.authentication.AuthenticationServiceSoapPort#endSession()
|
||||
*/
|
||||
public void endSession(final String ticket) throws RemoteException, AuthenticationFault
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ticket != null)
|
||||
{
|
||||
RetryingTransactionCallback<Object> callback = new RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute() throws Throwable
|
||||
{
|
||||
authenticationComponent.setSystemUserAsCurrentUser();
|
||||
authenticationService.invalidateTicket(ticket);
|
||||
authenticationService.clearCurrentSecurityContext();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Session ended for ticket '" + ticket + "'");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback);
|
||||
Utils.invalidateSession();
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new AuthenticationFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,810 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.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.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
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.cmr.version.VersionType;
|
||||
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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<CheckoutResult>()
|
||||
{
|
||||
public CheckoutResult execute()
|
||||
{
|
||||
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(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, original);
|
||||
workingCopies[x] = Utils.convertToReference(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, 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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<CheckinResult>()
|
||||
{
|
||||
public CheckinResult execute()
|
||||
{
|
||||
// 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 = convertCommnets(comments);
|
||||
|
||||
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(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, 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(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, 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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the named value array that contains the comments and converts it to a Map that the underlying
|
||||
* services can understand.
|
||||
*
|
||||
* @param comments the comments named value array
|
||||
* @return Map<String, Serializable> Map that can be used with the underlying services
|
||||
*/
|
||||
private Map<String, Serializable> convertCommnets(NamedValue[] comments)
|
||||
{
|
||||
// Map the comments into the expected map
|
||||
Map<String, Serializable> mapComments = new HashMap<String, Serializable>(comments.length);
|
||||
for (NamedValue value : comments)
|
||||
{
|
||||
if (value.getName().equals(VersionModel.PROP_VERSION_TYPE) == true)
|
||||
{
|
||||
mapComments.put(value.getName(), VersionType.valueOf(value.getValue()));
|
||||
}
|
||||
else
|
||||
{
|
||||
mapComments.put(value.getName(), value.getValue());
|
||||
}
|
||||
}
|
||||
return mapComments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<Reference>()
|
||||
{
|
||||
public Reference execute()
|
||||
{
|
||||
// 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 = convertCommnets(comments);
|
||||
|
||||
// CheckIn the content
|
||||
NodeRef origNodeRef = AuthoringWebService.this.cociService.checkin(
|
||||
nodeRef,
|
||||
versionProperties,
|
||||
contentUrl,
|
||||
keepCheckedOut);
|
||||
// Return the orig node ref
|
||||
return Utils.convertToReference(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, 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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<CancelCheckoutResult>()
|
||||
{
|
||||
public CancelCheckoutResult execute()
|
||||
{
|
||||
// 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(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, origNode);
|
||||
workingCopies[iIndex] = Utils.convertToReference(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, 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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<Reference[]>()
|
||||
{
|
||||
public Reference[] execute()
|
||||
{
|
||||
// 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(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, 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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<Reference[]>()
|
||||
{
|
||||
public Reference[] execute()
|
||||
{
|
||||
// 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(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, 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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<LockStatus[]>()
|
||||
{
|
||||
public LockStatus[] execute()
|
||||
{
|
||||
// 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(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, 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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<VersionResult>()
|
||||
{
|
||||
public VersionResult execute()
|
||||
{
|
||||
// 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 = convertCommnets(comments);
|
||||
|
||||
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(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, version.getVersionedNodeRef()));
|
||||
webServiceVersions.add(Utils.convertToVersion(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, 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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<VersionHistory>()
|
||||
{
|
||||
public VersionHistory execute()
|
||||
{
|
||||
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(AuthoringWebService.this.nodeService, AuthoringWebService.this.namespaceService, 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
|
||||
{
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute()
|
||||
{
|
||||
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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<VersionHistory>()
|
||||
{
|
||||
public VersionHistory execute()
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.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 static 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 (webAppCtx == null && msgCtx != null)
|
||||
{
|
||||
webAppCtx = Utils.getSpringContext(msgCtx);
|
||||
}
|
||||
|
||||
if (webAppCtx == null)
|
||||
{
|
||||
throw new AxisFault("Failed to retrieve the Spring web application context");
|
||||
}
|
||||
|
||||
return webAppCtx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initServiceDesc(SOAPService service, MessageContext msgContext) throws AxisFault
|
||||
{
|
||||
if( msgContext != null )
|
||||
{
|
||||
getWebAppContext(msgContext);
|
||||
}
|
||||
super.initServiceDesc(service, msgContext);
|
||||
}
|
||||
}
|
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.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
|
||||
{
|
||||
@SuppressWarnings("unused")
|
||||
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);
|
||||
}
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.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;
|
||||
}
|
||||
|
||||
}
|
@@ -1,459 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.classification;
|
||||
|
||||
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.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<Classification[]>()
|
||||
{
|
||||
public Classification[] execute()
|
||||
{
|
||||
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(dictionaryService);
|
||||
}
|
||||
|
||||
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(this.nodeService, this.namespaceService, 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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<Category[]>()
|
||||
{
|
||||
public Category[] execute()
|
||||
{
|
||||
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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<CategoriesResult[]>()
|
||||
{
|
||||
public CategoriesResult[] execute()
|
||||
{
|
||||
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(ClassificationWebService.this.nodeService, ClassificationWebService.this.namespaceService, 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(ClassificationWebService.this.nodeService, ClassificationWebService.this.namespaceService, 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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<CategoriesResult[]>()
|
||||
{
|
||||
public CategoriesResult[] execute()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
Reference[] categories = category.getCategories();
|
||||
ArrayList<NodeRef> categoryNodeRefs = null;
|
||||
if(categories == null)
|
||||
{
|
||||
categoryNodeRefs = new ArrayList<NodeRef>(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
categoryNodeRefs = new ArrayList<NodeRef>(categories.length);
|
||||
for (Reference categoryReference : categories)
|
||||
{
|
||||
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(ClassificationWebService.this.nodeService, ClassificationWebService.this.namespaceService, 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 transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<ClassDefinition>()
|
||||
{
|
||||
public ClassDefinition execute()
|
||||
{
|
||||
org.alfresco.service.cmr.dictionary.ClassDefinition classDefinition = ClassificationWebService.this.dictionaryService.getClass(QName.createQName(classification));
|
||||
return Utils.setupClassDefObject(dictionaryService, classDefinition);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
|
||||
throw new ClassificationFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,420 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.content;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.rmi.RemoteException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.activation.DataHandler;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
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.cmr.repository.TransformationOptions;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.axis.AxisFault;
|
||||
import org.apache.axis.Message;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.axis.attachments.AttachmentPart;
|
||||
import org.apache.axis.attachments.Attachments;
|
||||
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(final Predicate items, final String property)
|
||||
throws RemoteException, ContentFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<Content[]> callback = new RetryingTransactionCallback<Content[]>()
|
||||
{
|
||||
public Content[] execute() throws Throwable
|
||||
{
|
||||
// resolve the predicates
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(items, nodeService, searchService, namespaceService);
|
||||
List<Content> results = new ArrayList<Content>(nodes.size());
|
||||
for (NodeRef nodeRef : nodes)
|
||||
{
|
||||
// Add content to the result
|
||||
results.add(createContent(nodeRef, property));
|
||||
}
|
||||
|
||||
return results.toArray(new Content[results.size()]);
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
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.getServerName();
|
||||
if (req.getLocalPort() != 80)
|
||||
{
|
||||
address = address + ":" + req.getServerPort();
|
||||
}
|
||||
|
||||
// Get the file name
|
||||
String filename = (String)this.nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||
|
||||
// Filename may not exist if this node isn't a cm:object
|
||||
if (filename == null)
|
||||
{
|
||||
filename = "file.bin";
|
||||
}
|
||||
|
||||
// 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(this.nodeService, this.namespaceService, 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(this.nodeService, this.namespaceService, 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(final Reference node, final String property, final byte[] content, final ContentFormat format)
|
||||
throws RemoteException, ContentFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<Content> callback = new RetryingTransactionCallback<Content>()
|
||||
{
|
||||
public Content execute() throws Throwable
|
||||
{
|
||||
// create a NodeRef from the parent reference
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(node, nodeService, searchService, namespaceService);
|
||||
|
||||
// Get the content writer
|
||||
ContentWriter writer = 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
|
||||
InputStream is = new ByteArrayInputStream(content);
|
||||
writer.putContent(is);
|
||||
|
||||
// Debug
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Updated content for node with id: " + nodeRef.getId());
|
||||
}
|
||||
|
||||
// Return the content object
|
||||
return createContent(nodeRef, property);
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new ContentFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.content.ContentServiceSoapPort#writeWithAttachments(org.alfresco.repo.webservice.types.Reference[], java.lang.String[], org.alfresco.repo.webservice.types.ContentFormat[])
|
||||
*/
|
||||
public Content writeWithAttachment(final Reference node, final String property, final ContentFormat format)
|
||||
throws RemoteException, ContentFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<Content> callback = new RetryingTransactionCallback<Content>()
|
||||
{
|
||||
public Content execute() throws Throwable
|
||||
{
|
||||
AttachmentPart[] attachments = getMessageAttachments();
|
||||
if (attachments.length != 1)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Expecting only one attachment");
|
||||
}
|
||||
|
||||
// create a NodeRef from the parent reference
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(node, nodeService, searchService, namespaceService);
|
||||
|
||||
// Get the content writer
|
||||
ContentWriter writer = 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 (just need to get the first in the array since we are only expecting one attachment)
|
||||
DataHandler dh = attachments[0].getDataHandler();
|
||||
InputStream is = dh.getInputStream();
|
||||
writer.putContent(is);
|
||||
|
||||
// Debug
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Updated content for node with id: " + nodeRef.getId());
|
||||
}
|
||||
|
||||
// Return the content object
|
||||
return createContent(nodeRef, property);
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new ContentFault(0, e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private AttachmentPart[] getMessageAttachments()
|
||||
throws AxisFault
|
||||
{
|
||||
MessageContext msgContext = MessageContext.getCurrentContext();
|
||||
Message reqMsg = msgContext.getRequestMessage();
|
||||
Attachments messageAttachments = reqMsg.getAttachmentsImpl();
|
||||
if (null == messageAttachments)
|
||||
{
|
||||
return new AttachmentPart[0];
|
||||
}
|
||||
int attachmentCount = messageAttachments.getAttachmentCount();
|
||||
AttachmentPart attachments[] = new AttachmentPart[attachmentCount];
|
||||
Iterator it = messageAttachments.getAttachments().iterator();
|
||||
int count = 0;
|
||||
while (it.hasNext())
|
||||
{
|
||||
AttachmentPart part = (AttachmentPart)it.next();
|
||||
attachments[count++] = part;
|
||||
}
|
||||
|
||||
return attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.webservice.content.ContentServiceSoapPort#clear(org.alfresco.repo.webservice.types.Predicate,
|
||||
* java.lang.String)
|
||||
*/
|
||||
public Content[] clear(final Predicate items, final String property) throws RemoteException, ContentFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<Content[]> callback = new RetryingTransactionCallback<Content[]>()
|
||||
{
|
||||
public Content[] execute() throws Throwable
|
||||
{
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(items, nodeService, searchService, 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
|
||||
nodeService.setProperty(nodeRef, QName.createQName(property), null);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Cleared content node with id: " + nodeRef.getId());
|
||||
}
|
||||
|
||||
contents[x] = createContent(nodeRef, property);
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new ContentFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms content from one node and mimetype to another node and mimetype
|
||||
*
|
||||
* @see org.alfresco.repo.webservice.content.ContentServiceSoapPort#transform(org.alfresco.repo.webservice.types.Reference, java.lang.String, org.alfresco.repo.webservice.types.Reference, java.lang.String, org.alfresco.repo.webservice.types.ContentFormat)
|
||||
*/
|
||||
public Content transform(
|
||||
final Reference source,
|
||||
final String property,
|
||||
final Reference destinationReference,
|
||||
final String destinationProperty,
|
||||
final ContentFormat destinationFormat)
|
||||
throws RemoteException, ContentFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<Content> callback = new RetryingTransactionCallback<Content>()
|
||||
{
|
||||
public Content execute() throws Throwable
|
||||
{
|
||||
// Get the nodes and property qname's
|
||||
NodeRef sourceNodeRef = Utils.convertToNodeRef(source, ContentWebService.this.nodeService, ContentWebService.this.searchService, ContentWebService.this.namespaceService);
|
||||
NodeRef destinationNodeRef = Utils.convertToNodeRef(destinationReference, ContentWebService.this.nodeService, ContentWebService.this.searchService, ContentWebService.this.namespaceService);
|
||||
QName sourceQName = QName.createQName(property);
|
||||
QName destinationQName = QName.createQName(destinationProperty);
|
||||
|
||||
// Get the content reader
|
||||
ContentReader contentReader = ContentWebService.this.contentService.getReader(sourceNodeRef, sourceQName);
|
||||
if (contentReader == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Source content does not exist. Transform could not take place.");
|
||||
}
|
||||
|
||||
// Get the content writer
|
||||
ContentWriter contentWriter = ContentWebService.this.contentService.getWriter(destinationNodeRef, destinationQName, true);
|
||||
contentWriter.setEncoding(destinationFormat.getEncoding());
|
||||
contentWriter.setMimetype(destinationFormat.getMimetype());
|
||||
|
||||
TransformationOptions options = new TransformationOptions();
|
||||
options.setSourceNodeRef(sourceNodeRef);
|
||||
|
||||
// Transform the content
|
||||
ContentWebService.this.contentService.transform(contentReader, contentWriter, options);
|
||||
|
||||
// Return the content object to the user
|
||||
return createContent(destinationNodeRef, destinationProperty);
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new ContentFault(0, e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.dictionary;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.webservice.AbstractWebService;
|
||||
import org.alfresco.repo.webservice.Utils;
|
||||
import org.alfresco.repo.webservice.dictionary.ClassPredicate;
|
||||
import org.alfresco.repo.webservice.dictionary.DictionaryFault;
|
||||
import org.alfresco.repo.webservice.dictionary.DictionaryServiceSoapPort;
|
||||
import org.alfresco.repo.webservice.types.AssociationDefinition;
|
||||
import org.alfresco.repo.webservice.types.ClassDefinition;
|
||||
import org.alfresco.repo.webservice.types.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryException;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.InvalidClassException;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Web service implementation of the DictionaryService. The WSDL for this
|
||||
* service can be accessed from
|
||||
* http://localhost:8080/alfresco/wsdl/dictionary-service.wsdl
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class DictionaryWebService extends AbstractWebService implements DictionaryServiceSoapPort
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(DictionaryWebService.class);
|
||||
|
||||
// dependencies
|
||||
private DictionaryService dictionaryService;
|
||||
private NamespaceService namespaceService;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the instance of the DictionaryService to be used
|
||||
*
|
||||
* @param dictionaryService The DictionaryService
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the instance of the NamespaceService to be used
|
||||
*/
|
||||
public void setNamespaceService(NamespaceService namespaceService)
|
||||
{
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.webservice.dictionary.DictionaryServiceSoapPort#getClasses(org.alfresco.repo.webservice.dictionary.ClassPredicate[], org.alfresco.repo.webservice.dictionary.ClassPredicate[])
|
||||
*/
|
||||
public ClassDefinition[] getClasses(ClassPredicate types, ClassPredicate aspects) throws RemoteException, DictionaryFault
|
||||
{
|
||||
try
|
||||
{
|
||||
Set<org.alfresco.service.cmr.dictionary.ClassDefinition> classDefs = new HashSet<org.alfresco.service.cmr.dictionary.ClassDefinition>();
|
||||
classDefs.addAll(getClassDefs(types, false));
|
||||
classDefs.addAll(getClassDefs(aspects, true));
|
||||
|
||||
List<ClassDefinition> wsClassDefs = new ArrayList<ClassDefinition>(classDefs.size());
|
||||
for (org.alfresco.service.cmr.dictionary.ClassDefinition classDef : classDefs)
|
||||
{
|
||||
wsClassDefs.add(Utils.setupClassDefObject(dictionaryService, classDef));
|
||||
}
|
||||
|
||||
return wsClassDefs.toArray(new ClassDefinition[wsClassDefs.size()]);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new DictionaryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.webservice.dictionary.DictionaryServiceSoapPort#getProperties(java.lang.String[])
|
||||
*/
|
||||
public PropertyDefinition[] getProperties(String[] propertyNames) throws RemoteException, DictionaryFault
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertyDefinition[] propDefs = new PropertyDefinition[propertyNames.length];
|
||||
|
||||
int i = 0;
|
||||
for (String propertyName : propertyNames)
|
||||
{
|
||||
QName propertyQName = QName.createQName(propertyName, namespaceService);
|
||||
org.alfresco.service.cmr.dictionary.PropertyDefinition ddPropDef = dictionaryService.getProperty(propertyQName);
|
||||
if (ddPropDef == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Property propertyName does not exist.");
|
||||
}
|
||||
propDefs[i++] = Utils.setupPropertyDefObject(dictionaryService, ddPropDef);
|
||||
}
|
||||
|
||||
return propDefs;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new DictionaryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.webservice.dictionary.DictionaryServiceSoapPort#getAssociations(java.lang.String[])
|
||||
*/
|
||||
public AssociationDefinition[] getAssociations(String[] associationNames) throws RemoteException, DictionaryFault
|
||||
{
|
||||
try
|
||||
{
|
||||
AssociationDefinition[] assocDefs = new AssociationDefinition[associationNames.length];
|
||||
|
||||
int i = 0;
|
||||
for (String associationName : associationNames)
|
||||
{
|
||||
QName associationQName = QName.createQName(associationName, namespaceService);
|
||||
org.alfresco.service.cmr.dictionary.AssociationDefinition ddAssocDef = dictionaryService.getAssociation(associationQName);
|
||||
if (ddAssocDef == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Property propertyName does not exist.");
|
||||
}
|
||||
assocDefs[i++] = Utils.setupAssociationDefObject(dictionaryService, ddAssocDef);
|
||||
}
|
||||
|
||||
return assocDefs;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new DictionaryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.webservice.dictionary.DictionaryServiceSoapPort#isSubClass(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public boolean isSubClass(String className, String isSubClassOfName) throws RemoteException, DictionaryFault
|
||||
{
|
||||
try
|
||||
{
|
||||
QName classQName = QName.createQName(className, namespaceService);
|
||||
QName isSubClassOfQName = QName.createQName(isSubClassOfName, namespaceService);
|
||||
return dictionaryService.isSubClass(classQName, isSubClassOfQName);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new DictionaryFault(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve class definitions that match the provided class predicate
|
||||
*
|
||||
* @param predicate the class predicate to filter by
|
||||
* @param forAspects futher filtering on type or aspect
|
||||
* @return class definitions that match
|
||||
*/
|
||||
private Set<org.alfresco.service.cmr.dictionary.ClassDefinition> getClassDefs(ClassPredicate predicate, boolean forAspects)
|
||||
{
|
||||
Set<org.alfresco.service.cmr.dictionary.ClassDefinition> classDefs = new HashSet<org.alfresco.service.cmr.dictionary.ClassDefinition>();
|
||||
if (predicate != null)
|
||||
{
|
||||
String[] predicateTypeNames = predicate.getNames();
|
||||
if (predicateTypeNames != null)
|
||||
{
|
||||
// predicate class names have been provided, therefore retrieve class definitions for those
|
||||
for (String predicateTypeName : predicateTypeNames)
|
||||
{
|
||||
QName classQName = QName.createQName(predicateTypeName, namespaceService);
|
||||
org.alfresco.service.cmr.dictionary.ClassDefinition classDef = dictionaryService.getClass(classQName);
|
||||
if (classDef == null || classDef.isAspect() != forAspects)
|
||||
{
|
||||
throw new InvalidClassException(classQName);
|
||||
}
|
||||
classDefs.add(classDef);
|
||||
}
|
||||
|
||||
// also retrieve sub-classes and super-classes as specified by predicate
|
||||
if (predicate.isFollowSuperClass() || predicate.isFollowSubClass())
|
||||
{
|
||||
Set<org.alfresco.service.cmr.dictionary.ClassDefinition> touchedClassDefs = new HashSet<org.alfresco.service.cmr.dictionary.ClassDefinition>();
|
||||
for (org.alfresco.service.cmr.dictionary.ClassDefinition classDef : classDefs)
|
||||
{
|
||||
if (predicate.isFollowSuperClass())
|
||||
{
|
||||
getSuperClasses(classDef, touchedClassDefs, true);
|
||||
}
|
||||
else if (predicate.isFollowSubClass())
|
||||
{
|
||||
getSubClasses(classDef, touchedClassDefs, true);
|
||||
}
|
||||
}
|
||||
classDefs.addAll(touchedClassDefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// return all classes
|
||||
Collection<QName> classQNames = (forAspects) ? dictionaryService.getAllAspects() : dictionaryService.getAllTypes();
|
||||
for (QName classQName : classQNames)
|
||||
{
|
||||
classDefs.add(dictionaryService.getClass(classQName));
|
||||
}
|
||||
}
|
||||
|
||||
return classDefs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the super-class of the specified class
|
||||
*
|
||||
* @param classDef the class definition to retrieve super-classes for
|
||||
* @param superClasses the collection to place super-classes into
|
||||
* @param recurse true => recurse down the sub-class hierarchy
|
||||
*/
|
||||
private void getSuperClasses(org.alfresco.service.cmr.dictionary.ClassDefinition classDef, Set<org.alfresco.service.cmr.dictionary.ClassDefinition> superClasses, boolean recurse)
|
||||
{
|
||||
QName superClass = classDef.getParentName();
|
||||
if (superClass != null)
|
||||
{
|
||||
org.alfresco.service.cmr.dictionary.ClassDefinition superClassDef = dictionaryService.getClass(superClass);
|
||||
superClasses.add(superClassDef);
|
||||
if (recurse)
|
||||
{
|
||||
getSuperClasses(superClassDef, superClasses, recurse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the sub-class of the specified class
|
||||
*
|
||||
* @param classDef the class definition to retrieve sub-classes for
|
||||
* @param superClasses the collection to place sub-classes into
|
||||
* @param recurse true => recurse up the super-class hierarchy
|
||||
*/
|
||||
private void getSubClasses(org.alfresco.service.cmr.dictionary.ClassDefinition classDef, Set<org.alfresco.service.cmr.dictionary.ClassDefinition> subClasses, boolean recurse)
|
||||
{
|
||||
QName superClass = classDef.getName();
|
||||
|
||||
Collection<QName> subClassNames = (classDef.isAspect()) ? dictionaryService.getSubAspects(superClass, recurse) : dictionaryService.getSubTypes(superClass, recurse);
|
||||
|
||||
for (QName subClass : subClassNames)
|
||||
{
|
||||
org.alfresco.service.cmr.dictionary.ClassDefinition subClassDef = dictionaryService.getClass(subClass);
|
||||
subClasses.add(subClassDef);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.repo.webservice.AbstractQuery;
|
||||
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.ResultSet;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRow;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRowNode;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
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.QNamePattern;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
|
||||
/**
|
||||
* A query to retrieve normal node associations.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 2.1
|
||||
*/
|
||||
public class AssociationQuery extends AbstractQuery<ResultSet>
|
||||
{
|
||||
private static final long serialVersionUID = -672399618512462040L;
|
||||
|
||||
private Reference node;
|
||||
private Association association;
|
||||
|
||||
private final static String SOURCE = "source";
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* The node to query against
|
||||
* @param association
|
||||
* The association type to query or <tt>null</tt> to query all
|
||||
*/
|
||||
public AssociationQuery(Reference node, Association association)
|
||||
{
|
||||
this.node = node;
|
||||
this.association = association;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
sb.append("AssociationQuery")
|
||||
.append("[ node=").append(node.getUuid())
|
||||
.append(", association=").append(association)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public ResultSet execute(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
SearchService searchService = serviceRegistry.getSearchService();
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
DictionaryService dictionaryService = serviceRegistry.getDictionaryService();
|
||||
NamespaceService namespaceService = serviceRegistry.getNamespaceService();
|
||||
|
||||
// create the node ref and get the children from the repository
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(node, nodeService, searchService, namespaceService);
|
||||
List<AssociationRef> assocRefs = null;
|
||||
if (this.association == null)
|
||||
{
|
||||
assocRefs = nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL);
|
||||
}
|
||||
else
|
||||
{
|
||||
QNamePattern name = RegexQNamePattern.MATCH_ALL;
|
||||
String assocType = this.association.getAssociationType();
|
||||
if (assocType != null)
|
||||
{
|
||||
name = QName.createQName(assocType);
|
||||
}
|
||||
if (SOURCE.equals(this.association.getDirection()) == true)
|
||||
{
|
||||
assocRefs = nodeService.getSourceAssocs(nodeRef, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
assocRefs = nodeService.getTargetAssocs(nodeRef, name);
|
||||
}
|
||||
}
|
||||
|
||||
ResultSet results = new ResultSet();
|
||||
List<ResultSetRow> rows = new ArrayList<ResultSetRow>(assocRefs.size());
|
||||
|
||||
int index = 0;
|
||||
NodeRef childNodeRef = null;
|
||||
for (AssociationRef assocRef : assocRefs)
|
||||
{
|
||||
if (SOURCE.equals(this.association.getDirection()) == true)
|
||||
{
|
||||
childNodeRef = assocRef.getSourceRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
childNodeRef = assocRef.getTargetRef();
|
||||
}
|
||||
|
||||
Map<QName, Serializable> props = null;
|
||||
try
|
||||
{
|
||||
props = nodeService.getProperties(childNodeRef);
|
||||
}
|
||||
catch (AccessDeniedException e)
|
||||
{
|
||||
// user has no access to associated node
|
||||
}
|
||||
|
||||
if (props != null)
|
||||
{
|
||||
ResultSetRowNode rowNode = createResultSetRowNode(childNodeRef, nodeService);
|
||||
|
||||
// create columns for all the properties of the node
|
||||
// get the data for the row and build up the columns structure
|
||||
NamedValue[] columns = new NamedValue[props.size()+2];
|
||||
int col = 0;
|
||||
for (QName propName : props.keySet())
|
||||
{
|
||||
columns[col] = Utils.createNamedValue(dictionaryService, propName, props.get(propName));
|
||||
col++;
|
||||
}
|
||||
|
||||
// Now add the system columns containing the association details
|
||||
columns[col] = new NamedValue(SYS_COL_ASSOC_TYPE, Boolean.FALSE, assocRef.getTypeQName().toString(), null);
|
||||
|
||||
// Add one more column for the node's path
|
||||
col++;
|
||||
columns[col] = Utils.createNamedValue(
|
||||
dictionaryService,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "path"),
|
||||
nodeService.getPath(childNodeRef).toString());
|
||||
|
||||
ResultSetRow row = new ResultSetRow();
|
||||
row.setRowIndex(index);
|
||||
row.setNode(rowNode);
|
||||
row.setColumns(columns);
|
||||
|
||||
// add the row to the overall results
|
||||
rows.add(row);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
// add the rows to the result set and set the total row count
|
||||
results.setRows(rows.toArray(new ResultSetRow[0]));
|
||||
results.setTotalRowCount(rows.size());
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.webservice.AbstractQuery;
|
||||
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.ResultSet;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRow;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRowNode;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
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;
|
||||
|
||||
/**
|
||||
* A query to retrieve all child associations on a node.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 2.1
|
||||
*/
|
||||
public class ChildAssociationQuery extends AbstractQuery<ResultSet>
|
||||
{
|
||||
private static final long serialVersionUID = -4965097420552826582L;
|
||||
|
||||
private Reference node;
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* The node to query against
|
||||
*/
|
||||
public ChildAssociationQuery(Reference node)
|
||||
{
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
sb.append("ChildAssociationQuery")
|
||||
.append("[ node=").append(node.getUuid())
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public ResultSet execute(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
SearchService searchService = serviceRegistry.getSearchService();
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
DictionaryService dictionaryService = serviceRegistry.getDictionaryService();
|
||||
NamespaceService namespaceService = serviceRegistry.getNamespaceService();
|
||||
|
||||
// create the node ref and get the children from the repository
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(node, nodeService, searchService, namespaceService);
|
||||
List<ChildAssociationRef> assocRefs = nodeService.getChildAssocs(nodeRef);
|
||||
|
||||
int totalRows = assocRefs.size();
|
||||
|
||||
ResultSet results = new ResultSet();
|
||||
ResultSetRow[] rows = new ResultSetRow[totalRows];
|
||||
|
||||
int index = 0;
|
||||
for (ChildAssociationRef assocRef : assocRefs)
|
||||
{
|
||||
NodeRef childNodeRef = assocRef.getChildRef();
|
||||
ResultSetRowNode rowNode = createResultSetRowNode(childNodeRef, nodeService);
|
||||
|
||||
// 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()+5];
|
||||
int col = 0;
|
||||
for (QName propName : props.keySet())
|
||||
{
|
||||
columns[col] = Utils.createNamedValue(dictionaryService, propName, props.get(propName));
|
||||
col++;
|
||||
}
|
||||
|
||||
// Now add the system columns containing the association details
|
||||
columns[col] = new NamedValue(SYS_COL_ASSOC_TYPE, Boolean.FALSE, assocRef.getTypeQName().toString(), null);
|
||||
col++;
|
||||
columns[col] = new NamedValue(SYS_COL_ASSOC_NAME, Boolean.FALSE, assocRef.getQName().toString(), null);
|
||||
col++;
|
||||
columns[col] = new NamedValue(SYS_COL_IS_PRIMARY, Boolean.FALSE, Boolean.toString(assocRef.isPrimary()), null);
|
||||
col++;
|
||||
columns[col] = new NamedValue(SYS_COL_NTH_SIBLING, Boolean.FALSE, Integer.toString(assocRef.getNthSibling()), null);
|
||||
|
||||
// Add one more column for the node's path
|
||||
col++;
|
||||
columns[col] = Utils.createNamedValue(
|
||||
dictionaryService,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "path"),
|
||||
nodeService.getPath(childNodeRef).toString());
|
||||
|
||||
ResultSetRow row = new ResultSetRow();
|
||||
row.setRowIndex(index);
|
||||
row.setNode(rowNode);
|
||||
row.setColumns(columns);
|
||||
|
||||
// add the row to the overall results
|
||||
rows[index] = row;
|
||||
index++;
|
||||
}
|
||||
|
||||
// add the rows to the result set and set the total row count
|
||||
results.setRows(rows);
|
||||
results.setTotalRowCount(totalRows);
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.webservice.AbstractQuery;
|
||||
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.ResultSet;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRow;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRowNode;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
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;
|
||||
|
||||
/**
|
||||
* A query to retrieve all parent associations on a node.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 2.1
|
||||
*/
|
||||
public class ParentAssociationQuery extends AbstractQuery<ResultSet>
|
||||
{
|
||||
private static final long serialVersionUID = -4157476722256947274L;
|
||||
|
||||
private Reference node;
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* The node to query against
|
||||
*/
|
||||
public ParentAssociationQuery(Reference node)
|
||||
{
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
sb.append("ParentAssociationQuery")
|
||||
.append("[ node=").append(node.getUuid())
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public ResultSet execute(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
SearchService searchService = serviceRegistry.getSearchService();
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
DictionaryService dictionaryService = serviceRegistry.getDictionaryService();
|
||||
NamespaceService namespaceService = serviceRegistry.getNamespaceService();
|
||||
|
||||
// create the node ref and get the parent from the repository
|
||||
NodeRef nodeRef = Utils.convertToNodeRef(node, nodeService, searchService, namespaceService);
|
||||
List<ChildAssociationRef> assocRefs = nodeService.getParentAssocs(nodeRef);
|
||||
|
||||
int totalRows = assocRefs.size();
|
||||
|
||||
ResultSet results = new ResultSet();
|
||||
ResultSetRow[] rows = new ResultSetRow[totalRows];
|
||||
|
||||
int index = 0;
|
||||
for (ChildAssociationRef assocRef : assocRefs)
|
||||
{
|
||||
NodeRef parentNodeRef = assocRef.getParentRef();
|
||||
ResultSetRowNode rowNode = createResultSetRowNode(parentNodeRef, nodeService);
|
||||
|
||||
// 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()+5];
|
||||
int col = 0;
|
||||
for (QName propName : props.keySet())
|
||||
{
|
||||
columns[col] = Utils.createNamedValue(dictionaryService, propName, props.get(propName));
|
||||
col++;
|
||||
}
|
||||
|
||||
// Now add the system columns containing the association details
|
||||
columns[col] = new NamedValue(SYS_COL_ASSOC_TYPE, Boolean.FALSE, assocRef.getTypeQName().toString(), null);
|
||||
col++;
|
||||
columns[col] = new NamedValue(SYS_COL_ASSOC_NAME, Boolean.FALSE, assocRef.getQName().toString(), null);
|
||||
col++;
|
||||
columns[col] = new NamedValue(SYS_COL_IS_PRIMARY, Boolean.FALSE, Boolean.toString(assocRef.isPrimary()), null);
|
||||
col++;
|
||||
columns[col] = new NamedValue(SYS_COL_NTH_SIBLING, Boolean.FALSE, Integer.toString(assocRef.getNthSibling()), null);
|
||||
|
||||
// Add one more column for the node's path
|
||||
col++;
|
||||
columns[col] = Utils.createNamedValue(
|
||||
dictionaryService,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "path"),
|
||||
nodeService.getPath(parentNodeRef).toString());
|
||||
|
||||
ResultSetRow row = new ResultSetRow();
|
||||
row.setRowIndex(index);
|
||||
row.setNode(rowNode);
|
||||
row.setColumns(columns);
|
||||
|
||||
// add the row to the overall results
|
||||
rows[index] = row;
|
||||
index++;
|
||||
}
|
||||
|
||||
// add the rows to the result set and set the total row count
|
||||
results.setRows(rows);
|
||||
results.setTotalRowCount(totalRows);
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.repository;
|
||||
|
||||
import org.alfresco.repo.webservice.AbstractQuerySession;
|
||||
import org.alfresco.repo.webservice.ServerQuery;
|
||||
import org.alfresco.repo.webservice.types.ResultSet;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRow;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* A query session for use with {@linkplain RepositoryWebService node-related queries} against the
|
||||
* repository.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 2.1
|
||||
*/
|
||||
public class RepositoryQuerySession extends AbstractQuerySession<ResultSet, ResultSetRow>
|
||||
{
|
||||
private static final long serialVersionUID = -3621997639261137000L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(RepositoryQuerySession.class);
|
||||
|
||||
public RepositoryQuerySession(long maxResults, long batchSize, ServerQuery<ResultSet> query)
|
||||
{
|
||||
super(maxResults, batchSize, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResultSetRow[] makeArray(int size)
|
||||
{
|
||||
return new ResultSetRow[size];
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.webservice.QuerySession#getNextResults(org.alfresco.service.ServiceRegistry)
|
||||
*/
|
||||
public ResultSet getNextResults(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
ResultSet queryResults = getQueryResults(serviceRegistry);
|
||||
ResultSetRow[] allRows = queryResults.getRows();
|
||||
ResultSetRow[] batchedRows = getNextResults(allRows);
|
||||
// Build the resultset for the batched results
|
||||
ResultSet batchedResults = new ResultSet();
|
||||
batchedResults.setMetaData(queryResults.getMetaData());
|
||||
batchedResults.setRows(batchedRows);
|
||||
batchedResults.setTotalRowCount(allRows.length);
|
||||
logger.debug("total row count :"+allRows.length);
|
||||
// Done
|
||||
return batchedResults;
|
||||
}
|
||||
}
|
@@ -1,479 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.repo.webservice.AbstractWebService;
|
||||
import org.alfresco.repo.webservice.CMLUtil;
|
||||
import org.alfresco.repo.webservice.ServerQuery;
|
||||
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.Reference;
|
||||
import org.alfresco.repo.webservice.types.ResultSet;
|
||||
import org.alfresco.repo.webservice.types.Store;
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
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.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 CMLUtil cmlUtil;
|
||||
|
||||
/**
|
||||
* Sets the CML Util
|
||||
*
|
||||
* @param cmlUtil CML util object
|
||||
*/
|
||||
public void setCmlUtil(CMLUtil cmlUtil)
|
||||
{
|
||||
this.cmlUtil = cmlUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Store createStore(String scheme, String address) throws RemoteException, RepositoryFault
|
||||
{
|
||||
StoreRef storeRef = this.nodeService.createStore(scheme, address);
|
||||
return Utils.convertToStore(storeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Store[] getStores() throws RemoteException, RepositoryFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<Store[]> callback = new RetryingTransactionCallback<Store[]>()
|
||||
{
|
||||
public Store[] execute() throws Throwable
|
||||
{
|
||||
List<StoreRef> stores = 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());
|
||||
}
|
||||
|
||||
Store store = Utils.convertToStore(storeRef);
|
||||
returnStores[x] = store;
|
||||
}
|
||||
|
||||
return returnStores;
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new RepositoryFault(0, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given query, caching the results as required.
|
||||
*/
|
||||
private QueryResult executeQuery(final MessageContext msgContext, final ServerQuery<ResultSet> query) throws RepositoryFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<QueryResult> callback = new RetryingTransactionCallback<QueryResult>()
|
||||
{
|
||||
public QueryResult execute() throws Throwable
|
||||
{
|
||||
// Construct a session to handle the iteration
|
||||
long batchSize = Utils.getBatchSize(msgContext);
|
||||
RepositoryQuerySession session = new RepositoryQuerySession(Long.MAX_VALUE, batchSize, query);
|
||||
String sessionId = session.getId();
|
||||
|
||||
// Get the first batch of results
|
||||
ResultSet batchedResults = session.getNextResults(serviceRegistry);
|
||||
// Construct the result
|
||||
// TODO: http://issues.alfresco.com/browse/AR-1689
|
||||
boolean haveMoreResults = session.haveMoreResults();
|
||||
QueryResult queryResult = new QueryResult(
|
||||
haveMoreResults ? sessionId : null,
|
||||
batchedResults);
|
||||
|
||||
// Cache the session
|
||||
if (session.haveMoreResults())
|
||||
{
|
||||
querySessionCache.put(sessionId, session);
|
||||
}
|
||||
|
||||
// Done
|
||||
return queryResult;
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback, true);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
e.printStackTrace();
|
||||
throw new RepositoryFault(0, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public QueryResult query(final Store store, final Query query, final boolean includeMetaData) throws RemoteException, RepositoryFault
|
||||
{
|
||||
String language = query.getLanguage();
|
||||
if (language.equals(Utils.QUERY_LANG_LUCENE) == false)
|
||||
{
|
||||
throw new RepositoryFault(110, "Only '"
|
||||
+ Utils.QUERY_LANG_LUCENE
|
||||
+ "' queries are currently supported!");
|
||||
}
|
||||
|
||||
final MessageContext msgContext = MessageContext.getCurrentContext();
|
||||
SearchQuery serverQuery = new SearchQuery(store, query);
|
||||
QueryResult queryResult = executeQuery(msgContext, serverQuery);
|
||||
// Done
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public QueryResult queryChildren(final Reference node) throws RemoteException, RepositoryFault
|
||||
{
|
||||
final MessageContext msgContext = MessageContext.getCurrentContext();
|
||||
ChildAssociationQuery query = new ChildAssociationQuery(node);
|
||||
QueryResult queryResult = executeQuery(msgContext, query);
|
||||
// Done
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public QueryResult queryParents(final Reference node) throws RemoteException, RepositoryFault
|
||||
{
|
||||
final MessageContext msgContext = MessageContext.getCurrentContext();
|
||||
ParentAssociationQuery query = new ParentAssociationQuery(node);
|
||||
QueryResult queryResult = executeQuery(msgContext, query);
|
||||
// Done
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public QueryResult queryAssociated(final Reference node, final Association association) throws RemoteException, RepositoryFault
|
||||
{
|
||||
final MessageContext msgContext = MessageContext.getCurrentContext();
|
||||
AssociationQuery query = new AssociationQuery(node, association);
|
||||
QueryResult queryResult = executeQuery(msgContext, query);
|
||||
// Done
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public QueryResult fetchMore(final String querySessionId) throws RemoteException, RepositoryFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<QueryResult> callback = new RetryingTransactionCallback<QueryResult>()
|
||||
{
|
||||
public QueryResult execute() throws Throwable
|
||||
{
|
||||
RepositoryQuerySession session = null;
|
||||
try
|
||||
{
|
||||
// try and get the QuerySession with the given id from the cache
|
||||
session = (RepositoryQuerySession) querySessionCache.get(querySessionId);
|
||||
}
|
||||
catch (ClassCastException e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Query session was not generated by the RepositoryWebService: " + querySessionId);
|
||||
}
|
||||
throw new RepositoryFault(
|
||||
4,
|
||||
"querySession with id '" + querySessionId + "' is invalid");
|
||||
}
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Invalid querySession id requested: " + querySessionId);
|
||||
}
|
||||
throw new RepositoryFault(
|
||||
4,
|
||||
"querySession with id '" + querySessionId + "' is invalid");
|
||||
}
|
||||
|
||||
ResultSet moreResults = session.getNextResults(serviceRegistry);
|
||||
|
||||
// Drop the cache results if there are no more results expected
|
||||
if (!session.haveMoreResults())
|
||||
{
|
||||
querySessionCache.remove(querySessionId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We still need to update the cache with the latest session to
|
||||
// ensure that the instance gets replicated to other listening caches
|
||||
querySessionCache.put(querySessionId, session);
|
||||
}
|
||||
|
||||
// get the next batch of results
|
||||
// TODO: http://issues.alfresco.com/browse/AR-1689
|
||||
boolean haveMoreResults = session.haveMoreResults();
|
||||
QueryResult queryResult = new QueryResult(
|
||||
haveMoreResults ? querySessionId : null,
|
||||
moreResults);
|
||||
|
||||
// Done
|
||||
return queryResult;
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback, true);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (e instanceof RepositoryFault)
|
||||
{
|
||||
throw (RepositoryFault) e;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new RepositoryFault(0, e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public UpdateResult[] update(final CML statements) throws RemoteException, RepositoryFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<UpdateResult[]> callback = new RetryingTransactionCallback<UpdateResult[]>()
|
||||
{
|
||||
public UpdateResult[] execute() throws Throwable
|
||||
{
|
||||
return cmlUtil.executeCML(statements);
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new RepositoryFault(0, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public NodeDefinition[] describe(final Predicate items) throws RemoteException, RepositoryFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<NodeDefinition[]> callback = new RetryingTransactionCallback<NodeDefinition[]>()
|
||||
{
|
||||
public NodeDefinition[] execute() throws Throwable
|
||||
{
|
||||
List<NodeRef> nodes = Utils.resolvePredicate(items, nodeService, searchService, namespaceService);
|
||||
NodeDefinition[] nodeDefs = new NodeDefinition[nodes.size()];
|
||||
|
||||
for (int x = 0; x < nodes.size(); x++)
|
||||
{
|
||||
nodeDefs[x] = setupNodeDefObject(nodes.get(x));
|
||||
}
|
||||
|
||||
return nodeDefs;
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new RepositoryFault(0, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(this.dictionaryService, ddTypeDef);
|
||||
|
||||
Set<QName> aspectsQNames = this.nodeService.getAspects(nodeRef);
|
||||
ClassDefinition[] aspectDefs = new ClassDefinition[aspectsQNames.size()];
|
||||
int pos = 0;
|
||||
for (QName aspectQName : aspectsQNames)
|
||||
{
|
||||
AspectDefinition aspectDef = this.dictionaryService.getAspect(aspectQName);
|
||||
aspectDefs[pos] = Utils.setupClassDefObject(this.dictionaryService, aspectDef);
|
||||
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.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Node[] get(final Predicate where) throws RemoteException, RepositoryFault
|
||||
{
|
||||
try
|
||||
{
|
||||
RetryingTransactionCallback<Node[]> callback = new RetryingTransactionCallback<Node[]>()
|
||||
{
|
||||
public Node[] execute() throws Throwable
|
||||
{
|
||||
// Resolve the predicate to a list of node references
|
||||
List<NodeRef> nodeRefs = Utils.resolvePredicate(where, nodeService, searchService, namespaceService);
|
||||
List<Node> nodeList = new ArrayList<Node>();
|
||||
for (NodeRef nodeRef : nodeRefs)
|
||||
{
|
||||
// search can return nodes that no longer exist, so we need to ignore these
|
||||
if(nodeService.exists(nodeRef) == false)
|
||||
{
|
||||
if(logger.isDebugEnabled())
|
||||
{
|
||||
logger.warn("Search returned node that doesn't exist: " + nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the nodes reference
|
||||
Reference reference = Utils.convertToReference(nodeService, namespaceService, nodeRef);
|
||||
|
||||
// Get the nodes type
|
||||
String type = nodeService.getType(nodeRef).toString();
|
||||
|
||||
// Get the nodes aspects
|
||||
Set<QName> aspectQNames = 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 = nodeService.getProperties(nodeRef);
|
||||
NamedValue[] properties = new NamedValue[propertyMap.size()];
|
||||
int propertyIndex = 0;
|
||||
for (Map.Entry<QName, Serializable> entry : propertyMap.entrySet())
|
||||
{
|
||||
properties[propertyIndex] = Utils.createNamedValue(dictionaryService, entry.getKey(), entry.getValue());
|
||||
propertyIndex++;
|
||||
}
|
||||
|
||||
// Create the node and add to the array
|
||||
Node node = new Node(reference, type, aspects, properties);
|
||||
nodeList.add(node);
|
||||
}
|
||||
|
||||
Node[] nodes = nodeList.toArray(new Node[nodeList.size()]);
|
||||
|
||||
return nodes;
|
||||
}
|
||||
};
|
||||
return Utils.getRetryingTransactionHelper(MessageContext.getCurrentContext()).doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error("Unexpected error occurred", e);
|
||||
}
|
||||
throw new RepositoryFault(0, e.toString());
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.webservice.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.webservice.AbstractQuery;
|
||||
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.ResultSet;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRow;
|
||||
import org.alfresco.repo.webservice.types.ResultSetRowNode;
|
||||
import org.alfresco.repo.webservice.types.Store;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.Path;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* A query to using full search.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 2.1
|
||||
*/
|
||||
public class SearchQuery extends AbstractQuery<ResultSet>
|
||||
{
|
||||
private static final long serialVersionUID = 5429510102265380433L;
|
||||
|
||||
private Store store;
|
||||
private Query query;
|
||||
|
||||
/**
|
||||
* @param node The node to query against
|
||||
* @param association The association type to query or <tt>null</tt> to query all
|
||||
*/
|
||||
public SearchQuery(Store store, Query query)
|
||||
{
|
||||
this.store = store;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
sb.append("SearchQuery")
|
||||
.append("[ store=").append(this.store.getScheme()).append(":").append(this.store.getAddress())
|
||||
.append(" language=").append(this.query.getLanguage())
|
||||
.append(" statement=").append(this.query.getStatement())
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public ResultSet execute(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
SearchService searchService = serviceRegistry.getSearchService();
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
DictionaryService dictionaryService = serviceRegistry.getDictionaryService();
|
||||
|
||||
// handle the special search string of * meaning, get everything
|
||||
String statement = query.getStatement();
|
||||
if (statement.equals("*"))
|
||||
{
|
||||
statement = "ISNODE:*";
|
||||
}
|
||||
org.alfresco.service.cmr.search.ResultSet searchResults = null;
|
||||
try
|
||||
{
|
||||
StoreRef storeRef = Utils.convertToStoreRef(store);
|
||||
searchResults = searchService.query(storeRef, query.getLanguage(), statement);
|
||||
return convert(
|
||||
nodeService,
|
||||
dictionaryService,
|
||||
searchResults);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (searchResults != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
searchResults.close();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ResultSet convert(
|
||||
NodeService nodeService,
|
||||
DictionaryService dictionaryService,
|
||||
org.alfresco.service.cmr.search.ResultSet searchResults)
|
||||
{
|
||||
ResultSet results = new ResultSet();
|
||||
List<ResultSetRow> rowsList = new ArrayList<org.alfresco.repo.webservice.types.ResultSetRow>();
|
||||
|
||||
int index = 0;
|
||||
for (org.alfresco.service.cmr.search.ResultSetRow searchRow : searchResults)
|
||||
{
|
||||
NodeRef nodeRef = searchRow.getNodeRef();
|
||||
// Search can return nodes that no longer exist, so we need to ignore these
|
||||
if (!nodeService.exists(nodeRef))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ResultSetRowNode rowNode = createResultSetRowNode(nodeRef, nodeService);
|
||||
|
||||
// get the data for the row and build up the columns structure
|
||||
Map<String, Serializable> values = searchRow.getValues();
|
||||
NamedValue[] columns = new NamedValue[values.size() + 1];
|
||||
int col = 1;
|
||||
for (String attributeName : values.keySet())
|
||||
{
|
||||
columns[col] = Utils.createNamedValue(dictionaryService, QName.createQName(attributeName), values.get(attributeName));
|
||||
col++;
|
||||
}
|
||||
|
||||
// add one extra column for the node's path
|
||||
columns[0] = Utils.createNamedValue(dictionaryService, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "path"), nodeService.getPath(nodeRef).toString());
|
||||
|
||||
ResultSetRow row = new org.alfresco.repo.webservice.types.ResultSetRow();
|
||||
row.setColumns(columns);
|
||||
row.setScore(searchRow.getScore());
|
||||
row.setRowIndex(index);
|
||||
row.setNode(rowNode);
|
||||
|
||||
// add the row to the overall results list
|
||||
rowsList.add(row);
|
||||
index++;
|
||||
}
|
||||
|
||||
// Convert list to array
|
||||
int totalRows = rowsList.size();
|
||||
ResultSetRow[] rows = rowsList.toArray(new org.alfresco.repo.webservice.types.ResultSetRow[totalRows]);
|
||||
|
||||
// add the rows to the result set and set the total row count
|
||||
results.setRows(rows);
|
||||
results.setTotalRowCount(totalRows);
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.ws;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.apache.cxf.binding.soap.SoapMessage;
|
||||
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
|
||||
import org.apache.cxf.interceptor.Fault;
|
||||
import org.apache.cxf.phase.Phase;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class AuthenticationClearInterceptor extends AbstractSoapInterceptor
|
||||
{
|
||||
public AuthenticationClearInterceptor()
|
||||
{
|
||||
super(Phase.PRE_INVOKE);
|
||||
}
|
||||
|
||||
public void handleMessage(SoapMessage message) throws Fault
|
||||
{
|
||||
AuthenticationUtil.clearCurrentSecurityContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFault(SoapMessage message)
|
||||
{
|
||||
AuthenticationUtil.clearCurrentSecurityContext();
|
||||
super.handleFault(message);
|
||||
}
|
||||
}
|
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.ws;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.security.authentication.Authorization;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.cxf.binding.soap.SoapMessage;
|
||||
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
|
||||
import org.apache.cxf.interceptor.Fault;
|
||||
import org.apache.cxf.phase.Phase;
|
||||
import org.apache.ws.security.WSSecurityEngineResult;
|
||||
import org.apache.ws.security.WSUsernameTokenPrincipal;
|
||||
import org.apache.ws.security.handler.WSHandlerConstants;
|
||||
import org.apache.ws.security.handler.WSHandlerResult;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class AuthenticationInterceptor extends AbstractSoapInterceptor
|
||||
{
|
||||
private AuthenticationService authenticationService;
|
||||
private TransactionService transactionService;
|
||||
|
||||
public AuthenticationInterceptor()
|
||||
{
|
||||
super(Phase.PRE_INVOKE);
|
||||
}
|
||||
|
||||
public void handleMessage(SoapMessage message) throws Fault
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
WSHandlerResult handlerResult = ((List<WSHandlerResult>) message.getContextualProperty(WSHandlerConstants.RECV_RESULTS)).get(0);
|
||||
WSSecurityEngineResult secRes = (WSSecurityEngineResult) handlerResult.getResults().get(0);
|
||||
final WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) secRes.get(WSSecurityEngineResult.TAG_PRINCIPAL);
|
||||
|
||||
// Authenticate
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute() throws Throwable
|
||||
{
|
||||
try
|
||||
{
|
||||
Authorization auth = new Authorization(principal.getName(), principal.getPassword());
|
||||
if (auth.isTicket())
|
||||
{
|
||||
authenticationService.validate(auth.getTicket());
|
||||
}
|
||||
else
|
||||
{
|
||||
authenticationService.authenticate(auth.getUserName(), auth.getPassword().toCharArray());
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new SecurityException("Invalid user name or password specified");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setAuthenticationService(AuthenticationService authenticationService)
|
||||
{
|
||||
this.authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.ws;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
|
||||
import org.apache.ws.security.WSConstants;
|
||||
import org.apache.ws.security.WSPasswordCallback;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class AuthenticationTokenCallbackHandler implements CallbackHandler
|
||||
{
|
||||
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
|
||||
{
|
||||
WSPasswordCallback wssPasswordCallback = (WSPasswordCallback) callbacks[0];
|
||||
|
||||
if ((WSPasswordCallback.USERNAME_TOKEN_UNKNOWN != wssPasswordCallback.getUsage()) && (WSPasswordCallback.USERNAME_TOKEN != wssPasswordCallback.getUsage()))
|
||||
{
|
||||
throw new SecurityException("Only 'UsernameToken' usage is supported.");
|
||||
}
|
||||
|
||||
if (!WSConstants.PASSWORD_TEXT.equals(wssPasswordCallback.getPasswordType()))
|
||||
{
|
||||
throw new SecurityException("Password type '" + wssPasswordCallback.getPasswordType() + "' unsupported. Only '" + WSConstants.PW_TEXT + "' is supported.");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,190 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.ws;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import javax.activation.DataSource;
|
||||
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
|
||||
/**
|
||||
* DataSource facade for an Alfresco Content Reader
|
||||
*
|
||||
* @author Dmitry Lazurkin
|
||||
*/
|
||||
public class ContentReaderDataSource implements DataSource
|
||||
{
|
||||
private String mimetype;
|
||||
private InputStream inputStream;
|
||||
private String name;
|
||||
private long offset = 0;
|
||||
private long length = Long.MAX_VALUE / 2;
|
||||
private long sizeToRead = 0;
|
||||
|
||||
public ContentReaderDataSource(ContentReader contentReader, String name, BigInteger offset, BigInteger length, long contentSize)
|
||||
{
|
||||
createContentReaderDataSource(contentReader.getContentInputStream(), contentReader.getMimetype(), name, offset, length, contentSize);
|
||||
}
|
||||
|
||||
public ContentReaderDataSource(InputStream contentInputStream, String mimeType, String name, BigInteger offset, BigInteger length)
|
||||
{
|
||||
try
|
||||
{
|
||||
createContentReaderDataSource(contentInputStream, mimeType, name, offset, length, contentInputStream.available());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void createContentReaderDataSource(InputStream contentInputStream, String mimeType, String name, BigInteger offset, BigInteger length, long contentSize)
|
||||
{
|
||||
this.name = name;
|
||||
this.mimetype = mimeType;
|
||||
if (offset != null)
|
||||
{
|
||||
this.offset = offset.longValue();
|
||||
}
|
||||
if (length != null)
|
||||
{
|
||||
this.length = length.longValue();
|
||||
}
|
||||
if (this.offset + this.length < contentSize)
|
||||
{
|
||||
this.sizeToRead = this.length;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.sizeToRead = contentSize - this.offset;
|
||||
}
|
||||
if (this.sizeToRead < 0)
|
||||
{
|
||||
throw new RuntimeException("Offset value exceeds content size");
|
||||
}
|
||||
try
|
||||
{
|
||||
inputStream = new RangedInputStream(contentInputStream);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getContentType()
|
||||
{
|
||||
return mimetype;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException
|
||||
{
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() throws IOException
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getSizeToRead()
|
||||
{
|
||||
return sizeToRead;
|
||||
}
|
||||
|
||||
private class RangedInputStream extends InputStream
|
||||
{
|
||||
|
||||
private InputStream inputStream;
|
||||
private int bytesread;
|
||||
|
||||
private RangedInputStream(InputStream inputStream) throws IOException
|
||||
{
|
||||
super();
|
||||
this.inputStream = inputStream;
|
||||
this.inputStream.skip(offset);
|
||||
this.bytesread = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException
|
||||
{
|
||||
if (bytesread < sizeToRead)
|
||||
{
|
||||
bytesread++;
|
||||
return inputStream.read();
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException
|
||||
{
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException
|
||||
{
|
||||
if (len > sizeToRead - bytesread)
|
||||
{
|
||||
len = (int) (sizeToRead - bytesread);
|
||||
}
|
||||
int readed = inputStream.read(b, off, len);
|
||||
bytesread += readed;
|
||||
return readed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException
|
||||
{
|
||||
return (int) (sizeToRead - bytesread + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
inputStream.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws IOException
|
||||
{
|
||||
if (bytesread + n > sizeToRead)
|
||||
{
|
||||
n = (sizeToRead - n) > 0 ? (sizeToRead - n) : sizeToRead - bytesread;
|
||||
}
|
||||
n = inputStream.skip(n);
|
||||
bytesread += n;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,62 +0,0 @@
|
||||
package org.alfresco.repo.ws;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
|
||||
import org.apache.cxf.binding.soap.SoapMessage;
|
||||
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
|
||||
import org.apache.cxf.interceptor.Fault;
|
||||
import org.apache.cxf.phase.Phase;
|
||||
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
|
||||
import org.apache.ws.security.WSConstants;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
|
||||
/**
|
||||
* Interceptor that by default adds PasswordText type to Password element
|
||||
* if it doesn't have Type attribute. It should be done before WSSecurityEngine
|
||||
* processes Security header in scope of WSS4JInInterceptor execution.
|
||||
*
|
||||
* @author Viachaslau Tsikhanovich
|
||||
*
|
||||
*/
|
||||
public class PasswordTypeInterceptor extends AbstractSoapInterceptor
|
||||
{
|
||||
|
||||
private QName securityHeader = new QName(WSConstants.WSSE_NS, WSConstants.WSSE_LN);
|
||||
|
||||
public PasswordTypeInterceptor()
|
||||
{
|
||||
super(Phase.PRE_PROTOCOL);
|
||||
addBefore(Arrays.asList(WSS4JInInterceptor.class.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(SoapMessage message) throws Fault
|
||||
{
|
||||
if (message.hasHeader(securityHeader))
|
||||
{
|
||||
SOAPMessage saaj = message.getContent(SOAPMessage.class);
|
||||
Document document = saaj.getSOAPPart();
|
||||
NodeList nodes = document.getElementsByTagNameNS("*", WSConstants.PASSWORD_LN);
|
||||
if (nodes.getLength() > 0)
|
||||
{
|
||||
Node passwordNode = nodes.item(0);
|
||||
NamedNodeMap atts = passwordNode.getAttributes();
|
||||
if (null == atts.getNamedItem(WSConstants.PASSWORD_TYPE_ATTR))
|
||||
{
|
||||
Attr typeAttribute = document.createAttribute(WSConstants.PASSWORD_TYPE_ATTR);
|
||||
typeAttribute.setValue(WSConstants.PASSWORD_TEXT);
|
||||
atts.setNamedItem(typeAttribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user