/*
* (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*
* Contributors:
* Florent Guillaume
*/
package org.nuxeo.ecm.core.opencmis.impl.client;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.chemistry.opencmis.client.api.ChangeEvent;
import org.apache.chemistry.opencmis.client.api.ChangeEvents;
import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.apache.chemistry.opencmis.client.api.Document;
import org.apache.chemistry.opencmis.client.api.Folder;
import org.apache.chemistry.opencmis.client.api.ItemIterable;
import org.apache.chemistry.opencmis.client.api.ObjectId;
import org.apache.chemistry.opencmis.client.api.ObjectType;
import org.apache.chemistry.opencmis.client.api.OperationContext;
import org.apache.chemistry.opencmis.client.api.Policy;
import org.apache.chemistry.opencmis.client.api.QueryResult;
import org.apache.chemistry.opencmis.client.api.QueryStatement;
import org.apache.chemistry.opencmis.client.api.Relationship;
import org.apache.chemistry.opencmis.client.api.Session;
import org.apache.chemistry.opencmis.client.api.Tree;
import org.apache.chemistry.opencmis.client.runtime.ObjectIdImpl;
import org.apache.chemistry.opencmis.client.runtime.OperationContextImpl;
import org.apache.chemistry.opencmis.client.runtime.QueryResultImpl;
import org.apache.chemistry.opencmis.client.runtime.QueryStatementImpl;
import org.apache.chemistry.opencmis.client.runtime.util.AbstractPageFetcher;
import org.apache.chemistry.opencmis.client.runtime.util.CollectionIterable;
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.data.Ace;
import org.apache.chemistry.opencmis.commons.data.Acl;
import org.apache.chemistry.opencmis.commons.data.BulkUpdateObjectIdAndChangeToken;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData;
import org.apache.chemistry.opencmis.commons.data.ObjectData;
import org.apache.chemistry.opencmis.commons.data.ObjectList;
import org.apache.chemistry.opencmis.commons.data.Properties;
import org.apache.chemistry.opencmis.commons.data.PropertyData;
import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
import org.apache.chemistry.opencmis.commons.enums.BindingType;
import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
import org.apache.chemistry.opencmis.commons.enums.RelationshipDirection;
import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.BulkUpdateObjectIdAndChangeTokenImpl;
import org.apache.chemistry.opencmis.commons.server.CallContext;
import org.apache.chemistry.opencmis.commons.server.CmisService;
import org.apache.commons.lang.StringUtils;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoObjectData;
/**
* Nuxeo Persistent Session, having a direct connection to a Nuxeo {@link CoreSession}.
*/
public class NuxeoSession implements Session {
private static final long serialVersionUID = 1L;
public static final OperationContext DEFAULT_CONTEXT = new OperationContextImpl(null, false, true, false,
IncludeRelationships.NONE, null, true, null, true, 10);
private final CoreSession coreSession;
private final String repositoryId;
protected final NuxeoObjectFactory objectFactory;
private final CmisService service;
private final NuxeoBinding binding;
private OperationContext defaultContext = DEFAULT_CONTEXT;
public NuxeoSession(NuxeoBinding binding, CallContext context) {
this.coreSession = binding.getCoreSession();
repositoryId = context.getRepositoryId();
objectFactory = new NuxeoObjectFactory(this);
service = binding.service;
this.binding = binding;
}
@Override
public NuxeoObjectFactory getObjectFactory() {
return objectFactory;
}
@Override
public NuxeoBinding getBinding() {
return binding;
}
public CmisService getService() {
return service;
}
protected CoreSession getCoreSession() {
return coreSession;
}
@Override
public void clear() {
}
public void save() {
coreSession.save();
}
@Override
public void setDefaultContext(OperationContext defaultContext) {
this.defaultContext = defaultContext;
}
@Override
public OperationContext getDefaultContext() {
return defaultContext;
}
@Override
public Map<String, String> getSessionParameters() {
return Collections.emptyMap();
}
protected String getRepositoryId() {
return coreSession.getRepositoryName();
}
@Override
public ObjectId createObjectId(String id) {
return new ObjectIdImpl(id);
}
@Override
public ObjectId createDocument(Map<String, ?> properties, ObjectId folderId, ContentStream contentStream,
VersioningState versioningState) {
return createDocument(properties, folderId, contentStream, versioningState, null, null, null);
}
/** Converts from an untyped map to a {@link Properties} object. */
protected Properties convertProperties(Map<String, ?> properties) {
if (properties == null) {
return null;
}
// find type
String typeId = (String) properties.get(PropertyIds.OBJECT_TYPE_ID);
if (typeId == null) {
throw new IllegalArgumentException("Missing type");
}
ObjectType type = getTypeDefinition(typeId);
if (type == null) {
throw new IllegalArgumentException("Unknown type: " + typeId);
}
return objectFactory.convertProperties(properties, type, null, null);
}
@Override
public ObjectId createDocument(Map<String, ?> properties, ObjectId folderId, ContentStream contentStream,
VersioningState versioningState, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces) {
String id = service.createDocument(repositoryId, convertProperties(properties), folderId == null ? null
: folderId.getId(), contentStream, versioningState, objectFactory.convertPolicies(policies),
objectFactory.convertAces(addAces), objectFactory.convertAces(removeAces), null);
return createObjectId(id);
}
@Override
public ObjectId createFolder(Map<String, ?> properties, ObjectId folderId) {
return createFolder(properties, folderId, null, null, null);
}
@Override
public ObjectId createFolder(Map<String, ?> properties, ObjectId folderId, List<Policy> policies,
List<Ace> addAces, List<Ace> removeAces) {
String id = service.createFolder(repositoryId, convertProperties(properties), folderId == null ? null
: folderId.getId(), objectFactory.convertPolicies(policies), objectFactory.convertAces(addAces),
objectFactory.convertAces(removeAces), null);
return createObjectId(id);
}
@Override
public OperationContext createOperationContext() {
return new OperationContextImpl();
}
@Override
public OperationContext createOperationContext(Set<String> filter, boolean includeAcls,
boolean includeAllowableActions, boolean includePolicies, IncludeRelationships includeRelationships,
Set<String> renditionFilter, boolean includePathSegments, String orderBy, boolean cacheEnabled,
int maxItemsPerPage) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public ObjectId createPolicy(Map<String, ?> properties, ObjectId folderId) {
return createPolicy(properties, folderId, null, null, null);
}
@Override
public ObjectId createPolicy(Map<String, ?> properties, ObjectId folderId, List<Policy> policies,
List<Ace> addAces, List<Ace> removeAces) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public ObjectId createRelationship(Map<String, ?> properties) {
return createRelationship(properties, null, null, null);
}
@Override
public ObjectId createRelationship(Map<String, ?> properties, List<Policy> policies, List<Ace> addAces,
List<Ace> removeAces) {
String id = service.createRelationship(repositoryId, convertProperties(properties),
objectFactory.convertPolicies(policies), objectFactory.convertAces(addAces),
objectFactory.convertAces(removeAces), null);
return createObjectId(id);
}
@Override
public ObjectId createItem(Map<String, ?> properties, ObjectId folderId, List<Policy> policies, List<Ace> addAces,
List<Ace> removeAces) {
throw new CmisNotSupportedException();
}
@Override
public ObjectId createItem(Map<String, ?> properties, ObjectId folderId) {
throw new CmisNotSupportedException();
}
@Override
public ObjectId createDocumentFromSource(ObjectId source, Map<String, ?> properties, ObjectId folderId,
VersioningState versioningState) {
return createDocumentFromSource(source, properties, folderId, versioningState, null, null, null);
}
@Override
public ObjectId createDocumentFromSource(ObjectId source, Map<String, ?> properties, ObjectId folderId,
VersioningState versioningState, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public ItemIterable<Document> getCheckedOutDocs() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public ItemIterable<Document> getCheckedOutDocs(OperationContext context) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public ChangeEvents getContentChanges(String changeLogToken, boolean includeProperties, long maxNumItems) {
return getContentChanges(changeLogToken, includeProperties, maxNumItems, getDefaultContext());
}
@Override
public ChangeEvents getContentChanges(String changeLogToken, boolean includeProperties, long maxNumItems,
OperationContext context) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public ItemIterable<ChangeEvent> getContentChanges(String changeLogToken, boolean includeProperties) {
return getContentChanges(changeLogToken, includeProperties, getDefaultContext());
};
@Override
public ItemIterable<ChangeEvent> getContentChanges(String changeLogToken, boolean includeProperties,
OperationContext context) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
};
@Override
public Locale getLocale() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public boolean exists(ObjectId objectId) {
return exists(objectId.getId());
}
@Override
public boolean exists(String objectId) {
try {
service.getObject(repositoryId, objectId, PropertyIds.OBJECT_ID, Boolean.FALSE, IncludeRelationships.NONE,
"cmis:none", Boolean.FALSE, Boolean.FALSE, null);
return true;
} catch (CmisObjectNotFoundException e) {
return false;
}
}
@Override
public boolean existsPath(String parentPath, String name) {
if (parentPath == null || !parentPath.startsWith("/")) {
throw new CmisInvalidArgumentException("Invalid parent path: " + parentPath);
}
if (StringUtils.isEmpty(name)) {
throw new CmisInvalidArgumentException("Invalid empty name: " + name);
}
StringBuilder path = new StringBuilder(parentPath);
if (!parentPath.endsWith("/")) {
path.append('/');
}
path.append(name);
return existsPath(path.toString());
}
@Override
public boolean existsPath(String path) {
try {
service.getObjectByPath(repositoryId, path, PropertyIds.OBJECT_ID, Boolean.FALSE, IncludeRelationships.NONE,
"cmis:none", Boolean.FALSE, Boolean.FALSE, null);
return true;
} catch (CmisObjectNotFoundException e) {
return false;
}
}
@Override
public CmisObject getObject(ObjectId objectId) {
return getObject(objectId, getDefaultContext());
}
@Override
public CmisObject getObject(String objectId) {
return getObject(objectId, getDefaultContext());
}
/** Gets a CMIS object given a Nuxeo {@link DocumentModel}. */
public CmisObject getObject(DocumentModel doc, OperationContext context) {
ObjectData data = new NuxeoObjectData(service, doc, context);
return objectFactory.convertObject(data, context);
}
@Override
public CmisObject getObject(ObjectId objectId, OperationContext context) {
if (objectId == null) {
throw new CmisInvalidArgumentException("Missing object ID");
}
return getObject(objectId.getId(), context);
}
@Override
public CmisObject getObject(String objectId, OperationContext context) {
if (objectId == null) {
throw new CmisInvalidArgumentException("Missing object ID");
}
if (context == null) {
throw new CmisInvalidArgumentException("Missing operation context");
}
ObjectData data = service.getObject(repositoryId, objectId, context.getFilterString(),
Boolean.valueOf(context.isIncludeAllowableActions()), context.getIncludeRelationships(),
context.getRenditionFilterString(), Boolean.valueOf(context.isIncludePolicies()),
Boolean.valueOf(context.isIncludeAcls()), null);
return objectFactory.convertObject(data, context);
}
@Override
public CmisObject getObjectByPath(String path) {
return getObjectByPath(path, getDefaultContext());
}
@Override
public CmisObject getObjectByPath(String parentPath, String name) {
return getObjectByPath(parentPath, name, getDefaultContext());
}
@Override
public CmisObject getObjectByPath(String parentPath, String name, OperationContext context) {
if (parentPath == null || !parentPath.startsWith("/")) {
throw new CmisInvalidArgumentException("Invalid parent path: " + parentPath);
}
if (StringUtils.isEmpty(name)) {
throw new CmisInvalidArgumentException("Invalid empty name: " + name);
}
StringBuilder path = new StringBuilder(parentPath);
if (!parentPath.endsWith("/")) {
path.append('/');
}
path.append(name);
return getObjectByPath(path.toString(), context);
}
@Override
public CmisObject getObjectByPath(String path, OperationContext context) {
if (path == null || !path.startsWith("/")) {
throw new CmisInvalidArgumentException("Invalid path: " + path);
}
if (context == null) {
throw new CmisInvalidArgumentException("Missing operation context");
}
ObjectData data = service.getObjectByPath(repositoryId, path, context.getFilterString(),
Boolean.valueOf(context.isIncludeAllowableActions()), context.getIncludeRelationships(),
context.getRenditionFilterString(), Boolean.valueOf(context.isIncludePolicies()),
Boolean.valueOf(context.isIncludeAcls()), null);
return getObjectFactory().convertObject(data, context);
}
@Override
public RepositoryInfo getRepositoryInfo() {
return service.getRepositoryInfo(repositoryId, null);
}
@Override
public Folder getRootFolder() {
return getRootFolder(getDefaultContext());
}
@Override
public Folder getRootFolder(OperationContext context) {
String id = getRepositoryInfo().getRootFolderId();
CmisObject folder = getObject(createObjectId(id), context);
if (!(folder instanceof Folder)) {
throw new CmisRuntimeException("Root object is not a Folder but: " + folder.getClass().getName());
}
return (Folder) folder;
}
@Override
public ItemIterable<ObjectType> getTypeChildren(String typeId, boolean includePropertyDefinitions) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public ObjectType getTypeDefinition(String typeId) {
TypeDefinition typeDefinition = service.getTypeDefinition(repositoryId, typeId, null);
return objectFactory.convertTypeDefinition(typeDefinition);
}
@Override
public ObjectType getTypeDefinition(String typeId, boolean useCache) {
return getTypeDefinition(typeId);
}
@Override
public List<Tree<ObjectType>> getTypeDescendants(String typeId, int depth, boolean includePropertyDefinitions) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public ItemIterable<QueryResult> query(String statement, boolean searchAllVersions) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public ItemIterable<QueryResult> query(final String statement, final boolean searchAllVersions,
final OperationContext context) {
AbstractPageFetcher<QueryResult> pageFetcher = new AbstractPageFetcher<QueryResult>(
context.getMaxItemsPerPage()) {
@Override
protected Page<QueryResult> fetchPage(long skipCount) {
ObjectList results = service.query(repositoryId, statement, Boolean.valueOf(searchAllVersions),
Boolean.valueOf(context.isIncludeAllowableActions()), context.getIncludeRelationships(),
context.getRenditionFilterString(), BigInteger.valueOf(maxNumItems),
BigInteger.valueOf(skipCount), null);
// convert objects
List<QueryResult> page = new ArrayList<QueryResult>();
if (results.getObjects() != null) {
for (ObjectData data : results.getObjects()) {
page.add(new QueryResultImpl(NuxeoSession.this, data));
}
}
return new Page<QueryResult>(page, results.getNumItems(), results.hasMoreItems());
}
};
return new CollectionIterable<QueryResult>(pageFetcher);
}
@Override
public ItemIterable<CmisObject> queryObjects(String typeId, String where, boolean searchAllVersions,
OperationContext context) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public QueryStatement createQueryStatement(String statement) {
return new QueryStatementImpl(this, statement);
}
@Override
public QueryStatement createQueryStatement(Collection<String> selectPropertyIds, Map<String, String> fromTypes,
String whereClause, List<String> orderByPropertyIds) {
return new QueryStatementImpl(this, selectPropertyIds, fromTypes, whereClause, orderByPropertyIds);
}
@Override
public ItemIterable<Relationship> getRelationships(final ObjectId objectId,
final boolean includeSubRelationshipTypes, final RelationshipDirection relationshipDirection,
final ObjectType type, final OperationContext context) {
final String typeId = type == null ? null : type.getId();
AbstractPageFetcher<Relationship> pageFetcher = new AbstractPageFetcher<Relationship>(
context.getMaxItemsPerPage()) {
@Override
protected Page<Relationship> fetchPage(long skipCount) {
ObjectList relations = service.getObjectRelationships(repositoryId, objectId.getId(),
Boolean.valueOf(includeSubRelationshipTypes), relationshipDirection, typeId, null, null,
BigInteger.valueOf(maxNumItems), BigInteger.valueOf(skipCount), null);
// convert objects
List<Relationship> page = new ArrayList<Relationship>();
if (relations.getObjects() != null) {
for (ObjectData data : relations.getObjects()) {
CmisObject ob;
if (data instanceof NuxeoObjectData) {
ob = objectFactory.convertObject(data, context);
} else {
ob = getObject(data.getId(), context);
}
if (!(ob instanceof Relationship)) {
// should not happen...
continue;
}
page.add((Relationship) ob);
}
}
return new Page<Relationship>(page, relations.getNumItems(), relations.hasMoreItems());
}
};
return new CollectionIterable<Relationship>(pageFetcher);
}
@Override
public Acl getAcl(ObjectId objectId, boolean onlyBasicPermissions) {
return service.getAcl(repositoryId, objectId.getId(), Boolean.valueOf(onlyBasicPermissions), null);
}
@Override
public Acl setAcl(ObjectId objectId, List<Ace> aces) {
return service.applyAcl(repositoryId, objectId.getId(), new AccessControlListImpl(aces), null);
}
@Override
public Acl applyAcl(ObjectId objectId, List<Ace> addAces, List<Ace> removeAces, AclPropagation aclPropagation) {
return service.applyAcl(repositoryId, objectId.getId(), new AccessControlListImpl(addAces),
new AccessControlListImpl(removeAces), aclPropagation, null);
}
@Override
public void applyPolicy(ObjectId objectId, ObjectId... policyIds) {
throw new CmisNotSupportedException();
}
@Override
public void removePolicy(ObjectId objectId, ObjectId... policyIds) {
throw new CmisNotSupportedException();
}
@Override
public void removeObjectFromCache(ObjectId objectId) {
}
@Override
public void removeObjectFromCache(String objectId) {
}
@Override
public void delete(ObjectId objectId) {
delete(objectId, true);
}
@Override
public void delete(ObjectId objectId, boolean allVersions) {
service.deleteObject(repositoryId, objectId.getId(), Boolean.valueOf(allVersions), null);
}
@Override
public List<String> deleteTree(ObjectId folderId, boolean allVersions, UnfileObject unfile,
boolean continueOnFailure) {
FailedToDeleteData res = service.deleteTree(repositoryId, folderId.getId(), Boolean.valueOf(allVersions),
unfile, Boolean.valueOf(continueOnFailure), null);
return res.getIds();
}
@Override
public ContentStream getContentStream(ObjectId docId) {
return getContentStream(docId, null, null, null);
}
@Override
public ContentStream getContentStream(ObjectId docId, String streamId, BigInteger offset, BigInteger length) {
if (docId == null) {
throw new CmisInvalidArgumentException("Missing object ID");
}
return service.getContentStream(repositoryId, docId.getId(), streamId, offset, length, null);
}
@Override
public ObjectType createType(TypeDefinition type) {
throw new CmisNotSupportedException();
}
@Override
public ObjectType updateType(TypeDefinition type) {
throw new CmisNotSupportedException();
}
@Override
public void deleteType(String typeId) {
throw new CmisNotSupportedException();
}
@Override
public List<BulkUpdateObjectIdAndChangeToken> bulkUpdateProperties(List<CmisObject> objects,
Map<String, ?> properties, List<String> addSecondaryTypeIds, List<String> removeSecondaryTypeIds) {
List<BulkUpdateObjectIdAndChangeToken> idts = new ArrayList<BulkUpdateObjectIdAndChangeToken>(objects.size());
for (CmisObject object : objects) {
idts.add(new BulkUpdateObjectIdAndChangeTokenImpl(object.getId(), object.getChangeToken()));
}
return service.bulkUpdateProperties(repositoryId, idts, convertProperties(properties), addSecondaryTypeIds,
removeSecondaryTypeIds, null);
}
@Override
public Document getLatestDocumentVersion(ObjectId objectId) {
return getLatestDocumentVersion(objectId, false, getDefaultContext());
}
@Override
public Document getLatestDocumentVersion(String objectId, OperationContext context) {
if (objectId == null) {
throw new IllegalArgumentException("Object ID must be set!");
}
return getLatestDocumentVersion(createObjectId(objectId), false, context);
}
@Override
public Document getLatestDocumentVersion(String objectId, boolean major, OperationContext context) {
if (objectId == null) {
throw new IllegalArgumentException("Object ID must be set!");
}
return getLatestDocumentVersion(createObjectId(objectId), major, context);
}
@Override
public Document getLatestDocumentVersion(String objectId) {
if (objectId == null) {
throw new IllegalArgumentException("Object ID must be set!");
}
return getLatestDocumentVersion(createObjectId(objectId), false, getDefaultContext());
}
@Override
public Document getLatestDocumentVersion(ObjectId objectId, OperationContext context) {
return getLatestDocumentVersion(objectId, false, context);
}
@Override
/**
* @See org.apache.chemistry.opencmis.client.runtime.SessionImpl
*/
public Document getLatestDocumentVersion(ObjectId objectId, boolean major, OperationContext context) {
if (objectId == null || objectId.getId() == null) {
throw new IllegalArgumentException("Object ID must be set!");
}
if (context == null) {
throw new IllegalArgumentException("Operation context must be set!");
}
CmisObject result = null;
String versionSeriesId = null;
// first attempt: if we got a Document object, try getting the version
// series ID from it
if (objectId instanceof Document) {
versionSeriesId = ((Document) objectId).getVersionSeriesId();
}
// third attempt (Web Services only): get the version series ID from the
// repository
// (the AtomPub and Browser binding don't need the version series ID ->
// avoid roundtrip)
if (versionSeriesId == null) {
BindingType bindingType = getBinding().getBindingType();
if (bindingType == BindingType.WEBSERVICES || bindingType == BindingType.CUSTOM) {
// get the document to find the version series ID
ObjectData sourceObjectData = binding.getObjectService().getObject(getRepositoryId(), objectId.getId(),
PropertyIds.OBJECT_ID + "," + PropertyIds.VERSION_SERIES_ID, false, IncludeRelationships.NONE,
"cmis:none", false, false, null);
if (sourceObjectData.getProperties() != null
&& sourceObjectData.getProperties().getProperties() != null) {
PropertyData<?> verionsSeriesIdProp = sourceObjectData.getProperties().getProperties().get(
PropertyIds.VERSION_SERIES_ID);
if (verionsSeriesIdProp != null && verionsSeriesIdProp.getFirstValue() instanceof String) {
versionSeriesId = (String) verionsSeriesIdProp.getFirstValue();
}
}
// the Web Services binding needs the version series ID -> fail
if (versionSeriesId == null) {
throw new IllegalArgumentException("Object is not a document or not versionable!");
}
}
}
// get the object
ObjectData objectData = binding.getVersioningService().getObjectOfLatestVersion(getRepositoryId(),
objectId.getId(), versionSeriesId, major, context.getFilterString(),
context.isIncludeAllowableActions(), context.getIncludeRelationships(),
context.getRenditionFilterString(), context.isIncludePolicies(), context.isIncludeAcls(), null);
result = getObjectFactory().convertObject(objectData, context);
// check result
if (!(result instanceof Document)) {
throw new IllegalArgumentException("Latest version is not a document!");
}
return (Document) result;
}
@Override
public String getLatestChangeLogToken() {
return getBinding().getRepositoryService().getRepositoryInfo(getRepositoryId(), null).getLatestChangeLogToken();
}
}