You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by dc...@apache.org on 2010/02/16 17:04:07 UTC
svn commit: r910572 [6/36] - in /incubator/chemistry/trunk/opencmis: ./
_dev/ opencmis-client/ opencmis-client/opencmis-client-api/
opencmis-client/opencmis-client-api/src/
opencmis-client/opencmis-client-api/src/main/
opencmis-client/opencmis-client-a...
Added: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/AbstractAuthenticationProvider.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/AbstractAuthenticationProvider.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/AbstractAuthenticationProvider.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/AbstractAuthenticationProvider.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,107 @@
+/*
+ * 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.opencmis.client.provider.spi;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.opencmis.commons.SessionParameter;
+import org.w3c.dom.Element;
+
+/**
+ * Authentication provider class.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public abstract class AbstractAuthenticationProvider implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Session fSession;
+
+ /**
+ * Sets the {@link Session} the authentication provider lives in.
+ */
+ public void setSession(Session session) {
+ fSession = session;
+ }
+
+ /**
+ * Returns {@link Session}.
+ */
+ public Session getSession() {
+ return fSession;
+ }
+
+ /**
+ * Returns a set of HTTP headers (key-value pairs) that should be added to a HTTP call. This will
+ * be called by the AtomPub and the Web Services binding. You might want to check the binding in
+ * use before you set the headers.
+ *
+ * @param url
+ * the URL of the HTTP call
+ *
+ * @return the HTTP headers or <code>null</code> if no additional headers should be set
+ */
+ public Map<String, List<String>> getHTTPHeaders(String url) {
+ return null;
+ }
+
+ /**
+ * Returns a SOAP header that should be added to a Web Services call.
+ *
+ * @param portObject
+ * the port object
+ *
+ * @return the SOAP headers or <code>null</code> if no additional headers should be set
+ */
+ public Element getSOAPHeaders(Object portObject) {
+ return null;
+ }
+
+ /**
+ * Gets the user name from the session.
+ *
+ * @return the user name or <code>null</code> if the user name is not set
+ */
+ protected String getUser() {
+ Object userObject = getSession().get(SessionParameter.USER);
+ if (userObject instanceof String) {
+ return (String) userObject;
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets the password from the session.
+ *
+ * @return the password or <code>null</code> if the password is not set
+ */
+ protected String getPassword() {
+ Object passwordObject = getSession().get(SessionParameter.PASSWORD);
+ if (passwordObject instanceof String) {
+ return (String) passwordObject;
+ }
+
+ return null;
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/AbstractAuthenticationProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/CmisSpi.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/CmisSpi.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/CmisSpi.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/CmisSpi.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,96 @@
+/*
+ * 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.opencmis.client.provider.spi;
+
+import org.apache.opencmis.commons.provider.AclService;
+import org.apache.opencmis.commons.provider.DiscoveryService;
+import org.apache.opencmis.commons.provider.MultiFilingService;
+import org.apache.opencmis.commons.provider.NavigationService;
+import org.apache.opencmis.commons.provider.ObjectService;
+import org.apache.opencmis.commons.provider.PolicyService;
+import org.apache.opencmis.commons.provider.RelationshipService;
+import org.apache.opencmis.commons.provider.RepositoryService;
+import org.apache.opencmis.commons.provider.VersioningService;
+
+/**
+ * CMIS SPI interface.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public interface CmisSpi {
+ /**
+ * Gets a Repository Service interface object.
+ */
+ RepositoryService getRepositoryService();
+
+ /**
+ * Gets a Navigation Service interface object.
+ */
+ NavigationService getNavigationService();
+
+ /**
+ * Gets an Object Service interface object.
+ */
+ ObjectService getObjectService();
+
+ /**
+ * Gets a Versioning Service interface object.
+ */
+ VersioningService getVersioningService();
+
+ /**
+ * Gets a Relationship Service interface object.
+ */
+ RelationshipService getRelationshipService();
+
+ /**
+ * Gets a Discovery Service interface object.
+ */
+ DiscoveryService getDiscoveryService();
+
+ /**
+ * Gets a Multifiling Service interface object.
+ */
+ MultiFilingService getMultiFilingService();
+
+ /**
+ * Gets an ACL Service interface object.
+ */
+ AclService getAclService();
+
+ /**
+ * Gets a Policy Service interface object.
+ */
+ PolicyService getPolicyService();
+
+ /**
+ * Clears all caches of the current session.
+ */
+ void clearAllCaches();
+
+ /**
+ * Clears all caches of the current session that are related to the given repository.
+ *
+ * @param repositoryId
+ * the repository id
+ */
+ void clearRepositoryCache(String repositoryId);
+
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/CmisSpi.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/CmisSpiFactory.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/CmisSpiFactory.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/CmisSpiFactory.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/CmisSpiFactory.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,35 @@
+/*
+ * 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.opencmis.client.provider.spi;
+
+/**
+ * CMIS SPI factory interface.
+ *
+ * <p>
+ * A class implementing this interface MUST provide a default constructor.
+ * </p>
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public interface CmisSpiFactory {
+
+ CmisSpi getSpiInstance(Session session);
+
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/CmisSpiFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/Session.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/Session.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/Session.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/Session.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,60 @@
+/*
+ * 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.opencmis.client.provider.spi;
+
+import java.io.Serializable;
+
+/**
+ * CMIS provider session interface.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public interface Session extends Serializable {
+
+ /**
+ * Gets a session value.
+ */
+ Object get(String key);
+
+ /**
+ * Returns a session value or the default value if the key doesn't exist.
+ */
+ Object get(String key, Object defValue);
+
+ /**
+ * Returns a session value or the default value if the key doesn't exist.
+ */
+ int get(String key, int defValue);
+
+ /**
+ * Adds a non-transient session value.
+ */
+ void put(String key, Serializable object);
+
+ /**
+ * Adds a session value.
+ */
+ void put(String key, Object object, boolean isTransient);
+
+ /**
+ * Removes a session value.
+ */
+ void remove(String key);
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/Session.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/StandardAuthenticationProvider.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/StandardAuthenticationProvider.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/StandardAuthenticationProvider.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/StandardAuthenticationProvider.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,179 @@
+/*
+ * 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.opencmis.client.provider.spi;
+
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.opencmis.commons.SessionParameter;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Standard authentication provider class.
+ *
+ * Adds a basic authentication HTTP header and a WS-Security UsernameToken SOAP header.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class StandardAuthenticationProvider extends AbstractAuthenticationProvider {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String WSSE_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
+ private static final String WSU_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
+
+ @Override
+ public Map<String, List<String>> getHTTPHeaders(String url) {
+ Map<String, List<String>> result = null;
+
+ // only send HTTP header if configured
+ if (!isTrue(SessionParameter.AUTH_HTTP_BASIC)) {
+ return null;
+ }
+
+ // get user and password
+ String user = getUser();
+ String password = getPassword();
+
+ // if no user is set, don't create HTTP headers
+ if (user == null) {
+ return null;
+ }
+
+ if (password == null) {
+ password = "";
+ }
+
+ String authHeader = "";
+ try {
+ authHeader = "Basic "
+ + new String(Base64.encodeBase64((user + ":" + password).getBytes("ISO-8859-1")),
+ "ISO-8859-1");
+ }
+ catch (UnsupportedEncodingException e) {
+ // shouldn't happen...
+ return null;
+ }
+
+ result = new HashMap<String, List<String>>();
+ result.put("Authorization", Collections.singletonList(authHeader));
+
+ return result;
+ }
+
+ @Override
+ public Element getSOAPHeaders(Object portObject) {
+ // get user and password
+ String user = getUser();
+ String password = getPassword();
+
+ // only send SOAP header if configured
+ if (!isTrue(SessionParameter.AUTH_SOAP_USERNAMETOKEN)) {
+ return null;
+ }
+
+ // if no user is set, don't create SOAP header
+ if (user == null) {
+ return null;
+ }
+
+ if (password == null) {
+ password = "";
+ }
+
+ // set time
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
+ long created = System.currentTimeMillis();
+ long expires = created + 24 * 60 * 60 * 1000; // 24 hours
+
+ // create the SOAP header
+ try {
+ Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+
+ Element wsseSecurityElement = document.createElementNS(WSSE_NAMESPACE, "Security");
+
+ Element wsuTimestampElement = document.createElementNS(WSU_NAMESPACE, "Timestamp");
+ wsseSecurityElement.appendChild(wsuTimestampElement);
+
+ Element tsCreatedElement = document.createElementNS(WSU_NAMESPACE, "Created");
+ tsCreatedElement.setTextContent(sdf.format(created));
+ wsuTimestampElement.appendChild(tsCreatedElement);
+
+ Element tsExpiresElement = document.createElementNS(WSU_NAMESPACE, "Expires");
+ tsExpiresElement.setTextContent(sdf.format(expires));
+ wsuTimestampElement.appendChild(tsExpiresElement);
+
+ Element usernameTokenElement = document.createElementNS(WSSE_NAMESPACE, "UsernameToken");
+ wsseSecurityElement.appendChild(usernameTokenElement);
+
+ Element usernameElement = document.createElementNS(WSSE_NAMESPACE, "Username");
+ usernameElement.setTextContent(user);
+ usernameTokenElement.appendChild(usernameElement);
+
+ Element passwordElement = document.createElementNS(WSSE_NAMESPACE, "Password");
+ passwordElement.setTextContent(password);
+ passwordElement
+ .setAttribute("Type",
+ "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
+ usernameTokenElement.appendChild(passwordElement);
+
+ Element createdElement = document.createElementNS(WSU_NAMESPACE, "Created");
+ createdElement.setTextContent(sdf.format(created));
+ usernameTokenElement.appendChild(createdElement);
+
+ return wsseSecurityElement;
+ }
+ catch (ParserConfigurationException e) {
+ // shouldn't happen...
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns <code>true</code> if the given parameter exists in the session and is set to true,
+ * <code>false</code> otherwise.
+ */
+ private boolean isTrue(String parameterName) {
+ Object value = getSession().get(parameterName);
+
+ if (value instanceof Boolean) {
+ return ((Boolean) value).booleanValue();
+ }
+
+ if (value instanceof String) {
+ return Boolean.parseBoolean((String) value);
+ }
+
+ return false;
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/StandardAuthenticationProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AbstractAtomPubService.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AbstractAtomPubService.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AbstractAtomPubService.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AbstractAtomPubService.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,746 @@
+/*
+ * 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.opencmis.client.provider.spi.atompub;
+
+import static org.apache.opencmis.commons.impl.Converter.convert;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.opencmis.client.provider.spi.Session;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AtomBase;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AtomElement;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AtomEntry;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AtomLink;
+import org.apache.opencmis.client.provider.spi.atompub.objects.RepositoryWorkspace;
+import org.apache.opencmis.client.provider.spi.atompub.objects.ServiceDoc;
+import org.apache.opencmis.commons.PropertyIds;
+import org.apache.opencmis.commons.SessionParameter;
+import org.apache.opencmis.commons.api.ExtensionsData;
+import org.apache.opencmis.commons.api.TypeDefinition;
+import org.apache.opencmis.commons.enums.AclPropagation;
+import org.apache.opencmis.commons.enums.IncludeRelationships;
+import org.apache.opencmis.commons.exceptions.CmisBaseException;
+import org.apache.opencmis.commons.exceptions.CmisConnectionException;
+import org.apache.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.opencmis.commons.exceptions.CmisNotSupportedException;
+import org.apache.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.opencmis.commons.impl.Constants;
+import org.apache.opencmis.commons.impl.JaxBHelper;
+import org.apache.opencmis.commons.impl.ReturnVersion;
+import org.apache.opencmis.commons.impl.UrlBuilder;
+import org.apache.opencmis.commons.impl.dataobjects.AccessControlEntryImpl;
+import org.apache.opencmis.commons.impl.dataobjects.AccessControlListImpl;
+import org.apache.opencmis.commons.impl.dataobjects.AccessControlPrincipalDataImpl;
+import org.apache.opencmis.commons.impl.jaxb.CmisAccessControlListType;
+import org.apache.opencmis.commons.impl.jaxb.CmisObjectType;
+import org.apache.opencmis.commons.impl.jaxb.CmisPropertiesType;
+import org.apache.opencmis.commons.impl.jaxb.CmisPropertyId;
+import org.apache.opencmis.commons.impl.jaxb.CmisRepositoryInfoType;
+import org.apache.opencmis.commons.impl.jaxb.CmisTypeDefinitionType;
+import org.apache.opencmis.commons.provider.AccessControlEntry;
+import org.apache.opencmis.commons.provider.AccessControlList;
+import org.apache.opencmis.commons.provider.ObjectData;
+import org.apache.opencmis.commons.provider.RepositoryInfoData;
+
+/**
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class AbstractAtomPubService {
+
+ protected enum IdentifierType {
+ ID, PATH
+ };
+
+ protected static final String NAME_COLLECTION = "collection";
+ protected static final String NAME_URI_TEMPLATE = "uritemplate";
+ protected static final String NAME_PATH_SEGMENT = "pathSegment";
+ protected static final String NAME_RELATIVE_PATH_SEGMENT = "relativePathSegment";
+ protected static final String NAME_NUM_ITEMS = "numItems";
+
+ private Session fSession;
+
+ /**
+ * Sets the current session.
+ */
+ protected void setSession(Session session) {
+ fSession = session;
+ }
+
+ /**
+ * Gets the current session.
+ */
+ protected Session getSession() {
+ return fSession;
+ }
+
+ /**
+ * Returns the service document URL of this session.
+ */
+ protected String getServiceDocURL() {
+ Object url = fSession.get(SessionParameter.ATOMPUB_URL);
+ if (url instanceof String) {
+ return (String) url;
+ }
+
+ return null;
+ }
+
+ // ---- link cache ----
+
+ /**
+ * Returns the link cache or creates a new cache if it doesn't exist.
+ */
+ protected LinkCache getLinkCache() {
+ LinkCache linkCache = (LinkCache) getSession().get(SpiSessionParameter.LINK_CACHE);
+ if (linkCache == null) {
+ linkCache = new LinkCache(getSession());
+ getSession().put(SpiSessionParameter.LINK_CACHE, linkCache);
+ }
+
+ return linkCache;
+ }
+
+ /**
+ * Gets a link from the cache.
+ */
+ protected String getLink(String repositoryId, String id, String rel, String type) {
+ if (repositoryId == null) {
+ throw new CmisInvalidArgumentException("Repository id must be set!");
+ }
+
+ if (id == null) {
+ throw new CmisInvalidArgumentException("Object id must be set!");
+ }
+
+ return getLinkCache().getLink(repositoryId, id, rel, type);
+ }
+
+ /**
+ * Gets a link from the cache.
+ */
+ protected String getLink(String repositoryId, String id, String rel) {
+ return getLink(repositoryId, id, rel, null);
+ }
+
+ /**
+ * Gets a link from the cache if it is there or loads it into the cache if it is not there.
+ */
+ protected String loadLink(String repositoryId, String id, String rel, String type) {
+ String link = getLink(repositoryId, id, rel, type);
+ if (link == null) {
+ getObjectInternal(repositoryId, IdentifierType.ID, id, ReturnVersion.THIS, null, null, null,
+ null, null, null, null);
+ link = getLink(repositoryId, id, rel, type);
+ }
+
+ return link;
+ }
+
+ /**
+ * Adds a link to the cache.
+ */
+ protected void addLink(String repositoryId, String id, String rel, String type, String link) {
+ getLinkCache().addLink(repositoryId, id, rel, type, link);
+ }
+
+ /**
+ * Adds a link to the cache.
+ */
+ protected void addLink(String repositoryId, String id, AtomLink link) {
+ getLinkCache().addLink(repositoryId, id, link.getRel(), link.getType(), link.getHref());
+ }
+
+ /**
+ * Removes all links of an object.
+ */
+ protected void removeLinks(String repositoryId, String id) {
+ getLinkCache().removeLinks(repositoryId, id);
+ }
+
+ /**
+ * Gets a type link from the cache.
+ */
+ protected String getTypeLink(String repositoryId, String typeId, String rel, String type) {
+ if (repositoryId == null) {
+ throw new CmisInvalidArgumentException("Repository id must be set!");
+ }
+
+ if (typeId == null) {
+ throw new CmisInvalidArgumentException("Type id must be set!");
+ }
+
+ return getLinkCache().getTypeLink(repositoryId, typeId, rel, type);
+ }
+
+ /**
+ * Gets a type link from the cache.
+ */
+ protected String getTypeLink(String repositoryId, String typeId, String rel) {
+ return getTypeLink(repositoryId, typeId, rel, null);
+ }
+
+ /**
+ * Gets a link from the cache if it is there or loads it into the cache if it is not there.
+ */
+ protected String loadTypeLink(String repositoryId, String typeId, String rel, String type) {
+ String link = getTypeLink(repositoryId, typeId, rel, type);
+ if (link == null) {
+ getTypeDefinitionInternal(repositoryId, typeId);
+ link = getTypeLink(repositoryId, typeId, rel, type);
+ }
+
+ return link;
+ }
+
+ /**
+ * Adds a type link to the cache.
+ */
+ protected void addTypeLink(String repositoryId, String typeId, String rel, String type,
+ String link) {
+ getLinkCache().addTypeLink(repositoryId, typeId, rel, type, link);
+ }
+
+ /**
+ * Adds a type link to the cache.
+ */
+ protected void addTypeLink(String repositoryId, String typeId, AtomLink link) {
+ getLinkCache().addTypeLink(repositoryId, typeId, link.getRel(), link.getType(), link.getHref());
+ }
+
+ /**
+ * Removes all links of a type.
+ */
+ protected void removeTypeLinks(String repositoryId, String id) {
+ getLinkCache().removeTypeLinks(repositoryId, id);
+ }
+
+ /**
+ * Gets a collection from the cache.
+ */
+ protected String getCollection(String repositoryId, String collection) {
+ return getLinkCache().getCollection(repositoryId, collection);
+ }
+
+ /**
+ * Gets a collection from the cache if it is there or loads it into the cache if it is not there.
+ */
+ protected String loadCollection(String repositoryId, String collection) {
+ String link = getCollection(repositoryId, collection);
+ if (link == null) {
+ // cache repository info
+ getRepositoriesInternal(repositoryId);
+ link = getCollection(repositoryId, collection);
+ }
+
+ return link;
+ }
+
+ /**
+ * Adds a collection to the cache.
+ */
+ protected void addCollection(String repositoryId, String collection, String link) {
+ getLinkCache().addCollection(repositoryId, collection, link);
+ }
+
+ /**
+ * Gets a repository link from the cache.
+ */
+ protected String getRepositoryLink(String repositoryId, String rel) {
+ return getLinkCache().getRepositoryLink(repositoryId, rel);
+ }
+
+ /**
+ * Gets a repository link from the cache if it is there or loads it into the cache if it is not
+ * there.
+ */
+ protected String loadRepositoryLink(String repositoryId, String rel) {
+ String link = getRepositoryLink(repositoryId, rel);
+ if (link == null) {
+ // cache repository info
+ getRepositoriesInternal(repositoryId);
+ link = getRepositoryLink(repositoryId, rel);
+ }
+
+ return link;
+ }
+
+ /**
+ * Adds a repository link to the cache.
+ */
+ protected void addRepositoryLink(String repositoryId, String rel, String link) {
+ getLinkCache().addRepositoryLink(repositoryId, rel, link);
+ }
+
+ /**
+ * Adds a repository link to the cache.
+ */
+ protected void addRepositoryLink(String repositoryId, AtomLink link) {
+ addRepositoryLink(repositoryId, link.getRel(), link.getHref());
+ }
+
+ /**
+ * Gets an URI template from the cache.
+ */
+ protected String getTemplateLink(String repositoryId, String type, Map<String, Object> parameters) {
+ return getLinkCache().getTemplateLink(repositoryId, type, parameters);
+ }
+
+ /**
+ * Gets a template link from the cache if it is there or loads it into the cache if it is not
+ * there.
+ */
+ protected String loadTemplateLink(String repositoryId, String type, Map<String, Object> parameters) {
+ String link = getTemplateLink(repositoryId, type, parameters);
+ if (link == null) {
+ // cache repository info
+ getRepositoriesInternal(repositoryId);
+ link = getTemplateLink(repositoryId, type, parameters);
+ }
+
+ return link;
+ }
+
+ /**
+ * Adds an URI template to the cache.
+ */
+ protected void addTemplate(String repositoryId, String type, String link) {
+ getLinkCache().addTemplate(repositoryId, type, link);
+ }
+
+ // ---- exceptions ----
+
+ /**
+ * Converts a HTTP status code into an Exception.
+ */
+ protected CmisBaseException convertStatusCode(int code, String message, Throwable t) {
+ switch (code) {
+ case 400:
+ return new CmisInvalidArgumentException(message, t);
+ case 404:
+ return new CmisObjectNotFoundException(message, t);
+ case 403:
+ return new CmisPermissionDeniedException(message, t);
+ case 405:
+ return new CmisNotSupportedException(message, t);
+ case 409:
+ return new CmisConstraintException(message, t);
+ default:
+ return new CmisRuntimeException(message, t);
+ }
+ }
+
+ // ---- helpers ----
+
+ protected boolean is(String name, AtomElement element) {
+ return name.equals(element.getName().getLocalPart());
+ }
+
+ protected boolean isStr(String name, AtomElement element) {
+ return is(name, element) && (element.getObject() instanceof String);
+ }
+
+ protected boolean isInt(String name, AtomElement element) {
+ return is(name, element) && (element.getObject() instanceof BigInteger);
+ }
+
+ protected boolean isNextLink(AtomElement element) {
+ return Constants.REL_NEXT.equals(((AtomLink) element.getObject()).getRel());
+ }
+
+ /**
+ * Creates a CMIS object that only contains an id in the property list.
+ */
+ protected CmisObjectType createIdObject(String objectId) {
+ CmisObjectType object = new CmisObjectType();
+
+ CmisPropertiesType properties = new CmisPropertiesType();
+ object.setProperties(properties);
+
+ CmisPropertyId idProperty = new CmisPropertyId();
+ properties.getProperty().add(idProperty);
+ idProperty.setPropertyDefinitionId(PropertyIds.CMIS_OBJECT_ID);
+ idProperty.getValue().add(objectId);
+
+ return object;
+ }
+
+ /**
+ * Parses an input stream.
+ */
+ @SuppressWarnings("unchecked")
+ protected <T extends AtomBase> T parse(InputStream stream, Class<T> clazz) {
+ AtomPubParser parser = new AtomPubParser(stream);
+
+ try {
+ parser.parse();
+ }
+ catch (Exception e) {
+ throw new CmisConnectionException("Parsing exception!", e);
+ }
+
+ AtomBase parseResult = parser.getResults();
+
+ if (!clazz.isInstance(parseResult)) {
+ throw new CmisConnectionException("Unexpected document! Received "
+ + (parseResult == null ? "something unknown" : parseResult.getType()) + "!");
+ }
+
+ return (T) parseResult;
+ }
+
+ /**
+ * Performs a GET on an URL, checks the response code and returns the result.
+ */
+ protected HttpUtils.Response read(UrlBuilder url) {
+ // make the call
+ HttpUtils.Response resp = HttpUtils.invokeGET(url, fSession);
+
+ // check response code
+ if (resp.getResponseCode() != 200) {
+ throw convertStatusCode(resp.getResponseCode(), resp.getResponseMessage(), null);
+ }
+
+ return resp;
+ }
+
+ /**
+ * Performs a POST on an URL, checks the response code and returns the result.
+ */
+ protected HttpUtils.Response post(UrlBuilder url, String contentType, HttpUtils.Output writer) {
+ // make the call
+ HttpUtils.Response resp = HttpUtils.invokePOST(url, contentType, writer, fSession);
+
+ // check response code
+ if (resp.getResponseCode() != 201) {
+ throw convertStatusCode(resp.getResponseCode(), resp.getResponseMessage(), null);
+ }
+
+ return resp;
+ }
+
+ /**
+ * Performs a PUT on an URL, checks the response code and returns the result.
+ */
+ protected HttpUtils.Response put(UrlBuilder url, String contentType, HttpUtils.Output writer) {
+ // make the call
+ HttpUtils.Response resp = HttpUtils.invokePUT(url, contentType, writer, fSession);
+
+ // check response code
+ if ((resp.getResponseCode() < 200) || (resp.getResponseCode() > 299)) {
+ throw convertStatusCode(resp.getResponseCode(), resp.getResponseMessage(), null);
+ }
+
+ return resp;
+ }
+
+ /**
+ * Performs a DELETE on an URL, checks the response code and returns the result.
+ */
+ protected void delete(UrlBuilder url) {
+ // make the call
+ HttpUtils.Response resp = HttpUtils.invokeDELETE(url, fSession);
+
+ // check response code
+ if (resp.getResponseCode() != 204) {
+ throw convertStatusCode(resp.getResponseCode(), resp.getResponseMessage(), null);
+ }
+ }
+
+ // ---- common operations ----
+
+ /**
+ * Checks if at least one ACE list is not empty.
+ */
+ protected boolean isAclMergeRequired(AccessControlList addAces, AccessControlList removeAces) {
+ return (addAces != null && addAces.getAces() != null && !addAces.getAces().isEmpty())
+ || (removeAces != null && removeAces.getAces() != null && !removeAces.getAces().isEmpty());
+ }
+
+ /**
+ * Merges the new ACL from original, add and remove ACEs lists.
+ */
+ protected AccessControlList mergeAcls(AccessControlList originalAces, AccessControlList addAces,
+ AccessControlList removeAces) {
+
+ if ((originalAces == null) || (originalAces.getAces() == null)) {
+ originalAces = new AccessControlListImpl(new ArrayList<AccessControlEntry>());
+ }
+
+ if ((addAces == null) || (addAces.getAces() == null)) {
+ throw new IllegalArgumentException("add ACEs must not be null!");
+ }
+
+ if ((removeAces == null) || (removeAces.getAces() == null)) {
+ throw new IllegalArgumentException("remove ACEs must not be null!");
+ }
+
+ Map<String, Set<String>> originals = convertACEsToMap(originalAces.getAces());
+ Map<String, Set<String>> adds = convertACEsToMap(addAces.getAces());
+ Map<String, Set<String>> removes = convertACEsToMap(removeAces.getAces());
+ List<AccessControlEntry> newACEs = new ArrayList<AccessControlEntry>();
+
+ // iterate through the original ACEs
+ for (Map.Entry<String, Set<String>> ace : originals.entrySet()) {
+
+ // add permissions
+ Set<String> addPermissions = adds.get(ace.getKey());
+ if (addPermissions != null) {
+ ace.getValue().addAll(addPermissions);
+ }
+
+ // remove permissions
+ Set<String> removePermissions = removes.get(ace.getKey());
+ if (removePermissions != null) {
+ ace.getValue().removeAll(removePermissions);
+ }
+
+ // create new ACE
+ if (!ace.getValue().isEmpty()) {
+ newACEs.add(new AccessControlEntryImpl(new AccessControlPrincipalDataImpl(ace.getKey()),
+ new ArrayList<String>(ace.getValue())));
+ }
+ }
+
+ // find all ACEs that should be added but are not in the original ACE list
+ for (Map.Entry<String, Set<String>> ace : adds.entrySet()) {
+ if (!originals.containsKey(ace.getKey()) && !ace.getValue().isEmpty()) {
+ newACEs.add(new AccessControlEntryImpl(new AccessControlPrincipalDataImpl(ace.getKey()),
+ new ArrayList<String>(ace.getValue())));
+ }
+ }
+
+ return new AccessControlListImpl(newACEs);
+ }
+
+ /**
+ * Converts a list of ACEs into Map for better handling.
+ */
+ private Map<String, Set<String>> convertACEsToMap(List<AccessControlEntry> aces) {
+ Map<String, Set<String>> result = new HashMap<String, Set<String>>();
+
+ for (AccessControlEntry ace : aces) {
+ // don't consider indirect ACEs - we can't change them
+ if (!ace.isDirect()) {
+ // ignore
+ continue;
+ }
+
+ // although a principal must not be null, check it
+ if ((ace.getPrincipal() == null) || (ace.getPrincipal().getPrincipalId() == null)) {
+ // ignore
+ continue;
+ }
+
+ Set<String> permissions = new HashSet<String>();
+ if (ace.getPermissions() != null) {
+ permissions.addAll(ace.getPermissions());
+ }
+
+ result.put(ace.getPrincipal().getPrincipalId(), permissions);
+ }
+
+ return result;
+ }
+
+ /**
+ * Retrieves the Service Document from the server and caches the repository info objects,
+ * collections, links, URI templates, etc.
+ */
+ @SuppressWarnings("unchecked")
+ protected List<RepositoryInfoData> getRepositoriesInternal(String repositoryId) {
+ List<RepositoryInfoData> repInfos = new ArrayList<RepositoryInfoData>();
+
+ // retrieve service doc
+ UrlBuilder url = new UrlBuilder(getServiceDocURL());
+ url.addParameter(Constants.PARAM_REPOSITORY_ID, repositoryId);
+
+ // read and parse
+ HttpUtils.Response resp = read(url);
+ ServiceDoc serviceDoc = parse(resp.getStream(), ServiceDoc.class);
+
+ // walk through the workspaces
+ for (RepositoryWorkspace ws : serviceDoc.getWorkspaces()) {
+ if (ws.getId() == null) {
+ // found a non-CMIS workspace
+ continue;
+ }
+
+ for (AtomElement element : ws.getElements()) {
+ if (is(NAME_COLLECTION, element)) {
+ Map<String, String> colMap = (Map<String, String>) element.getObject();
+ addCollection(ws.getId(), colMap.get("collectionType"), colMap.get("href"));
+ }
+ else if (element.getObject() instanceof AtomLink) {
+ addRepositoryLink(ws.getId(), (AtomLink) element.getObject());
+ }
+ else if (is(NAME_URI_TEMPLATE, element)) {
+ Map<String, String> tempMap = (Map<String, String>) element.getObject();
+ addTemplate(ws.getId(), tempMap.get("type"), tempMap.get("template"));
+ }
+ else if (element.getObject() instanceof CmisRepositoryInfoType) {
+ repInfos.add(convert((CmisRepositoryInfoType) element.getObject()));
+ }
+ }
+ }
+
+ return repInfos;
+ }
+
+ /**
+ * Retrieves an object from the server and caches the links.
+ */
+ protected ObjectData getObjectInternal(String repositoryId, IdentifierType idOrPath,
+ String objectIdOrPath, ReturnVersion returnVersion, String filter,
+ Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+ String renditionFilter, Boolean includePolicyIds, Boolean includeAcl, ExtensionsData extension) {
+ ObjectData result = null;
+
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ parameters.put(Constants.PARAM_ID, objectIdOrPath);
+ parameters.put(Constants.PARAM_PATH, objectIdOrPath);
+ parameters.put(Constants.PARAM_RETURN_VERSION, returnVersion);
+ parameters.put(Constants.PARAM_FILTER, filter);
+ parameters.put(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
+ parameters.put(Constants.PARAM_ACL, includeAcl);
+ parameters.put(Constants.PARAM_POLICY_IDS, includePolicyIds);
+ parameters.put(Constants.PARAM_RELATIONSHIPS, includeRelationships);
+ parameters.put(Constants.PARAM_RENDITION_FILTER, renditionFilter);
+
+ String link = loadTemplateLink(repositoryId,
+ (idOrPath == IdentifierType.ID ? Constants.TEMPLATE_OBJECT_BY_ID
+ : Constants.TEMPLATE_OBJECT_BY_PATH), parameters);
+ if (link == null) {
+ throw new CmisObjectNotFoundException("Unknown repository!");
+ }
+
+ UrlBuilder url = new UrlBuilder(link);
+ // workaround for missing template parameter in the CMIS spec
+ if ((returnVersion != null) && (returnVersion != ReturnVersion.THIS)) {
+ url.addParameter(Constants.PARAM_RETURN_VERSION, returnVersion);
+ }
+
+ // read and parse
+ HttpUtils.Response resp = read(url);
+ AtomEntry entry = parse(resp.getStream(), AtomEntry.class);
+
+ // we expect a CMIS entry
+ if (entry.getId() == null) {
+ throw new CmisConnectionException("Received Atom entry is not a CMIS entry!");
+ }
+
+ // clean up cache
+ removeLinks(repositoryId, entry.getId());
+
+ // walk through the entry
+ for (AtomElement element : entry.getElements()) {
+ if (element.getObject() instanceof AtomLink) {
+ addLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
+ }
+ else if (element.getObject() instanceof CmisObjectType) {
+ result = convert((CmisObjectType) element.getObject());
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Retrieves a type definition.
+ */
+ protected TypeDefinition getTypeDefinitionInternal(String repositoryId, String typeId) {
+ TypeDefinition result = null;
+
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ parameters.put(Constants.PARAM_ID, typeId);
+
+ String link = loadTemplateLink(repositoryId, Constants.TEMPLATE_TYPE_BY_ID, parameters);
+ if (link == null) {
+ throw new CmisObjectNotFoundException("Unknown repository!");
+ }
+
+ // read and parse
+ HttpUtils.Response resp = read(new UrlBuilder(link));
+ AtomEntry entry = parse(resp.getStream(), AtomEntry.class);
+
+ // we expect a CMIS entry
+ if (entry.getId() == null) {
+ throw new CmisConnectionException("Received Atom entry is not a CMIS entry!");
+ }
+
+ // clean up cache
+ removeTypeLinks(repositoryId, entry.getId());
+
+ // walk through the entry
+ for (AtomElement element : entry.getElements()) {
+ if (element.getObject() instanceof AtomLink) {
+ addTypeLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
+ }
+ else if (element.getObject() instanceof CmisTypeDefinitionType) {
+ result = convert((CmisTypeDefinitionType) element.getObject());
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Updates the ACL of an object.
+ */
+ protected AtomEntry updateAcl(String repositoryId, String objectId, AccessControlList acl,
+ AclPropagation aclPropagation) {
+
+ // find the link
+ String link = loadLink(repositoryId, objectId, Constants.REL_ACL, Constants.MEDIATYPE_ACL);
+
+ if (link == null) {
+ throw new CmisObjectNotFoundException(
+ "Unknown repository or object or ACLs are not supported!");
+ }
+
+ UrlBuilder aclUrl = new UrlBuilder(link);
+ aclUrl.addParameter(Constants.PARAM_ACL_PROPAGATION, aclPropagation);
+
+ // set up object and writer
+ final CmisAccessControlListType aclJaxb = convert(acl);
+
+ // update
+ HttpUtils.Response resp = put(aclUrl, Constants.MEDIATYPE_ACL, new HttpUtils.Output() {
+ public void write(OutputStream out) throws Exception {
+ JaxBHelper.marshal(JaxBHelper.CMIS_OBJECT_FACTORY.createAcl(aclJaxb), out, false);
+ }
+ });
+
+ // parse new entry
+ return parse(resp.getStream(), AtomEntry.class);
+ }
+
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AbstractAtomPubService.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AclServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AclServiceImpl.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AclServiceImpl.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AclServiceImpl.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,115 @@
+/*
+ * 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.opencmis.client.provider.spi.atompub;
+
+import static org.apache.opencmis.commons.impl.Converter.convert;
+
+import org.apache.opencmis.client.provider.spi.Session;
+import org.apache.opencmis.client.provider.spi.atompub.objects.Acl;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AtomElement;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AtomEntry;
+import org.apache.opencmis.commons.api.ExtensionsData;
+import org.apache.opencmis.commons.enums.AclPropagation;
+import org.apache.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.opencmis.commons.impl.Constants;
+import org.apache.opencmis.commons.impl.UrlBuilder;
+import org.apache.opencmis.commons.impl.jaxb.CmisObjectType;
+import org.apache.opencmis.commons.provider.AccessControlList;
+import org.apache.opencmis.commons.provider.AclService;
+
+/**
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class AclServiceImpl extends AbstractAtomPubService implements AclService {
+
+ /**
+ * Constructor.
+ */
+ public AclServiceImpl(Session session) {
+ setSession(session);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.ACLService#applyACL(java.lang.String, java.lang.String,
+ * org.apache.opencmis.client.provider.AccessControlList, org.apache.opencmis.client.provider.AccessControlList,
+ * org.apache.opencmis.commons.enums.ACLPropagation, org.apache.opencmis.client.provider.ExtensionsData)
+ */
+ public AccessControlList applyAcl(String repositoryId, String objectId,
+ AccessControlList addAces, AccessControlList removeAces, AclPropagation aclPropagation,
+ ExtensionsData extension) {
+ AccessControlList result = null;
+
+ // fetch the current ACL
+ AccessControlList originalAces = getAcl(repositoryId, objectId, false, null);
+
+ // if no changes required, just return the ACL
+ if (!isAclMergeRequired(addAces, removeAces)) {
+ return originalAces;
+ }
+
+ // merge ACLs
+ AccessControlList newACL = mergeAcls(originalAces, addAces, removeAces);
+
+ // update ACL
+ AtomEntry entry = updateAcl(repositoryId, objectId, newACL, aclPropagation);
+
+ // walk through the entry and find updated ACL
+ for (AtomElement element : entry.getElements()) {
+ if (element.getObject() instanceof CmisObjectType) {
+ // extract new ACL
+ CmisObjectType object = (CmisObjectType) element.getObject();
+ result = convert(object.getAcl(), object.isExactACL());
+
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.ACLService#getACL(java.lang.String, java.lang.String,
+ * java.lang.Boolean, org.apache.opencmis.client.provider.ExtensionsData)
+ */
+ public AccessControlList getAcl(String repositoryId, String objectId,
+ Boolean onlyBasicPermissions, ExtensionsData extension) {
+
+ // find the link
+ String link = loadLink(repositoryId, objectId, Constants.REL_ACL, Constants.MEDIATYPE_ACL);
+
+ if (link == null) {
+ throw new CmisObjectNotFoundException("Unknown repository or object or ACLs are not support!");
+ }
+
+ UrlBuilder url = new UrlBuilder(link);
+ url.addParameter(Constants.PARAM_ONLY_BASIC_PERMISSIONS, onlyBasicPermissions);
+
+ // read and parse
+ HttpUtils.Response resp = read(url);
+ Acl acl = parse(resp.getStream(), Acl.class);
+
+ return convert(acl.getACL(), null);
+ }
+
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AclServiceImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AtomEntryWriter.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AtomEntryWriter.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AtomEntryWriter.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AtomEntryWriter.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,178 @@
+/*
+ * 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.opencmis.client.provider.spi.atompub;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.opencmis.commons.PropertyIds;
+import org.apache.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.opencmis.commons.impl.Constants;
+import org.apache.opencmis.commons.impl.JaxBHelper;
+import org.apache.opencmis.commons.impl.jaxb.CmisObjectType;
+import org.apache.opencmis.commons.impl.jaxb.CmisProperty;
+import org.apache.opencmis.commons.impl.jaxb.CmisPropertyString;
+
+/**
+ * Writes a CMIS Atom entry to an output stream.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class AtomEntryWriter implements CmisAtomPubConstants {
+
+ private static final String PREFIX_ATOM = "atom";
+ private static final String PREFIX_CMIS = "cmis";
+ private static final String PREFIX_RESTATOM = "cmisra";
+
+ private static final int BUFFER_SIZE = 4096;
+
+ private CmisObjectType fObject;
+ private InputStream fStream;
+ private String fMediaType;
+
+ /**
+ * Constructor.
+ */
+ public AtomEntryWriter(CmisObjectType object) {
+ this(object, null, null);
+ }
+
+ /**
+ * Constructor.
+ */
+ public AtomEntryWriter(CmisObjectType object, String mediaType, InputStream stream) {
+ if ((object == null) || (object.getProperties() == null)) {
+ throw new CmisInvalidArgumentException("Object and properties must not be null!");
+ }
+
+ if ((stream != null) && (mediaType == null)) {
+ throw new CmisInvalidArgumentException("Media type must be set if a stream is present!");
+ }
+
+ fObject = object;
+ fMediaType = mediaType;
+ fStream = stream;
+ }
+
+ /**
+ * Writes the entry to an output stream.
+ */
+ public void write(OutputStream out) throws Exception {
+ XMLOutputFactory factory = XMLOutputFactory.newInstance();
+ XMLStreamWriter writer = factory.createXMLStreamWriter(out, "UTF-8");
+
+ writer.setPrefix(PREFIX_ATOM, Constants.NAMESPACE_ATOM);
+ writer.setPrefix(PREFIX_CMIS, Constants.NAMESPACE_CMIS);
+ writer.setPrefix(PREFIX_RESTATOM, Constants.NAMESPACE_RESTATOM);
+
+ // start doc
+ writer.writeStartDocument();
+
+ // start entry
+ writer.writeStartElement(Constants.NAMESPACE_ATOM, TAG_ENTRY);
+ writer.writeNamespace(PREFIX_ATOM, Constants.NAMESPACE_ATOM);
+ writer.writeNamespace(PREFIX_CMIS, Constants.NAMESPACE_CMIS);
+ writer.writeNamespace(PREFIX_RESTATOM, Constants.NAMESPACE_RESTATOM);
+
+ // atom:id
+ writer.writeStartElement(Constants.NAMESPACE_ATOM, TAG_ATOM_ID);
+ writer.writeCharacters("urn:uuid:00000000-0000-0000-0000-00000000000");
+ writer.writeEndElement();
+
+ // atom:title
+ writer.writeStartElement(Constants.NAMESPACE_ATOM, TAG_ATOM_TITLE);
+ writer.writeCharacters(getTitle());
+ writer.writeEndElement();
+
+ // atom:updated
+ writer.writeStartElement(Constants.NAMESPACE_ATOM, TAG_ATOM_UPDATED);
+ writer.writeCharacters(getUpdated());
+ writer.writeEndElement();
+
+ // content
+ if (fStream != null) {
+ writer.writeStartElement(Constants.NAMESPACE_RESTATOM, TAG_CONTENT);
+
+ writer.writeStartElement(Constants.NAMESPACE_RESTATOM, TAG_CONTENT_MEDIATYPE);
+ writer.writeCharacters(fMediaType);
+ writer.writeEndElement();
+
+ writer.writeStartElement(Constants.NAMESPACE_RESTATOM, TAG_CONTENT_BASE64);
+ writer.writeCharacters(getContent());
+ writer.writeEndElement();
+
+ writer.writeEndElement();
+ }
+
+ // object
+ JaxBHelper.marshal(JaxBHelper.CMIS_EXTRA_OBJECT_FACTORY.createObject(fObject), writer, true);
+
+ // end entry
+ writer.writeEndElement();
+
+ // end document
+ writer.writeEndDocument();
+
+ writer.flush();
+ }
+
+ // ---- internal ----
+
+ private String getTitle() {
+ String result = "";
+
+ for (CmisProperty property : fObject.getProperties().getProperty()) {
+ if (PropertyIds.CMIS_NAME.equals(property.getPropertyDefinitionId())
+ && (property instanceof CmisPropertyString)) {
+ List<String> values = ((CmisPropertyString) property).getValue();
+ if (!values.isEmpty()) {
+ return values.get(0);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private String getUpdated() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ return sdf.format(new Date());
+ }
+
+ private String getContent() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int b;
+ while ((b = fStream.read(buffer)) > -1) {
+ baos.write(buffer, 0, b);
+ }
+
+ return new String(Base64.encodeBase64Chunked(baos.toByteArray()), "UTF-8");
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AtomEntryWriter.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AtomPubParser.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AtomPubParser.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AtomPubParser.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AtomPubParser.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,644 @@
+/*
+ * 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.opencmis.client.provider.spi.atompub;
+
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.opencmis.client.provider.spi.atompub.objects.Acl;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AllowableActions;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AtomBase;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AtomElement;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AtomEntry;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AtomFeed;
+import org.apache.opencmis.client.provider.spi.atompub.objects.AtomLink;
+import org.apache.opencmis.client.provider.spi.atompub.objects.RepositoryWorkspace;
+import org.apache.opencmis.client.provider.spi.atompub.objects.ServiceDoc;
+import org.apache.opencmis.commons.impl.Constants;
+import org.apache.opencmis.commons.impl.JaxBHelper;
+import org.apache.opencmis.commons.impl.jaxb.CmisAccessControlListType;
+import org.apache.opencmis.commons.impl.jaxb.CmisAllowableActionsType;
+import org.apache.opencmis.commons.impl.jaxb.CmisObjectType;
+import org.apache.opencmis.commons.impl.jaxb.CmisProperty;
+import org.apache.opencmis.commons.impl.jaxb.CmisPropertyId;
+import org.apache.opencmis.commons.impl.jaxb.CmisRepositoryInfoType;
+import org.apache.opencmis.commons.impl.jaxb.CmisTypeDefinitionType;
+import org.apache.opencmis.commons.impl.jaxb.EnumPropertiesBase;
+
+/**
+ * AtomPub Parser.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class AtomPubParser implements CmisAtomPubConstants {
+
+ // public constants
+ public static final String LINK_REL_CONTENT = "@@content@@";
+
+ private InputStream fStream;
+ private AtomBase fParseResult;
+
+ public AtomPubParser(InputStream stream) {
+ if (stream == null) {
+ throw new IllegalArgumentException("No stream.");
+ }
+
+ fStream = stream;
+ }
+
+ /**
+ * Parses the stream.
+ */
+ public void parse() throws Exception {
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ XMLStreamReader parser = factory.createXMLStreamReader(fStream);
+
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ QName name = parser.getName();
+
+ if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())) {
+ if (TAG_FEED.equals(name.getLocalPart())) {
+ fParseResult = parseFeed(parser);
+ break;
+ }
+ else if (TAG_ENTRY.equals(name.getLocalPart())) {
+ fParseResult = parseEntry(parser);
+ break;
+ }
+ }
+ else if (Constants.NAMESPACE_CMIS.equals(name.getNamespaceURI())) {
+ if (TAG_ALLOWABLEACTIONS.equals(name.getLocalPart())) {
+ fParseResult = parseAllowableActions(parser);
+ break;
+ }
+ else if (TAG_ACL.equals(name.getLocalPart())) {
+ fParseResult = parseACL(parser);
+ break;
+ }
+ }
+ else if (Constants.NAMESPACE_APP.equals(name.getNamespaceURI())) {
+ if (TAG_SERVICE.equals(name.getLocalPart())) {
+ fParseResult = parseServiceDoc(parser);
+ break;
+ }
+ }
+ }
+
+ if (!next(parser)) {
+ break;
+ }
+ }
+
+ parser.close();
+ }
+
+ /**
+ * Return the parse results.
+ */
+ public AtomBase getResults() {
+ return fParseResult;
+ }
+
+ /**
+ * Parses a service document.
+ */
+ private ServiceDoc parseServiceDoc(XMLStreamReader parser) throws Exception {
+ ServiceDoc result = new ServiceDoc();
+
+ next(parser);
+
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ QName name = parser.getName();
+
+ if (Constants.NAMESPACE_APP.equals(name.getNamespaceURI())) {
+ if (TAG_WORKSPACE.equals(name.getLocalPart())) {
+ result.addWorkspace(parseWorkspace(parser));
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else if (event == XMLStreamReader.END_ELEMENT) {
+ break;
+ }
+ else {
+ if (!next(parser)) {
+ break;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Parses a workspace element in a service document.
+ */
+ private RepositoryWorkspace parseWorkspace(XMLStreamReader parser) throws Exception {
+ RepositoryWorkspace workspace = new RepositoryWorkspace();
+
+ next(parser);
+
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ AtomElement element = parseWorkspaceElement(parser);
+
+ // check if we can extract the workspace id
+ if ((element != null) && (element.getObject() instanceof CmisRepositoryInfoType)) {
+ workspace.setId(((CmisRepositoryInfoType) element.getObject()).getRepositoryId());
+ }
+
+ // add to workspace
+ workspace.addElement(element);
+ }
+ else if (event == XMLStreamReader.END_ELEMENT) {
+ break;
+ }
+ else {
+ if (!next(parser)) {
+ break;
+ }
+ }
+ }
+
+ next(parser);
+
+ return workspace;
+ }
+
+ /**
+ * Parses an Atom feed.
+ */
+ private AtomFeed parseFeed(XMLStreamReader parser) throws Exception {
+ AtomFeed result = new AtomFeed();
+
+ next(parser);
+
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ QName name = parser.getName();
+
+ if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())) {
+ if (TAG_LINK.equals(name.getLocalPart())) {
+ result.addElement(parseLink(parser));
+ }
+ else if (TAG_ENTRY.equals(name.getLocalPart())) {
+ result.addEntry(parseEntry(parser));
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else if (Constants.NAMESPACE_RESTATOM.equals(name.getNamespaceURI())) {
+ if (TAG_NUM_ITEMS.equals(name.getLocalPart())) {
+ result.addElement(parseBigInteger(parser));
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else if (event == XMLStreamReader.END_ELEMENT) {
+ break;
+ }
+ else {
+ if (!next(parser)) {
+ break;
+ }
+ }
+ }
+
+ next(parser);
+
+ return result;
+ }
+
+ /**
+ * Parses an Atom entry.
+ */
+ private AtomEntry parseEntry(XMLStreamReader parser) throws Exception {
+ AtomEntry result = new AtomEntry();
+
+ next(parser);
+
+ // walk through all tags in entry
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ AtomElement element = parseElement(parser);
+ if (element != null) {
+ // add to entry
+ result.addElement(element);
+
+ // find and set object id
+ if (element.getObject() instanceof CmisObjectType) {
+ for (CmisProperty prop : ((CmisObjectType) element.getObject()).getProperties()
+ .getProperty()) {
+ if (EnumPropertiesBase.CMIS_OBJECT_ID.value().equals(prop.getPropertyDefinitionId())) {
+ result.setId(((CmisPropertyId) prop).getValue().get(0));
+ }
+ }
+ }
+ else if (element.getObject() instanceof CmisTypeDefinitionType) {
+ result.setId(((CmisTypeDefinitionType) element.getObject()).getId());
+ }
+ }
+ }
+ else if (event == XMLStreamReader.END_ELEMENT) {
+ break;
+ }
+ else {
+ if (!next(parser)) {
+ break;
+ }
+ }
+ }
+
+ next(parser);
+
+ return result;
+ }
+
+ /**
+ * Parses an Allowable Actions document.
+ */
+ private AllowableActions parseAllowableActions(XMLStreamReader parser) throws Exception {
+ AtomElement elemenet = unmarshalElement(parser, CmisAllowableActionsType.class);
+ return new AllowableActions((CmisAllowableActionsType) elemenet.getObject());
+ }
+
+ /**
+ * Parses an ACL document.
+ */
+ private Acl parseACL(XMLStreamReader parser) throws Exception {
+ AtomElement elemenet = unmarshalElement(parser, CmisAccessControlListType.class);
+ return new Acl((CmisAccessControlListType) elemenet.getObject());
+ }
+
+ /**
+ * Parses an element.
+ */
+ private AtomElement parseElement(XMLStreamReader parser) throws Exception {
+ QName name = parser.getName();
+
+ if (Constants.NAMESPACE_RESTATOM.equals(name.getNamespaceURI())) {
+ if (TAG_OBJECT.equals(name.getLocalPart())) {
+ return unmarshalElement(parser, CmisObjectType.class);
+ }
+ else if (TAG_PATH_SEGMENT.equals(name.getLocalPart())
+ || TAG_RELATIVE_PATH_SEGMENT.equals(name.getLocalPart())) {
+ return parseText(parser);
+ }
+ else if (TAG_TYPE.equals(name.getLocalPart())) {
+ return unmarshalElement(parser, CmisTypeDefinitionType.class);
+ }
+ else if (TAG_CHILDREN.equals(name.getLocalPart())) {
+ return parseChildren(parser);
+ }
+ }
+ else if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())) {
+ if (TAG_LINK.equals(name.getLocalPart())) {
+ return parseLink(parser);
+ }
+ else if (TAG_CONTENT.equals(name.getLocalPart())) {
+ return parseAtomContentSrc(parser);
+ }
+ }
+
+ // we don't know it - skip it
+ skip(parser);
+
+ return null;
+ }
+
+ /**
+ * Unmarshals a JAXB element.
+ */
+ private <T> AtomElement unmarshalElement(XMLStreamReader parser, Class<T> cmisType)
+ throws Exception {
+ QName name = parser.getName();
+
+ Unmarshaller u = JaxBHelper.createUnmarshaller();
+ JAXBElement<T> object = u.unmarshal(parser, cmisType);
+
+ return new AtomElement(name, object.getValue());
+ }
+
+ /**
+ * Parses a children element.
+ */
+ private AtomElement parseChildren(XMLStreamReader parser) throws Exception {
+ AtomElement result = null;
+ QName childName = parser.getName();
+
+ next(parser);
+
+ // walk through the children tag
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ QName name = parser.getName();
+
+ if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())) {
+ if (TAG_FEED.equals(name.getLocalPart())) {
+ result = new AtomElement(childName, parseFeed(parser));
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else if (event == XMLStreamReader.END_ELEMENT) {
+ break;
+ }
+ else {
+ if (!next(parser)) {
+ break;
+ }
+ }
+ }
+
+ next(parser);
+
+ return result;
+ }
+
+ /**
+ * Parses a workspace element.
+ */
+ private AtomElement parseWorkspaceElement(XMLStreamReader parser) throws Exception {
+ QName name = parser.getName();
+
+ if (Constants.NAMESPACE_RESTATOM.equals(name.getNamespaceURI())) {
+ if (TAG_REPOSITORY_INFO.equals(name.getLocalPart())) {
+ return unmarshalElement(parser, CmisRepositoryInfoType.class);
+ }
+ else if (TAG_URI_TEMPLATE.equals(name.getLocalPart())) {
+ return parseTemplate(parser);
+ }
+ }
+ else if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())) {
+ if (TAG_LINK.equals(name.getLocalPart())) {
+ return parseLink(parser);
+ }
+ }
+ else if (Constants.NAMESPACE_APP.equals(name.getNamespaceURI())) {
+ if (TAG_COLLECTION.equals(name.getLocalPart())) {
+ return parseCollection(parser);
+ }
+ }
+
+ // we don't know it - skip it
+ skip(parser);
+
+ return null;
+ }
+
+ /**
+ * Parses a collection tag.
+ */
+ private AtomElement parseCollection(XMLStreamReader parser) throws Exception {
+ QName name = parser.getName();
+ Map<String, String> result = new HashMap<String, String>();
+
+ result.put("href", parser.getAttributeValue(null, "href"));
+
+ next(parser);
+
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ QName tagName = parser.getName();
+ if (Constants.NAMESPACE_RESTATOM.equals(tagName.getNamespaceURI())
+ && TAG_COLLECTION_TYPE.equals(tagName.getLocalPart())) {
+ result.put("collectionType", readText(parser));
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else if (event == XMLStreamReader.END_ELEMENT) {
+ break;
+ }
+ else {
+ if (!next(parser)) {
+ break;
+ }
+ }
+ }
+
+ next(parser);
+
+ return new AtomElement(name, result);
+ }
+
+ /**
+ * Parses a template tag.
+ */
+ private AtomElement parseTemplate(XMLStreamReader parser) throws Exception {
+ QName name = parser.getName();
+ Map<String, String> result = new HashMap<String, String>();
+
+ next(parser);
+
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ QName tagName = parser.getName();
+ if (Constants.NAMESPACE_RESTATOM.equals(tagName.getNamespaceURI())) {
+ if (TAG_TEMPLATE_TEMPLATE.equals(tagName.getLocalPart())) {
+ result.put("template", readText(parser));
+ }
+ else if (TAG_TEMPLATE_TYPE.equals(tagName.getLocalPart())) {
+ result.put("type", readText(parser));
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else if (event == XMLStreamReader.END_ELEMENT) {
+ break;
+ }
+ else {
+ if (!next(parser)) {
+ break;
+ }
+ }
+ }
+
+ next(parser);
+
+ return new AtomElement(name, result);
+ }
+
+ /**
+ * Parses a link tag.
+ */
+ private AtomElement parseLink(XMLStreamReader parser) throws Exception {
+ QName name = parser.getName();
+ AtomLink result = new AtomLink();
+
+ // save attributes
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ if (LINK_REL.equals(parser.getAttributeLocalName(i))) {
+ result.setRel(parser.getAttributeValue(i));
+ }
+ else if (LINK_HREF.equals(parser.getAttributeLocalName(i))) {
+ result.setHref(parser.getAttributeValue(i));
+ }
+ else if (LINK_TYPE.equals(parser.getAttributeLocalName(i))) {
+ result.setType(parser.getAttributeValue(i));
+ }
+ }
+
+ // skip enclosed tags, if any
+ skip(parser);
+
+ return new AtomElement(name, result);
+ }
+
+ /**
+ * Parses a link tag.
+ */
+ private AtomElement parseAtomContentSrc(XMLStreamReader parser) throws Exception {
+ QName name = parser.getName();
+ AtomLink result = new AtomLink();
+ result.setRel(LINK_REL_CONTENT);
+
+ // save attributes
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ if (CONTENT_SRC.equals(parser.getAttributeLocalName(i))) {
+ result.setHref(parser.getAttributeValue(i));
+ }
+ }
+
+ // skip enclosed tags, if any
+ skip(parser);
+
+ return new AtomElement(name, result);
+ }
+
+ /**
+ * Parses a text tag.
+ */
+ private AtomElement parseText(XMLStreamReader parser) throws Exception {
+ QName name = parser.getName();
+ return new AtomElement(name, readText(parser));
+ }
+
+ /**
+ * Parses a text tag and convert it into an integer.
+ */
+ private AtomElement parseBigInteger(XMLStreamReader parser) throws Exception {
+ QName name = parser.getName();
+ return new AtomElement(name, new BigInteger(readText(parser)));
+ }
+
+ /**
+ * Parses a tag that contains text.
+ */
+ private String readText(XMLStreamReader parser) throws Exception {
+ StringBuilder sb = new StringBuilder();
+
+ next(parser);
+
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.END_ELEMENT) {
+ break;
+ }
+ else if (event == XMLStreamReader.CHARACTERS) {
+ String s = parser.getText();
+ if (s != null) {
+ sb.append(s);
+ }
+ }
+ else if (event == XMLStreamReader.START_ELEMENT) {
+ throw new RuntimeException("Unexpected tag: " + parser.getName());
+ }
+
+ if (!next(parser)) {
+ break;
+ }
+ }
+
+ next(parser);
+
+ return sb.toString();
+ }
+
+ /**
+ * Skips a tag or subtree.
+ */
+ private void skip(XMLStreamReader parser) throws Exception {
+ int level = 1;
+ while (next(parser)) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ level++;
+ }
+ else if (event == XMLStreamReader.END_ELEMENT) {
+ level--;
+ if (level == 0) {
+ break;
+ }
+ }
+ }
+
+ next(parser);
+ }
+
+ private boolean next(XMLStreamReader parser) throws Exception {
+ if (parser.hasNext()) {
+ parser.next();
+ return true;
+ }
+
+ return false;
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/AtomPubParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/CmisAtomPubConstants.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/CmisAtomPubConstants.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/CmisAtomPubConstants.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/CmisAtomPubConstants.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,69 @@
+/*
+ * 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.opencmis.client.provider.spi.atompub;
+
+/**
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public interface CmisAtomPubConstants {
+
+ // service doc
+ String TAG_SERVICE = "service";
+ String TAG_WORKSPACE = "workspace";
+ String TAG_REPOSITORY_INFO = "repositoryInfo";
+ String TAG_COLLECTION = "collection";
+ String TAG_COLLECTION_TYPE = "collectionType";
+ String TAG_URI_TEMPLATE = "uritemplate";
+ String TAG_TEMPLATE_TEMPLATE = "template";
+ String TAG_TEMPLATE_TYPE = "type";
+ String TAG_LINK = "link";
+
+ // atom
+ String TAG_ATOM_ID = "id";
+ String TAG_ATOM_TITLE = "title";
+ String TAG_ATOM_UPDATED = "updated";
+
+ // feed
+ String TAG_FEED = "feed";
+
+ // entry
+ String TAG_ENTRY = "entry";
+ String TAG_OBJECT = "object";
+ String TAG_NUM_ITEMS = "numItems";
+ String TAG_PATH_SEGMENT = "pathSegment";
+ String TAG_RELATIVE_PATH_SEGMENT = "relativePathSegment";
+ String TAG_TYPE = "type";
+ String TAG_CHILDREN = "children";
+ String TAG_CONTENT = "content";
+ String TAG_CONTENT_MEDIATYPE = "mediatype";
+ String TAG_CONTENT_BASE64 = "base64";
+
+ // allowable actions
+ String TAG_ALLOWABLEACTIONS = "allowableActions";
+
+ // ACL
+ String TAG_ACL = "acl";
+
+ // links
+ String LINK_REL = "rel";
+ String LINK_HREF = "href";
+ String LINK_TYPE = "type";
+ String CONTENT_SRC = "src";
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/CmisAtomPubConstants.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/CmisAtomPubSpi.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/CmisAtomPubSpi.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/CmisAtomPubSpi.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-client/opencmis-provider-impl/src/main/java/org/apache/opencmis/client/provider/spi/atompub/CmisAtomPubSpi.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,218 @@
+/*
+ * 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.opencmis.client.provider.spi.atompub;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.opencmis.client.provider.spi.CmisSpi;
+import org.apache.opencmis.client.provider.spi.CmisSpiFactory;
+import org.apache.opencmis.client.provider.spi.Session;
+import org.apache.opencmis.commons.provider.AclService;
+import org.apache.opencmis.commons.provider.DiscoveryService;
+import org.apache.opencmis.commons.provider.MultiFilingService;
+import org.apache.opencmis.commons.provider.NavigationService;
+import org.apache.opencmis.commons.provider.ObjectService;
+import org.apache.opencmis.commons.provider.PolicyService;
+import org.apache.opencmis.commons.provider.RelationshipService;
+import org.apache.opencmis.commons.provider.RepositoryService;
+import org.apache.opencmis.commons.provider.VersioningService;
+
+/**
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class CmisAtomPubSpi implements CmisSpiFactory, CmisSpi {
+
+ private static Log log = LogFactory.getLog(CmisAtomPubSpi.class);
+
+ private Session fSession;
+
+ private RepositoryService fRepositoryService;
+ private NavigationService fNavigationService;
+ private ObjectService fObjectService;
+ private VersioningService fVersioningService;
+ private DiscoveryService fDiscoveryService;
+ private MultiFilingService fMultiFilingService;
+ private RelationshipService fRelationshipService;
+ private PolicyService fPolicyService;
+ private AclService fACLService;
+
+ /**
+ * Constructor.
+ */
+ public CmisAtomPubSpi() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.opencmis.client.provider.spi.CMISSPIFactory#getSPIInstance(org.apache.opencmis.client.provider
+ * .spi.Session)
+ */
+ public CmisSpi getSpiInstance(Session session) {
+ if (log.isDebugEnabled()) {
+ log.debug("Initializing AtomPub SPI...");
+ }
+
+ fSession = session;
+
+ return this;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.spi.CMISSPI#getRepositoryService()
+ */
+ public RepositoryService getRepositoryService() {
+ if (fRepositoryService == null) {
+ fRepositoryService = new RepositoryServiceImpl(fSession);
+ }
+
+ return fRepositoryService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.spi.CMISSPI#getNavigationService()
+ */
+ public NavigationService getNavigationService() {
+ if (fNavigationService == null) {
+ fNavigationService = new NavigationServiceImpl(fSession);
+ }
+
+ return fNavigationService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.spi.CMISSPI#getObjectService()
+ */
+ public ObjectService getObjectService() {
+ if (fObjectService == null) {
+ fObjectService = new ObjectServiceImpl(fSession);
+ }
+
+ return fObjectService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.spi.CMISSPI#getDiscoveryService()
+ */
+ public DiscoveryService getDiscoveryService() {
+ if (fDiscoveryService == null) {
+ fDiscoveryService = new DiscoveryServiceImpl(fSession);
+ }
+
+ return fDiscoveryService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.spi.CMISSPI#getVersioningService()
+ */
+ public VersioningService getVersioningService() {
+ if (fVersioningService == null) {
+ fVersioningService = new VersioningServiceImpl(fSession);
+ }
+
+ return fVersioningService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.spi.CMISSPI#getMultiFilingService()
+ */
+ public MultiFilingService getMultiFilingService() {
+ if (fMultiFilingService == null) {
+ fMultiFilingService = new MultiFilingServiceImpl(fSession);
+ }
+
+ return fMultiFilingService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.spi.CMISSPI#getRelationshipService()
+ */
+ public RelationshipService getRelationshipService() {
+ if (fRelationshipService == null) {
+ fRelationshipService = new RelationshipServiceImpl(fSession);
+ }
+
+ return fRelationshipService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.spi.CMISSPI#getPolicyService()
+ */
+ public PolicyService getPolicyService() {
+ if (fPolicyService == null) {
+ fPolicyService = new PolicyServiceImpl(fSession);
+ }
+
+ return fPolicyService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.spi.CMISSPI#getACLService()
+ */
+ public AclService getAclService() {
+ if (fACLService == null) {
+ fACLService = new AclServiceImpl(fSession);
+ }
+
+ return fACLService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.spi.CMISSPI#clearAllCaches()
+ */
+ public void clearAllCaches() {
+ fSession.remove(SpiSessionParameter.LINK_CACHE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.client.provider.spi.CMISSPI#clearRepositoryCache(java.lang.String)
+ */
+ public void clearRepositoryCache(String repositoryId) {
+ LinkCache linkCache = (LinkCache) fSession.get(SpiSessionParameter.LINK_CACHE);
+ if (linkCache != null) {
+ linkCache.clearRepository(repositoryId);
+ }
+ }
+
+}