Moving to root below branch label

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2005 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2005-12-08 07:13:07 +00:00
commit 3e7141dc1a
225 changed files with 48004 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.webservice.repository;
import org.alfresco.util.GUID;
/**
* Abstract implementation of a QuerySession providing support
* for automatic id generation and provides support for
* paging through query results.
*
* @author gavinc
*/
public abstract class AbstractQuerySession implements QuerySession
{
protected int batchSize;
protected int position = 0;
private String id;
/**
* Common constructor that initialises the session's id and batch size
*
* @param batchSize The batch size this session will use
*/
public AbstractQuerySession(int batchSize)
{
this.id = GUID.generate();
this.batchSize = batchSize;
}
/**
* @see org.alfresco.repo.webservice.repository.QuerySession#getId()
*/
public String getId()
{
return this.id;
}
/**
* Calculates the index of the last row to retrieve.
*
* @param totalRowCount The total number of rows in the results
* @return The index of the last row to return
*/
protected int calculateLastRowIndex(int totalRowCount)
{
int lastRowIndex = totalRowCount;
// set the last row index if there are more results available
// than the batch size
if ((this.batchSize != -1) && ((this.position + this.batchSize) < totalRowCount))
{
lastRowIndex = this.position + this.batchSize;
}
return lastRowIndex;
}
/**
* Calculates the value of the next position.
* If the end of the result set is reached the position is set to -1
*
* @param totalRowCount The total number of rows in the results
* @param queryResult The QueryResult object being returned to the client,
* if there are no more results the id is removed from the QueryResult instance
*/
protected void updatePosition(int totalRowCount, QueryResult queryResult)
{
this.position += this.batchSize;
if (this.position >= totalRowCount)
{
// signify that there are no more results
this.position = -1;
queryResult.setQuerySession(null);
}
}
}

View File

