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 [23/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-...
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/CmisRepositoryContextListener.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/CmisRepositoryContextListener.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/CmisRepositoryContextListener.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/CmisRepositoryContextListener.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,136 @@
+/*
+ * 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.server.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.opencmis.server.spi.AbstractServicesFactory;
+
+/**
+ * CMIS context listener.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class CmisRepositoryContextListener implements ServletContextListener {
+
+ public static final String SERVICES_FACTORY = "org.apache.opencmis.servicesfactory";
+
+ private static final Log log = LogFactory.getLog(CmisRepositoryContextListener.class.getName());
+
+ private static final String CONFIG_FILENAME = "/repository.properties";
+ private static final String PROPERTY_CLASS = "class";
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
+ */
+ public void contextInitialized(ServletContextEvent sce) {
+ // create services factory
+ AbstractServicesFactory factory = createServicesFactory(CONFIG_FILENAME);
+
+ // set the services factory into the servlet context
+ sce.getServletContext().setAttribute(SERVICES_FACTORY, factory);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
+ */
+ public void contextDestroyed(ServletContextEvent sce) {
+ // destroy services factory
+ AbstractServicesFactory factory = (AbstractServicesFactory) sce.getServletContext()
+ .getAttribute(SERVICES_FACTORY);
+ if (factory != null) {
+ factory.destroy();
+ }
+ }
+
+ /**
+ * Creates a services factory.
+ */
+ private AbstractServicesFactory createServicesFactory(String filename) {
+ // load properties
+ InputStream stream = this.getClass().getResourceAsStream(filename);
+
+ if (stream == null) {
+ log.warn("Cannot find configuration!");
+ return null;
+ }
+
+ Properties props = new Properties();
+ try {
+ props.load(stream);
+ }
+ catch (IOException e) {
+ log.warn("Cannot load configuration: " + e, e);
+ return null;
+ }
+
+ // get 'class' property
+ String className = props.getProperty(PROPERTY_CLASS);
+ if (className == null) {
+ log.warn("Configuration doesn't contain the property 'class'!");
+ return null;
+ }
+
+ // create a factory instance
+ Object object = null;
+ try {
+ object = Class.forName(className).newInstance();
+ }
+ catch (Exception e) {
+ log.warn("Could not create a services factory instance: " + e, e);
+ return null;
+ }
+
+ if (!(object instanceof AbstractServicesFactory)) {
+ log.warn("The provided class is not a sub class of AbstractServicesFactory!");
+ }
+
+ AbstractServicesFactory factory = (AbstractServicesFactory) object;
+
+ // initialize factory instance
+ Map<String, String> parameters = new HashMap<String, String>();
+
+ for (Enumeration<?> e = props.propertyNames(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ String value = props.getProperty(key);
+ parameters.put(key, value);
+ }
+
+ factory.init(parameters);
+
+ log.info("Initialized Services Factory: " + parameters);
+
+ return factory;
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/CmisRepositoryContextListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/ObjectInfoHolderImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/ObjectInfoHolderImpl.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/ObjectInfoHolderImpl.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/ObjectInfoHolderImpl.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,68 @@
+/*
+ * 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.server.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.opencmis.server.spi.ObjectInfo;
+import org.apache.opencmis.server.spi.ObjectInfoHolder;
+
+/**
+ * Implementation of the {@link ObjectInfo} interface.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class ObjectInfoHolderImpl implements ObjectInfoHolder {
+
+ private Map<String, ObjectInfo> fObjectInfoMap;
+
+ /**
+ * Constructor.
+ */
+ public ObjectInfoHolderImpl() {
+ fObjectInfoMap = new HashMap<String, ObjectInfo>();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.server.spi.ObjectInfoHolder#addObjectInfo(org.apache.opencmis.server.spi.ObjectInfo)
+ */
+ public void addObjectInfo(ObjectInfo info) {
+ if (info == null) {
+ throw new IllegalArgumentException("Object Info must not be null!");
+ }
+ if (info.getId() == null) {
+ throw new IllegalArgumentException("Object Info Id must not be null!");
+ }
+
+ fObjectInfoMap.put(info.getId(), info);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.opencmis.server.spi.ObjectInfoHolder#getObjectInfo(java.lang.String)
+ */
+ public ObjectInfo getObjectInfo(String id) {
+ return fObjectInfoMap.get(id);
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/ObjectInfoHolderImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AclDocument.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AclDocument.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AclDocument.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AclDocument.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,58 @@
+/*
+ * 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.server.impl.atompub;
+
+import static org.apache.opencmis.commons.impl.Converter.convert;
+
+import java.io.OutputStream;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.opencmis.commons.impl.JaxBHelper;
+import org.apache.opencmis.commons.impl.jaxb.CmisAccessControlListType;
+import org.apache.opencmis.commons.provider.AccessControlList;
+
+/**
+ * ACL document.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class AclDocument {
+
+ /**
+ * Creates an ACL document.
+ */
+ public AclDocument() {
+ }
+
+ /**
+ * Writes an object.
+ */
+ public void writeAcl(AccessControlList acl, OutputStream out) throws XMLStreamException,
+ JAXBException {
+ CmisAccessControlListType aclJaxb = convert(acl);
+ if (aclJaxb == null) {
+ return;
+ }
+
+ JaxBHelper.marshal(JaxBHelper.CMIS_OBJECT_FACTORY.createAcl(aclJaxb), out, false);
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AclDocument.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AclService.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AclService.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AclService.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AclService.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,124 @@
+/*
+ * 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.server.impl.atompub;
+
+import static org.apache.opencmis.commons.impl.Converter.convert;
+import static org.apache.opencmis.server.impl.atompub.AtomPubUtils.getBooleanParameter;
+import static org.apache.opencmis.server.impl.atompub.AtomPubUtils.getEnumParameter;
+import static org.apache.opencmis.server.impl.atompub.AtomPubUtils.getStringParameter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.opencmis.commons.enums.AclPropagation;
+import org.apache.opencmis.commons.exceptions.CmisInvalidArgumentException;
+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.jaxb.CmisAccessControlListType;
+import org.apache.opencmis.commons.provider.AccessControlList;
+import org.apache.opencmis.server.spi.AbstractServicesFactory;
+import org.apache.opencmis.server.spi.CallContext;
+import org.apache.opencmis.server.spi.CmisAclService;
+
+/**
+ * ACL Service operations.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class AclService {
+
+ /**
+ * Get ACL.
+ */
+ public static void getAcl(CallContext context, AbstractServicesFactory factory,
+ String repositoryId, HttpServletRequest request, HttpServletResponse response)
+ throws Exception {
+ CmisAclService service = factory.getAclService();
+
+ // get parameters
+ String objectId = getStringParameter(request, Constants.PARAM_ID);
+ Boolean onlyBasicPermissions = getBooleanParameter(request,
+ Constants.PARAM_ONLY_BASIC_PERMISSIONS);
+
+ // execute
+ AccessControlList acl = service.getAcl(context, repositoryId, objectId, onlyBasicPermissions,
+ null);
+
+ if (acl == null) {
+ throw new CmisRuntimeException("ACL is null!");
+ }
+
+ // set headers
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.setContentType(Constants.MEDIATYPE_ACL);
+
+ // write XML
+ AclDocument aclDocument = new AclDocument();
+ aclDocument.writeAcl(acl, response.getOutputStream());
+ }
+
+ /**
+ * Apply ACL.
+ */
+ public static void applyAcl(CallContext context, AbstractServicesFactory factory,
+ String repositoryId, HttpServletRequest request, HttpServletResponse response)
+ throws Exception {
+ CmisAclService service = factory.getAclService();
+
+ // get parameters
+ String objectId = getStringParameter(request, Constants.PARAM_ID);
+ AclPropagation aclPropagation = getEnumParameter(request, Constants.PARAM_ACL_PROPAGATION,
+ AclPropagation.class);
+
+ Object aclRequest = null;
+ try {
+ Unmarshaller u = JaxBHelper.createUnmarshaller();
+ aclRequest = u.unmarshal(request.getInputStream());
+ }
+ catch (Exception e) {
+ throw new CmisInvalidArgumentException("Invalid ACL request: " + e, e);
+ }
+
+ if (!(aclRequest instanceof JAXBElement<?>)) {
+ throw new CmisInvalidArgumentException("Not an ACL document!");
+ }
+
+ if (!(((JAXBElement<?>) aclRequest).getValue() instanceof CmisAccessControlListType)) {
+ throw new CmisInvalidArgumentException("Not an ACL document!");
+ }
+
+ AccessControlList aces = convert((CmisAccessControlListType) ((JAXBElement<?>) aclRequest)
+ .getValue(), null);
+
+ // execute
+ AccessControlList acl = service.applyAcl(context, repositoryId, objectId, aces, aclPropagation);
+
+ // set headers
+ response.setStatus(HttpServletResponse.SC_CREATED);
+ response.setContentType(Constants.MEDIATYPE_ACL);
+
+ // write XML
+ AclDocument aclDocument = new AclDocument();
+ aclDocument.writeAcl(acl, response.getOutputStream());
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AclService.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AllowableActionsDocument.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AllowableActionsDocument.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AllowableActionsDocument.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AllowableActionsDocument.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,59 @@
+/*
+ * 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.server.impl.atompub;
+
+import static org.apache.opencmis.commons.impl.Converter.convert;
+
+import java.io.OutputStream;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.opencmis.commons.impl.JaxBHelper;
+import org.apache.opencmis.commons.impl.jaxb.CmisAllowableActionsType;
+import org.apache.opencmis.commons.provider.AllowableActionsData;
+
+/**
+ * Allowable Actions document.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class AllowableActionsDocument {
+
+ /**
+ * Creates an Allowable Actions document.
+ */
+ public AllowableActionsDocument() {
+ }
+
+ /**
+ * Writes an object.
+ */
+ public void writeAllowableActions(AllowableActionsData allowableActions, OutputStream out)
+ throws XMLStreamException, JAXBException {
+ CmisAllowableActionsType allowableActionsJaxb = convert(allowableActions);
+ if (allowableActionsJaxb == null) {
+ return;
+ }
+
+ JaxBHelper.marshal(JaxBHelper.CMIS_OBJECT_FACTORY.createAllowableActions(allowableActionsJaxb),
+ out, false);
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AllowableActionsDocument.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomDocumentBase.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomDocumentBase.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomDocumentBase.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomDocumentBase.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,355 @@
+/*
+ * 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.server.impl.atompub;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.opencmis.commons.impl.Constants;
+
+/**
+ * Atom base class.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public abstract class AtomDocumentBase extends XMLDocumentBase {
+
+ private static final String ID_PREFIX = "http://opencmis.org/";
+ private static final String ID_DUMMY = "http://opencmis.org/no-id";
+
+ private SimpleDateFormat fDateFormater;
+
+ /**
+ * Formats a DateTime.
+ */
+ public String formatDate(long millis) {
+ if (fDateFormater == null) {
+ fDateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
+ fDateFormater.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
+
+ return fDateFormater.format(millis);
+ }
+
+ /**
+ * Generates a valid Atom id.
+ */
+ public String generateAtomId(String input) {
+ if (input == null) {
+ return ID_DUMMY;
+ }
+
+ try {
+ return ID_PREFIX + (new String(Base64.encodeBase64(input.getBytes("UTF-8"))));
+ }
+ catch (UnsupportedEncodingException e) {
+ return ID_DUMMY;
+ }
+ }
+
+ /**
+ * Writes a simple tag.
+ */
+ public void writeSimpleTag(String namespace, String name, String value) throws XMLStreamException {
+ if (value == null) {
+ return;
+ }
+
+ XMLStreamWriter xsw = getWriter();
+
+ xsw.writeStartElement(namespace, name);
+ xsw.writeCharacters(value);
+ xsw.writeEndElement();
+ }
+
+ /**
+ * Writes a simple date tag.
+ */
+ public void writeSimpleDate(String namespace, String name, GregorianCalendar value)
+ throws XMLStreamException {
+ if (value == null) {
+ return;
+ }
+
+ writeSimpleTag(namespace, name, formatDate(value.getTimeInMillis()));
+ }
+
+ /**
+ * Writes a simple date tag.
+ */
+ public void writeSimpleDate(String namespace, String name, long millis) throws XMLStreamException {
+ writeSimpleTag(namespace, name, formatDate(millis));
+ }
+
+ /**
+ * Writes an Atom id tag.
+ */
+ public void writeId(String id) throws XMLStreamException {
+ writeSimpleTag(Constants.NAMESPACE_ATOM, "id", id);
+ }
+
+ /**
+ * Writes an Atom title tag.
+ */
+ public void writeTitle(String title) throws XMLStreamException {
+ writeSimpleTag(Constants.NAMESPACE_ATOM, "title", title);
+ }
+
+ /**
+ * Writes an Atom author tag.
+ */
+ public void writeAuthor(String author) throws XMLStreamException {
+ XMLStreamWriter xsw = getWriter();
+
+ xsw.writeStartElement(Constants.NAMESPACE_ATOM, "author");
+ writeSimpleTag(Constants.NAMESPACE_ATOM, "name", author);
+ xsw.writeEndElement();
+ }
+
+ /**
+ * Writes an Atom updated tag.
+ */
+ public void writeUpdated(GregorianCalendar updated) throws XMLStreamException {
+ writeSimpleDate(Constants.NAMESPACE_ATOM, "updated", updated);
+ }
+
+ /**
+ * Writes an Atom updated tag.
+ */
+ public void writeUpdated(long updated) throws XMLStreamException {
+ writeSimpleDate(Constants.NAMESPACE_ATOM, "updated", updated);
+ }
+
+ /**
+ * Writes an Atom published tag.
+ */
+ public void writePublished(GregorianCalendar published) throws XMLStreamException {
+ writeSimpleDate(Constants.NAMESPACE_ATOM, "published", published);
+ }
+
+ /**
+ * Writes an Atom published tag.
+ */
+ public void writePublished(long published) throws XMLStreamException {
+ writeSimpleDate(Constants.NAMESPACE_ATOM, "published", published);
+ }
+
+ /**
+ * Writes a CMIS pathSegment tag.
+ */
+ public void writePathSegment(String pathSegment) throws XMLStreamException {
+ writeSimpleTag(Constants.NAMESPACE_RESTATOM, "pathSegment", pathSegment);
+ }
+
+ /**
+ * Writes a CMIS relativePathSegment tag.
+ */
+ public void writeRelativePathSegment(String relativePathSegment) throws XMLStreamException {
+ writeSimpleTag(Constants.NAMESPACE_RESTATOM, "relativePathSegment", relativePathSegment);
+ }
+
+ /**
+ * Writes an Atom collection.
+ */
+ public void writeCollection(String href, String collectionType, String text, String... accept)
+ throws XMLStreamException {
+ XMLStreamWriter xsw = getWriter();
+
+ xsw.writeStartElement(Constants.NAMESPACE_APP, "collection");
+ xsw.writeAttribute("href", href);
+
+ if (collectionType != null) {
+ xsw.writeStartElement(Constants.NAMESPACE_RESTATOM, "collectionType");
+ xsw.writeCharacters(collectionType);
+ xsw.writeEndElement();
+ }
+
+ xsw.writeStartElement(Constants.NAMESPACE_ATOM, "title");
+ xsw.writeAttribute("type", text);
+ xsw.writeCharacters(text);
+ xsw.writeEndElement();
+
+ for (String ct : accept) {
+ xsw.writeStartElement(Constants.NAMESPACE_APP, "accept");
+ xsw.writeCharacters(ct);
+ xsw.writeEndElement();
+ }
+
+ xsw.writeEndElement();
+ }
+
+ /**
+ * Writes a link.
+ */
+ public void writeLink(String rel, String href, String type, String id) throws XMLStreamException {
+ XMLStreamWriter xsw = getWriter();
+
+ xsw.writeStartElement(Constants.NAMESPACE_ATOM, "link");
+
+ xsw.writeAttribute("rel", rel);
+ xsw.writeAttribute("href", href);
+ if (type != null) {
+ xsw.writeAttribute("type", type);
+ }
+ if (id != null) {
+ xsw.writeAttribute(Constants.NAMESPACE_RESTATOM, "id", id);
+ }
+
+ xsw.writeEndElement();
+ }
+
+ public void writeServiceLink(String href, String repositoryId) throws XMLStreamException {
+ try {
+ writeLink(Constants.REL_SERVICE, href + "?repositoryId="
+ + URLEncoder.encode(repositoryId, "UTF-8"), Constants.MEDIATYPE_SERVICE, null);
+ }
+ catch (UnsupportedEncodingException e) {
+ }
+ }
+
+ public void writeSelfLink(String href, String id) throws XMLStreamException {
+ writeLink(Constants.REL_SELF, href, Constants.MEDIATYPE_ENTRY, id);
+ }
+
+ public void writeEnclosureLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_ENCLOSURE, href, Constants.MEDIATYPE_ENTRY, null);
+ }
+
+ public void writeEditLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_EDIT, href, Constants.MEDIATYPE_ENTRY, null);
+ }
+
+ public void writeAlternateLink(String href, String type, String kind, String title,
+ BigInteger length) throws XMLStreamException {
+ XMLStreamWriter xsw = getWriter();
+
+ xsw.writeStartElement(Constants.NAMESPACE_ATOM, "link");
+
+ xsw.writeAttribute("rel", Constants.REL_ALTERNATE);
+ xsw.writeAttribute("href", href);
+ if (type != null) {
+ xsw.writeAttribute("type", type);
+ }
+ if (kind != null) {
+ xsw.writeAttribute(Constants.NAMESPACE_RESTATOM, "renditionKind", kind);
+ }
+ if (title != null) {
+ xsw.writeAttribute("title", title);
+ }
+ if (length != null) {
+ xsw.writeAttribute("length", length.toString());
+ }
+
+ xsw.writeEndElement();
+ }
+
+ public void writeWorkingCopyLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_WORKINGCOPY, href, Constants.MEDIATYPE_ENTRY, null);
+ }
+
+ public void writeUpLink(String href, String type) throws XMLStreamException {
+ writeLink(Constants.REL_UP, href, type, null);
+ }
+
+ public void writeDownLink(String href, String type) throws XMLStreamException {
+ writeLink(Constants.REL_DOWN, href, type, null);
+ }
+
+ public void writeVersionHistoryLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_VERSIONHISTORY, href, Constants.MEDIATYPE_FEED, null);
+ }
+
+ public void writeCurrentVerionsLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_CURRENTVERSION, href, Constants.MEDIATYPE_ENTRY, null);
+ }
+
+ public void writeEditMediaLink(String href, String type) throws XMLStreamException {
+ writeLink(Constants.REL_EDITMEDIA, href, type, null);
+ }
+
+ public void writeDescribedByLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_DESCRIBEDBY, href, Constants.MEDIATYPE_ENTRY, null);
+ }
+
+ public void writeAllowableActionsLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_ALLOWABLEACTIONS, href, Constants.MEDIATYPE_ALLOWABLEACTION, null);
+ }
+
+ public void writeAclLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_ACL, href, Constants.MEDIATYPE_ACL, null);
+ }
+
+ public void writePoliciesLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_POLICIES, href, Constants.MEDIATYPE_FEED, null);
+ }
+
+ public void writeRelationshipsLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_RELATIONSHIPS, href, Constants.MEDIATYPE_FEED, null);
+ }
+
+ public void writeRelationshipSourceLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_SOURCE, href, Constants.MEDIATYPE_ENTRY, null);
+ }
+
+ public void writeRelationshipTargetLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_TARGET, href, Constants.MEDIATYPE_ENTRY, null);
+ }
+
+ public void writeFolderTreeLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_FOLDERTREE, href, Constants.MEDIATYPE_DESCENDANTS, null);
+ }
+
+ public void writeTypeUpLink(String href, String type) throws XMLStreamException {
+ writeLink(Constants.REL_UP, href, type, null);
+ }
+
+ public void writeTypeDownLink(String href, String type) throws XMLStreamException {
+ writeLink(Constants.REL_DOWN, href, type, null);
+ }
+
+ public void writeViaLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_VIA, href, Constants.MEDIATYPE_ENTRY, null);
+ }
+
+ public void writeFirstLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_FIRST, href, Constants.MEDIATYPE_FEED, null);
+ }
+
+ public void writeLastLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_LAST, href, Constants.MEDIATYPE_FEED, null);
+ }
+
+ public void writePreviousLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_PREV, href, Constants.MEDIATYPE_FEED, null);
+ }
+
+ public void writeNextLink(String href) throws XMLStreamException {
+ writeLink(Constants.REL_NEXT, href, Constants.MEDIATYPE_FEED, null);
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomDocumentBase.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomEntry.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomEntry.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomEntry.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomEntry.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,144 @@
+/*
+ * 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.server.impl.atompub;
+
+import static org.apache.opencmis.commons.impl.Converter.convert;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.opencmis.commons.api.TypeDefinition;
+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.CmisTypeDefinitionType;
+import org.apache.opencmis.commons.provider.ObjectData;
+import org.apache.opencmis.server.spi.ObjectInfo;
+
+/**
+ * Atom Entry class.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class AtomEntry extends AtomDocumentBase {
+
+ private final static String DEFAULT_AUTHOR = "unknown";
+
+ /**
+ * Creates an Atom entry document.
+ */
+ public AtomEntry() {
+ }
+
+ /**
+ * Creates an Atom entry that is embedded somewhere.
+ */
+ public AtomEntry(XMLStreamWriter writer) {
+ setWriter(writer);
+ }
+
+ /**
+ * Opens the entry tag.
+ */
+ public void startEntry(boolean isRoot) throws XMLStreamException {
+ getWriter().writeStartElement(Constants.NAMESPACE_ATOM, "entry");
+
+ if (isRoot) {
+ writeNamespace(Constants.NAMESPACE_ATOM);
+ writeNamespace(Constants.NAMESPACE_CMIS);
+ writeNamespace(Constants.NAMESPACE_RESTATOM);
+ }
+ }
+
+ /**
+ * Closes the entry tag.
+ */
+ public void endEntry() throws XMLStreamException {
+ getWriter().writeEndElement();
+ }
+
+ /**
+ * Writes an object.
+ */
+ public void writeObject(ObjectData object, ObjectInfo info, String contentSrc,
+ String contentType, String pathSegment, String relativePathSegment)
+ throws XMLStreamException, JAXBException {
+ CmisObjectType objectJaxb = convert(object);
+ if (objectJaxb == null) {
+ return;
+ }
+
+ writeAuthor(info.getCreatedBy());
+ writeId(generateAtomId(info.getId()));
+ writePublished(info.getCreationDate());
+ writeTitle(info.getName());
+ writeUpdated(info.getLastModificationDate());
+
+ writeContent(contentSrc, contentType);
+
+ JaxBHelper.marshal(JaxBHelper.CMIS_EXTRA_OBJECT_FACTORY.createObject(objectJaxb), getWriter(),
+ true);
+
+ writePathSegment(pathSegment);
+ writeRelativePathSegment(relativePathSegment);
+ }
+
+ /**
+ * Writes a type.
+ *
+ * @throws JAXBException
+ */
+ public void writeType(TypeDefinition type) throws XMLStreamException, JAXBException {
+ CmisTypeDefinitionType typeJaxb = convert(type);
+ if (typeJaxb == null) {
+ return;
+ }
+
+ long now = System.currentTimeMillis();
+
+ writeAuthor(DEFAULT_AUTHOR);
+ writeId(generateAtomId(type.getId()));
+ writeTitle(type.getDisplayName());
+ writeUpdated(now);
+
+ JaxBHelper.marshal(JaxBHelper.CMIS_EXTRA_OBJECT_FACTORY.createTypeDefinition(typeJaxb),
+ getWriter(), true);
+ }
+
+ /**
+ * Writes a content tag.
+ */
+ public void writeContent(String src, String type) throws XMLStreamException {
+ if (src == null) {
+ return;
+ }
+
+ XMLStreamWriter xsw = getWriter();
+ xsw.writeStartElement(Constants.NAMESPACE_ATOM, "content");
+
+ xsw.writeAttribute("src", src);
+ if (type != null) {
+ xsw.writeAttribute("type", type);
+ }
+
+ xsw.writeEndElement();
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomEntry.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomEntryParser.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomEntryParser.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomEntryParser.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomEntryParser.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,409 @@
+/*
+ * 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.server.impl.atompub;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.List;
+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.commons.codec.binary.Base64;
+import org.apache.opencmis.commons.PropertyIds;
+import org.apache.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.opencmis.commons.exceptions.CmisNotSupportedException;
+import org.apache.opencmis.commons.impl.Constants;
+import org.apache.opencmis.commons.impl.Converter;
+import org.apache.opencmis.commons.impl.JaxBHelper;
+import org.apache.opencmis.commons.impl.dataobjects.ContentStreamDataImpl;
+import org.apache.opencmis.commons.impl.jaxb.CmisObjectType;
+import org.apache.opencmis.commons.provider.AccessControlList;
+import org.apache.opencmis.commons.provider.ContentStreamData;
+import org.apache.opencmis.commons.provider.ObjectData;
+import org.apache.opencmis.commons.provider.PropertiesData;
+import org.apache.opencmis.commons.provider.PropertyData;
+import org.apache.opencmis.commons.provider.PropertyIdData;
+
+/**
+ * Parser for Atom Entries.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class AtomEntryParser {
+
+ private final static String TAG_ENTRY = "entry";
+ private final static String TAG_OBJECT = "object";
+ private final static String TAG_CONTENT = "content";
+ private final static String TAG_BASE64 = "base64";
+ private final static String TAG_MEDIATYPE = "mediatype";
+
+ private final static String ATTR_SRC = "src";
+ private final static String ATTR_TYPE = "type";
+
+ private ObjectData fObject;
+ private ContentStreamDataImpl fAtomContentStream;
+ private ContentStreamDataImpl fCmisContentStream;
+
+ /**
+ * Constructor.
+ */
+ public AtomEntryParser() {
+ }
+
+ /**
+ * Constructor that immediately parses the given stream.
+ */
+ public AtomEntryParser(InputStream stream) throws Exception {
+ parse(stream);
+ }
+
+ /**
+ * Returns the object.
+ */
+ public ObjectData getObject() {
+ return fObject;
+ }
+
+ /**
+ * Returns the properties of the object.
+ */
+ public PropertiesData getProperties() {
+ return (fObject == null ? null : fObject.getProperties());
+ }
+
+ /**
+ * Returns the Id of the object.
+ */
+ public String getId() {
+ PropertiesData properties = getProperties();
+ if (properties == null) {
+ return null;
+ }
+
+ Map<String, PropertyData<?>> propertiesMap = properties.getProperties();
+ if (propertiesMap == null) {
+ return null;
+ }
+
+ PropertyData<?> property = propertiesMap.get(PropertyIds.CMIS_OBJECT_ID);
+ if (property instanceof PropertyIdData) {
+ return ((PropertyIdData) property).getFirstValue();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the ACL of the object.
+ */
+ public AccessControlList getAcl() {
+ return (fObject == null ? null : fObject.getAcl());
+ }
+
+ /**
+ * Returns the policy id list of the object.
+ */
+ public List<String> getPolicyIds() {
+ if ((fObject == null) || (fObject.getPolicyIds() == null)) {
+ return null;
+ }
+
+ return fObject.getPolicyIds().getPolicyIds();
+ }
+
+ /**
+ * Returns the content stream.
+ */
+ public ContentStreamData getContentStream() {
+ return (fCmisContentStream == null ? fAtomContentStream : fCmisContentStream);
+ }
+
+ /**
+ * Parses the stream.
+ */
+ public void parse(InputStream stream) throws Exception {
+ fObject = null;
+ fAtomContentStream = null;
+ fCmisContentStream = null;
+
+ if (stream == null) {
+ return;
+ }
+
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ XMLStreamReader parser = factory.createXMLStreamReader(stream);
+
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ QName name = parser.getName();
+
+ if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())
+ && (TAG_ENTRY.equals(name.getLocalPart()))) {
+ parseEntry(parser);
+ break;
+ }
+ else {
+ throw new CmisInvalidArgumentException("XML is not an Atom entry!");
+ }
+ }
+
+ if (!next(parser)) {
+ break;
+ }
+ }
+
+ parser.close();
+ }
+
+ /**
+ * Parses an Atom entry.
+ */
+ private void parseEntry(XMLStreamReader parser) throws Exception {
+ next(parser);
+
+ // walk through all tags in entry
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ QName name = parser.getName();
+
+ if (Constants.NAMESPACE_RESTATOM.equals(name.getNamespaceURI())) {
+ if (TAG_OBJECT.equals(name.getLocalPart())) {
+ parseObject(parser);
+ }
+ else if (TAG_CONTENT.equals(name.getLocalPart())) {
+ parseCmisContent(parser);
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())) {
+ if (TAG_CONTENT.equals(name.getLocalPart())) {
+ parseAtomContent(parser);
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else if (event == XMLStreamReader.END_ELEMENT) {
+ break;
+ }
+ else {
+ if (!next(parser)) {
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Parses a CMIS object.
+ */
+ private void parseObject(XMLStreamReader parser) throws Exception {
+ Unmarshaller u = JaxBHelper.createUnmarshaller();
+ JAXBElement<CmisObjectType> object = u.unmarshal(parser, CmisObjectType.class);
+
+ if (object != null) {
+ fObject = Converter.convert(object.getValue());
+ }
+ }
+
+ /**
+ * Extract the content stream.
+ */
+ private void parseAtomContent(XMLStreamReader parser) throws Exception {
+ fAtomContentStream = new ContentStreamDataImpl();
+
+ // read attributes
+ String type = "text";
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ QName attrName = parser.getAttributeName(i);
+ if (ATTR_TYPE.equals(attrName.getLocalPart())) {
+ fAtomContentStream.setMimeType(parser.getAttributeValue(i));
+ if (parser.getAttributeValue(i) != null) {
+ type = parser.getAttributeValue(i).trim().toLowerCase();
+ }
+ }
+ else if (ATTR_SRC.equals(attrName.getLocalPart())) {
+ throw new CmisNotSupportedException("External content not supported!");
+ }
+ }
+
+ next(parser);
+
+ if (type.equals("text") || type.equals("html")) {
+ fAtomContentStream.setStream(new ByteArrayInputStream(readText(parser).getBytes("UTF-8")));
+ }
+ else if (type.equals("xhtml")) {
+ fAtomContentStream.setStream(copy(parser));
+ }
+ else if (type.endsWith("/xml") || type.endsWith("+xml")) {
+ fAtomContentStream.setStream(copy(parser));
+ }
+ else if (type.startsWith("text/")) {
+ fAtomContentStream.setStream(new ByteArrayInputStream(readText(parser).getBytes("UTF-8")));
+ }
+ else {
+ fAtomContentStream.setStream(new ByteArrayInputStream(Base64.decodeBase64(readText(parser))));
+ }
+ }
+
+ /**
+ * Extract the content stream.
+ */
+ private void parseCmisContent(XMLStreamReader parser) throws Exception {
+ fCmisContentStream = new ContentStreamDataImpl();
+
+ next(parser);
+
+ // walk through all tags in content
+ while (true) {
+ int event = parser.getEventType();
+ if (event == XMLStreamReader.START_ELEMENT) {
+ QName name = parser.getName();
+
+ if (Constants.NAMESPACE_RESTATOM.equals(name.getNamespaceURI())) {
+ if (TAG_MEDIATYPE.equals(name.getLocalPart())) {
+ fCmisContentStream.setMimeType(readText(parser));
+ }
+ else if (TAG_BASE64.equals(name.getLocalPart())) {
+ fCmisContentStream.setStream(new ByteArrayInputStream(Base64
+ .decodeBase64(readText(parser))));
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else {
+ skip(parser);
+ }
+ }
+ else if (event == XMLStreamReader.END_ELEMENT) {
+ break;
+ }
+ else {
+ if (!next(parser)) {
+ break;
+ }
+ }
+ }
+
+ next(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();
+ }
+
+ /**
+ * Copies a subtree into a stream.
+ */
+ private InputStream copy(XMLStreamReader parser) throws Exception {
+ // ToDo: implement copy
+
+ 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);
+
+ return null;
+ }
+
+ /**
+ * 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;
+ }
+}
\ No newline at end of file
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomEntryParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomFeed.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomFeed.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomFeed.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomFeed.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,169 @@
+/*
+ * 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.server.impl.atompub;
+
+import java.math.BigInteger;
+import java.util.GregorianCalendar;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.opencmis.commons.impl.Constants;
+import org.apache.opencmis.commons.impl.UrlBuilder;
+
+/**
+ * Atom Feed class.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class AtomFeed extends AtomDocumentBase {
+
+ public static final BigInteger DEFAULT_PAGE_SIZE = BigInteger.valueOf(100);
+
+ /**
+ * Creates an Atom feed document.
+ */
+ public AtomFeed() {
+ }
+
+ /**
+ * Creates an Atom feed that is embedded somewhere.
+ */
+ public AtomFeed(XMLStreamWriter writer) {
+ setWriter(writer);
+ }
+
+ /**
+ * Opens the feed tag.
+ */
+ public void startFeed(boolean isRoot) throws XMLStreamException {
+ getWriter().writeStartElement(Constants.NAMESPACE_ATOM, "feed");
+
+ if (isRoot) {
+ writeNamespace(Constants.NAMESPACE_ATOM);
+ writeNamespace(Constants.NAMESPACE_CMIS);
+ writeNamespace(Constants.NAMESPACE_RESTATOM);
+ writeNamespace(Constants.NAMESPACE_APP);
+ }
+ }
+
+ /**
+ * Opens the children tag.
+ */
+ public void startChildren() throws XMLStreamException {
+ XMLStreamWriter writer = getWriter();
+ writer.writeStartElement(Constants.NAMESPACE_RESTATOM, "children");
+ }
+
+ /**
+ * Closes the feed tag.
+ */
+ public void endChildren() throws XMLStreamException {
+ getWriter().writeEndElement();
+ }
+
+ /**
+ * Closes the feed tag.
+ */
+ public void endFeed() throws XMLStreamException {
+ getWriter().writeEndElement();
+ }
+
+ /**
+ * Writes the feed elements that are required by Atom.
+ */
+ public void writeFeedElements(String id, String author, String title, GregorianCalendar updated,
+ String pathSegment, BigInteger numItems) throws XMLStreamException {
+ writeAuthor(author);
+ writeId(generateAtomId(id));
+ writeTitle(title);
+ writeUpdated(updated);
+ writePathSegment(pathSegment);
+ writeNumItems(numItems);
+ }
+
+ /**
+ * Writes a CMIS numItems tag.
+ */
+ public void writeNumItems(BigInteger numItems) throws XMLStreamException {
+ if (numItems == null) {
+ return;
+ }
+
+ writeSimpleTag(Constants.NAMESPACE_RESTATOM, "numItems", numItems.toString());
+ }
+
+ /**
+ * Writes paging links.
+ */
+ public void writePagingLinks(UrlBuilder pagingUrl, BigInteger maxItems, BigInteger skipCount,
+ BigInteger numItems, Boolean hasMoreItems, BigInteger pageSize) throws XMLStreamException {
+
+ if ((skipCount == null) || (skipCount.compareTo(BigInteger.ZERO) == -1)) {
+ skipCount = BigInteger.ZERO;
+ }
+
+ if ((maxItems == null) || (maxItems.compareTo(BigInteger.ZERO) == -1)) {
+ if ((pageSize == null) || (pageSize.compareTo(BigInteger.ZERO) == -1)) {
+ maxItems = DEFAULT_PAGE_SIZE;
+ }
+ else {
+ maxItems = pageSize;
+ }
+ }
+
+ // if not first page -> add "first" and "previous" link
+ if (skipCount.compareTo(BigInteger.ZERO) == 1) {
+ // first link
+ UrlBuilder firstLink = new UrlBuilder(pagingUrl);
+ firstLink.addParameter(Constants.PARAM_SKIP_COUNT, "0");
+ firstLink.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
+ writeFirstLink(firstLink.toString());
+
+ // previous link
+ UrlBuilder previousLink = new UrlBuilder(pagingUrl);
+ previousLink.addParameter(Constants.PARAM_SKIP_COUNT, skipCount.subtract(maxItems).max(
+ BigInteger.ZERO));
+ previousLink.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
+ writePreviousLink(previousLink.toString());
+ }
+
+ // if has more -> add "next" link
+ if ((hasMoreItems != null) && hasMoreItems.booleanValue()) {
+ // next link
+ UrlBuilder nextLink = new UrlBuilder(pagingUrl);
+ nextLink.addParameter(Constants.PARAM_SKIP_COUNT, skipCount.add(maxItems));
+ nextLink.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
+ writeNextLink(nextLink.toString());
+ }
+
+ // if not last page -> add "last" link
+ if ((numItems != null) && (numItems.compareTo(BigInteger.ZERO) == 1)) {
+ BigInteger lastSkip = numItems.subtract(maxItems).max(BigInteger.ZERO);
+ if (lastSkip.compareTo(BigInteger.ZERO) == 1) {
+ // last link
+ UrlBuilder lastLink = new UrlBuilder(pagingUrl);
+ lastLink.addParameter(Constants.PARAM_SKIP_COUNT, lastSkip);
+ lastLink.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
+ writeLastLink(lastLink.toString());
+ }
+ }
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomFeed.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomPubUtils.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomPubUtils.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomPubUtils.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomPubUtils.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,496 @@
+/*
+ * 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.server.impl.atompub;
+
+import java.lang.reflect.Method;
+import java.math.BigInteger;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.bind.JAXBException;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.opencmis.commons.api.TypeDefinition;
+import org.apache.opencmis.commons.api.TypeDefinitionContainer;
+import org.apache.opencmis.commons.enums.BaseObjectTypeIds;
+import org.apache.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.opencmis.commons.impl.Constants;
+import org.apache.opencmis.commons.impl.ReturnVersion;
+import org.apache.opencmis.commons.impl.UrlBuilder;
+import org.apache.opencmis.commons.provider.ObjectData;
+import org.apache.opencmis.commons.provider.ObjectInFolderContainer;
+import org.apache.opencmis.commons.provider.PropertiesData;
+import org.apache.opencmis.commons.provider.PropertyData;
+import org.apache.opencmis.server.spi.ObjectInfo;
+import org.apache.opencmis.server.spi.ObjectInfoHolder;
+import org.apache.opencmis.server.spi.RenditionInfo;
+
+/**
+ * This class contains operations used by all services.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public final class AtomPubUtils {
+
+ public static final String RESOURCE_CHILDREN = "children";
+ public static final String RESOURCE_DESCENDANTS = "descendants";
+ public static final String RESOURCE_FOLDERTREE = "foldertree";
+ public static final String RESOURCE_TYPE = "type";
+ public static final String RESOURCE_TYPES = "types";
+ public static final String RESOURCE_TYPESDESC = "typedesc";
+ public static final String RESOURCE_ENTRY = "entry";
+ public static final String RESOURCE_PARENTS = "parents";
+ public static final String RESOURCE_VERSIONS = "versions";
+ public static final String RESOURCE_ALLOWABLEACIONS = "allowableactions";
+ public static final String RESOURCE_ACL = "acl";
+ public static final String RESOURCE_POLICIES = "policies";
+ public static final String RESOURCE_RELATIONSHIPS = "relationships";
+ public static final String RESOURCE_OBJECTBYID = "id";
+ public static final String RESOURCE_OBJECTBYPATH = "path";
+ public static final String RESOURCE_QUERY = "query";
+ public static final String RESOURCE_CHECKEDOUT = "checkedout";
+ public static final String RESOURCE_UNFILED = "unfiled";
+ public static final String RESOURCE_CHANGES = "changes";
+ public static final String RESOURCE_CONTENT = "content";
+
+ public static final BigInteger PAGE_SIZE = BigInteger.valueOf(100);
+
+ public static final String TYPE_AUTHOR = "unknown";
+
+ /**
+ * Private constructor.
+ */
+ private AtomPubUtils() {
+ }
+
+ /**
+ * Compiles the base URL for links, collections and templates.
+ */
+ public static UrlBuilder compileBaseUrl(HttpServletRequest request, String repositoryId) {
+ UrlBuilder url = new UrlBuilder(request.getScheme(), request.getServerName(), request
+ .getServerPort(), null);
+
+ url.addPath(request.getContextPath());
+ url.addPath(request.getServletPath());
+
+ if (repositoryId != null) {
+ url.addPath(repositoryId);
+ }
+
+ return url;
+ }
+
+ /**
+ * Compiles a URL for links, collections and templates.
+ */
+ public static String compileUrl(UrlBuilder baseUrl, String resource, String id) {
+ return compileUrlBuilder(baseUrl, resource, id).toString();
+ }
+
+ /**
+ * Compiles a URL for links, collections and templates.
+ */
+ public static UrlBuilder compileUrlBuilder(UrlBuilder baseUrl, String resource, String id) {
+ UrlBuilder url = new UrlBuilder(baseUrl);
+ url.addPath(resource);
+
+ if (id != null) {
+ url.addParameter("id", id);
+ }
+
+ return url;
+ }
+
+ // -------------------------------------------------------------------------
+ // --- parameters ---
+ // -------------------------------------------------------------------------
+
+ /**
+ * Extracts a string parameter.
+ */
+ public static String getStringParameter(HttpServletRequest request, String name) {
+ return request.getParameter(name);
+ }
+
+ /**
+ * Extracts a boolean parameter (with default).
+ */
+ public static boolean getBooleanParameter(HttpServletRequest request, String name, boolean def) {
+ String value = request.getParameter(name);
+ if (value == null) {
+ return def;
+ }
+
+ return Boolean.valueOf(value);
+ }
+
+ /**
+ * Extracts a boolean parameter.
+ */
+ public static Boolean getBooleanParameter(HttpServletRequest request, String name) {
+ String value = request.getParameter(name);
+ if (value == null) {
+ return null;
+ }
+
+ return Boolean.valueOf(value);
+ }
+
+ /**
+ * Extracts an integer parameter (with default).
+ */
+ public static BigInteger getBigIntegerParameter(HttpServletRequest request, String name, long def) {
+ BigInteger result = getBigIntegerParameter(request, name);
+ if (result == null) {
+ result = BigInteger.valueOf(def);
+ }
+
+ return result;
+ }
+
+ /**
+ * Extracts an integer parameter.
+ */
+ public static BigInteger getBigIntegerParameter(HttpServletRequest request, String name) {
+ String value = request.getParameter(name);
+ if (value == null) {
+ return null;
+ }
+
+ try {
+ return new BigInteger(value);
+ }
+ catch (Exception e) {
+ throw new CmisInvalidArgumentException("Invalid parameter '" + name + "'!");
+ }
+ }
+
+ /**
+ * Extracts an enum parameter.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T getEnumParameter(HttpServletRequest request, String name, Class<T> clazz) {
+ String value = request.getParameter(name);
+ if (value == null) {
+ return null;
+ }
+
+ try {
+ Method m = clazz.getMethod("fromValue", new Class[] { String.class });
+ return (T) m.invoke(null, new Object[] { value });
+ }
+ catch (IllegalArgumentException iae) {
+ throw new CmisInvalidArgumentException("Invalid parameter '" + name + "'!");
+ }
+ catch (Exception e) {
+ throw new CmisRuntimeException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Extracts a property from an object.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T getProperty(ObjectData object, String name, Class<T> clazz) {
+ if (object == null) {
+ return null;
+ }
+
+ PropertiesData propData = object.getProperties();
+ if (propData == null) {
+ return null;
+ }
+
+ Map<String, PropertyData<?>> properties = propData.getProperties();
+ if (properties == null) {
+ return null;
+ }
+
+ PropertyData<?> property = properties.get(name);
+ if (property == null) {
+ return null;
+ }
+
+ Object value = property.getFirstValue();
+ if (!clazz.isInstance(value)) {
+ return null;
+ }
+
+ return (T) value;
+ }
+
+ // -------------------------------------------------------------------------
+ // --- entry builder ---
+ // -------------------------------------------------------------------------
+
+ /**
+ * Writes the a object entry.
+ */
+ public static void writeObjectEntry(AtomEntry entry, ObjectData object,
+ ObjectInfoHolder infoHolder, List<ObjectInFolderContainer> children, String repositoryId,
+ String pathSegment, String relativePathSegment, UrlBuilder baseUrl, boolean isRoot)
+ throws XMLStreamException, JAXBException {
+ if ((object == null) || (infoHolder == null)) {
+ throw new CmisRuntimeException("Object or Object Info not set!");
+ }
+
+ ObjectInfo info = infoHolder.getObjectInfo(object.getId());
+ if (info == null) {
+ throw new CmisRuntimeException("Object Info not found!");
+ }
+
+ // start
+ entry.startEntry(isRoot);
+
+ // write object
+ String contentSrc = null;
+
+ if (info.hasContent()) {
+ UrlBuilder contentSrcBuilder = compileUrlBuilder(baseUrl, RESOURCE_CONTENT, info.getId());
+ if (info.getFileName() != null) {
+ contentSrcBuilder.addPath(info.getFileName());
+ }
+
+ contentSrc = contentSrcBuilder.toString();
+ }
+
+ entry.writeObject(object, info, contentSrc, info.getContentType(), pathSegment,
+ relativePathSegment);
+
+ // write links
+ entry.writeServiceLink(baseUrl.toString(), repositoryId);
+
+ entry.writeSelfLink(compileUrl(baseUrl, RESOURCE_ENTRY, info.getId()), info.getId());
+ entry.writeEnclosureLink(compileUrl(baseUrl, RESOURCE_ENTRY, info.getId()));
+ entry.writeEditLink(compileUrl(baseUrl, RESOURCE_ENTRY, info.getId()));
+ entry.writeDescribedByLink(compileUrl(baseUrl, RESOURCE_TYPE, info.getTypeId()));
+ entry.writeAllowableActionsLink(compileUrl(baseUrl, RESOURCE_ALLOWABLEACIONS, info.getId()));
+
+ if (info.hasParent()) {
+ entry.writeUpLink(compileUrl(baseUrl, RESOURCE_PARENTS, info.getId()),
+ Constants.MEDIATYPE_FEED);
+ }
+
+ if (info.getBaseType() == BaseObjectTypeIds.CMIS_FOLDER) {
+ entry.writeDownLink(compileUrl(baseUrl, RESOURCE_CHILDREN, info.getId()),
+ Constants.MEDIATYPE_FEED);
+
+ if (info.supportsDescendants()) {
+ entry.writeDownLink(compileUrl(baseUrl, RESOURCE_DESCENDANTS, info.getId()),
+ Constants.MEDIATYPE_DESCENDANTS);
+ }
+
+ if (info.supportsFolderTree()) {
+ entry.writeFolderTreeLink(compileUrl(baseUrl, RESOURCE_FOLDERTREE, info.getId()));
+ }
+ }
+
+ if (info.hasVersionHistory()) {
+ entry.writeVersionHistoryLink(compileUrl(baseUrl, RESOURCE_VERSIONS, info.getId()));
+ }
+
+ if (!info.isCurrentVersion()) {
+ UrlBuilder cvUrl = compileUrlBuilder(baseUrl, RESOURCE_ENTRY, info.getId());
+ cvUrl.addParameter(Constants.PARAM_RETURN_VERSION, ReturnVersion.LATEST);
+ entry.writeEditLink(cvUrl.toString());
+ }
+
+ if (contentSrc != null) {
+ entry.writeEditMediaLink(contentSrc, info.getContentType());
+ }
+
+ if (info.getWorkingCopyId() != null) {
+ entry.writeWorkingCopyLink(compileUrl(baseUrl, RESOURCE_ENTRY, info.getWorkingCopyId()));
+ }
+
+ if (info.getWorkingCopyOriginalId() != null) {
+ entry.writeViaLink(compileUrl(baseUrl, RESOURCE_ENTRY, info.getWorkingCopyOriginalId()));
+ }
+
+ if (info.getRenditionInfos() != null) {
+ for (RenditionInfo ri : info.getRenditionInfos()) {
+ entry.writeAlternateLink(compileUrl(baseUrl, RESOURCE_CONTENT, ri.getId()), ri
+ .getContenType(), ri.getKind(), ri.getTitle(), ri.getLength());
+ }
+ }
+
+ if (info.hasAcl()) {
+ entry.writeAclLink(compileUrl(baseUrl, RESOURCE_ACL, info.getId()));
+ }
+
+ if (info.supportsPolicies()) {
+ entry.writeAclLink(compileUrl(baseUrl, RESOURCE_POLICIES, info.getId()));
+ }
+
+ if (info.supportsRelationships()) {
+ entry.writeRelationshipsLink(compileUrl(baseUrl, RESOURCE_RELATIONSHIPS, info.getId()));
+ }
+
+ if (info.getRelationshipSourceIds() != null) {
+ for (String id : info.getRelationshipSourceIds()) {
+ entry.writeRelationshipSourceLink(compileUrl(baseUrl, RESOURCE_ENTRY, id));
+ }
+ }
+
+ if (info.getRelationshipTargetIds() != null) {
+ for (String id : info.getRelationshipTargetIds()) {
+ entry.writeRelationshipTargetLink(compileUrl(baseUrl, RESOURCE_ENTRY, id));
+ }
+ }
+
+ // write children
+ if ((children != null) && (children.size() > 0)) {
+ writeObjectChildren(entry, info, children, infoHolder, repositoryId, baseUrl);
+ }
+
+ // we are done
+ entry.endEntry();
+ }
+
+ /**
+ * Writes an objects entry children feed.
+ */
+ public static void writeObjectChildren(AtomEntry entry, ObjectInfo folderInfo,
+ List<ObjectInFolderContainer> children, ObjectInfoHolder infoHolder, String repositoryId,
+ UrlBuilder baseUrl) throws XMLStreamException, JAXBException {
+
+ // start
+ AtomFeed feed = new AtomFeed(entry.getWriter());
+ feed.startChildren();
+ feed.startFeed(false);
+
+ // write basic Atom feed elements
+ feed.writeFeedElements(folderInfo.getId(), folderInfo.getCreatedBy(), folderInfo.getName(),
+ folderInfo.getLastModificationDate(), null, null);
+
+ // write links
+ feed.writeServiceLink(baseUrl.toString(), repositoryId);
+
+ feed.writeSelfLink(compileUrl(baseUrl, RESOURCE_DESCENDANTS, folderInfo.getId()), null);
+
+ feed.writeViaLink(compileUrl(baseUrl, RESOURCE_ENTRY, folderInfo.getId()));
+
+ feed.writeDownLink(compileUrl(baseUrl, RESOURCE_CHILDREN, folderInfo.getId()),
+ Constants.MEDIATYPE_FEED);
+
+ feed.writeDownLink(compileUrl(baseUrl, RESOURCE_FOLDERTREE, folderInfo.getId()),
+ Constants.MEDIATYPE_DESCENDANTS);
+
+ feed.writeUpLink(compileUrl(baseUrl, RESOURCE_PARENTS, folderInfo.getId()),
+ Constants.MEDIATYPE_FEED);
+
+ for (ObjectInFolderContainer container : children) {
+ if ((container != null) && (container.getObject() != null)) {
+ writeObjectEntry(entry, container.getObject().getObject(), infoHolder, container
+ .getChildren(), repositoryId, container.getObject().getPathSegment(), null, baseUrl,
+ false);
+ }
+ }
+
+ // we are done
+ feed.endFeed();
+ feed.endChildren();
+ }
+
+ /**
+ * Writes the a type entry.
+ */
+ public static void writeTypeEntry(AtomEntry entry, TypeDefinition type,
+ List<TypeDefinitionContainer> children, String repositoryId, UrlBuilder baseUrl,
+ boolean isRoot) throws XMLStreamException, JAXBException {
+
+ // start
+ entry.startEntry(isRoot);
+
+ // write type
+ entry.writeType(type);
+
+ // write links
+ entry.writeServiceLink(baseUrl.toString(), repositoryId);
+
+ entry.writeSelfLink(compileUrl(baseUrl, RESOURCE_TYPE, type.getId()), type.getId());
+ entry.writeEnclosureLink(compileUrl(baseUrl, RESOURCE_TYPE, type.getId()));
+ if (type.getParentId() != null) {
+ entry.writeUpLink(compileUrl(baseUrl, RESOURCE_TYPE, type.getParentId()),
+ Constants.MEDIATYPE_ENTRY);
+ }
+ UrlBuilder downLink = compileUrlBuilder(baseUrl, RESOURCE_TYPES, null);
+ downLink.addParameter(Constants.PARAM_TYPE_ID, type.getId());
+ entry.writeDownLink(downLink.toString(), Constants.MEDIATYPE_CHILDREN);
+ entry.writeDescribedByLink(compileUrl(baseUrl, RESOURCE_TYPE, type.getBaseId().value()));
+
+ // write children
+ if ((children != null) && (children.size() > 0)) {
+ writeTypeChildren(entry, type, children, repositoryId, baseUrl);
+ }
+
+ // we are done
+ entry.endEntry();
+ }
+
+ /**
+ * Writes the a type entry children feed.
+ */
+ private static void writeTypeChildren(AtomEntry entry, TypeDefinition type,
+ List<TypeDefinitionContainer> children, String repositoryId, UrlBuilder baseUrl)
+ throws XMLStreamException, JAXBException {
+
+ // start
+ AtomFeed feed = new AtomFeed(entry.getWriter());
+ feed.startChildren();
+ feed.startFeed(false);
+
+ // write basic Atom feed elements
+ feed.writeFeedElements(type.getId(), TYPE_AUTHOR, type.getDisplayName(),
+ new GregorianCalendar(), null, null);
+
+ feed.writeServiceLink(baseUrl.toString(), repositoryId);
+
+ UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_TYPESDESC, null);
+ selfLink.addParameter(Constants.PARAM_TYPE_ID, type.getId());
+ feed.writeSelfLink(selfLink.toString(), type.getId());
+
+ feed.writeViaLink(compileUrl(baseUrl, RESOURCE_TYPE, type.getId()));
+
+ UrlBuilder downLink = compileUrlBuilder(baseUrl, RESOURCE_TYPES, null);
+ downLink.addParameter(Constants.PARAM_TYPE_ID, type.getId());
+ feed.writeDownLink(downLink.toString(), Constants.MEDIATYPE_FEED);
+
+ if (type.getParentId() != null) {
+ feed.writeUpLink(compileUrl(baseUrl, RESOURCE_TYPE, type.getParentId()),
+ Constants.MEDIATYPE_ENTRY);
+ }
+
+ // write tree
+ for (TypeDefinitionContainer container : children) {
+ if ((container != null) && (container.getTypeDefinition() != null)) {
+ writeTypeEntry(entry, container.getTypeDefinition(), container.getChildren(), repositoryId,
+ baseUrl, false);
+ }
+ }
+
+ // we are done
+ feed.endFeed();
+ feed.endChildren();
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/AtomPubUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/BasicAuthCallContextHandler.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/BasicAuthCallContextHandler.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/BasicAuthCallContextHandler.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/BasicAuthCallContextHandler.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,81 @@
+/*
+ * 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.server.impl.atompub;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.opencmis.server.spi.CallContext;
+
+/**
+ * Call Context handler that handles basic authentication.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public class BasicAuthCallContextHandler implements CallContextHandler {
+
+ /**
+ * Constructor.
+ */
+ public BasicAuthCallContextHandler() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.apache.opencmis.server.impl.atompub.CallContextHandler#getCallContextMap(javax.servlet.http.
+ * HttpServletRequest)
+ */
+ public Map<String, String> getCallContextMap(HttpServletRequest request) {
+ Map<String, String> result = null;
+
+ String authHeader = request.getHeader("Authorization");
+ if ((authHeader != null) && (authHeader.trim().toLowerCase().startsWith("basic "))) {
+ int x = authHeader.lastIndexOf(' ');
+ if (x == -1) {
+ return result;
+ }
+
+ String credentials = null;
+ try {
+ credentials = new String(Base64.decodeBase64(authHeader.substring(x + 1).getBytes(
+ "ISO-8859-1")), "ISO-8859-1");
+ }
+ catch (Exception e) {
+ return result;
+ }
+
+ x = credentials.indexOf(':');
+ if (x == -1) {
+ return result;
+ }
+
+ // extract user and password and add them to map
+ result = new HashMap<String, String>();
+ result.put(CallContext.USERNAME, credentials.substring(0, x));
+ result.put(CallContext.PASSWORD, credentials.substring(x + 1));
+ }
+
+ return result;
+ }
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/BasicAuthCallContextHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/CallContextHandler.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/CallContextHandler.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/CallContextHandler.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/CallContextHandler.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,39 @@
+/*
+ * 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.server.impl.atompub;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.opencmis.server.spi.CallContext;
+
+/**
+ * Call Context handler interface.
+ *
+ * @author <a href="mailto:fmueller@opentext.com">Florian Müller</a>
+ *
+ */
+public interface CallContextHandler {
+
+ /**
+ * Returns key-value pairs that will be added to the {@link CallContext}.
+ */
+ Map<String, String> getCallContextMap(HttpServletRequest request);
+}
Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-impl/src/main/java/org/apache/opencmis/server/impl/atompub/CallContextHandler.java
------------------------------------------------------------------------------
svn:eol-style = native