/******************************************************************************* * Copyright (c) 2013 aegif. * * This file is part of NemakiWare. * * NemakiWare is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NemakiWare 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along with NemakiWare. * If not, see <http://www.gnu.org/licenses/>. * * Contributors: * linzhixing(https://github.com/linzhixing) - initial API and implementation ******************************************************************************/ package jp.aegif.nemaki.cmis.factory; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import org.apache.chemistry.opencmis.commons.PropertyIds; import org.apache.chemistry.opencmis.commons.data.Acl; import org.apache.chemistry.opencmis.commons.data.AllowableActions; import org.apache.chemistry.opencmis.commons.data.BulkUpdateObjectIdAndChangeToken; import org.apache.chemistry.opencmis.commons.data.ContentStream; import org.apache.chemistry.opencmis.commons.data.ExtensionsData; import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData; import org.apache.chemistry.opencmis.commons.data.ObjectData; import org.apache.chemistry.opencmis.commons.data.ObjectInFolderContainer; import org.apache.chemistry.opencmis.commons.data.ObjectInFolderData; import org.apache.chemistry.opencmis.commons.data.ObjectInFolderList; import org.apache.chemistry.opencmis.commons.data.ObjectList; import org.apache.chemistry.opencmis.commons.data.ObjectParentData; import org.apache.chemistry.opencmis.commons.data.Properties; import org.apache.chemistry.opencmis.commons.data.PropertyData; import org.apache.chemistry.opencmis.commons.data.RenditionData; import org.apache.chemistry.opencmis.commons.data.RepositoryCapabilities; import org.apache.chemistry.opencmis.commons.data.RepositoryInfo; import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition; import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer; import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList; import org.apache.chemistry.opencmis.commons.enums.AclPropagation; import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; import org.apache.chemistry.opencmis.commons.enums.CapabilityAcl; 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.CmisObjectNotFoundException; import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException; import org.apache.chemistry.opencmis.commons.impl.server.AbstractCmisService; import org.apache.chemistry.opencmis.commons.impl.server.ObjectInfoImpl; import org.apache.chemistry.opencmis.commons.impl.server.RenditionInfoImpl; import org.apache.chemistry.opencmis.commons.server.CallContext; import org.apache.chemistry.opencmis.commons.server.ObjectInfo; import org.apache.chemistry.opencmis.commons.server.RenditionInfo; import org.apache.chemistry.opencmis.commons.spi.Holder; import org.apache.chemistry.opencmis.server.support.wrapper.CallContextAwareCmisService; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import jp.aegif.nemaki.cmis.service.AclService; import jp.aegif.nemaki.cmis.service.DiscoveryService; import jp.aegif.nemaki.cmis.service.NavigationService; import jp.aegif.nemaki.cmis.service.ObjectService; import jp.aegif.nemaki.cmis.service.PolicyService; import jp.aegif.nemaki.cmis.service.RelationshipService; import jp.aegif.nemaki.cmis.service.RepositoryService; import jp.aegif.nemaki.cmis.service.VersioningService; /** * Nemaki CMIS service. */ public class CmisService extends AbstractCmisService implements CallContextAwareCmisService { /** * Context data of the current CMIS call. */ private CallContext context; /** * Map containing all Nemaki repositories. */ private AclService aclService; private DiscoveryService discoveryService; private NavigationService navigationService; private ObjectService objectService; private RepositoryService repositoryService; private VersioningService versioningService; private PolicyService policyService; private RelationshipService relationshipService; private static final Log log = LogFactory.getLog(CmisService.class); /** * Create a new NemakiCmisService. */ public CmisService() { } // --- Navigation Service Implementation --- private ObjectInfo setObjectInfo(String repositoryId, ObjectData object) { ObjectInfo info = null; // object info has not been found -> create one try { info = getObjectInfoIntern(repositoryId, object); // add object info addObjectInfo(info); } catch (Exception e) { e.printStackTrace(); } finally { } return info; } private void setObjectInfoInTree(String repositoryId, List<ObjectInFolderContainer> list) { // Set ObjecInfo if (CollectionUtils.isNotEmpty(list)) { for (ObjectInFolderContainer o : list) { setObjectInfo(repositoryId, o.getObject().getObject()); // TODO traverse descendant if (CollectionUtils.isNotEmpty(o.getChildren())) { setObjectInfoInTree(repositoryId, o.getChildren()); } } } } /** * This method is customized based on OpenCMIS code */ @Override protected ObjectInfo getObjectInfoIntern(String repositoryId, ObjectData object) { // if the object has no properties, stop here if (object.getProperties() == null || object.getProperties().getProperties() == null) { throw new CmisRuntimeException("No properties!"); } ObjectInfoImpl info = new ObjectInfoImpl(); // get the repository info RepositoryInfo repositoryInfo = getRepositoryInfo(repositoryId, null); // general properties info.setObject(object); info.setId(object.getId()); info.setName(getStringProperty(object, PropertyIds.NAME)); info.setCreatedBy(getStringProperty(object, PropertyIds.CREATED_BY)); info.setCreationDate(getDateTimeProperty(object, PropertyIds.CREATED_BY)); info.setLastModificationDate(getDateTimeProperty(object, PropertyIds.LAST_MODIFICATION_DATE)); info.setTypeId(getIdProperty(object, PropertyIds.OBJECT_TYPE_ID)); info.setBaseType(object.getBaseTypeId()); // versioning info.setIsCurrentVersion(object.getBaseTypeId() == BaseTypeId.CMIS_DOCUMENT); info.setWorkingCopyId(null); info.setWorkingCopyOriginalId(null); info.setVersionSeriesId(getIdProperty(object, PropertyIds.VERSION_SERIES_ID)); if (info.getVersionSeriesId() != null) { Boolean isLatest = getBooleanProperty(object, PropertyIds.IS_LATEST_VERSION); info.setIsCurrentVersion(isLatest == null ? true : isLatest.booleanValue()); Boolean isCheckedOut = getBooleanProperty(object, PropertyIds.IS_VERSION_SERIES_CHECKED_OUT); if (isCheckedOut != null && isCheckedOut.booleanValue()) { info.setWorkingCopyId(getIdProperty(object, PropertyIds.VERSION_SERIES_CHECKED_OUT_ID)); // get latest version // // Nemaki Cusomization START //// /* * List<ObjectData> versions = getAllVersions(repositoryId, * object.getId(), info.getVersionSeriesId(), null, * Boolean.FALSE, null); if (versions != null && versions.size() * > 0) { * info.setWorkingCopyOriginalId(versions.get(0).getId()); } */ // NOTE:Spec2.2.7.6 only says the first element of // getAllVersions MUST be PWC. // When isCheckedOut = true, PWC MUST exsits, and // cmis:versionSeriesCheckedOutId is PWC id(2.1.13.5.1). info.setWorkingCopyOriginalId(getIdProperty(object, PropertyIds.VERSION_SERIES_CHECKED_OUT_ID)); // // Nemaki Cusomization END //// } } // content String fileName = getStringProperty(object, PropertyIds.CONTENT_STREAM_FILE_NAME); String mimeType = getStringProperty(object, PropertyIds.CONTENT_STREAM_MIME_TYPE); String streamId = getIdProperty(object, PropertyIds.CONTENT_STREAM_ID); BigInteger length = getIntegerProperty(object, PropertyIds.CONTENT_STREAM_LENGTH); boolean hasContent = fileName != null || mimeType != null || streamId != null || length != null; if (hasContent) { info.setHasContent(hasContent); info.setContentType(mimeType); info.setFileName(fileName); } else { info.setHasContent(false); info.setContentType(null); info.setFileName(null); } // parents if (object.getBaseTypeId() == BaseTypeId.CMIS_RELATIONSHIP) { info.setHasParent(false); } else if (object.getBaseTypeId() == BaseTypeId.CMIS_FOLDER) { info.setHasParent(!object.getId().equals(repositoryInfo.getRootFolderId())); // // Nemaki Cusomization START //// /* * } else { try { List<ObjectParentData> parents = * getObjectParents(repositoryId, object.getId(), null, * Boolean.FALSE, IncludeRelationships.NONE, "cmis:none", * Boolean.FALSE, null); info.setHasParent(parents.size() > 0); } * catch (CmisInvalidArgumentException e) { * info.setHasParent(false); } } */ } else { String objecTypeId = getIdProperty(object, PropertyIds.OBJECT_TYPE_ID); TypeDefinition typeDefinition = getTypeDefinition(repositoryId, objecTypeId, null); if (typeDefinition.isFileable()) { boolean unfiling = (repositoryInfo.getCapabilities().isUnfilingSupported() == null) ? false : repositoryInfo.getCapabilities().isUnfilingSupported(); if (unfiling) { List<ObjectParentData> parents = getObjectParents(repositoryId, object.getId(), null, Boolean.FALSE, IncludeRelationships.NONE, "cmis:none", Boolean.FALSE, null); info.setHasParent(parents != null && parents.size() >= 0); } else { info.setHasParent(true); } } else { info.setHasParent(false); } } // // Nemaki Cusomization END //// // policies and relationships info.setSupportsRelationships(false); info.setSupportsPolicies(false); TypeDefinitionList baseTypesList = getTypeChildren(repositoryId, null, Boolean.FALSE, BigInteger.valueOf(4), BigInteger.ZERO, null); for (TypeDefinition type : baseTypesList.getList()) { if (BaseTypeId.CMIS_RELATIONSHIP.value().equals(type.getId())) { info.setSupportsRelationships(true); } else if (BaseTypeId.CMIS_POLICY.value().equals(type.getId())) { info.setSupportsPolicies(true); } } // renditions info.setRenditionInfos(null); List<RenditionData> renditions = object.getRenditions(); if (renditions != null && renditions.size() > 0) { List<RenditionInfo> renditionInfos = new ArrayList<RenditionInfo>(); for (RenditionData rendition : renditions) { RenditionInfoImpl renditionInfo = new RenditionInfoImpl(); renditionInfo.setId(rendition.getStreamId()); renditionInfo.setKind(rendition.getKind()); renditionInfo.setContentType(rendition.getMimeType()); renditionInfo.setTitle(rendition.getTitle()); renditionInfo.setLength(rendition.getBigLength()); renditionInfos.add(renditionInfo); } info.setRenditionInfos(renditionInfos); } // relationships info.setRelationshipSourceIds(null); info.setRelationshipTargetIds(null); List<ObjectData> relationships = object.getRelationships(); if (relationships != null && relationships.size() > 0) { List<String> sourceIds = new ArrayList<String>(); List<String> targetIds = new ArrayList<String>(); for (ObjectData relationship : relationships) { String sourceId = getIdProperty(relationship, PropertyIds.SOURCE_ID); String targetId = getIdProperty(relationship, PropertyIds.TARGET_ID); if (object.getId().equals(sourceId)) { sourceIds.add(relationship.getId()); } if (object.getId().equals(targetId)) { targetIds.add(relationship.getId()); } } if (sourceIds.size() > 0) { info.setRelationshipSourceIds(sourceIds); } if (targetIds.size() > 0) { info.setRelationshipTargetIds(targetIds); } } // global settings info.setHasAcl(false); info.setSupportsDescendants(false); info.setSupportsFolderTree(false); RepositoryCapabilities capabilities = repositoryInfo.getCapabilities(); if (capabilities != null) { info.setHasAcl(capabilities.getAclCapability() == CapabilityAcl.DISCOVER || capabilities.getAclCapability() == CapabilityAcl.MANAGE); if (object.getBaseTypeId() == BaseTypeId.CMIS_FOLDER) { info.setSupportsDescendants(Boolean.TRUE.equals(capabilities.isGetDescendantsSupported())); info.setSupportsFolderTree(Boolean.TRUE.equals(capabilities.isGetFolderTreeSupported())); } } return info; } // --- Navigation Service Implementation --- /** * Gets the list of child objects contained in the specified folder. */ @Override public ObjectInFolderList getChildren(String repositoryId, String folderId, String filter, String orderBy, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegment, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) { Holder<ObjectData> parentObjectData = new Holder<ObjectData>(null); ObjectInFolderList children = navigationService.getChildren(getCallContext(), repositoryId, folderId, filter, orderBy, includeAllowableActions, null, null, includePathSegment, maxItems, skipCount, extension, parentObjectData); if (parentObjectData != null && parentObjectData.getValue() != null) { setObjectInfo(repositoryId, parentObjectData.getValue()); } if (children != null) { for (ObjectInFolderData o : children.getObjects()) { setObjectInfo(repositoryId, o.getObject()); } } return children; } /** * Gets the set of descendant objects contained in the specified folder or * any of its child folders. */ @Override public List<ObjectInFolderContainer> getDescendants(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegment, ExtensionsData extension) { Holder<ObjectData> anscestorObjectData = new Holder<ObjectData>(null); List<ObjectInFolderContainer> result = navigationService.getDescendants(getCallContext(), repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships, renditionFilter, includePathSegment, false, extension, anscestorObjectData); if (anscestorObjectData != null && anscestorObjectData.getValue() != null) { setObjectInfo(repositoryId, anscestorObjectData.getValue()); } setObjectInfoInTree(repositoryId, result); return result; } /** * Gets the set of descendant folder objects contained in the specified * folder. */ @Override public List<ObjectInFolderContainer> getFolderTree(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegment, ExtensionsData extension) { Holder<ObjectData> anscestorObjectData = new Holder<ObjectData>(null); List<ObjectInFolderContainer> result = navigationService.getDescendants(getCallContext(), repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships, renditionFilter, includePathSegment, true, extension, anscestorObjectData); if (anscestorObjectData != null && anscestorObjectData.getValue() != null) { setObjectInfo(repositoryId, anscestorObjectData.getValue()); } setObjectInfoInTree(repositoryId, result); return result; } /** * Gets the parent folder object for the specified folder object. */ @Override public ObjectData getFolderParent(String repositoryId, String folderId, String filter, ExtensionsData extension) { return navigationService.getFolderParent(getCallContext(), repositoryId, folderId, filter); } /** * Gets the parent folder(s) for the specified non-folder, fileable object. */ @Override public List<ObjectParentData> getObjectParents(String repositoryId, String objectId, String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, Boolean includeRelativePathSegment, ExtensionsData extension) { List<ObjectParentData> parents = navigationService.getObjectParents(getCallContext(), repositoryId, objectId, filter, includeAllowableActions, includeRelationships, renditionFilter, includeRelativePathSegment, extension); return parents; } /** * Gets the list of documents that are checked out that the user has access * to. No checkout for now, so empty. */ @Override public ObjectList getCheckedOutDocs(String repositoryId, String folderId, String filter, String orderBy, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) { return navigationService.getCheckedOutDocs(getCallContext(), repositoryId, folderId, filter, orderBy, includeAllowableActions, includeRelationships, renditionFilter, maxItems, skipCount, extension); } // ---- Object Service Implementation --- /** * Creates a new document, folder or policy. The property * "cmis:objectTypeId" defines the type and implicitly the base type. */ @Override public String create(String repositoryId, Properties properties, String folderId, ContentStream contentStream, VersioningState versioningState, List<String> policies, ExtensionsData extension) { ObjectData object = objectService.create(getCallContext(), repositoryId, properties, folderId, contentStream, versioningState, policies, extension); setObjectInfo(repositoryId, object); return object.getId(); } /** * Creates a document object of the specified type (given by the * cmis:objectTypeId property) in the (optionally) specified location. */ @Override public String createDocument(String repositoryId, Properties properties, String folderId, ContentStream contentStream, VersioningState versioningState, List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) { return objectService.createDocument(getCallContext(), repositoryId, properties, folderId, contentStream, versioningState, policies, addAces, removeAces); } /** * Creates a document object as a copy of the given source document in the * (optionally) specified location. */ @Override public String createDocumentFromSource(String repositoryId, String sourceId, Properties properties, String folderId, VersioningState versioningState, List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) { return objectService.createDocumentFromSource(getCallContext(), repositoryId, sourceId, properties, folderId, versioningState, policies, addAces, removeAces); } /** * Creates a folder object of the specified type (given by the * cmis:objectTypeId property) in the specified location. */ @Override public String createFolder(String repositoryId, Properties properties, String folderId, List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) { return objectService.createFolder(getCallContext(), repositoryId, properties, folderId, policies, addAces, removeAces, extension); } @Override public String createRelationship(String repositoryId, Properties properties, List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) { return objectService.createRelationship(getCallContext(), repositoryId, properties, policies, addAces, removeAces, extension); } @Override public String createPolicy(String repositoryId, Properties properties, String folderId, List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) { return objectService.createPolicy(getCallContext(), repositoryId, properties, folderId, policies, addAces, removeAces, extension); } /** * Deletes the content stream for the specified document object. */ @Override public void deleteContentStream(String repositoryId, Holder<String> objectId, Holder<String> changeToken, ExtensionsData extension) { objectService.deleteContentStream(getCallContext(), repositoryId, objectId, changeToken, extension); } /** * Deletes an object or cancels a check out. For the Web Services binding * this is always an object deletion. For the AtomPub it depends on the * referenced object. If it is a checked out document then the check out * must be canceled. If the object is not a checked out document then the * object must be deleted. */ @Override public void deleteObjectOrCancelCheckOut(String repositoryId, String objectId, Boolean allVersions, ExtensionsData extension) { // TODO When checkOut implemented, implement switching the two methods ObjectData o = getObject(repositoryId, objectId, null, false, IncludeRelationships.NONE, null, null, null, null); PropertyData<?> isPWC = o.getProperties().getProperties().get(PropertyIds.IS_PRIVATE_WORKING_COPY); if (isPWC != null && isPWC.getFirstValue().equals(true)) { versioningService.cancelCheckOut(getCallContext(), repositoryId, objectId, null); } else { objectService.deleteObject(getCallContext(), repositoryId, objectId, allVersions); } } /** * Deletes the specified folder object and all of its child- and * descendant-objects. */ @Override public FailedToDeleteData deleteTree(String repositoryId, String folderId, Boolean allVersions, UnfileObject unfileObjects, Boolean continueOnFailure, ExtensionsData extension) { return objectService.deleteTree(getCallContext(), repositoryId, folderId, allVersions, unfileObjects, continueOnFailure, extension); } /** * Gets the list of allowable actions for an object. */ @Override public AllowableActions getAllowableActions(String repositoryId, String objectId, ExtensionsData extension) { return objectService.getAllowableActions(getCallContext(), repositoryId, objectId); } /** * Gets the content stream for the specified document object, or gets a * rendition stream for a specified rendition of a document or folder * object. */ @Override public ContentStream getContentStream(String repositoryId, String objectId, String streamId, BigInteger offset, BigInteger length, ExtensionsData extension) { return objectService.getContentStream(getCallContext(), repositoryId, objectId, streamId, offset, length); } /** * Gets the specified information for the object specified by id. */ @Override public ObjectData getObject(String repositoryId, String objectId, String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds, Boolean includeAcl, ExtensionsData extension) { ObjectData objectData = objectService.getObject(getCallContext(), repositoryId, objectId, filter, includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds, includeAcl, extension); setObjectInfo(repositoryId, objectData); return objectData; } /** * Gets the specified information for the object specified by path. */ @Override public ObjectData getObjectByPath(String repositoryId, String path, String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds, Boolean includeAcl, ExtensionsData extension) { ObjectData objectData = objectService.getObjectByPath(getCallContext(), repositoryId, path, filter, includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds, includeAcl, extension); setObjectInfo(repositoryId, objectData); return objectData; } /** * Gets the list of properties for an object. */ @Override public Properties getProperties(String repositoryId, String objectId, String filter, ExtensionsData extension) { ObjectData object = objectService.getObject(getCallContext(), repositoryId, objectId, filter, false, IncludeRelationships.NONE, null, false, false, extension); return object.getProperties(); } /** * Gets the list of associated renditions for the specified object. Only * rendition attributes are returned, not rendition stream. No renditions, * so empty. */ @Override public List<RenditionData> getRenditions(String repositoryId, String objectId, String renditionFilter, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) { return objectService.getRenditions(getCallContext(), repositoryId, objectId, renditionFilter, maxItems, skipCount, extension); } /** * Moves the specified file-able object from one folder to another. */ @Override public void moveObject(String repositoryId, Holder<String> objectId, String targetFolderId, String sourceFolderId, ExtensionsData extension) { // TODO Implement permission check here // PermissionMapping.CAN_GET_PROPERTIES_OBJECT objectService.moveObject(getCallContext(), repositoryId, objectId, sourceFolderId, targetFolderId); } /** * Sets the content stream for the specified document object. */ @Override public void setContentStream(String repositoryId, Holder<String> objectId, Boolean overwriteFlag, Holder<String> changeToken, ContentStream contentStream, ExtensionsData extension) { objectService.setContentStream(getCallContext(), repositoryId, objectId, overwriteFlag, contentStream, changeToken); } /** * Updates properties of the specified object. */ @Override public void updateProperties(String repositoryId, Holder<String> objectId, Holder<String> changeToken, Properties properties, ExtensionsData extension) { objectService.updateProperties(getCallContext(), repositoryId, objectId, properties, changeToken); } // --- Versioning Service Implementation --- @Override public void checkOut(String repositoryId, Holder<String> objectId, ExtensionsData extension, Holder<Boolean> contentCopied) { versioningService.checkOut(getCallContext(), repositoryId, objectId, extension, contentCopied); } @Override public void cancelCheckOut(String repositoryId, String objectId, ExtensionsData extension) { versioningService.cancelCheckOut(getCallContext(), repositoryId, objectId, extension); } @Override public void checkIn(String repositoryId, Holder<String> objectId, Boolean major, Properties properties, ContentStream contentStream, String checkinComment, List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) { versioningService.checkIn(getCallContext(), repositoryId, objectId, major, properties, contentStream, checkinComment, policies, addAces, removeAces, extension); } /** * Returns the list of all document objects in the specified version series, * sorted by the property "cmis:creationDate" descending. */ @Override public List<ObjectData> getAllVersions(String repositoryId, String objectId, String versionSeriesId, String filter, Boolean includeAllowableActions, ExtensionsData extension) { List<ObjectData> result = versioningService.getAllVersions(getCallContext(), repositoryId, objectId, versionSeriesId, filter, includeAllowableActions, extension); if (CollectionUtils.isNotEmpty(result)) { for (ObjectData o : result) { setObjectInfo(repositoryId, o); } } return result; } /** * Get the latest document object in the version series. */ @Override public ObjectData getObjectOfLatestVersion(String repositoryId, String objectId, String versionSeriesId, Boolean major, String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds, Boolean includeAcl, ExtensionsData extension) { return versioningService.getObjectOfLatestVersion(context, repositoryId, objectId, versionSeriesId, major, filter, includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds, includeAcl, extension); } /** * Get a subset of the properties for the latest document object in the * version series. */ @Override public Properties getPropertiesOfLatestVersion(String repositoryId, String objectId, String versionSeriesId, Boolean major, String filter, ExtensionsData extension) { ObjectData object = getObjectOfLatestVersion(repositoryId, objectId, versionSeriesId, major, filter, false, IncludeRelationships.NONE, null, false, false, extension); return object.getProperties(); } // --- ACL Service Implementation --- /** * Applies a new ACL (Access Control List) to an object. Since it is not * possible to transmit an "add ACL" and a "remove ACL" via AtomPub, the * merging has to be done on the client side. The ACEs provided here is * supposed to the new complete ACL. */ @Override public Acl applyAcl(String repositoryId, String objectId, Acl aces, AclPropagation aclPropagation) { return aclService.applyAcl(getCallContext(), repositoryId, objectId, aces, aclPropagation); } /** * Get the ACL (Access Control List) currently applied to the specified * object. */ @Override public Acl getAcl(String repositoryId, String objectId, Boolean onlyBasicPermissions, ExtensionsData extension) { return aclService.getAcl(getCallContext(), repositoryId, objectId, onlyBasicPermissions); } // --- Repository Service Implementation --- /** * Returns information about the CMIS repository, the optional capabilities * it supports and its access control information. */ @Override public RepositoryInfo getRepositoryInfo(String repositoryId, ExtensionsData extension) { RepositoryInfo info = repositoryService.getRepositoryInfo(repositoryId); if (info == null) { throw new CmisObjectNotFoundException("Unknown repository '" + repositoryId + "'!"); } else { return info; } } /** * Returns a list of CMIS repository information available from this CMIS * service endpoint. In contrast to the CMIS specification this method * returns repository infos not only repository ids. (See OpenCMIS doc) */ @Override public List<RepositoryInfo> getRepositoryInfos(ExtensionsData arg0) { return repositoryService.getRepositoryInfos(); } /** * Returns the list of object types defined for the repository that are * children of the specified type. */ @Override public TypeDefinitionList getTypeChildren(String repositoryId, String typeId, Boolean includePropertyDefinitions, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) { return repositoryService.getTypeChildren(getCallContext(), repositoryId, typeId, includePropertyDefinitions, maxItems, skipCount); } /** * Gets the definition of the specified object type. */ @Override public TypeDefinition getTypeDefinition(String repositoryId, String typeId, ExtensionsData extension) { return repositoryService.getTypeDefinition(getCallContext(), repositoryId, typeId); } /** * Returns the set of descendant object type defined for the repository * under the specified type. */ @Override public List<TypeDefinitionContainer> getTypeDescendants(String repositoryId, String typeId, BigInteger depth, Boolean includePropertyDefinitions, ExtensionsData extension) { return repositoryService.getTypeDescendants(getCallContext(), repositoryId, typeId, depth, includePropertyDefinitions); } // --- Discovery Service Implementation --- /** * Executes a CMIS query statement against the contents of the repository. */ @Override public ObjectList query(String repositoryId, String statement, Boolean searchAllVersions, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) { return discoveryService.query(getCallContext(), repositoryId, statement, searchAllVersions, includeAllowableActions, includeRelationships, renditionFilter, maxItems, skipCount, extension); } @Override public ObjectList getContentChanges(String repositoryId, Holder<String> changeLogToken, Boolean includeProperties, String filter, Boolean includePolicyIds, Boolean includeAcl, BigInteger maxItems, ExtensionsData extension) { return discoveryService.getContentChanges(getCallContext(), repositoryId, changeLogToken, includeProperties, filter, includePolicyIds, includeAcl, maxItems, extension); } // --- Relationship Service Implementation --- @Override public ObjectList getObjectRelationships(String repositoryId, String objectId, Boolean includeSubRelationshipTypes, RelationshipDirection relationshipDirection, String typeId, String filter, Boolean includeAllowableActions, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) { return relationshipService.getObjectRelationships(getCallContext(), repositoryId, objectId, includeSubRelationshipTypes, relationshipDirection, typeId, filter, includeAllowableActions, maxItems, skipCount, extension); } // --- Policy Service Implementation --- @Override public void applyPolicy(String repositoryId, String policyId, String objectId, ExtensionsData extension) { policyService.applyPolicy(getCallContext(), repositoryId, policyId, objectId, extension); } @Override public void removePolicy(String repositoryId, String policyId, String objectId, ExtensionsData extension) { policyService.removePolicy(getCallContext(), repositoryId, policyId, objectId, extension); } @Override public List<ObjectData> getAppliedPolicies(String repositoryId, String objectId, String filter, ExtensionsData extension) { return policyService.getAppliedPolicies(getCallContext(), repositoryId, objectId, filter, extension); } // --- Multi-filing Service Implementation --- @Override public void addObjectToFolder(String repositoryId, String objectId, String folderId, Boolean allVersions, ExtensionsData extension) { // TODO Auto-generated method stub super.addObjectToFolder(repositoryId, objectId, folderId, allVersions, extension); } @Override public void removeObjectFromFolder(String repositoryId, String objectId, String folderId, ExtensionsData extension) { // TODO Auto-generated method stub super.removeObjectFromFolder(repositoryId, objectId, folderId, extension); } @Override public void appendContentStream(String repositoryId, Holder<String> objectId, Holder<String> changeToken, ContentStream contentStream, boolean isLastChunk, ExtensionsData extension) { objectService.appendContentStream(getCallContext(), repositoryId, objectId, changeToken, contentStream, isLastChunk, extension); ; } @Override public List<BulkUpdateObjectIdAndChangeToken> bulkUpdateProperties(String repositoryId, List<BulkUpdateObjectIdAndChangeToken> objectIdAndChangeToken, Properties properties, List<String> addSecondaryTypeIds, List<String> removeSecondaryTypeIds, ExtensionsData extension) { return objectService.bulkUpdateProperties(getCallContext(), repositoryId, objectIdAndChangeToken, properties, addSecondaryTypeIds, removeSecondaryTypeIds, extension); } @Override public String createItem(String repositoryId, Properties properties, String folderId, List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) { return objectService.createItem(getCallContext(), repositoryId, properties, folderId, policies, addAces, removeAces, extension); } @Override public TypeDefinition createType(String repositoryId, TypeDefinition type, ExtensionsData extension) { return repositoryService.createType(getCallContext(), repositoryId, type, extension); } @Override public void deleteType(String repositoryId, String typeId, ExtensionsData extension) { repositoryService.deleteType(getCallContext(), repositoryId, typeId, extension); } @Override public TypeDefinition updateType(String repositoryId, TypeDefinition type, ExtensionsData extension) { return repositoryService.updateType(getCallContext(), repositoryId, type, extension); } /* * Setters/Getters */ public void setCallContext(CallContext context) { this.context = context; if (log.isTraceEnabled()) { log.trace("nemaki_log[FACTORY]" + "CmisService@" + this.hashCode() + " with CallContext@" + this.context.hashCode() + "[repositoryId=" + context.getRepositoryId() + ", userId=" + context.getUsername() + "] has benn changed to CallContext@" + context.hashCode() + "[repositoryId=" + context.getRepositoryId() + ", userId=" + context.getUsername() + "]"); } } public CallContext getCallContext() { return context; } public void setAclService(AclService aclService) { this.aclService = aclService; } public void setDiscoveryService(DiscoveryService discoveryService) { this.discoveryService = discoveryService; } public void setNavigationService(NavigationService navigationService) { this.navigationService = navigationService; } public void setObjectService(ObjectService objectService) { this.objectService = objectService; } public void setRepositoryService(RepositoryService repositoryService) { this.repositoryService = repositoryService; } public void setVersioningService(VersioningService versioningService) { this.versioningService = versioningService; } public void setPolicyService(PolicyService policyService) { this.policyService = policyService; } public void setRelationshipService(RelationshipService relationshipService) { this.relationshipService = relationshipService; } @Override public void close() { if (log.isTraceEnabled()) { log.trace("nemaki_log[FACTORY]" + "CmisService@" + this.hashCode() + " with CallContext@" + context.hashCode() + "[repositoryId=" + context.getRepositoryId() + ", userId=" + context.getUsername() + "] is closed"); } super.close(); } }