You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by je...@apache.org on 2010/04/16 16:00:25 UTC
svn commit: r934878 [4/13] - in
/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src:
main/java/org/apache/chemistry/opencmis/inmemory/
main/java/org/apache/chemistry/opencmis/inmemory/clientprovider/ mai...
Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java?rev=934878&r1=934877&r2=934878&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java Fri Apr 16 14:00:23 2010
@@ -75,932 +75,906 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class InMemoryObjectServiceImpl extends AbstractServiceImpl implements CmisObjectService {
- private static final Log LOG = LogFactory.getLog(ServiceFactory.class.getName());
+ private static final Log LOG = LogFactory.getLog(ServiceFactory.class.getName());
- AtomLinkInfoProvider fAtomLinkProvider;
+ AtomLinkInfoProvider fAtomLinkProvider;
- public InMemoryObjectServiceImpl(StoreManager storeManager) {
- super(storeManager);
- fAtomLinkProvider = new AtomLinkInfoProvider(fStoreManager);
- }
-
- public String createDocument(CallContext context, String repositoryId, Properties properties,
- String folderId, ContentStream contentStream, VersioningState versioningState,
- List<String> policies, Acl addAces, Acl removeAces,
- ExtensionsData extension) {
-
- try {
- LOG.debug("start createDocument()");
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- StoredObject so = createDocumentIntern(repositoryId, properties, folderId, contentStream,
- versioningState, policies, addAces, removeAces, extension);
- LOG.debug("stop createDocument()");
- return so.getId();
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public String createDocumentFromSource(CallContext context, String repositoryId, String sourceId,
- Properties properties, String folderId, VersioningState versioningState,
- List<String> policies, Acl addAces, Acl removeAces,
- ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- LOG.debug("start createDocumentFromSource()");
-
- StoredObject so = checkStandardParameters(repositoryId, sourceId);
-
- ContentStream content = getContentStream(context, repositoryId, sourceId, null,
- BigInteger.valueOf(-1), BigInteger.valueOf(-1), null);
-
- if (so == null)
- throw new CmisObjectNotFoundException("Unknown object id: " + sourceId);
-
- // build properties collection
- List<String> requestedIds = FilterParser.getRequestedIdsFromFilter("*");
-
- Properties existingProps = PropertyCreationHelper.getPropertiesFromObject(repositoryId,
- so, fStoreManager, requestedIds);
-
- PropertiesImpl newPD = new PropertiesImpl();
- // copy all existing properties
- for (PropertyData<?> prop : existingProps.getProperties().values()) {
- newPD.addProperty(prop);
- }
- // overwrite all new properties
- for (PropertyData<?> prop : properties.getProperties().values()) {
- newPD.addProperty(prop);
- }
-
- String res = createDocument(context, repositoryId, newPD, folderId, content, versioningState,
- policies, addAces, removeAces, null);
- LOG.debug("stop createDocumentFromSource()");
- return res;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public String createFolder(CallContext context, String repositoryId, Properties properties,
- String folderId, List<String> policies, Acl addAces,
- Acl removeAces, ExtensionsData extension) {
- try {
- LOG.debug("start createFolder()");
- RuntimeContext.attachCfg(context);
-
- Folder folder = createFolderIntern(repositoryId, properties, folderId, policies, addAces,
- removeAces, extension);
- LOG.debug("stop createFolder()");
- return folder.getId();
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public String createPolicy(CallContext context, String repositoryId, Properties properties,
- String folderId, List<String> policies, Acl addAces,
- Acl removeAces, ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- // TODO to be completed if ACLs are implemented
- LOG.debug("start createPolicy()");
- checkStandardParameters(repositoryId, folderId);
- StoredObject so = createPolicyIntern(repositoryId, properties, folderId, policies, addAces,
- removeAces, extension);
- LOG.debug("stop createPolicy()");
- return so == null ? null : so.getId();
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public String createRelationship(CallContext context, String repositoryId,
- Properties properties, List<String> policies, Acl addAces,
- Acl removeAces, ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- // TODO to be completed if relationships are implemented
- LOG.debug("start createRelationship()");
- checkRepositoryId(repositoryId);
- StoredObject so = createRelationshipIntern(repositoryId, properties, policies, addAces,
- removeAces, extension);
- LOG.debug("stop createRelationship()");
- return so == null ? null : so.getId();
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.opencmis.server.spi.CmisObjectService#create(org.opencmis.server.spi.CallContext,
- * java.lang.String, org.opencmis.client.provider.PropertiesData, java.lang.String,
- * org.opencmis.client.provider.ContentStreamData, org.opencmis.commons.enums.VersioningState,
- * org.opencmis.client.provider.ExtensionsData, org.opencmis.server.spi.ObjectInfoHolder)
- *
- * An additional create call compared to the ObjectService from the CMIS spec. This one is needed
- * because the Atom binding in the server implementation does not know what kind of object needs
- * to be created. Also the ObjectInfoHolder needs to be filled.
- */
- @SuppressWarnings("unchecked")
- public ObjectData create(CallContext context, String repositoryId, Properties properties,
- String folderId, ContentStream contentStream, VersioningState versioningState,
- List<String> policies, ExtensionsData extension, ObjectInfoHolder objectInfos) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- if (null == properties || null == properties.getProperties())
- throw new RuntimeException("Cannot create object, without properties.");
-
- // Find out what kind of object needs to be created
- PropertyData<String> pd = (PropertyData<String>) properties.getProperties().get(
- PropertyIds.OBJECT_TYPE_ID);
- String typeId = pd == null ? null : pd.getFirstValue();
- if (null == typeId)
- throw new RuntimeException(
- "Cannot create object, without a type (no property with id CMIS_OBJECT_TYPE_ID).");
-
- TypeDefinitionContainer typeDefC = fStoreManager.getTypeById(repositoryId, typeId);
- if (typeDefC == null)
- throw new RuntimeException("Cannot create object, a type with id " + typeId + " is unknown");
-
- // check if the given type is a document type
- BaseTypeId typeBaseId = typeDefC.getTypeDefinition().getBaseTypeId();
- StoredObject so = null;
- if (typeBaseId.equals(InMemoryDocumentTypeDefinition.getRootDocumentType().getBaseTypeId())) {
- so = createDocumentIntern(repositoryId, properties, folderId, contentStream,
- versioningState, null, null, null, null);
- }
- else if (typeBaseId.equals(InMemoryFolderTypeDefinition.getRootFolderType().getBaseTypeId())) {
- so = createFolderIntern(repositoryId, properties, folderId, null, null, null, null);
- }
- else if (typeBaseId.equals(InMemoryPolicyTypeDefinition.getRootPolicyType().getBaseTypeId())) {
- so = createPolicyIntern(repositoryId, properties, folderId, null, null, null, null);
- }
- else if (typeBaseId.equals(InMemoryRelationshipTypeDefinition.getRootRelationshipType()
- .getBaseTypeId())) {
- so = createRelationshipIntern(repositoryId, properties, null, null, null, null);
- }
- else
- LOG.error("The type contains an unknown base object id, object can't be created");
-
- // Make a call to getObject to convert the resulting id into an ObjectData
- ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
- IncludeRelationships.NONE, null, false, false, extension);
-
- fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
- return od;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public void deleteContentStream(CallContext context, String repositoryId,
- Holder<String> objectId, Holder<String> changeToken, ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- LOG.debug("start deleteContentStream()");
- StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
-
- if (so == null)
- throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
-
- if (!(so instanceof Content))
- throw new CmisObjectNotFoundException("Id" + objectId
- + " does not refer to a document, but only documents can have content");
-
- ((Content) so).setContent(null, true);
- LOG.debug("stop deleteContentStream()");
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public void deleteObjectOrCancelCheckOut(CallContext context, String repositoryId,
- String objectId, Boolean allVersions, ExtensionsData extension) {
-
- try {
- LOG.debug("start deleteObject()");
- checkStandardParameters(repositoryId, objectId);
- ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
- LOG.info("delete object for id: " + objectId);
-
- // check if it is the root folder
- if (objectId.equals(objectStore.getRootFolder().getId()))
- throw new CmisNotSupportedException("You can't delete a root folder");
-
- objectStore.deleteObject(objectId);
- LOG.debug("stop deleteObject()");
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public FailedToDeleteData deleteTree(CallContext context, String repositoryId, String folderId,
- Boolean allVersions, UnfileObject unfileObjects, Boolean continueOnFailure,
- ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- LOG.debug("start deleteTree()");
- StoredObject so = checkStandardParameters(repositoryId, folderId);
- List<String> failedToDeleteIds = new ArrayList<String>();
- FailedToDeleteDataImpl result = new FailedToDeleteDataImpl();
-
- if (null == allVersions)
- allVersions = true;
- if (null == unfileObjects)
- unfileObjects = UnfileObject.DELETE;
- if (null == continueOnFailure)
- continueOnFailure = false;
-
- ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
-
- if (null == so)
- throw new RuntimeException("Cannot delete object with id " + folderId
- + ". Object does not exist.");
-
- if (!(so instanceof Folder))
- throw new RuntimeException("deleteTree can only be invoked on a folder, but id " + folderId
- + " does not refer to a folder");
-
- if (unfileObjects == UnfileObject.UNFILE)
- throw new CmisNotSupportedException("This repository does not support unfile operations.");
-
- // check if it is the root folder
- if (folderId.equals(objectStore.getRootFolder().getId()))
- throw new CmisNotSupportedException("You can't delete a root folder");
-
- // recursively delete folder
- deleteRecursive(objectStore, (Folder) so, continueOnFailure, allVersions, failedToDeleteIds);
-
- result.setIds(failedToDeleteIds);
- LOG.debug("stop deleteTree()");
- return result;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public AllowableActions getAllowableActions(CallContext context, String repositoryId,
- String objectId, ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- LOG.debug("start getAllowableActions()");
- StoredObject so = checkStandardParameters(repositoryId, objectId);
- ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
-
- if (so == null)
- throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
-
- AllowableActions allowableActions = DataObjectCreator.fillAllowableActions(objectStore,
- so);
- LOG.debug("stop getAllowableActions()");
- return allowableActions;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public ContentStream getContentStream(CallContext context, String repositoryId,
- String objectId, String streamId, BigInteger offset, BigInteger length,
- ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- LOG.debug("start getContentStream()");
- StoredObject so = checkStandardParameters(repositoryId, objectId);
-
- if (so == null)
- throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
-
- if (!(so instanceof Content))
- throw new CmisObjectNotFoundException("Id" + objectId
- + " does not refer to a document or version, but only those can have content");
-
- ContentStream csd = getContentStream(so, streamId, offset, length);
- LOG.debug("stop getContentStream()");
- return csd;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public ObjectData getObject(CallContext context, String repositoryId, String objectId,
- String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
- String renditionFilter, Boolean includePolicyIds, Boolean includeAcl,
- ExtensionsData extension, ObjectInfoHolder objectInfos) {
-
- try {
- LOG.debug("start getObject()");
-
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- StoredObject so = checkStandardParameters(repositoryId, objectId);
-
- if (so == null)
- throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
-
- ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, filter,
- includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds,
- includeAcl, extension);
-
- fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
-
- LOG.debug("stop getObject()");
-
- return od;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public ObjectData getObjectByPath(CallContext context, String repositoryId, String path,
- String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
- String renditionFilter, Boolean includePolicyIds, Boolean includeAcl,
- ExtensionsData extension, ObjectInfoHolder objectInfos) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- LOG.debug("start getObjectByPath()");
- checkRepositoryId(repositoryId);
- ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
- StoredObject so = objectStore.getObjectByPath(path);
-
- if (so == null)
- throw new CmisObjectNotFoundException("Unknown path: " + path);
-
- ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, filter,
- includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds,
- includeAcl, extension);
-
- LOG.debug("stop getObjectByPath()");
-
- // To be able to provide all Atom links in the response we need additional information:
- fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
-
- return od;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public Properties getProperties(CallContext context, String repositoryId, String objectId,
- String filter, ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- LOG.debug("start getProperties()");
- StoredObject so = checkStandardParameters(repositoryId, objectId);
-
- if (so == null)
- throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
-
- // build properties collection
- List<String> requestedIds = FilterParser.getRequestedIdsFromFilter(filter);
- Properties props = PropertyCreationHelper.getPropertiesFromObject(repositoryId, so,
- fStoreManager, requestedIds);
- LOG.debug("stop getProperties()");
- return props;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public List<RenditionData> getRenditions(CallContext context, String repositoryId,
- String objectId, String renditionFilter, BigInteger maxItems, BigInteger skipCount,
- ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- // TODO to be completed if renditions are implemented
- LOG.debug("start getRenditions()");
- checkStandardParameters(repositoryId, objectId);
- LOG.debug("stop getRenditions()");
- return null;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public ObjectData moveObject(CallContext context, String repositoryId, Holder<String> objectId,
- String targetFolderId, String sourceFolderId, ExtensionsData extension,
- ObjectInfoHolder objectInfos) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- LOG.debug("start moveObject()");
- StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
- Folder targetFolder = null;
- Folder sourceFolder = null;
- ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
- Filing spo = null;
-
- if (null == so)
- throw new CmisObjectNotFoundException("Unknown object: " + objectId.getValue());
- else if (so instanceof Filing)
- spo = (Filing) so;
- else
- throw new CmisInvalidArgumentException("Object must be folder or document: "
- + objectId.getValue());
-
- StoredObject soTarget = objectStore.getObjectById(targetFolderId);
- if (null == soTarget)
- throw new CmisObjectNotFoundException("Unknown target folder: " + targetFolderId);
- else if (soTarget instanceof Folder)
- targetFolder = (Folder) soTarget;
- else
- throw new CmisNotSupportedException("Destination " + targetFolderId
- + " of a move operation must be a folder");
-
- StoredObject soSource = objectStore.getObjectById(sourceFolderId);
- if (null == soSource)
- throw new CmisObjectNotFoundException("Unknown source folder: " + sourceFolderId);
- else if (soSource instanceof Folder)
- sourceFolder = (Folder) soSource;
- else
- throw new CmisNotSupportedException("Source " + sourceFolderId
- + " of a move operation must be a folder");
-
- boolean foundOldParent = false;
- for (Folder parent : spo.getParents()) {
- if (parent.getId().equals(soSource.getId())) {
- foundOldParent = true;
- break;
- }
- }
- if (!foundOldParent)
- throw new CmisNotSupportedException("Cannot move object, source folder " + sourceFolderId
- + "is not a parent of object " + objectId.getValue());
-
- if (so instanceof Folder && hasDescendant((Folder) so, targetFolder)) {
- throw new CmisNotSupportedException(
- "Destination of a move cannot be a subfolder of the source");
- }
-
- spo.move(sourceFolder, targetFolder);
- objectId.setValue(so.getId());
- LOG.debug("stop moveObject()");
-
- // To be able to provide all Atom links in the response we need additional information:
- fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
-
- ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
- IncludeRelationships.NONE, null, false, false, extension);
-
- return od;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public void setContentStream(CallContext context, String repositoryId, Holder<String> objectId,
- Boolean overwriteFlag, Holder<String> changeToken, ContentStream contentStream,
- ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- LOG.debug("start setContentStream()");
- checkStandardParameters(repositoryId, objectId.getValue());
-
- ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
- StoredObject so = folderStore.getObjectById(objectId.getValue());
- Content content;
-
- if (!(so instanceof Document || so instanceof VersionedDocument || so instanceof DocumentVersion))
- throw new CmisObjectNotFoundException("Id" + objectId
- + " does not refer to a document, but only documents can have content");
-
- if (so instanceof Document)
- content = ((Document) so);
- else if (so instanceof DocumentVersion) {
- // something that is versionable check the proper status of the object
- String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
- testHasProperCheckedOutStatus(so, user);
- content = (DocumentVersion) so;
- }
- else
- throw new IllegalArgumentException(
- "Content cannot be set on this object (must be document or version)");
-
- if (!overwriteFlag && content.getContent(0, -1) != null)
- throw new CmisConstraintException(
- "cannot overwrite existing content if overwrite flag is not set");
-
- content.setContent(contentStream, true);
- LOG.debug("stop setContentStream()");
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public ObjectData updateProperties(CallContext context, String repositoryId,
- Holder<String> objectId, Holder<String> changeToken, Properties properties,
- Acl acl, ExtensionsData extension, ObjectInfoHolder objectInfos) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- LOG.debug("start updateProperties()");
- StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
-
- // Validation
- TypeDefinition typeDef = getTypeDefinition(repositoryId, so);
- boolean isCheckedOut = false;
-
- // if the object is a versionable object it must be checked-out
- if (so instanceof VersionedDocument || so instanceof DocumentVersion) {
- String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
- // VersionedDocument verDoc = testIsNotCheckedOutBySomeoneElse(so, user);
- testHasProperCheckedOutStatus(so, user);
- isCheckedOut = true;
- }
-
- Map<String, PropertyData<?>> oldProperties = so.getProperties();
-
- // check properties for validity
- TypeValidator.validateProperties(typeDef, properties, false);
-
- if (changeToken != null && changeToken.getValue() != null
- && Long.valueOf(so.getChangeToken()) > Long.valueOf(changeToken.getValue()))
- throw new CmisUpdateConflictException(" updateProperties failed: outdated changeToken");
-
- // update properties
- boolean hasUpdatedName = false;
- boolean hasUpdatedOtherProps = false;
-
- for (String key : properties.getProperties().keySet()) {
- if (key.equals(PropertyIds.NAME))
- continue; // ignore here
-
- PropertyData<?> value = properties.getProperties().get(key);
- PropertyDefinition<?> propDef = typeDef.getPropertyDefinitions().get(key);
- if (value.getValues() == null || value.getFirstValue() == null) {
- // delete property
- // check if a required a property
- if (propDef.isRequired())
- throw new CmisConstraintException(
- "updateProperties failed, following property can't be deleted, because it is required: "
- + key);
- oldProperties.remove(key);
- hasUpdatedOtherProps = true;
- }
- else {
- if (propDef.getUpdatability().equals(Updatability.WHENCHECKEDOUT) && !isCheckedOut)
- throw new CmisConstraintException(
- "updateProperties failed, following property can't be updated, because it is not checked-out: "
- + key);
- else if (!propDef.getUpdatability().equals(Updatability.READWRITE))
- throw new CmisConstraintException(
- "updateProperties failed, following property can't be updated, because it is not writable: "
- + key);
- oldProperties.put(key, value);
- hasUpdatedOtherProps = true;
- }
- }
-
- // get name from properties and perform special rename to check if path
- // already exists
- PropertyData<?> pd = properties.getProperties().get(PropertyIds.NAME);
- if (pd != null && so instanceof Filing) {
- String newName = (String) pd.getFirstValue();
- List<Folder> parents = ((Filing) so).getParents();
- if (so instanceof Folder && parents.isEmpty())
- throw new CmisConstraintException(
- "updateProperties failed, you cannot rename the root folder");
- for (Folder parent : parents) {
- if (parent.hasChild(newName))
- throw new CmisConstraintException(
- "updateProperties failed, cannot rename because path already exists.");
- }
- so.rename((String) pd.getFirstValue()); // note: this does persist
- hasUpdatedName = true;
- }
-
- if (hasUpdatedOtherProps) {
- // set user, creation date, etc.
- String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
-
- if (user == null)
- user = "unknown";
- so.updateSystemBasePropertiesWhenModified(properties.getProperties(), user);
- // set changeToken
- so.persist();
- }
-
- if (hasUpdatedName || hasUpdatedOtherProps) {
- objectId.setValue(so.getId()); // might have a new id
- if (null != changeToken) {
- String changeTokenVal = so.getChangeToken();
- LOG.info("updateProperties(), new change token is: " + changeTokenVal);
- changeToken.setValue(changeTokenVal);
- }
- }
-
- if (null != acl) {
- LOG.warn("Setting ACLs is currently not supported by this implementation, acl is ignored");
- // if implemented add this call:
- // fAclService.appyAcl(context, repositoryId, acl, null, AclPropagation.OBJECTONLY,
- // extension);
- }
-
- // To be able to provide all Atom links in the response we need additional information:
- fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
-
- ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
- IncludeRelationships.NONE, null, false, false, extension);
-
- LOG.debug("stop updateProperties()");
-
- return od;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- // ///////////////////////////////////////////////////////
- // private helper methods
-
- private StoredObject createDocumentIntern(String repositoryId, Properties properties,
- String folderId, ContentStream contentStream, VersioningState versioningState,
- List<String> policies, Acl addACEs, Acl removeACEs,
- ExtensionsData extension) {
- checkRepositoryId(repositoryId);
-
- ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
-
- // get name from properties
- PropertyData<?> pd = properties.getProperties().get(PropertyIds.NAME);
- String name = (String) pd.getFirstValue();
-
- // Validation stuff
- TypeValidator.validateRequiredSystemProperties(properties);
- TypeDefinition typeDef = getTypeDefinition(repositoryId, properties);
-
- Folder folder = null;
- if (null != folderId) {
- StoredObject so = objectStore.getObjectById(folderId);
-
- if (null == so)
- throw new CmisInvalidArgumentException(" Cannot create document, folderId: " + folderId
- + " is invalid");
-
- if (so instanceof Folder)
- folder = (Folder) so;
- else
- throw new CmisInvalidArgumentException(
- "Can't creat document, folderId does not refer to a folder: " + folderId);
-
- TypeValidator.validateAllowedChildObjectTypes(typeDef, folder.getAllowedChildObjectTypeIds());
- }
-
- // check if the given type is a document type
- if (!typeDef.getBaseTypeId().equals(BaseTypeId.CMIS_DOCUMENT))
- throw new RuntimeException("Cannot create a document, with a non-document type: "
- + typeDef.getId());
-
- // check name syntax
- if (!NameValidator.isValidId(name))
- throw new CmisInvalidArgumentException(NameValidator.ERROR_ILLEGAL_NAME);
-
- TypeValidator.validateVersionStateForCreate((DocumentTypeDefinition) typeDef, versioningState);
- TypeValidator.validateProperties(typeDef, properties, true);
-
- // set user, creation date, etc.
- String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
- if (user == null)
- user = "unknown";
-
- StoredObject so = null;
-
- // Now we are sure to have document type definition:
- if (((DocumentTypeDefinition) typeDef).isVersionable()) {
- VersionedDocument verDoc = fStoreManager.getObjectStore(repositoryId)
- .createVersionedDocument(name);
- verDoc.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
- verDoc.setCustomProperties(properties.getProperties());
- DocumentVersion version = verDoc.addVersion(contentStream, versioningState, user);
- if (null != folder)
- folder.addChildDocument(verDoc); // add document to folder and set parent in doc
- else
- verDoc.persist();
- version.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
- version.setCustomProperties(properties.getProperties());
- version.persist();
- so = version; // return the version and not the version series to caller
- }
- else {
- Document doc = fStoreManager.getObjectStore(repositoryId).createDocument(name);
- doc.setContent(contentStream, false);
- // add document to folder
- doc.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
- doc.setCustomProperties(properties.getProperties());
- if (null != folder)
- folder.addChildDocument(doc); // add document to folder and set parent in doc
- else
- doc.persist();
- so = doc;
- }
-
- // policies, addACEs, removeACEs, extension are ignored for
- // now.
- return so;
- }
-
- private Folder createFolderIntern(String repositoryId, Properties properties,
- String folderId, List<String> policies, Acl addAces,
- Acl removeAces, ExtensionsData extension) {
-
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- checkStandardParameters(repositoryId, folderId);
-
- ObjectStore fs = fStoreManager.getObjectStore(repositoryId);
- StoredObject so = null;
- Folder parent = null;
-
- // get required properties
- PropertyData<?> pd = properties.getProperties().get(PropertyIds.NAME);
- String folderName = (String) pd.getFirstValue();
- if (null == folderName || folderName.length() == 0)
- throw new CmisInvalidArgumentException("Cannot create a folder without a name.");
-
- // check name syntax
- if (!NameValidator.isValidId(folderName))
- throw new CmisInvalidArgumentException(NameValidator.ERROR_ILLEGAL_NAME);
-
-
- TypeValidator.validateRequiredSystemProperties(properties);
-
- TypeDefinition typeDef = getTypeDefinition(repositoryId, properties);
-
- // check if the given type is a folder type
- if (!typeDef.getBaseTypeId().equals(BaseTypeId.CMIS_FOLDER))
- throw new RuntimeException("Cannot create a folder, with a non-folder type: "
- + typeDef.getId());
-
- TypeValidator.validateProperties(typeDef, properties, true);
-
- // create folder
- try {
- LOG.info("get folder for id: " + folderId);
- so = fs.getObjectById(folderId);
- }
- catch (Exception e) {
- throw new CmisObjectNotFoundException("Failed to retrieve folder.", e);
- }
-
- if (so instanceof Folder)
- parent = (Folder) so;
- else
- throw new CmisInvalidArgumentException(
- "Can't create folder, folderId does not refer to a folder: " + folderId);
- try {
- ObjectStore objStore = fStoreManager.getObjectStore(repositoryId);
- Folder newFolder = objStore.createFolder(folderName);
- // set default system attributes
- String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
- if (user == null)
- user = "unknown";
- newFolder.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
- newFolder.setCustomProperties(properties.getProperties());
- parent.addChildFolder(newFolder);
- LOG.debug("stop createFolder()");
- return newFolder;
- }
- catch (Exception e) {
- throw new CmisInvalidArgumentException("Failed to create child folder.", e);
- }
- }
-
- private StoredObject createPolicyIntern(String repositoryId, Properties properties,
- String folderId, List<String> policies, Acl addAces,
- Acl removeAces, ExtensionsData extension) {
- return null;
- }
-
- private StoredObject createRelationshipIntern(String repositoryId, Properties properties,
- List<String> policies, Acl addAces, Acl removeAces,
- ExtensionsData extension) {
- return null;
- }
-
- private boolean hasDescendant(Folder sourceFolder, Folder targetFolder) {
- String sourceId = sourceFolder.getId();
- String targetId = targetFolder.getId();
- while (targetId != null) {
- // log.info("comparing source id " + sourceId + " with predecessor " +
- // targetId);
- if (targetId.equals(sourceId))
- return true;
- targetFolder = targetFolder.getParent();
- if (null != targetFolder)
- targetId = targetFolder.getId();
- else
- targetId = null;
- }
- return false;
- }
-
- /**
- * Recursively delete a tree by traversing it and first deleting all children and then the object
- * itself
- *
- * @param folderStore
- * @param parentFolder
- * @param continueOnFailure
- * @param allVersions
- * @param failedToDeleteIds
- * @return returns true if operation should continue, false if it should stop
- */
- private boolean deleteRecursive(ObjectStore folderStore, Folder parentFolder,
- boolean continueOnFailure, boolean allVersions, List<String> failedToDeleteIds) {
- List<StoredObject> children = parentFolder.getChildren(-1, -1);
-
- if (null == children)
- return true;
-
- for (StoredObject child : children) {
- if (child instanceof Folder) {
- boolean mustContinue = deleteRecursive(folderStore, (Folder) child, continueOnFailure,
- allVersions, failedToDeleteIds);
- if (!mustContinue && !continueOnFailure)
- return false; // stop further deletions
- }
- else {
- try {
- folderStore.deleteObject(child.getId());
- }
- catch (Exception e) {
- failedToDeleteIds.add(child.getId());
- }
- }
- }
- folderStore.deleteObject(parentFolder.getId());
- return true;
- }
-
- private ContentStream getContentStream(StoredObject so, String streamId, BigInteger offset,
- BigInteger length) {
-
- long lOffset = offset == null ? 0 : offset.longValue();
- long lLength = length == null ? -1 : length.longValue();
- ContentStream csd = ((Content) so).getContent(lOffset, lLength);
- return csd;
- }
+ public InMemoryObjectServiceImpl(StoreManager storeManager) {
+ super(storeManager);
+ fAtomLinkProvider = new AtomLinkInfoProvider(fStoreManager);
+ }
+
+ public String createDocument(CallContext context, String repositoryId, Properties properties, String folderId,
+ ContentStream contentStream, VersioningState versioningState, List<String> policies, Acl addAces,
+ Acl removeAces, ExtensionsData extension) {
+
+ try {
+ LOG.debug("start createDocument()");
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ StoredObject so = createDocumentIntern(repositoryId, properties, folderId, contentStream, versioningState,
+ policies, addAces, removeAces, extension);
+ LOG.debug("stop createDocument()");
+ return so.getId();
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public String createDocumentFromSource(CallContext context, String repositoryId, String sourceId,
+ Properties properties, String folderId, VersioningState versioningState, List<String> policies,
+ Acl addAces, Acl removeAces, ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ LOG.debug("start createDocumentFromSource()");
+
+ StoredObject so = checkStandardParameters(repositoryId, sourceId);
+
+ ContentStream content = getContentStream(context, repositoryId, sourceId, null, BigInteger.valueOf(-1),
+ BigInteger.valueOf(-1), null);
+
+ if (so == null)
+ throw new CmisObjectNotFoundException("Unknown object id: " + sourceId);
+
+ // build properties collection
+ List<String> requestedIds = FilterParser.getRequestedIdsFromFilter("*");
+
+ Properties existingProps = PropertyCreationHelper.getPropertiesFromObject(repositoryId, so, fStoreManager,
+ requestedIds);
+
+ PropertiesImpl newPD = new PropertiesImpl();
+ // copy all existing properties
+ for (PropertyData<?> prop : existingProps.getProperties().values()) {
+ newPD.addProperty(prop);
+ }
+ // overwrite all new properties
+ for (PropertyData<?> prop : properties.getProperties().values()) {
+ newPD.addProperty(prop);
+ }
+
+ String res = createDocument(context, repositoryId, newPD, folderId, content, versioningState, policies,
+ addAces, removeAces, null);
+ LOG.debug("stop createDocumentFromSource()");
+ return res;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public String createFolder(CallContext context, String repositoryId, Properties properties, String folderId,
+ List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) {
+ try {
+ LOG.debug("start createFolder()");
+ RuntimeContext.attachCfg(context);
+
+ Folder folder = createFolderIntern(repositoryId, properties, folderId, policies, addAces, removeAces,
+ extension);
+ LOG.debug("stop createFolder()");
+ return folder.getId();
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public String createPolicy(CallContext context, String repositoryId, Properties properties, String folderId,
+ List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ // TODO to be completed if ACLs are implemented
+ LOG.debug("start createPolicy()");
+ checkStandardParameters(repositoryId, folderId);
+ StoredObject so = createPolicyIntern(repositoryId, properties, folderId, policies, addAces, removeAces,
+ extension);
+ LOG.debug("stop createPolicy()");
+ return so == null ? null : so.getId();
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public String createRelationship(CallContext context, String repositoryId, Properties properties,
+ List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ // TODO to be completed if relationships are implemented
+ LOG.debug("start createRelationship()");
+ checkRepositoryId(repositoryId);
+ StoredObject so = createRelationshipIntern(repositoryId, properties, policies, addAces, removeAces,
+ extension);
+ LOG.debug("stop createRelationship()");
+ return so == null ? null : so.getId();
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.opencmis.server.spi.CmisObjectService#create(org.opencmis.server.
+ * spi.CallContext, java.lang.String,
+ * org.opencmis.client.provider.PropertiesData, java.lang.String,
+ * org.opencmis.client.provider.ContentStreamData,
+ * org.opencmis.commons.enums.VersioningState,
+ * org.opencmis.client.provider.ExtensionsData,
+ * org.opencmis.server.spi.ObjectInfoHolder)
+ *
+ * An additional create call compared to the ObjectService from the CMIS
+ * spec. This one is needed because the Atom binding in the server
+ * implementation does not know what kind of object needs to be created.
+ * Also the ObjectInfoHolder needs to be filled.
+ */
+ @SuppressWarnings("unchecked")
+ public ObjectData create(CallContext context, String repositoryId, Properties properties, String folderId,
+ ContentStream contentStream, VersioningState versioningState, List<String> policies,
+ ExtensionsData extension, ObjectInfoHolder objectInfos) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ if (null == properties || null == properties.getProperties())
+ throw new RuntimeException("Cannot create object, without properties.");
+
+ // Find out what kind of object needs to be created
+ PropertyData<String> pd = (PropertyData<String>) properties.getProperties().get(PropertyIds.OBJECT_TYPE_ID);
+ String typeId = pd == null ? null : pd.getFirstValue();
+ if (null == typeId)
+ throw new RuntimeException(
+ "Cannot create object, without a type (no property with id CMIS_OBJECT_TYPE_ID).");
+
+ TypeDefinitionContainer typeDefC = fStoreManager.getTypeById(repositoryId, typeId);
+ if (typeDefC == null)
+ throw new RuntimeException("Cannot create object, a type with id " + typeId + " is unknown");
+
+ // check if the given type is a document type
+ BaseTypeId typeBaseId = typeDefC.getTypeDefinition().getBaseTypeId();
+ StoredObject so = null;
+ if (typeBaseId.equals(InMemoryDocumentTypeDefinition.getRootDocumentType().getBaseTypeId())) {
+ so = createDocumentIntern(repositoryId, properties, folderId, contentStream, versioningState, null,
+ null, null, null);
+ } else if (typeBaseId.equals(InMemoryFolderTypeDefinition.getRootFolderType().getBaseTypeId())) {
+ so = createFolderIntern(repositoryId, properties, folderId, null, null, null, null);
+ } else if (typeBaseId.equals(InMemoryPolicyTypeDefinition.getRootPolicyType().getBaseTypeId())) {
+ so = createPolicyIntern(repositoryId, properties, folderId, null, null, null, null);
+ } else if (typeBaseId.equals(InMemoryRelationshipTypeDefinition.getRootRelationshipType().getBaseTypeId())) {
+ so = createRelationshipIntern(repositoryId, properties, null, null, null, null);
+ } else
+ LOG.error("The type contains an unknown base object id, object can't be created");
+
+ // Make a call to getObject to convert the resulting id into an
+ // ObjectData
+ ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
+ IncludeRelationships.NONE, null, false, false, extension);
+
+ fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+ return od;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public void deleteContentStream(CallContext context, String repositoryId, Holder<String> objectId,
+ Holder<String> changeToken, ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ LOG.debug("start deleteContentStream()");
+ StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
+
+ if (so == null)
+ throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+ if (!(so instanceof Content))
+ throw new CmisObjectNotFoundException("Id" + objectId
+ + " does not refer to a document, but only documents can have content");
+
+ ((Content) so).setContent(null, true);
+ LOG.debug("stop deleteContentStream()");
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public void deleteObjectOrCancelCheckOut(CallContext context, String repositoryId, String objectId,
+ Boolean allVersions, ExtensionsData extension) {
+
+ try {
+ LOG.debug("start deleteObject()");
+ checkStandardParameters(repositoryId, objectId);
+ ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+ LOG.info("delete object for id: " + objectId);
+
+ // check if it is the root folder
+ if (objectId.equals(objectStore.getRootFolder().getId()))
+ throw new CmisNotSupportedException("You can't delete a root folder");
+
+ objectStore.deleteObject(objectId);
+ LOG.debug("stop deleteObject()");
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public FailedToDeleteData deleteTree(CallContext context, String repositoryId, String folderId,
+ Boolean allVersions, UnfileObject unfileObjects, Boolean continueOnFailure, ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ LOG.debug("start deleteTree()");
+ StoredObject so = checkStandardParameters(repositoryId, folderId);
+ List<String> failedToDeleteIds = new ArrayList<String>();
+ FailedToDeleteDataImpl result = new FailedToDeleteDataImpl();
+
+ if (null == allVersions)
+ allVersions = true;
+ if (null == unfileObjects)
+ unfileObjects = UnfileObject.DELETE;
+ if (null == continueOnFailure)
+ continueOnFailure = false;
+
+ ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+
+ if (null == so)
+ throw new RuntimeException("Cannot delete object with id " + folderId + ". Object does not exist.");
+
+ if (!(so instanceof Folder))
+ throw new RuntimeException("deleteTree can only be invoked on a folder, but id " + folderId
+ + " does not refer to a folder");
+
+ if (unfileObjects == UnfileObject.UNFILE)
+ throw new CmisNotSupportedException("This repository does not support unfile operations.");
+
+ // check if it is the root folder
+ if (folderId.equals(objectStore.getRootFolder().getId()))
+ throw new CmisNotSupportedException("You can't delete a root folder");
+
+ // recursively delete folder
+ deleteRecursive(objectStore, (Folder) so, continueOnFailure, allVersions, failedToDeleteIds);
+
+ result.setIds(failedToDeleteIds);
+ LOG.debug("stop deleteTree()");
+ return result;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public AllowableActions getAllowableActions(CallContext context, String repositoryId, String objectId,
+ ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ LOG.debug("start getAllowableActions()");
+ StoredObject so = checkStandardParameters(repositoryId, objectId);
+ ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+
+ if (so == null)
+ throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+ AllowableActions allowableActions = DataObjectCreator.fillAllowableActions(objectStore, so);
+ LOG.debug("stop getAllowableActions()");
+ return allowableActions;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public ContentStream getContentStream(CallContext context, String repositoryId, String objectId, String streamId,
+ BigInteger offset, BigInteger length, ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ LOG.debug("start getContentStream()");
+ StoredObject so = checkStandardParameters(repositoryId, objectId);
+
+ if (so == null)
+ throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+ if (!(so instanceof Content))
+ throw new CmisObjectNotFoundException("Id" + objectId
+ + " does not refer to a document or version, but only those can have content");
+
+ ContentStream csd = getContentStream(so, streamId, offset, length);
+ LOG.debug("stop getContentStream()");
+ return csd;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public ObjectData getObject(CallContext context, String repositoryId, String objectId, String filter,
+ Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
+ Boolean includePolicyIds, Boolean includeAcl, ExtensionsData extension, ObjectInfoHolder objectInfos) {
+
+ try {
+ LOG.debug("start getObject()");
+
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ StoredObject so = checkStandardParameters(repositoryId, objectId);
+
+ if (so == null)
+ throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+ ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, filter, includeAllowableActions,
+ includeRelationships, renditionFilter, includePolicyIds, includeAcl, extension);
+
+ fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+
+ LOG.debug("stop getObject()");
+
+ return od;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public ObjectData getObjectByPath(CallContext context, String repositoryId, String path, String filter,
+ Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
+ Boolean includePolicyIds, Boolean includeAcl, ExtensionsData extension, ObjectInfoHolder objectInfos) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ LOG.debug("start getObjectByPath()");
+ checkRepositoryId(repositoryId);
+ ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+ StoredObject so = objectStore.getObjectByPath(path);
+
+ if (so == null)
+ throw new CmisObjectNotFoundException("Unknown path: " + path);
+
+ ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, filter, includeAllowableActions,
+ includeRelationships, renditionFilter, includePolicyIds, includeAcl, extension);
+
+ LOG.debug("stop getObjectByPath()");
+
+ // To be able to provide all Atom links in the response we need
+ // additional information:
+ fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+
+ return od;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public Properties getProperties(CallContext context, String repositoryId, String objectId, String filter,
+ ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ LOG.debug("start getProperties()");
+ StoredObject so = checkStandardParameters(repositoryId, objectId);
+
+ if (so == null)
+ throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+ // build properties collection
+ List<String> requestedIds = FilterParser.getRequestedIdsFromFilter(filter);
+ Properties props = PropertyCreationHelper.getPropertiesFromObject(repositoryId, so, fStoreManager,
+ requestedIds);
+ LOG.debug("stop getProperties()");
+ return props;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public List<RenditionData> getRenditions(CallContext context, String repositoryId, String objectId,
+ String renditionFilter, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ // TODO to be completed if renditions are implemented
+ LOG.debug("start getRenditions()");
+ checkStandardParameters(repositoryId, objectId);
+ LOG.debug("stop getRenditions()");
+ return null;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public ObjectData moveObject(CallContext context, String repositoryId, Holder<String> objectId,
+ String targetFolderId, String sourceFolderId, ExtensionsData extension, ObjectInfoHolder objectInfos) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ LOG.debug("start moveObject()");
+ StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
+ Folder targetFolder = null;
+ Folder sourceFolder = null;
+ ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+ Filing spo = null;
+
+ if (null == so)
+ throw new CmisObjectNotFoundException("Unknown object: " + objectId.getValue());
+ else if (so instanceof Filing)
+ spo = (Filing) so;
+ else
+ throw new CmisInvalidArgumentException("Object must be folder or document: " + objectId.getValue());
+
+ StoredObject soTarget = objectStore.getObjectById(targetFolderId);
+ if (null == soTarget)
+ throw new CmisObjectNotFoundException("Unknown target folder: " + targetFolderId);
+ else if (soTarget instanceof Folder)
+ targetFolder = (Folder) soTarget;
+ else
+ throw new CmisNotSupportedException("Destination " + targetFolderId
+ + " of a move operation must be a folder");
+
+ StoredObject soSource = objectStore.getObjectById(sourceFolderId);
+ if (null == soSource)
+ throw new CmisObjectNotFoundException("Unknown source folder: " + sourceFolderId);
+ else if (soSource instanceof Folder)
+ sourceFolder = (Folder) soSource;
+ else
+ throw new CmisNotSupportedException("Source " + sourceFolderId
+ + " of a move operation must be a folder");
+
+ boolean foundOldParent = false;
+ for (Folder parent : spo.getParents()) {
+ if (parent.getId().equals(soSource.getId())) {
+ foundOldParent = true;
+ break;
+ }
+ }
+ if (!foundOldParent)
+ throw new CmisNotSupportedException("Cannot move object, source folder " + sourceFolderId
+ + "is not a parent of object " + objectId.getValue());
+
+ if (so instanceof Folder && hasDescendant((Folder) so, targetFolder)) {
+ throw new CmisNotSupportedException("Destination of a move cannot be a subfolder of the source");
+ }
+
+ spo.move(sourceFolder, targetFolder);
+ objectId.setValue(so.getId());
+ LOG.debug("stop moveObject()");
+
+ // To be able to provide all Atom links in the response we need
+ // additional information:
+ fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+
+ ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
+ IncludeRelationships.NONE, null, false, false, extension);
+
+ return od;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public void setContentStream(CallContext context, String repositoryId, Holder<String> objectId,
+ Boolean overwriteFlag, Holder<String> changeToken, ContentStream contentStream, ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ LOG.debug("start setContentStream()");
+ checkStandardParameters(repositoryId, objectId.getValue());
+
+ ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
+ StoredObject so = folderStore.getObjectById(objectId.getValue());
+ Content content;
+
+ if (!(so instanceof Document || so instanceof VersionedDocument || so instanceof DocumentVersion))
+ throw new CmisObjectNotFoundException("Id" + objectId
+ + " does not refer to a document, but only documents can have content");
+
+ if (so instanceof Document)
+ content = ((Document) so);
+ else if (so instanceof DocumentVersion) {
+ // something that is versionable check the proper status of the
+ // object
+ String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
+ testHasProperCheckedOutStatus(so, user);
+ content = (DocumentVersion) so;
+ } else
+ throw new IllegalArgumentException("Content cannot be set on this object (must be document or version)");
+
+ if (!overwriteFlag && content.getContent(0, -1) != null)
+ throw new CmisConstraintException("cannot overwrite existing content if overwrite flag is not set");
+
+ content.setContent(contentStream, true);
+ LOG.debug("stop setContentStream()");
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public ObjectData updateProperties(CallContext context, String repositoryId, Holder<String> objectId,
+ Holder<String> changeToken, Properties properties, Acl acl, ExtensionsData extension,
+ ObjectInfoHolder objectInfos) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ LOG.debug("start updateProperties()");
+ StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
+
+ // Validation
+ TypeDefinition typeDef = getTypeDefinition(repositoryId, so);
+ boolean isCheckedOut = false;
+
+ // if the object is a versionable object it must be checked-out
+ if (so instanceof VersionedDocument || so instanceof DocumentVersion) {
+ String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
+ // VersionedDocument verDoc =
+ // testIsNotCheckedOutBySomeoneElse(so, user);
+ testHasProperCheckedOutStatus(so, user);
+ isCheckedOut = true;
+ }
+
+ Map<String, PropertyData<?>> oldProperties = so.getProperties();
+
+ // check properties for validity
+ TypeValidator.validateProperties(typeDef, properties, false);
+
+ if (changeToken != null && changeToken.getValue() != null
+ && Long.valueOf(so.getChangeToken()) > Long.valueOf(changeToken.getValue()))
+ throw new CmisUpdateConflictException(" updateProperties failed: outdated changeToken");
+
+ // update properties
+ boolean hasUpdatedName = false;
+ boolean hasUpdatedOtherProps = false;
+
+ for (String key : properties.getProperties().keySet()) {
+ if (key.equals(PropertyIds.NAME))
+ continue; // ignore here
+
+ PropertyData<?> value = properties.getProperties().get(key);
+ PropertyDefinition<?> propDef = typeDef.getPropertyDefinitions().get(key);
+ if (value.getValues() == null || value.getFirstValue() == null) {
+ // delete property
+ // check if a required a property
+ if (propDef.isRequired())
+ throw new CmisConstraintException(
+ "updateProperties failed, following property can't be deleted, because it is required: "
+ + key);
+ oldProperties.remove(key);
+ hasUpdatedOtherProps = true;
+ } else {
+ if (propDef.getUpdatability().equals(Updatability.WHENCHECKEDOUT) && !isCheckedOut)
+ throw new CmisConstraintException(
+ "updateProperties failed, following property can't be updated, because it is not checked-out: "
+ + key);
+ else if (!propDef.getUpdatability().equals(Updatability.READWRITE))
+ throw new CmisConstraintException(
+ "updateProperties failed, following property can't be updated, because it is not writable: "
+ + key);
+ oldProperties.put(key, value);
+ hasUpdatedOtherProps = true;
+ }
+ }
+
+ // get name from properties and perform special rename to check if
+ // path
+ // already exists
+ PropertyData<?> pd = properties.getProperties().get(PropertyIds.NAME);
+ if (pd != null && so instanceof Filing) {
+ String newName = (String) pd.getFirstValue();
+ List<Folder> parents = ((Filing) so).getParents();
+ if (so instanceof Folder && parents.isEmpty())
+ throw new CmisConstraintException("updateProperties failed, you cannot rename the root folder");
+ for (Folder parent : parents) {
+ if (parent.hasChild(newName))
+ throw new CmisConstraintException(
+ "updateProperties failed, cannot rename because path already exists.");
+ }
+ so.rename((String) pd.getFirstValue()); // note: this does
+ // persist
+ hasUpdatedName = true;
+ }
+
+ if (hasUpdatedOtherProps) {
+ // set user, creation date, etc.
+ String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
+
+ if (user == null)
+ user = "unknown";
+ so.updateSystemBasePropertiesWhenModified(properties.getProperties(), user);
+ // set changeToken
+ so.persist();
+ }
+
+ if (hasUpdatedName || hasUpdatedOtherProps) {
+ objectId.setValue(so.getId()); // might have a new id
+ if (null != changeToken) {
+ String changeTokenVal = so.getChangeToken();
+ LOG.info("updateProperties(), new change token is: " + changeTokenVal);
+ changeToken.setValue(changeTokenVal);
+ }
+ }
+
+ if (null != acl) {
+ LOG.warn("Setting ACLs is currently not supported by this implementation, acl is ignored");
+ // if implemented add this call:
+ // fAclService.appyAcl(context, repositoryId, acl, null,
+ // AclPropagation.OBJECTONLY,
+ // extension);
+ }
+
+ // To be able to provide all Atom links in the response we need
+ // additional information:
+ fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+
+ ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
+ IncludeRelationships.NONE, null, false, false, extension);
+
+ LOG.debug("stop updateProperties()");
+
+ return od;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ // ///////////////////////////////////////////////////////
+ // private helper methods
+
+ private StoredObject createDocumentIntern(String repositoryId, Properties properties, String folderId,
+ ContentStream contentStream, VersioningState versioningState, List<String> policies, Acl addACEs,
+ Acl removeACEs, ExtensionsData extension) {
+ checkRepositoryId(repositoryId);
+
+ ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+
+ // get name from properties
+ PropertyData<?> pd = properties.getProperties().get(PropertyIds.NAME);
+ String name = (String) pd.getFirstValue();
+
+ // Validation stuff
+ TypeValidator.validateRequiredSystemProperties(properties);
+ TypeDefinition typeDef = getTypeDefinition(repositoryId, properties);
+
+ Folder folder = null;
+ if (null != folderId) {
+ StoredObject so = objectStore.getObjectById(folderId);
+
+ if (null == so)
+ throw new CmisInvalidArgumentException(" Cannot create document, folderId: " + folderId + " is invalid");
+
+ if (so instanceof Folder)
+ folder = (Folder) so;
+ else
+ throw new CmisInvalidArgumentException("Can't creat document, folderId does not refer to a folder: "
+ + folderId);
+
+ TypeValidator.validateAllowedChildObjectTypes(typeDef, folder.getAllowedChildObjectTypeIds());
+ }
+
+ // check if the given type is a document type
+ if (!typeDef.getBaseTypeId().equals(BaseTypeId.CMIS_DOCUMENT))
+ throw new RuntimeException("Cannot create a document, with a non-document type: " + typeDef.getId());
+
+ // check name syntax
+ if (!NameValidator.isValidId(name))
+ throw new CmisInvalidArgumentException(NameValidator.ERROR_ILLEGAL_NAME);
+
+ TypeValidator.validateVersionStateForCreate((DocumentTypeDefinition) typeDef, versioningState);
+ TypeValidator.validateProperties(typeDef, properties, true);
+
+ // set user, creation date, etc.
+ String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
+ if (user == null)
+ user = "unknown";
+
+ StoredObject so = null;
+
+ // Now we are sure to have document type definition:
+ if (((DocumentTypeDefinition) typeDef).isVersionable()) {
+ VersionedDocument verDoc = fStoreManager.getObjectStore(repositoryId).createVersionedDocument(name);
+ verDoc.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
+ verDoc.setCustomProperties(properties.getProperties());
+ DocumentVersion version = verDoc.addVersion(contentStream, versioningState, user);
+ if (null != folder)
+ folder.addChildDocument(verDoc); // add document to folder and
+ // set parent in doc
+ else
+ verDoc.persist();
+ version.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
+ version.setCustomProperties(properties.getProperties());
+ version.persist();
+ so = version; // return the version and not the version series to
+ // caller
+ } else {
+ Document doc = fStoreManager.getObjectStore(repositoryId).createDocument(name);
+ doc.setContent(contentStream, false);
+ // add document to folder
+ doc.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
+ doc.setCustomProperties(properties.getProperties());
+ if (null != folder)
+ folder.addChildDocument(doc); // add document to folder and set
+ // parent in doc
+ else
+ doc.persist();
+ so = doc;
+ }
+
+ // policies, addACEs, removeACEs, extension are ignored for
+ // now.
+ return so;
+ }
+
+ private Folder createFolderIntern(String repositoryId, Properties properties, String folderId,
+ List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) {
+
+ // Attach the CallContext to a thread local context that can be accessed
+ // from everywhere
+ checkStandardParameters(repositoryId, folderId);
+
+ ObjectStore fs = fStoreManager.getObjectStore(repositoryId);
+ StoredObject so = null;
+ Folder parent = null;
+
+ // get required properties
+ PropertyData<?> pd = properties.getProperties().get(PropertyIds.NAME);
+ String folderName = (String) pd.getFirstValue();
+ if (null == folderName || folderName.length() == 0)
+ throw new CmisInvalidArgumentException("Cannot create a folder without a name.");
+
+ // check name syntax
+ if (!NameValidator.isValidId(folderName))
+ throw new CmisInvalidArgumentException(NameValidator.ERROR_ILLEGAL_NAME);
+
+ TypeValidator.validateRequiredSystemProperties(properties);
+
+ TypeDefinition typeDef = getTypeDefinition(repositoryId, properties);
+
+ // check if the given type is a folder type
+ if (!typeDef.getBaseTypeId().equals(BaseTypeId.CMIS_FOLDER))
+ throw new RuntimeException("Cannot create a folder, with a non-folder type: " + typeDef.getId());
+
+ TypeValidator.validateProperties(typeDef, properties, true);
+
+ // create folder
+ try {
+ LOG.info("get folder for id: " + folderId);
+ so = fs.getObjectById(folderId);
+ } catch (Exception e) {
+ throw new CmisObjectNotFoundException("Failed to retrieve folder.", e);
+ }
+
+ if (so instanceof Folder)
+ parent = (Folder) so;
+ else
+ throw new CmisInvalidArgumentException("Can't create folder, folderId does not refer to a folder: "
+ + folderId);
+ try {
+ ObjectStore objStore = fStoreManager.getObjectStore(repositoryId);
+ Folder newFolder = objStore.createFolder(folderName);
+ // set default system attributes
+ String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
+ if (user == null)
+ user = "unknown";
+ newFolder.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
+ newFolder.setCustomProperties(properties.getProperties());
+ parent.addChildFolder(newFolder);
+ LOG.debug("stop createFolder()");
+ return newFolder;
+ } catch (Exception e) {
+ throw new CmisInvalidArgumentException("Failed to create child folder.", e);
+ }
+ }
+
+ private StoredObject createPolicyIntern(String repositoryId, Properties properties, String folderId,
+ List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) {
+ return null;
+ }
+
+ private StoredObject createRelationshipIntern(String repositoryId, Properties properties, List<String> policies,
+ Acl addAces, Acl removeAces, ExtensionsData extension) {
+ return null;
+ }
+
+ private boolean hasDescendant(Folder sourceFolder, Folder targetFolder) {
+ String sourceId = sourceFolder.getId();
+ String targetId = targetFolder.getId();
+ while (targetId != null) {
+ // log.info("comparing source id " + sourceId + " with predecessor "
+ // +
+ // targetId);
+ if (targetId.equals(sourceId))
+ return true;
+ targetFolder = targetFolder.getParent();
+ if (null != targetFolder)
+ targetId = targetFolder.getId();
+ else
+ targetId = null;
+ }
+ return false;
+ }
+
+ /**
+ * Recursively delete a tree by traversing it and first deleting all
+ * children and then the object itself
+ *
+ * @param folderStore
+ * @param parentFolder
+ * @param continueOnFailure
+ * @param allVersions
+ * @param failedToDeleteIds
+ * @return returns true if operation should continue, false if it should
+ * stop
+ */
+ private boolean deleteRecursive(ObjectStore folderStore, Folder parentFolder, boolean continueOnFailure,
+ boolean allVersions, List<String> failedToDeleteIds) {
+ List<StoredObject> children = parentFolder.getChildren(-1, -1);
+
+ if (null == children)
+ return true;
+
+ for (StoredObject child : children) {
+ if (child instanceof Folder) {
+ boolean mustContinue = deleteRecursive(folderStore, (Folder) child, continueOnFailure, allVersions,
+ failedToDeleteIds);
+ if (!mustContinue && !continueOnFailure)
+ return false; // stop further deletions
+ } else {
+ try {
+ folderStore.deleteObject(child.getId());
+ } catch (Exception e) {
+ failedToDeleteIds.add(child.getId());
+ }
+ }
+ }
+ folderStore.deleteObject(parentFolder.getId());
+ return true;
+ }
+
+ private ContentStream getContentStream(StoredObject so, String streamId, BigInteger offset, BigInteger length) {
+
+ long lOffset = offset == null ? 0 : offset.longValue();
+ long lLength = length == null ? -1 : length.longValue();
+ ContentStream csd = ((Content) so).getContent(lOffset, lLength);
+ return csd;
+ }
}
Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryRepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryRepositoryServiceImpl.java?rev=934878&r1=934877&r2=934878&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryRepositoryServiceImpl.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryRepositoryServiceImpl.java Fri Apr 16 14:00:23 2010
@@ -36,144 +36,145 @@ import org.apache.chemistry.opencmis.inm
import org.apache.chemistry.opencmis.server.spi.CallContext;
import org.apache.chemistry.opencmis.server.spi.CmisRepositoryService;
-public class InMemoryRepositoryServiceImpl extends AbstractServiceImpl implements
- CmisRepositoryService {
+public class InMemoryRepositoryServiceImpl extends AbstractServiceImpl implements CmisRepositoryService {
- public InMemoryRepositoryServiceImpl(StoreManager storeManager) {
- super(storeManager);
- }
-
- public RepositoryInfo getRepositoryInfo(CallContext context, String repositoryId,
- ExtensionsData extension) {
-
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- RepositoryInfo repoInfo = getRepositoryInfoFromStoreManager(repositoryId);
-
- return repoInfo;
- }
-
- public List<RepositoryInfo> getRepositoryInfos(CallContext context, ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- List<RepositoryInfo> res = new ArrayList<RepositoryInfo>();
- List<String> repIds = fStoreManager.getAllRepositoryIds();
- for (String repId : repIds) {
- res.add(fStoreManager.getRepositoryInfo(repId));
- }
- return res;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public TypeDefinitionList getTypeChildren(CallContext context, String repositoryId,
- String typeId, Boolean includePropertyDefinitions, BigInteger maxItems, BigInteger skipCount,
- ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- getRepositoryInfoFromStoreManager(repositoryId); // just to check if repository exists
-
- int skip = skipCount == null ? 0 : skipCount.intValue();
- int max = maxItems == null ? -1 : maxItems.intValue();
-
- TypeDefinitionListImpl result = new TypeDefinitionListImpl();
- List<TypeDefinitionContainer> children;
- if (typeId == null) {
- // spec says that base types must be returned in this case
- children = fStoreManager.getRootTypes(repositoryId);
- }
- else {
- children = getTypeDescendants(context, repositoryId, typeId, BigInteger.valueOf(1),
- includePropertyDefinitions, null);
- }
- result.setNumItems(BigInteger.valueOf(children.size()));
- result.setHasMoreItems(children.size() > max - skip);
- List<TypeDefinition> childrenTypes = new ArrayList<TypeDefinition>();
- ListIterator<TypeDefinitionContainer> it = children.listIterator(skip);
- if (max < 0)
- max = children.size();
- for (int i = skip; i < max + skip && it.hasNext(); i++)
- childrenTypes.add(it.next().getTypeDefinition());
-
- result.setList(childrenTypes);
- return result;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public TypeDefinition getTypeDefinition(CallContext context, String repositoryId, String typeId,
- ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- getRepositoryInfoFromStoreManager(repositoryId); // just to check if repository exists
-
- TypeDefinitionContainer tc = fStoreManager.getTypeById(repositoryId, typeId);
- if (tc != null) {
- return tc.getTypeDefinition();
- }
- else
- throw new CmisObjectNotFoundException("unknown type id: " + typeId);
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- public List<TypeDefinitionContainer> getTypeDescendants(CallContext context, String repositoryId,
- String typeId, BigInteger depth, Boolean includePropertyDefinitions, ExtensionsData extension) {
-
- try {
- // Attach the CallContext to a thread local context that can be accessed from everywhere
- RuntimeContext.attachCfg(context);
-
- getRepositoryInfoFromStoreManager(repositoryId); // just to check if repository exists
-
- if (depth != null && depth.intValue() == 0)
- throw new CmisInvalidArgumentException("depth == 0 is illegal in getTypeDescendants");
-
- List<TypeDefinitionContainer> result = null;
- if (typeId == null) {
- // spec says that depth must be ignored in this case
- Collection<TypeDefinitionContainer> tmp = fStoreManager.getTypeDefinitionList(repositoryId,
- includePropertyDefinitions);
- result = new ArrayList<TypeDefinitionContainer> (tmp);
- }
- else {
- TypeDefinitionContainer tc = fStoreManager.getTypeById(repositoryId, typeId,
- includePropertyDefinitions, depth==null ? -1 : depth.intValue());
- if (tc == null)
- throw new CmisInvalidArgumentException("unknown type id: " + typeId);
- else
- result = tc.getChildren();
- }
-
- return result;
- }
- finally {
- RuntimeContext.remove();
- }
- }
-
- private RepositoryInfo getRepositoryInfoFromStoreManager(String repositoryId) {
- RepositoryInfo repoInfo = fStoreManager.getRepositoryInfo(repositoryId);
- if (null == repoInfo || !repoInfo.getId().equals(repositoryId)) {
- throw new CmisInvalidArgumentException("Unknown repository: " + repositoryId);
- }
- return repoInfo;
- }
+ public InMemoryRepositoryServiceImpl(StoreManager storeManager) {
+ super(storeManager);
+ }
+
+ public RepositoryInfo getRepositoryInfo(CallContext context, String repositoryId, ExtensionsData extension) {
+
+ // Attach the CallContext to a thread local context that can be accessed
+ // from everywhere
+ RuntimeContext.attachCfg(context);
+
+ RepositoryInfo repoInfo = getRepositoryInfoFromStoreManager(repositoryId);
+
+ return repoInfo;
+ }
+
+ public List<RepositoryInfo> getRepositoryInfos(CallContext context, ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ List<RepositoryInfo> res = new ArrayList<RepositoryInfo>();
+ List<String> repIds = fStoreManager.getAllRepositoryIds();
+ for (String repId : repIds) {
+ res.add(fStoreManager.getRepositoryInfo(repId));
+ }
+ return res;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public TypeDefinitionList getTypeChildren(CallContext context, String repositoryId, String typeId,
+ Boolean includePropertyDefinitions, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ getRepositoryInfoFromStoreManager(repositoryId); // just to check if
+ // repository
+ // exists
+
+ int skip = skipCount == null ? 0 : skipCount.intValue();
+ int max = maxItems == null ? -1 : maxItems.intValue();
+
+ TypeDefinitionListImpl result = new TypeDefinitionListImpl();
+ List<TypeDefinitionContainer> children;
+ if (typeId == null) {
+ // spec says that base types must be returned in this case
+ children = fStoreManager.getRootTypes(repositoryId);
+ } else {
+ children = getTypeDescendants(context, repositoryId, typeId, BigInteger.valueOf(1),
+ includePropertyDefinitions, null);
+ }
+ result.setNumItems(BigInteger.valueOf(children.size()));
+ result.setHasMoreItems(children.size() > max - skip);
+ List<TypeDefinition> childrenTypes = new ArrayList<TypeDefinition>();
+ ListIterator<TypeDefinitionContainer> it = children.listIterator(skip);
+ if (max < 0)
+ max = children.size();
+ for (int i = skip; i < max + skip && it.hasNext(); i++)
+ childrenTypes.add(it.next().getTypeDefinition());
+
+ result.setList(childrenTypes);
+ return result;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public TypeDefinition getTypeDefinition(CallContext context, String repositoryId, String typeId,
+ ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ getRepositoryInfoFromStoreManager(repositoryId); // just to check if
+ // repository
+ // exists
+
+ TypeDefinitionContainer tc = fStoreManager.getTypeById(repositoryId, typeId);
+ if (tc != null) {
+ return tc.getTypeDefinition();
+ } else
+ throw new CmisObjectNotFoundException("unknown type id: " + typeId);
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ public List<TypeDefinitionContainer> getTypeDescendants(CallContext context, String repositoryId, String typeId,
+ BigInteger depth, Boolean includePropertyDefinitions, ExtensionsData extension) {
+
+ try {
+ // Attach the CallContext to a thread local context that can be
+ // accessed from everywhere
+ RuntimeContext.attachCfg(context);
+
+ getRepositoryInfoFromStoreManager(repositoryId); // just to check if
+ // repository
+ // exists
+
+ if (depth != null && depth.intValue() == 0)
+ throw new CmisInvalidArgumentException("depth == 0 is illegal in getTypeDescendants");
+
+ List<TypeDefinitionContainer> result = null;
+ if (typeId == null) {
+ // spec says that depth must be ignored in this case
+ Collection<TypeDefinitionContainer> tmp = fStoreManager.getTypeDefinitionList(repositoryId,
+ includePropertyDefinitions);
+ result = new ArrayList<TypeDefinitionContainer>(tmp);
+ } else {
+ TypeDefinitionContainer tc = fStoreManager.getTypeById(repositoryId, typeId,
+ includePropertyDefinitions, depth == null ? -1 : depth.intValue());
+ if (tc == null)
+ throw new CmisInvalidArgumentException("unknown type id: " + typeId);
+ else
+ result = tc.getChildren();
+ }
+
+ return result;
+ } finally {
+ RuntimeContext.remove();
+ }
+ }
+
+ private RepositoryInfo getRepositoryInfoFromStoreManager(String repositoryId) {
+ RepositoryInfo repoInfo = fStoreManager.getRepositoryInfo(repositoryId);
+ if (null == repoInfo || !repoInfo.getId().equals(repositoryId)) {
+ throw new CmisInvalidArgumentException("Unknown repository: " + repositoryId);
+ }
+ return repoInfo;
+ }
}