@@ -0,0 +1,166 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.webservice.repository;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.webservice.Utils;
import org.alfresco.repo.webservice.types.NamedValue;
import org.alfresco.repo.webservice.types.Reference;
import org.alfresco.repo.webservice.types.ResultSetRow;
import org.alfresco.repo.webservice.types.ResultSetRowNode;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Implementation of a QuerySession that stores the results from a query for
* associations
*
* @author Roy Wetherall
*/
public class AssociatedQuerySession extends AbstractQuerySession
{
private static final long serialVersionUID = 6488008047324436124L;
private transient static Log logger = LogFactory
.getLog(AssociatedQuerySession.class);
private Reference node;
/**
* Constructs a AssociatedQuerySession
*
* @param batchSize
* The batch size to use for this session
* @param node
* The node to retrieve the associations
*/
public AssociatedQuerySession(int batchSize, Reference node)
{
super(batchSize);
this.node = node;
}
/**
* @see org.alfresco.repo.webservice.repository.QuerySession#getNextResultsBatch(org.alfresco.service.cmr.search.SearchService,
* org.alfresco.service.cmr.repository.NodeService,
* org.alfresco.service.namespace.NamespaceService)
*/
public QueryResult getNextResultsBatch(SearchService searchService,
NodeService nodeService, NamespaceService namespaceService)
{
QueryResult queryResult = null;
if (this.position != -1)
{
if (logger.isDebugEnabled())
logger.debug("Before getNextResultsBatch: " + toString());
// create the node ref and get the children from the repository
NodeRef nodeRef = Utils.convertToNodeRef(this.node, nodeService,
searchService, namespaceService);
List<AssociationRef> assocs = nodeService.getTargetAssocs(nodeRef,
RegexQNamePattern.MATCH_ALL);
int totalRows = assocs.size();
int lastRow = calculateLastRowIndex(totalRows);
int currentBatchSize = lastRow - this.position;
if (logger.isDebugEnabled())
logger.debug("Total rows = " + totalRows
+ ", current batch size = " + currentBatchSize);
org.alfresco.repo.webservice.types.ResultSet batchResults = new org.alfresco.repo.webservice.types.ResultSet();
org.alfresco.repo.webservice.types.ResultSetRow[] rows = new org.alfresco.repo.webservice.types.ResultSetRow[currentBatchSize];
int arrPos = 0;
for (int x = this.position; x < lastRow; x++)
{
AssociationRef assoc = assocs.get(x);
NodeRef childNodeRef = assoc.getTargetRef();
ResultSetRowNode rowNode = new ResultSetRowNode(childNodeRef
.getId(), nodeService.getType(childNodeRef).toString(),
null);
// create columns for all the properties of the node
// get the data for the row and build up the columns structure
Map<QName, Serializable> props = nodeService
.getProperties(childNodeRef);
NamedValue[] columns = new NamedValue[props.size()];
int col = 0;
for (QName propName : props.keySet())
{
String value = null;
Serializable valueObj = props.get(propName);
if (valueObj != null)
{
value = valueObj.toString();
}
columns[col] = new NamedValue(propName.toString(), value);
col++;
}
ResultSetRow row = new ResultSetRow();
row.setRowIndex(x);
row.setNode(rowNode);
row.setColumns(columns);
// add the row to the overall results
rows[arrPos] = row;
arrPos++;
}
// add the rows to the result set and set the total row count
batchResults.setRows(rows);
batchResults.setTotalRowCount(totalRows);
queryResult = new QueryResult(getId(), batchResults);
// move the position on
updatePosition(totalRows, queryResult);
if (logger.isDebugEnabled())
logger.debug("After getNextResultsBatch: " + toString());
}
return queryResult;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
StringBuilder builder = new StringBuilder(super.toString());
builder.append(" (id=").append(getId());
builder.append(" batchSize=").append(this.batchSize);
builder.append(" position=").append(this.position);
builder.append(" node-id=").append(this.node.getUuid()).append(")");
return builder.toString();
}
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.webservice.repository;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.webservice.Utils;
import org.alfresco.repo.webservice.types.NamedValue;
import org.alfresco.repo.webservice.types.Reference;
import org.alfresco.repo.webservice.types.ResultSetRow;
import org.alfresco.repo.webservice.types.ResultSetRowNode;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Implementation of a QuerySession that stores the results from a query for children
*
* @author gavinc
*/
public class ChildrenQuerySession extends AbstractQuerySession
{
private static final long serialVersionUID = -5347036309571057074L;
private transient static Log logger = LogFactory.getLog(ChildrenQuerySession.class);
private Reference node;
/**
* Constructs a ChildrenQuerySession
*
* @param batchSize The batch size to use for this session
* @param node The node to retrieve the parents
*/
public ChildrenQuerySession(int batchSize, Reference node)
{
super(batchSize);
this.node = node;
}
/**
* @see org.alfresco.repo.webservice.repository.QuerySession#getNextResultsBatch(org.alfresco.service.cmr.search.SearchService, org.alfresco.service.cmr.repository.NodeService, org.alfresco.service.namespace.NamespaceService)
*/
public QueryResult getNextResultsBatch(SearchService searchService, NodeService nodeService, NamespaceService namespaceService)
{
QueryResult queryResult = null;
if (this.position != -1)
{
if (logger.isDebugEnabled())
logger.debug("Before getNextResultsBatch: " + toString());
// create the node ref and get the children from the repository
NodeRef nodeRef = Utils.convertToNodeRef(this.node, nodeService, searchService, namespaceService);
List<ChildAssociationRef> kids = nodeService.getChildAssocs(nodeRef);
int totalRows = kids.size();
int lastRow = calculateLastRowIndex(totalRows);
int currentBatchSize = lastRow - this.position;
if (logger.isDebugEnabled())
logger.debug("Total rows = " + totalRows + ", current batch size = " + currentBatchSize);
org.alfresco.repo.webservice.types.ResultSet batchResults = new org.alfresco.repo.webservice.types.ResultSet();
org.alfresco.repo.webservice.types.ResultSetRow[] rows = new org.alfresco.repo.webservice.types.ResultSetRow[currentBatchSize];
int arrPos = 0;
for (int x = this.position; x < lastRow; x++)
{
ChildAssociationRef assoc = kids.get(x);
NodeRef childNodeRef = assoc.getChildRef();
ResultSetRowNode rowNode = new ResultSetRowNode(childNodeRef.getId(), nodeService.getType(childNodeRef).toString(), null);
// create columns for all the properties of the node
// get the data for the row and build up the columns structure
Map<QName, Serializable> props = nodeService.getProperties(childNodeRef);
NamedValue[] columns = new NamedValue[props.size()];
int col = 0;
for (QName propName : props.keySet())
{
String value = null;
Serializable valueObj = props.get(propName);
if (valueObj != null)
{
value = valueObj.toString();
}
columns[col] = new NamedValue(propName.toString(), value);
col++;
}
ResultSetRow row = new ResultSetRow();
row.setRowIndex(x);
row.setNode(rowNode);
row.setColumns(columns);
// add the row to the overall results
rows[arrPos] = row;
arrPos++;
}
// add the rows to the result set and set the total row count
batchResults.setRows(rows);
batchResults.setTotalRowCount(totalRows);
queryResult = new QueryResult(getId(), batchResults);
// move the position on
updatePosition(totalRows, queryResult);
if (logger.isDebugEnabled())
logger.debug("After getNextResultsBatch: " + toString());
}
return queryResult;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
StringBuilder builder = new StringBuilder(super.toString());
builder.append(" (id=").append(getId());
builder.append(" batchSize=").append(this.batchSize);
builder.append(" position=").append(this.position);
builder.append(" node-id=").append(this.node.getUuid()).append(")");
return builder.toString();
}
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.webservice.repository;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.webservice.Utils;
import org.alfresco.repo.webservice.types.NamedValue;
import org.alfresco.repo.webservice.types.Reference;
import org.alfresco.repo.webservice.types.ResultSetRow;
import org.alfresco.repo.webservice.types.ResultSetRowNode;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Implementation of a QuerySession that stores the results from a query for parents
*
* @author gavinc
*/
public class ParentsQuerySession extends AbstractQuerySession
{
private static final long serialVersionUID = 2539375863409175463L;
private transient static Log logger = LogFactory.getLog(ParentsQuerySession.class);
private Reference node;
/**
* Constructs a ParentsQuerySession
*
* @param batchSize The batch size to use for this session
* @param node The node to retrieve the parents
*/
public ParentsQuerySession(int batchSize, Reference node)
{
super(batchSize);
this.node = node;
}
/**
* @see org.alfresco.repo.webservice.repository.QuerySession#getNextResultsBatch(org.alfresco.service.cmr.search.SearchService, org.alfresco.service.cmr.repository.NodeService, org.alfresco.service.namespace.NamespaceService)
*/
public QueryResult getNextResultsBatch(SearchService searchService, NodeService nodeService, NamespaceService namespaceService)
{
QueryResult queryResult = null;
if (this.position != -1)
{
if (logger.isDebugEnabled())
logger.debug("Before getNextResultsBatch: " + toString());
// create the node ref and get the children from the repository
NodeRef nodeRef = Utils.convertToNodeRef(this.node, nodeService, searchService, namespaceService);
List<ChildAssociationRef> parents = nodeService.getParentAssocs(nodeRef);
int totalRows = parents.size();
int lastRow = calculateLastRowIndex(totalRows);
int currentBatchSize = lastRow - this.position;
if (logger.isDebugEnabled())
logger.debug("Total rows = " + totalRows + ", current batch size = " + currentBatchSize);
org.alfresco.repo.webservice.types.ResultSet batchResults = new org.alfresco.repo.webservice.types.ResultSet();
org.alfresco.repo.webservice.types.ResultSetRow[] rows = new org.alfresco.repo.webservice.types.ResultSetRow[currentBatchSize];
int arrPos = 0;
for (int x = this.position; x < lastRow; x++)
{
ChildAssociationRef assoc = parents.get(x);
NodeRef parentNodeRef = assoc.getParentRef();
ResultSetRowNode rowNode = new ResultSetRowNode(parentNodeRef.getId(), nodeService.getType(parentNodeRef).toString(), null);
// create columns for all the properties of the node
// get the data for the row and build up the columns structure
Map<QName, Serializable> props = nodeService.getProperties(parentNodeRef);
NamedValue[] columns = new NamedValue[props.size()];
int col = 0;
for (QName propName : props.keySet())
{
String value = null;
Serializable valueObj = props.get(propName);
if (valueObj != null)
{
value = valueObj.toString();
}
columns[col] = new NamedValue(propName.toString(), value);
col++;
}
ResultSetRow row = new ResultSetRow();
row.setRowIndex(x);
row.setNode(rowNode);
row.setColumns(columns);
// add the row to the overall results
rows[arrPos] = row;
arrPos++;
}
// add the rows to the result set and set the total row count
batchResults.setRows(rows);
batchResults.setTotalRowCount(totalRows);
queryResult = new QueryResult(getId(), batchResults);
// move the position on
updatePosition(totalRows, queryResult);
if (logger.isDebugEnabled())
logger.debug("After getNextResultsBatch: " + toString());
}
return queryResult;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
StringBuilder builder = new StringBuilder(super.toString());
builder.append(" (id=").append(getId());
builder.append(" batchSize=").append(this.batchSize);
builder.append(" position=").append(this.position);
builder.append(" node-id=").append(this.node.getUuid()).append(")");
return builder.toString();
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.webservice.repository;
import java.io.Serializable;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
/**
* Interface definition for a QuerySession.
*
* @author gavinc
*/
public interface QuerySession extends Serializable
{
/**
* Retrieves the id this query session can be identified as
*
* @return Id of this query session
*/
public String getId();
/**
* Returns a QueryResult object representing the next batch of results.
* QueryResult will contain a maximum of items as determined by the
* <code>fetchSize</code> element of the QueryConfiguration SOAP header.
*
* When the last batch of results is being returned the querySession of
* QueryResult will be null.
*
* @see org.alfresco.repo.webservice.repository.QuerySession#getId()
* @param searchService The SearchService to use for gathering the results
* @param nodeService The NodeService to use for gathering the results
* @param namespaceService The NamespaceService to use
* @return QueryResult containing the next batch of results or null if there
* are no more results
*/
public QueryResult getNextResultsBatch(SearchService searchService, NodeService nodeService,
NamespaceService namespaceService);
}

View File

@@ -0,0 +1,681 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.webservice.repository;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.transaction.UserTransaction;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.webservice.AbstractWebService;
import org.alfresco.repo.webservice.CMLUtil;
import org.alfresco.repo.webservice.Utils;
import org.alfresco.repo.webservice.types.CML;
import org.alfresco.repo.webservice.types.ClassDefinition;
import org.alfresco.repo.webservice.types.NamedValue;
import org.alfresco.repo.webservice.types.Node;
import org.alfresco.repo.webservice.types.NodeDefinition;
import org.alfresco.repo.webservice.types.Predicate;
import org.alfresco.repo.webservice.types.Query;
import org.alfresco.repo.webservice.types.QueryLanguageEnum;
import org.alfresco.repo.webservice.types.Reference;
import org.alfresco.repo.webservice.types.Store;
import org.alfresco.repo.webservice.types.StoreEnum;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.namespace.QName;
import org.apache.axis.MessageContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Web service implementation of the RepositoryService. The WSDL for this
* service can be accessed from
* http://localhost:8080/alfresco/wsdl/repository-service.wsdl
*
* @author gavinc
*/
public class RepositoryWebService extends AbstractWebService implements
RepositoryServiceSoapPort
{
private static Log logger = LogFactory.getLog(RepositoryWebService.class);
private DictionaryService dictionaryService;
private CMLUtil cmlUtil;
private SimpleCache<String, QuerySession> querySessionCache;
/**
* Sets the instance of the DictionaryService to be used
*
* @param dictionaryService
* The DictionaryService
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* Sets the CML Util
*
* @param cmlUtil CML util object
*/
public void setCmlUtil(CMLUtil cmlUtil)
{
this.cmlUtil = cmlUtil;
}
/**
* Sets the instance of the SimpleCache to be used
*
* @param querySessionCache
* The SimpleCache
*/
public void setQuerySessionCache(
SimpleCache<String, QuerySession> querySessionCache)
{
this.querySessionCache = querySessionCache;
}
/**
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#getStores()
*/
public Store[] getStores() throws RemoteException, RepositoryFault
{
UserTransaction tx = null;
try
{
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
tx.begin();
List<StoreRef> stores = this.nodeService.getStores();
Store[] returnStores = new Store[stores.size()];
for (int x = 0; x < stores.size(); x++)
{
StoreRef storeRef = stores.get(x);
if (logger.isDebugEnabled() == true)
{
logger.debug("Store protocol :" + storeRef.getProtocol());
}
StoreEnum storeEnum = StoreEnum.fromString(storeRef
.getProtocol());
Store store = new Store(storeEnum, storeRef.getIdentifier());
returnStores[x] = store;
}
// commit the transaction
tx.commit();
return returnStores;
} catch (Throwable e)
{
// rollback the transaction
try
{
if (tx != null)
{
tx.rollback();
}
} catch (Exception ex)
{
}
if (logger.isDebugEnabled())
{
logger.error("Unexpected error occurred", e);
}
throw new RepositoryFault(0, e.getMessage());
}
}
/**
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#query(org.alfresco.repo.webservice.types.Store,
* org.alfresco.repo.webservice.types.Query, boolean)
*/
public QueryResult query(Store store, Query query, boolean includeMetaData)
throws RemoteException, RepositoryFault
{
QueryLanguageEnum langEnum = query.getLanguage();
if (langEnum.equals(QueryLanguageEnum.cql)
|| langEnum.equals(QueryLanguageEnum.xpath))
{
throw new RepositoryFault(110, "Only '"
+ QueryLanguageEnum.lucene.getValue()
+ "' queries are currently supported!");
}
UserTransaction tx = null;
MessageContext msgContext = MessageContext.getCurrentContext();
try
{
tx = Utils.getUserTransaction(msgContext);
tx.begin();
// setup a query session and get the first batch of results
QuerySession querySession = new ResultSetQuerySession(Utils
.getBatchSize(msgContext), store, query, includeMetaData);
QueryResult queryResult = querySession
.getNextResultsBatch(this.searchService, this.nodeService,
this.namespaceService);
// add the session to the cache if there are more results to come
if (queryResult.getQuerySession() != null)
{
// this.querySessionCache.putQuerySession(querySession);
this.querySessionCache.put(queryResult.getQuerySession(),
querySession);
}
// commit the transaction
tx.commit();
return queryResult;
} catch (Throwable e)
{
// rollback the transaction
try
{
if (tx != null)
{
tx.rollback();
}
} catch (Exception ex)
{
}
if (logger.isDebugEnabled())
{
logger.error("Unexpected error occurred", e);
}
e.printStackTrace();
throw new RepositoryFault(0, e.getMessage());
}
}
/**
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#queryChildren(org.alfresco.repo.webservice.types.Reference)
*/
public QueryResult queryChildren(Reference node) throws RemoteException,
RepositoryFault
{
UserTransaction tx = null;
try
{
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
tx.begin();
// setup a query session and get the first batch of results
QuerySession querySession = new ChildrenQuerySession(Utils
.getBatchSize(MessageContext.getCurrentContext()), node);
QueryResult queryResult = querySession
.getNextResultsBatch(this.searchService, this.nodeService,
this.namespaceService);
// add the session to the cache if there are more results to come
if (queryResult.getQuerySession() != null)
{
// this.querySessionCache.putQuerySession(querySession);
this.querySessionCache.put(queryResult.getQuerySession(),
querySession);
}
// commit the transaction
tx.commit();
return queryResult;
} catch (Throwable e)
{
// rollback the transaction
try
{
if (tx != null)
{
tx.rollback();
}
} catch (Exception ex)
{
}
if (logger.isDebugEnabled())
{
logger.error("Unexpected error occurred", e);
}
throw new RepositoryFault(0, e.getMessage());
}
}
/**
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#queryParents(org.alfresco.repo.webservice.types.Reference)
*/
public QueryResult queryParents(Reference node) throws RemoteException,
RepositoryFault
{
UserTransaction tx = null;
try
{
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
tx.begin();
// setup a query session and get the first batch of results
QuerySession querySession = new ParentsQuerySession(Utils
.getBatchSize(MessageContext.getCurrentContext()), node);
QueryResult queryResult = querySession
.getNextResultsBatch(this.searchService, this.nodeService,
this.namespaceService);
// add the session to the cache if there are more results to come
if (queryResult.getQuerySession() != null)
{
// this.querySessionCache.putQuerySession(querySession);
this.querySessionCache.put(queryResult.getQuerySession(),
querySession);
}
// commit the transaction
tx.commit();
return queryResult;
} catch (Throwable e)
{
// rollback the transaction
try
{
if (tx != null)
{
tx.rollback();
}
} catch (Exception ex)
{
}
if (logger.isDebugEnabled())
{
logger.error("Unexpected error occurred", e);
}
throw new RepositoryFault(0, e.getMessage());
}
}
/**
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#queryAssociated(org.alfresco.repo.webservice.types.Reference,
* org.alfresco.repo.webservice.repository.Association[])
*/
public QueryResult queryAssociated(Reference node, Association[] association)
throws RemoteException, RepositoryFault
{
UserTransaction tx = null;
try
{
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
tx.begin();
// setup a query session and get the first batch of results
QuerySession querySession = new AssociatedQuerySession(Utils.getBatchSize(MessageContext.getCurrentContext()), node);
QueryResult queryResult = querySession
.getNextResultsBatch(this.searchService, this.nodeService,
this.namespaceService);
// add the session to the cache if there are more results to come
if (queryResult.getQuerySession() != null)
{
// this.querySessionCache.putQuerySession(querySession);
this.querySessionCache.put(queryResult.getQuerySession(),
querySession);
}
// commit the transaction
tx.commit();
return queryResult;
}
catch (Throwable e)
{
// rollback the transaction
try
{
if (tx != null)
{
tx.rollback();
}
} catch (Exception ex)
{
}
if (logger.isDebugEnabled())
{
logger.error("Unexpected error occurred", e);
}
throw new RepositoryFault(0, e.getMessage());
}
}
/**
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#fetchMore(java.lang.String)
*/
public QueryResult fetchMore(String querySession) throws RemoteException,
RepositoryFault
{
QueryResult queryResult = null;
UserTransaction tx = null;
try
{
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
tx.begin();
// try and get the QuerySession with the given id from the cache
QuerySession session = this.querySessionCache.get(querySession);
if (session == null)
{
if (logger.isDebugEnabled())
logger.debug("Invalid querySession id requested: "
+ querySession);
throw new RepositoryFault(4, "querySession with id '"
+ querySession + "' is invalid");
}
// get the next batch of results
queryResult = session.getNextResultsBatch(this.searchService,
this.nodeService, this.namespaceService);
// remove the QuerySession from the cache if there are no more
// results to come
if (queryResult.getQuerySession() == null)
{
this.querySessionCache.remove(querySession);
}
// commit the transaction
tx.commit();
return queryResult;
} catch (Throwable e)
{
// rollback the transaction
try
{
if (tx != null)
{
tx.rollback();
}
} catch (Exception ex)
{
}
if (e instanceof RepositoryFault)
{
throw (RepositoryFault) e;
} else
{
if (logger.isDebugEnabled())
{
logger.error("Unexpected error occurred", e);
}
throw new RepositoryFault(0, e.getMessage());
}
}
}
/**
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#update(org.alfresco.repo.webservice.types.CML)
*/
public UpdateResult[] update(CML statements) throws RemoteException,
RepositoryFault
{
UpdateResult[] result = null;
UserTransaction tx = null;
try
{
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
tx.begin();
result = this.cmlUtil.executeCML(statements);
// commit the transaction
tx.commit();
return result;
}
catch (Throwable e)
{
// rollback the transaction
try
{
if (tx != null)
{
tx.rollback();
}
} catch (Exception ex)
{
}
if (logger.isDebugEnabled())
{
logger.error("Unexpected error occurred", e);
}
throw new RepositoryFault(0, e.getMessage());
}
}
/**
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#describe(org.alfresco.repo.webservice.types.Predicate)
*/
public NodeDefinition[] describe(Predicate items) throws RemoteException,
RepositoryFault
{
NodeDefinition[] nodeDefs = null;
UserTransaction tx = null;
try
{
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
tx.begin();
List<NodeRef> nodes = Utils
.resolvePredicate(items, this.nodeService,
this.searchService, this.namespaceService);
nodeDefs = new NodeDefinition[nodes.size()];
for (int x = 0; x < nodes.size(); x++)
{
nodeDefs[x] = setupNodeDefObject(nodes.get(x));
}
// commit the transaction
tx.commit();
return nodeDefs;
} catch (Throwable e)
{
// rollback the transaction
try
{
if (tx != null)
{
tx.rollback();
}
} catch (Exception ex)
{
}
if (logger.isDebugEnabled())
{
logger.error("Unexpected error occurred", e);
}
throw new RepositoryFault(0, e.getMessage());
}
}
/**
* Creates a NodeDefinition web service type object for the given
* repository NodeRef instance
*
* @param nodeRef The NodeRef to generate the NodeDefinition for
* @return The NodeDefinition representation of nodeRef
*/
private NodeDefinition setupNodeDefObject(NodeRef nodeRef)
{
if (logger.isDebugEnabled())
logger.debug("Building NodeDefinition for node: " + nodeRef);
TypeDefinition ddTypeDef = this.dictionaryService
.getType(this.nodeService.getType(nodeRef));
// create the web service ClassDefinition type from the data dictionary TypeDefinition
ClassDefinition typeDef = Utils.setupClassDefObject(ddTypeDef);
// create the web service ClassDefinition types to represent the aspects
ClassDefinition[] aspectDefs = null;
List<AspectDefinition> aspects = ddTypeDef.getDefaultAspects();
if (aspects != null)
{
aspectDefs = new ClassDefinition[aspects.size()];
int pos = 0;
for (AspectDefinition ddAspectDef : aspects)
{
aspectDefs[pos] = Utils.setupClassDefObject(ddAspectDef);
pos++;
}
}
return new NodeDefinition(typeDef, aspectDefs);
}
/**
* Gets the nodes associatiated with the predicate provided. Usefull when the store and ids of the required
* nodes are known.
*
* @see org.alfresco.repo.webservice.repository.RepositoryServiceSoapPort#get(org.alfresco.repo.webservice.types.Predicate)
*/
public Node[] get(Predicate where) throws RemoteException, RepositoryFault
{
Node[] nodes = null;
UserTransaction tx = null;
try
{
tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
tx.begin();
// Resolve the predicate to a list of node references
List<NodeRef> nodeRefs = Utils.resolvePredicate(where, this.nodeService, this.searchService, this.namespaceService);
nodes = new Node[nodeRefs.size()];
int index = 0;
for (NodeRef nodeRef : nodeRefs)
{
// Get the nodes reference
Reference reference = Utils.convertToReference(nodeRef);
// Get the nodes type
String type = this.nodeService.getType(nodeRef).toString();
// Get the nodes aspects
Set<QName> aspectQNames = this.nodeService.getAspects(nodeRef);
String[] aspects = new String[aspectQNames.size()];
int aspectIndex = 0;
for (QName aspectQName : aspectQNames)
{
aspects[aspectIndex] = aspectQName.toString();
aspectIndex++;
}
// Get the nodes properties
Map<QName, Serializable> propertyMap = this.nodeService.getProperties(nodeRef);
NamedValue[] properties = new NamedValue[propertyMap.size()];
int propertyIndex = 0;
for (Map.Entry<QName, Serializable> entry : propertyMap.entrySet())
{
String value = null;
try
{
value = DefaultTypeConverter.INSTANCE.convert(String.class, entry.getValue());
}
catch (Throwable exception)
{
value = entry.getValue().toString();
}
properties[propertyIndex] = new NamedValue(entry.getKey().toString(), value);
propertyIndex++;
}
// Create the node and add to the array
Node node = new Node(reference, type, aspects, properties);
nodes[index] = node;
index++;
}
// commit the transaction
tx.commit();
}
catch (Throwable e)
{
// rollback the transaction
try
{
if (tx != null)
{
tx.rollback();
}
}
catch (Exception ex)
{
// Ignore
}
if (logger.isDebugEnabled())
{
logger.error("Unexpected error occurred", e);
}
throw new RepositoryFault(0, e.getMessage());
}
return nodes;
}
}

View File

@@ -0,0 +1,188 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.webservice.repository;
import java.io.Serializable;
import java.util.Map;
import org.alfresco.repo.webservice.Utils;
import org.alfresco.repo.webservice.types.NamedValue;
import org.alfresco.repo.webservice.types.Query;
import org.alfresco.repo.webservice.types.ResultSetRowNode;
import org.alfresco.repo.webservice.types.Store;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Implementation of a QuerySession that retrieves results from a repository ResultSet
*
* @author gavinc
*/
public class ResultSetQuerySession extends AbstractQuerySession
{
private static final long serialVersionUID = -9154514445963635138L;
private transient static Log logger = LogFactory.getLog(ResultSetQuerySession.class);
private Store store;
private Query query;
private boolean includeMetaData;
/**
* Constructs a ResultSetQuerySession
*
* @param batchSize The batch size to use for this session
* @param store The repository store to query against
* @param query The query to execute
* @param includeMetaData Whether to include metadata in the query results
*/
public ResultSetQuerySession(int batchSize, Store store, Query query, boolean includeMetaData)
{
super(batchSize);
this.store = store;
this.query = query;
this.includeMetaData = includeMetaData;
}
/**
* @see org.alfresco.repo.webservice.repository.QuerySession#getNextResultsBatch(org.alfresco.service.cmr.search.SearchService, org.alfresco.service.cmr.repository.NodeService, org.alfresco.service.namespace.NamespaceService)
*/
public QueryResult getNextResultsBatch(SearchService searchService, NodeService nodeService, NamespaceService namespaceService)
{
QueryResult queryResult = null;
if (this.position != -1)
{
if (logger.isDebugEnabled())
logger.debug("Before getNextResultsBatch: " + toString());
// handle the special search string of * meaning, get everything
String statement = query.getStatement();
if (statement.equals("*"))
{
statement = "ISNODE:*";
}
ResultSet searchResults = null;
try
{
searchResults = searchService.query(Utils.convertToStoreRef(this.store),
this.query.getLanguage().getValue(), statement);
int totalRows = searchResults.length();
int lastRow = calculateLastRowIndex(totalRows);
int currentBatchSize = lastRow - this.position;
if (logger.isDebugEnabled())
logger.debug("Total rows = " + totalRows + ", current batch size = " + currentBatchSize);
org.alfresco.repo.webservice.types.ResultSet batchResults = new org.alfresco.repo.webservice.types.ResultSet();
org.alfresco.repo.webservice.types.ResultSetRow[] rows = new org.alfresco.repo.webservice.types.ResultSetRow[currentBatchSize];
int arrPos = 0;
for (int x = this.position; x < lastRow; x++)
{
ResultSetRow origRow = searchResults.getRow(x);
NodeRef nodeRef = origRow.getNodeRef();
ResultSetRowNode rowNode = new ResultSetRowNode(nodeRef.getId(), nodeService.getType(nodeRef).toString(), null);
// get the data for the row and build up the columns structure
Map<Path, Serializable> values = origRow.getValues();
NamedValue[] columns = new NamedValue[values.size()];
int col = 0;
for (Path path : values.keySet())
{
String value = null;
Serializable valueObj = values.get(path);
if (valueObj != null)
{
value = valueObj.toString();
}
// Get the attribute QName from the result path
String attributeName = path.last().toString();
if (attributeName.startsWith("@") == true)
{
attributeName = attributeName.substring(1);
}
columns[col] = new NamedValue(attributeName, value);
col++;
}
org.alfresco.repo.webservice.types.ResultSetRow row = new org.alfresco.repo.webservice.types.ResultSetRow();
row.setColumns(columns);
row.setScore(origRow.getScore());
row.setRowIndex(x);
row.setNode(rowNode);
// add the row to the overall results
rows[arrPos] = row;
arrPos++;
}
// TODO: build up the meta data data structure if we've been asked to
// add the rows to the result set and set the total row count
batchResults.setRows(rows);
batchResults.setTotalRowCount(totalRows);
queryResult = new QueryResult(getId(), batchResults);
// move the position on
updatePosition(totalRows, queryResult);
if (logger.isDebugEnabled())
logger.debug("After getNextResultsBatch: " + toString());
}
finally
{
if (searchResults != null)
{
searchResults.close();
}
}
}
return queryResult;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
StringBuilder builder = new StringBuilder(super.toString());
builder.append(" (id=").append(getId());
builder.append(" batchSize=").append(this.batchSize);
builder.append(" position=").append(this.position);
builder.append(" store=").append(this.store.getScheme().getValue()).append(":").append(this.store.getAddress());
builder.append(" language=").append(this.query.getLanguage().getValue());
builder.append(" statement=").append(this.query.getStatement());
builder.append(")");
return builder.toString();
}
}