Return-Path: X-Original-To: apmail-chemistry-commits-archive@www.apache.org Delivered-To: apmail-chemistry-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 7F88910EF0 for ; Fri, 23 Aug 2013 12:48:40 +0000 (UTC) Received: (qmail 2103 invoked by uid 500); 23 Aug 2013 12:48:39 -0000 Delivered-To: apmail-chemistry-commits-archive@chemistry.apache.org Received: (qmail 1997 invoked by uid 500); 23 Aug 2013 12:48:38 -0000 Mailing-List: contact commits-help@chemistry.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@chemistry.apache.org Delivered-To: mailing list commits@chemistry.apache.org Received: (qmail 1986 invoked by uid 99); 23 Aug 2013 12:48:37 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 23 Aug 2013 12:48:36 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 23 Aug 2013 12:48:29 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 886E9238889B; Fri, 23 Aug 2013 12:48:07 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1516830 [1/3] - in /chemistry/opencmis/trunk: chemistry-opencmis-server/chemistry-opencmis-server-archetype/src/main/resources/archetype-resources/src/main/webapp/ chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/... Date: Fri, 23 Aug 2013 12:48:06 -0000 To: commits@chemistry.apache.org From: fmui@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20130823124807.886E9238889B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: fmui Date: Fri Aug 23 12:48:06 2013 New Revision: 1516830 URL: http://svn.apache.org/r1516830 Log: refactored FileShare repository, added CMIS 1.1 features + a few minor fixes Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/ContentRangeInputStream.java (with props) chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisService.java (with props) chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisServiceFactory.java (with props) chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareRepositoryManager.java (with props) chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareTypeManager.java (with props) chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareUserManager.java (with props) chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareUtils.java (with props) chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/resources/log4j.properties (with props) chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/webapp/index.jsp (with props) Removed: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareService.java chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareServiceFactory.java chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/RepositoryMap.java chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/TypeManager.java Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-archetype/src/main/resources/archetype-resources/src/main/webapp/index.jsp chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/pom.xml chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareRepository.java chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/webapp/WEB-INF/classes/repository.properties chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/TypeDefinitionFactory.java chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/TypeDefinitionFactoryTest.java chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/types/BaseTypesTest.java Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-archetype/src/main/resources/archetype-resources/src/main/webapp/index.jsp URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-archetype/src/main/resources/archetype-resources/src/main/webapp/index.jsp?rev=1516830&r1=1516829&r2=1516830&view=diff ============================================================================== --- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-archetype/src/main/resources/archetype-resources/src/main/webapp/index.jsp (original) +++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-archetype/src/main/resources/archetype-resources/src/main/webapp/index.jsp Fri Aug 23 12:48:06 2013 @@ -51,7 +51,7 @@

The ${artifactId} server is a CMIS server based on Apache Chemistry OpenCMIS.

You need a CMIS client to access this server. Download the CMIS Workbench.

-

Access Informatio

+

Access Information

CMIS 1.1

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java?rev=1516830&r1=1516829&r2=1516830&view=diff ============================================================================== --- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java (original) +++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java Fri Aug 23 12:48:06 2013 @@ -714,7 +714,8 @@ public class ObjectService { PropertiesImpl properties = new PropertiesImpl(); object.setProperties(properties); - properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_ID, idAndToken.getId())); + properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_ID, + idAndToken.getNewId() != null ? idAndToken.getNewId() : idAndToken.getId())); if (idAndToken.getChangeToken() != null) { properties.addProperty(new PropertyStringImpl(PropertyIds.CHANGE_TOKEN, idAndToken Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/pom.xml URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/pom.xml?rev=1516830&r1=1516829&r2=1516830&view=diff ============================================================================== --- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/pom.xml (original) +++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/pom.xml Fri Aug 23 12:48:06 2013 @@ -53,6 +53,15 @@ ${project.groupId} chemistry-opencmis-server-bindings-war + + index.html + css/** + images/** + web/** + WEB-INF/classes/sample-repository.properties + WEB-INF/token/** + WEB-INF/websphere/** + @@ -63,24 +72,31 @@ ${project.groupId} - chemistry-opencmis-commons-api + chemistry-opencmis-server-bindings-war ${project.version} + war ${project.groupId} - chemistry-opencmis-commons-impl + chemistry-opencmis-server-support ${project.version} - ${project.groupId} - chemistry-opencmis-server-bindings-war - ${project.version} - war + org.slf4j + slf4j-log4j12 + ${slf4j.version} - + ${project.groupId} - chemistry-opencmis-server-support + chemistry-opencmis-server-bindings ${project.version} + provided + + + javax.servlet + servlet-api + 2.4 + provided Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/ContentRangeInputStream.java URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/ContentRangeInputStream.java?rev=1516830&view=auto ============================================================================== --- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/ContentRangeInputStream.java (added) +++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/ContentRangeInputStream.java Fri Aug 23 12:48:06 2013 @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.chemistry.opencmis.fileshare; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; + +import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException; + +public class ContentRangeInputStream extends FilterInputStream { + + private static final int BUFFER_SIZE = 4096; + + private long offset; + private long length; + private long remaining; + + public ContentRangeInputStream(InputStream stream, BigInteger offset, BigInteger length) { + super(stream); + + this.offset = offset != null ? offset.longValue() : 0; + this.length = length != null ? length.longValue() : Long.MAX_VALUE; + + this.remaining = this.length; + + if (this.offset > 0) { + skipBytes(); + } + } + + private void skipBytes() { + long remainingSkipBytes = offset; + + try { + while (remainingSkipBytes > 0) { + long skipped = super.skip(remainingSkipBytes); + remainingSkipBytes -= skipped; + + if (skipped == 0) { + // stream might not support skipping + skipBytesByReading(remainingSkipBytes); + break; + } + } + } catch (IOException e) { + throw new CmisRuntimeException("Skipping the stream failed!", e); + } + } + + private void skipBytesByReading(long remainingSkipBytes) { + try { + final byte[] buffer = new byte[BUFFER_SIZE]; + while (remainingSkipBytes > 0) { + long skipped = super.read(buffer, 0, (int) Math.min(buffer.length, remainingSkipBytes)); + if (skipped == -1) { + break; + } + + remainingSkipBytes -= skipped; + } + } catch (IOException e) { + throw new CmisRuntimeException("Reading the stream failed!", e); + } + } + + @Override + public boolean markSupported() { + return false; + } + + @Override + public long skip(long n) throws IOException { + if (remaining <= 0) { + return 0; + } + + long skipped = super.skip(n); + remaining -= skipped; + + return skipped; + } + + @Override + public int available() throws IOException { + if (remaining <= 0) { + return 0; + } + + int avail = super.available(); + + if (remaining < avail) { + return (int) remaining; + } + + return avail; + } + + @Override + public int read() throws IOException { + if (remaining <= 0) { + return -1; + } + + remaining--; + + return super.read(); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (remaining <= 0) { + return -1; + } + + int readBytes = super.read(b, off, (int) Math.min(len, remaining)); + if (readBytes == -1) { + return -1; + } + + remaining -= readBytes; + + return readBytes; + } + + @Override + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } +} Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/ContentRangeInputStream.java ------------------------------------------------------------------------------ svn:eol-style = native Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisService.java URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisService.java?rev=1516830&view=auto ============================================================================== --- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisService.java (added) +++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisService.java Fri Aug 23 12:48:06 2013 @@ -0,0 +1,337 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.chemistry.opencmis.fileshare; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +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.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.RenditionData; +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.IncludeRelationships; +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.impl.dataobjects.ObjectListImpl; +import org.apache.chemistry.opencmis.commons.impl.server.AbstractCmisService; +import org.apache.chemistry.opencmis.commons.server.CallContext; +import org.apache.chemistry.opencmis.commons.spi.Holder; + +/** + * FileShare Service implementation. + */ +public class FileShareCmisService extends AbstractCmisService { + + private final FileShareRepositoryManager repositoryManager; + private CallContext context; + + public FileShareCmisService(final FileShareRepositoryManager repositoryManager) { + this.repositoryManager = repositoryManager; + } + + // --- Call Context --- + + /** + * Sets the call context. + * + * This method should only be called by the service factory. + */ + public void setCallContext(CallContext context) { + this.context = context; + } + + /** + * Gets the call context. + */ + public CallContext getCallContext() { + return context; + } + + /** + * Gets the repository for the current call. + */ + public FileShareRepository getRepository() { + return repositoryManager.getRepository(getCallContext().getRepositoryId()); + } + + // --- repository service --- + + @Override + public RepositoryInfo getRepositoryInfo(String repositoryId, ExtensionsData extension) { + for (FileShareRepository fsr : repositoryManager.getRepositories()) { + if (fsr.getRepositoryId().equals(repositoryId)) { + return fsr.getRepositoryInfo(getCallContext()); + } + } + + throw new CmisObjectNotFoundException("Unknown repository '" + repositoryId + "'!"); + } + + @Override + public List getRepositoryInfos(ExtensionsData extension) { + List result = new ArrayList(); + + for (FileShareRepository fsr : repositoryManager.getRepositories()) { + result.add(fsr.getRepositoryInfo(getCallContext())); + } + + return result; + } + + @Override + public TypeDefinitionList getTypeChildren(String repositoryId, String typeId, Boolean includePropertyDefinitions, + BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) { + return getRepository().getTypeChildren(getCallContext(), typeId, includePropertyDefinitions, maxItems, + skipCount); + } + + @Override + public TypeDefinition getTypeDefinition(String repositoryId, String typeId, ExtensionsData extension) { + return getRepository().getTypeDefinition(getCallContext(), typeId); + } + + @Override + public List getTypeDescendants(String repositoryId, String typeId, BigInteger depth, + Boolean includePropertyDefinitions, ExtensionsData extension) { + return getRepository().getTypeDescendants(getCallContext(), typeId, depth, includePropertyDefinitions); + } + + // --- navigation service --- + + @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) { + return getRepository().getChildren(getCallContext(), folderId, filter, includeAllowableActions, + includePathSegment, maxItems, skipCount, this); + } + + @Override + public List getDescendants(String repositoryId, String folderId, BigInteger depth, + String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, + String renditionFilter, Boolean includePathSegment, ExtensionsData extension) { + return getRepository().getDescendants(getCallContext(), folderId, depth, filter, includeAllowableActions, + includePathSegment, this, false); + } + + @Override + public ObjectData getFolderParent(String repositoryId, String folderId, String filter, ExtensionsData extension) { + return getRepository().getFolderParent(getCallContext(), folderId, filter, this); + } + + @Override + public List getFolderTree(String repositoryId, String folderId, BigInteger depth, + String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, + String renditionFilter, Boolean includePathSegment, ExtensionsData extension) { + return getRepository().getDescendants(getCallContext(), folderId, depth, filter, includeAllowableActions, + includePathSegment, this, true); + } + + @Override + public List getObjectParents(String repositoryId, String objectId, String filter, + Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, + Boolean includeRelativePathSegment, ExtensionsData extension) { + return getRepository().getObjectParents(getCallContext(), objectId, filter, includeAllowableActions, + includeRelativePathSegment, this); + } + + @Override + public ObjectList getCheckedOutDocs(String repositoryId, String folderId, String filter, String orderBy, + Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, + BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) { + ObjectListImpl result = new ObjectListImpl(); + result.setHasMoreItems(false); + result.setNumItems(BigInteger.ZERO); + List emptyList = Collections.emptyList(); + result.setObjects(emptyList); + + return result; + } + + // --- object service --- + + @Override + public String create(String repositoryId, Properties properties, String folderId, ContentStream contentStream, + VersioningState versioningState, List policies, ExtensionsData extension) { + ObjectData object = getRepository().create(getCallContext(), properties, folderId, contentStream, + versioningState, this); + + return object.getId(); + } + + @Override + public String createDocument(String repositoryId, Properties properties, String folderId, + ContentStream contentStream, VersioningState versioningState, List policies, Acl addAces, + Acl removeAces, ExtensionsData extension) { + return getRepository().createDocument(getCallContext(), properties, folderId, contentStream, versioningState); + } + + @Override + public String createDocumentFromSource(String repositoryId, String sourceId, Properties properties, + String folderId, VersioningState versioningState, List policies, Acl addAces, Acl removeAces, + ExtensionsData extension) { + return getRepository().createDocumentFromSource(getCallContext(), sourceId, properties, folderId, + versioningState); + } + + @Override + public String createFolder(String repositoryId, Properties properties, String folderId, List policies, + Acl addAces, Acl removeAces, ExtensionsData extension) { + return getRepository().createFolder(getCallContext(), properties, folderId); + } + + @Override + public void deleteObjectOrCancelCheckOut(String repositoryId, String objectId, Boolean allVersions, + ExtensionsData extension) { + getRepository().deleteObject(getCallContext(), objectId); + } + + @Override + public FailedToDeleteData deleteTree(String repositoryId, String folderId, Boolean allVersions, + UnfileObject unfileObjects, Boolean continueOnFailure, ExtensionsData extension) { + return getRepository().deleteTree(getCallContext(), folderId, continueOnFailure); + } + + @Override + public AllowableActions getAllowableActions(String repositoryId, String objectId, ExtensionsData extension) { + return getRepository().getAllowableActions(getCallContext(), objectId); + } + + @Override + public ContentStream getContentStream(String repositoryId, String objectId, String streamId, BigInteger offset, + BigInteger length, ExtensionsData extension) { + return getRepository().getContentStream(getCallContext(), objectId, offset, length); + } + + @Override + public ObjectData getObject(String repositoryId, String objectId, String filter, Boolean includeAllowableActions, + IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds, + Boolean includeAcl, ExtensionsData extension) { + return getRepository().getObject(getCallContext(), objectId, null, filter, includeAllowableActions, includeAcl, + this); + } + + @Override + public ObjectData getObjectByPath(String repositoryId, String path, String filter, Boolean includeAllowableActions, + IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds, + Boolean includeAcl, ExtensionsData extension) { + return getRepository().getObjectByPath(getCallContext(), path, filter, includeAllowableActions, includeAcl, + this); + } + + @Override + public Properties getProperties(String repositoryId, String objectId, String filter, ExtensionsData extension) { + ObjectData object = getRepository().getObject(getCallContext(), objectId, null, filter, false, false, this); + return object.getProperties(); + } + + @Override + public List getRenditions(String repositoryId, String objectId, String renditionFilter, + BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) { + return Collections.emptyList(); + } + + @Override + public void moveObject(String repositoryId, Holder objectId, String targetFolderId, String sourceFolderId, + ExtensionsData extension) { + getRepository().moveObject(getCallContext(), objectId, targetFolderId, this); + } + + @Override + public void setContentStream(String repositoryId, Holder objectId, Boolean overwriteFlag, + Holder changeToken, ContentStream contentStream, ExtensionsData extension) { + getRepository().changeContentStream(getCallContext(), objectId, overwriteFlag, contentStream, false); + } + + @Override + public void appendContentStream(String repositoryId, Holder objectId, Holder changeToken, + ContentStream contentStream, boolean isLastChunk, ExtensionsData extension) { + getRepository().changeContentStream(getCallContext(), objectId, true, contentStream, true); + } + + @Override + public void deleteContentStream(String repositoryId, Holder objectId, Holder changeToken, + ExtensionsData extension) { + getRepository().changeContentStream(getCallContext(), objectId, true, null, false); + } + + @Override + public void updateProperties(String repositoryId, Holder objectId, Holder changeToken, + Properties properties, ExtensionsData extension) { + getRepository().updateProperties(getCallContext(), objectId, properties, this); + } + + @Override + public List bulkUpdateProperties(String repositoryId, + List objectIdAndChangeToken, Properties properties, + List addSecondaryTypeIds, List removeSecondaryTypeIds, ExtensionsData extension) { + return getRepository().bulkUpdateProperties(getCallContext(), objectIdAndChangeToken, properties, this); + } + + // --- versioning service --- + + @Override + public List getAllVersions(String repositoryId, String objectId, String versionSeriesId, String filter, + Boolean includeAllowableActions, ExtensionsData extension) { + ObjectData theVersion = getRepository().getObject(getCallContext(), objectId, versionSeriesId, filter, + includeAllowableActions, false, this); + + return Collections.singletonList(theVersion); + } + + @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 getRepository().getObject(getCallContext(), objectId, versionSeriesId, filter, includeAllowableActions, + includeAcl, this); + } + + @Override + public Properties getPropertiesOfLatestVersion(String repositoryId, String objectId, String versionSeriesId, + Boolean major, String filter, ExtensionsData extension) { + ObjectData object = getRepository().getObject(getCallContext(), objectId, versionSeriesId, filter, false, + false, null); + + return object.getProperties(); + } + + // --- ACL service --- + + @Override + public Acl getAcl(String repositoryId, String objectId, Boolean onlyBasicPermissions, ExtensionsData extension) { + return getRepository().getAcl(getCallContext(), objectId); + } +} Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisService.java ------------------------------------------------------------------------------ svn:eol-style = native Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisServiceFactory.java URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisServiceFactory.java?rev=1516830&view=auto ============================================================================== --- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisServiceFactory.java (added) +++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisServiceFactory.java Fri Aug 23 12:48:06 2013 @@ -0,0 +1,251 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.chemistry.opencmis.fileshare; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.chemistry.opencmis.commons.impl.server.AbstractServiceFactory; +import org.apache.chemistry.opencmis.commons.server.CallContext; +import org.apache.chemistry.opencmis.commons.server.CmisService; +import org.apache.chemistry.opencmis.server.support.CmisServiceWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * FileShare Service Factory. + */ +public class FileShareCmisServiceFactory extends AbstractServiceFactory { + + private static final Logger LOG = LoggerFactory.getLogger(FileShareCmisServiceFactory.class); + + private static final String PREFIX_LOGIN = "login."; + private static final String PREFIX_REPOSITORY = "repository."; + private static final String PREFIX_TYPE = "type."; + private static final String SUFFIX_READWRITE = ".readwrite"; + private static final String SUFFIX_READONLY = ".readonly"; + + /** Default maxItems value for getTypeChildren()}. */ + private static final BigInteger DEFAULT_MAX_ITEMS_TYPES = BigInteger.valueOf(50); + + /** Default depth value for getTypeDescendants(). */ + private static final BigInteger DEFAULT_DEPTH_TYPES = BigInteger.valueOf(-1); + + /** + * Default maxItems value for getChildren() and other methods returning + * lists of objects. + */ + private static final BigInteger DEFAULT_MAX_ITEMS_OBJECTS = BigInteger.valueOf(200); + + /** Default depth value for getDescendants(). */ + private static final BigInteger DEFAULT_DEPTH_OBJECTS = BigInteger.valueOf(10); + + /** Each thread gets its own {@link FileShareCmisService} instance. */ + private ThreadLocal> threadLocalService = new ThreadLocal>(); + + private FileShareRepositoryManager repositoryManager; + private FileShareUserManager userManager; + private FileShareTypeManager typeManager; + + public FileShareRepositoryManager getRepositoryManager() { + return repositoryManager; + } + + public FileShareUserManager getUserManager() { + return userManager; + } + + public FileShareTypeManager getTypeManager() { + return typeManager; + } + + @Override + public void init(Map parameters) { + repositoryManager = new FileShareRepositoryManager(); + userManager = new FileShareUserManager(); + typeManager = new FileShareTypeManager(); + + readConfiguration(parameters); + } + + @Override + public void destroy() { + threadLocalService = null; + } + + @Override + public CmisService getService(CallContext context) { + // authenticate the user + // if the authentication fails, authenticate() throws a + // CmisPermissionDeniedException + userManager.authenticate(context); + + // get service object for this thread + CmisServiceWrapper wrapperService = threadLocalService.get(); + if (wrapperService == null) { + // there is no service object for this thread -> create one + FileShareCmisService fileShareService = new FileShareCmisService(repositoryManager); + wrapperService = new CmisServiceWrapper(fileShareService, DEFAULT_MAX_ITEMS_TYPES, + DEFAULT_DEPTH_TYPES, DEFAULT_MAX_ITEMS_OBJECTS, DEFAULT_DEPTH_OBJECTS); + threadLocalService.set(wrapperService); + } + + // hand over the call context to the service object + wrapperService.getWrappedService().setCallContext(context); + + return wrapperService; + } + + // ---- helpers ---- + + /** + * Reads the configuration and sets up the repositories, logins, and type + * definitions. + */ + private void readConfiguration(Map parameters) { + List keys = new ArrayList(parameters.keySet()); + Collections.sort(keys); + + for (String key : keys) { + if (key.startsWith(PREFIX_LOGIN)) { + // get logins + String usernameAndPassword = replaceSystemProperties(parameters.get(key)); + if (usernameAndPassword == null) { + continue; + } + + String username = usernameAndPassword; + String password = ""; + + int x = usernameAndPassword.indexOf(':'); + if (x > -1) { + username = usernameAndPassword.substring(0, x); + password = usernameAndPassword.substring(x + 1); + } + + LOG.info("Adding login '{}'.", username); + + userManager.addLogin(username, password); + } else if (key.startsWith(PREFIX_TYPE)) { + // load type definition + String typeFile = replaceSystemProperties(parameters.get(key)); + + LOG.info("Loading type definition from file: {}", typeFile); + + try { + typeManager.loadTypeDefinitionFromFile(typeFile); + } catch (Exception e) { + LOG.warn("Could not load type defintion from file '{}': {}", typeFile, e.getMessage(), e); + } + } else if (key.startsWith(PREFIX_REPOSITORY)) { + // configure repositories + String repositoryId = key.substring(PREFIX_REPOSITORY.length()).trim(); + int x = repositoryId.lastIndexOf('.'); + if (x > 0) { + repositoryId = repositoryId.substring(0, x); + } + + if (repositoryId.length() == 0) { + throw new IllegalArgumentException("No repository id!"); + } + + if (key.endsWith(SUFFIX_READWRITE)) { + // read-write users + FileShareRepository fsr = repositoryManager.getRepository(repositoryId); + for (String user : split(parameters.get(key))) { + fsr.setUserReadWrite(replaceSystemProperties(user)); + } + } else if (key.endsWith(SUFFIX_READONLY)) { + // read-only users + FileShareRepository fsr = repositoryManager.getRepository(repositoryId); + for (String user : split(parameters.get(key))) { + fsr.setUserReadOnly(replaceSystemProperties(user)); + } + } else { + // new repository + String root = replaceSystemProperties(parameters.get(key)); + + LOG.info("Adding repository '{}': {}", repositoryId, root); + + FileShareRepository fsr = new FileShareRepository(repositoryId, root, typeManager); + repositoryManager.addRepository(fsr); + } + } + } + } + + /** + * Splits a string by comma. + */ + private List split(String csl) { + if (csl == null) { + return Collections.emptyList(); + } + + List result = new ArrayList(); + for (String s : csl.split(",")) { + result.add(s.trim()); + } + + return result; + } + + /** + * Finds all substrings in curly braces and replaces them with the value of + * the corresponding system property. + */ + private String replaceSystemProperties(String s) { + if (s == null) { + return null; + } + + StringBuilder result = new StringBuilder(); + StringBuilder property = null; + boolean inProperty = false; + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + if (inProperty) { + if (c == '}') { + String value = System.getProperty(property.toString()); + if (value != null) { + result.append(value); + } + inProperty = false; + } else { + property.append(c); + } + } else { + if (c == '{') { + property = new StringBuilder(); + inProperty = true; + } else { + result.append(c); + } + } + } + + return result.toString(); + } + +} Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-fileshare/src/main/java/org/apache/chemistry/opencmis/fileshare/FileShareCmisServiceFactory.java ------------------------------------------------------------------------------ svn:eol-style = native