You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2011/04/18 11:29:46 UTC
svn commit: r1094397 [1/3] - in
/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings:
./ src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/
src/main/java/org/apache/chemistry/opencmis/server/impl/browser/...
Author: fmui
Date: Mon Apr 18 09:29:45 2011
New Revision: 1094397
URL: http://svn.apache.org/viewvc?rev=1094397&view=rev
Log:
CMIS-358: Moved browser binding code to server framework
Added:
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/BrowserBindingUtils.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/CmisBrowserBindingServlet.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ControlParser.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/DiscoveryService.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/NavigationService.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ObjectService.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/POSTHttpServletRequestWrapper.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/RepositoryService.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/TypeCache.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/VersioningService.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/json/
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/json/JSONConstants.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/json/JSONConverter.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/css/
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/css/opencmis.css (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/images/
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/images/asf_logo.png (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/images/chemistry_logo_small.png (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/index.html (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/web/
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/web/createdocument.html (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/web/createfolder.html (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/web/demo.html (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/web/index.html (with props)
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/web/opencmis.js (with props)
Modified:
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/pom.xml
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/CmisAtomPubServlet.java
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/shared/ExceptionHelper.java
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/web.xml
Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/pom.xml
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/pom.xml?rev=1094397&r1=1094396&r2=1094397&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/pom.xml (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/pom.xml Mon Apr 18 09:29:45 2011
@@ -78,6 +78,26 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>commons-fileupload</groupId>
+ <artifactId>commons-fileupload</artifactId>
+ <version>1.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ </dependency>
+ <dependency>
+ <groupId>com.googlecode.json-simple</groupId>
+ <artifactId>json-simple</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/CmisAtomPubServlet.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/CmisAtomPubServlet.java?rev=1094397&r1=1094396&r2=1094397&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/CmisAtomPubServlet.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/CmisAtomPubServlet.java Mon Apr 18 09:29:45 2011
@@ -49,6 +49,7 @@ import org.apache.chemistry.opencmis.ser
import org.apache.chemistry.opencmis.server.shared.Dispatcher;
import org.apache.chemistry.opencmis.server.shared.ExceptionHelper;
import org.apache.chemistry.opencmis.server.shared.HttpUtils;
+import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -281,17 +282,20 @@ public class CmisAtomPubServlet extends
PrintWriter pw = response.getWriter();
response.setStatus(statusCode);
response.setContentType("text/html");
-
- pw.print("<html><head><title>Apache Chemistry OpenCMIS - " + exceptionName + " error</title>"
+
+ pw.print("<html><head><title>Apache Chemistry OpenCMIS - "
+ + exceptionName
+ + " error</title>"
+ "<style><!--H1 {font-size:24px;line-height:normal;font-weight:bold;background-color:#f0f0f0;color:#003366;border-bottom:1px solid #3c78b5;padding:2px;} "
+ "BODY {font-family:Verdana,arial,sans-serif;color:black;font-size:14px;} "
+ "HR {color:#3c78b5;height:1px;}--></style></head><body>");
pw.print("<h1>HTTP Status " + statusCode + " - <!--exception-->" + exceptionName + "<!--/exception--></h1>");
- pw.print("<p><!--message-->" + ex.getMessage() + "<!--/message--></p>");
+ pw.print("<p><!--message-->" + StringEscapeUtils.escapeHtml(ex.getMessage()) + "<!--/message--></p>");
String st = ExceptionHelper.getStacktraceAsString(ex);
if (st != null) {
- pw.print("<hr noshade='noshade'/><!--stacktrace--><pre>\n" + st + "\n</pre><!--/stacktrace--><hr noshade='noshade'/>");
+ pw.print("<hr noshade='noshade'/><!--stacktrace--><pre>\n" + st
+ + "\n</pre><!--/stacktrace--><hr noshade='noshade'/>");
}
pw.print("</body></html>");
Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/BrowserBindingUtils.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/BrowserBindingUtils.java?rev=1094397&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/BrowserBindingUtils.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/BrowserBindingUtils.java Mon Apr 18 09:29:45 2011
@@ -0,0 +1,492 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser;
+
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getStringParameter;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.data.Ace;
+import org.apache.chemistry.opencmis.commons.data.Acl;
+import org.apache.chemistry.opencmis.commons.data.ContentStream;
+import org.apache.chemistry.opencmis.commons.data.ObjectData;
+import org.apache.chemistry.opencmis.commons.data.Properties;
+import org.apache.chemistry.opencmis.commons.data.PropertyData;
+import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.impl.Base64;
+import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlEntryImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlPrincipalDataImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertiesImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyBooleanImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDateTimeImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDecimalImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyHtmlImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIdImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIntegerImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyUriImpl;
+import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
+import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
+import org.apache.chemistry.opencmis.server.shared.HttpUtils;
+import org.json.simple.JSONObject;
+import org.json.simple.JSONStreamAware;
+
+public class BrowserBindingUtils {
+
+ public static final String JSON_MIME_TYPE = "application/json";
+
+ public static final String ROOT_PATH_FRAGMENT = "root";
+
+ public static final String SELECTOR_LAST_RESULT = "lastResult";
+
+ public static final String SELECTOR_TYPE_CHILDREN = "typeChildren";
+ public static final String SELECTOR_TYPE_DESCENDANTS = "typeDescendants";
+ public static final String SELECTOR_TYPE_DEFINITION = "typeDefintion";
+
+ public static final String SELECTOR_CONTENT = "content";
+ public static final String SELECTOR_OBJECT = "object";
+ public static final String SELECTOR_CHILDREN = "children";
+ public static final String SELECTOR_DESCENDANTS = "descendants";
+ public static final String SELECTOR_PARENTS = "parents";
+ public static final String SELECTOR_FOLDER_TREE = "folder";
+ public static final String SELECTOR_QUERY = "query";
+ public static final String SELECTOR_VERSIONS = "versions";
+
+ public static final String CMISACTION_CREATEDOCUMENT = "createDocument";
+ public static final String CMISACTION_CREATEFOLDER = "createFolder";
+ public static final String CMISACTION_QUERY = "query";
+
+ public static final String PARAM_SELECTOR = "selector";
+ public static final String PARAM_TRANSACTION = "transaction";
+ public static final String PARAM_CLIENTTOKEN = "clientToken";
+
+ public static final String CONTROL_CMISACTION = "cmisaction";
+ public static final String CONTROL_TRANSACTION = "transaction";
+ public static final String CONTROL_OBJECT_ID = "objectid";
+ public static final String CONTROL_PROP_ID = "propertyid";
+ public static final String CONTROL_PROP_VALUE = "propertyvalue";
+ public static final String CONTROL_POLICY = "policy";
+ public static final String CONTROL_ADD_ACE_PRINCIPAL = "addACEPrincipal";
+ public static final String CONTROL_ADD_ACE_PERMISSION = "addACEPermission";
+ public static final String CONTROL_REMOVE_ACE_PRINCIPAL = "removeACEPrincipal";
+ public static final String CONTROL_REMOVE_ACE_PERMISSION = "removeACEPermission";
+ public static final String CONTROL_CONTENT_TYPE = "contenttype";
+ public static final String CONTROL_FILENAME = "filename";
+
+ public static final String CONTEXT_OBJECT_ID = "org.apache.chemistry.openmis.browserbinding.objectId";
+ public static final String CONTEXT_OBJECT_TYPE_ID = "org.apache.chemistry.openmis.browserbinding.objectTypeId";
+ public static final String CONTEXT_BASETYPE_ID = "org.apache.chemistry.openmis.browserbinding.basetypeId";
+ public static final String CONTEXT_TRANSACTION = "org.apache.chemistry.openmis.browserbinding.transaction";
+
+ public enum CallUrl {
+ SERVICE, REPOSITORY, ROOT
+ }
+
+ /**
+ * Compiles the base URL for links, collections and templates.
+ */
+ public static UrlBuilder compileBaseUrl(HttpServletRequest request) {
+ UrlBuilder url = new UrlBuilder(request.getScheme(), request.getServerName(), request.getServerPort(), null);
+
+ url.addPath(request.getContextPath());
+ url.addPath(request.getServletPath());
+
+ return url;
+ }
+
+ public static UrlBuilder compileRepositoryUrl(HttpServletRequest request, String repositoryId) {
+ return compileBaseUrl(request).addPathSegment(repositoryId);
+ }
+
+ public static UrlBuilder compileRootUrl(HttpServletRequest request, String repositoryId) {
+ return compileRepositoryUrl(request, repositoryId).addPathSegment(BrowserBindingUtils.ROOT_PATH_FRAGMENT);
+ }
+
+ /**
+ * Returns the current CMIS path.
+ */
+ public static String getPath(HttpServletRequest request) {
+ String[] pathFragments = HttpUtils.splitPath(request);
+ if (pathFragments.length < 2) {
+ return null;
+ }
+ if (pathFragments.length == 2) {
+ return "/";
+ }
+
+ StringBuilder sb = new StringBuilder();
+ for (int i = 2; i < pathFragments.length; i++) {
+ if (pathFragments[i].length() == 0) {
+ continue;
+ }
+
+ sb.append("/");
+ sb.append(pathFragments[i]);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Returns the object id of the current request.
+ */
+ public static void prepareContext(CallContext context, CallUrl callUrl, CmisService service, String repositoryId,
+ String objectId, String transaction, HttpServletRequest request) {
+ if (context instanceof CallContextImpl) {
+ ((CallContextImpl) context).put(CONTEXT_TRANSACTION, transaction);
+ }
+
+ if (callUrl != CallUrl.ROOT) {
+ return;
+ }
+
+ ObjectData object = null;
+
+ if (objectId != null) {
+ object = service.getObject(repositoryId, objectId, null, false, IncludeRelationships.NONE, "cmis:none",
+ false, false, null);
+ } else {
+ object = service.getObjectByPath(repositoryId, getPath(request), null, false, IncludeRelationships.NONE,
+ "cmis:none", false, false, null);
+ }
+
+ if (context instanceof CallContextImpl) {
+ ((CallContextImpl) context).put(CONTEXT_OBJECT_ID, object.getId());
+ ((CallContextImpl) context).put(CONTEXT_OBJECT_TYPE_ID,
+ getProperty(object, PropertyIds.OBJECT_TYPE_ID, String.class));
+ ((CallContextImpl) context).put(CONTEXT_BASETYPE_ID,
+ getProperty(object, PropertyIds.BASE_TYPE_ID, String.class));
+ }
+ }
+
+ /**
+ * 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;
+ }
+
+ Properties 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;
+ }
+
+ public static Properties createProperties(ControlParser controlParser, String typeId, TypeCache typeCache) {
+ List<String> propertyIds = controlParser.getValues(CONTROL_PROP_ID);
+ if (propertyIds == null) {
+ return null;
+ }
+
+ Map<Integer, String> singleValuePropertyMap = controlParser.getOneDimMap(CONTROL_PROP_VALUE);
+ Map<Integer, Map<Integer, String>> multiValuePropertyMap = controlParser.getTwoDimMap(CONTROL_PROP_VALUE);
+
+ if (typeId == null) {
+ // it's a create call -> find type id in properties
+ int i = 0;
+ for (String propertId : propertyIds) {
+ if (PropertyIds.OBJECT_TYPE_ID.equals(propertId)) {
+ typeId = singleValuePropertyMap.get(i);
+ break;
+ }
+
+ i++;
+ }
+
+ if (typeId == null) {
+ throw new CmisInvalidArgumentException(PropertyIds.OBJECT_TYPE_ID + " not set!");
+ }
+ }
+
+ TypeDefinition typeDef = typeCache.getTypeDefinition(typeId);
+ if (typeDef == null) {
+ throw new CmisInvalidArgumentException("Invalid type: " + typeId);
+ }
+
+ PropertiesImpl result = new PropertiesImpl();
+
+ int i = 0;
+ for (String propertyId : propertyIds) {
+ PropertyDefinition<?> propDef = typeDef.getPropertyDefinitions().get(propertyId);
+ if (propDef == null) {
+ throw new CmisInvalidArgumentException(propertyId + " is unknown!");
+ }
+
+ PropertyData<?> propertyData = null;
+
+ if (singleValuePropertyMap.containsKey(i)) {
+ propertyData = createPropertyData(propDef, singleValuePropertyMap.get(i));
+ } else if (multiValuePropertyMap.containsKey(i)) {
+ propertyData = createPropertyData(propDef, controlParser.getValues(CONTROL_PROP_VALUE, i));
+ } else {
+ propertyData = createPropertyData(propDef, null);
+ }
+
+ result.addProperty(propertyData);
+
+ i++;
+ }
+
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static PropertyData<?> createPropertyData(PropertyDefinition<?> propDef, Object value) {
+
+ List<String> strValues;
+ if (value == null) {
+ strValues = Collections.emptyList();
+ } else if (value instanceof String) {
+ strValues = new ArrayList<String>();
+ strValues.add((String) value);
+ } else {
+ strValues = (List<String>) value;
+ }
+
+ PropertyData<?> propertyData = null;
+ switch (propDef.getPropertyType()) {
+ case STRING:
+ propertyData = new PropertyStringImpl(propDef.getId(), strValues);
+ break;
+ case ID:
+ propertyData = new PropertyIdImpl(propDef.getId(), strValues);
+ break;
+ case BOOLEAN:
+ List<Boolean> boolValues = new ArrayList<Boolean>(strValues.size());
+ try {
+ for (String s : strValues) {
+ boolValues.add(Boolean.valueOf(s));
+ }
+ } catch (NumberFormatException e) {
+ throw new CmisInvalidArgumentException(propDef.getId() + " value is not a boolean value!");
+ }
+ propertyData = new PropertyBooleanImpl(propDef.getId(), boolValues);
+ break;
+ case INTEGER:
+ List<BigInteger> intValues = new ArrayList<BigInteger>(strValues.size());
+ try {
+ for (String s : strValues) {
+ intValues.add(new BigInteger(s));
+ }
+ } catch (NumberFormatException e) {
+ throw new CmisInvalidArgumentException(propDef.getId() + " value is not an integer value!");
+ }
+ propertyData = new PropertyIntegerImpl(propDef.getId(), intValues);
+ break;
+ case DECIMAL:
+ List<BigDecimal> decValues = new ArrayList<BigDecimal>(strValues.size());
+ try {
+ for (String s : strValues) {
+ decValues.add(new BigDecimal(s));
+ }
+ } catch (NumberFormatException e) {
+ throw new CmisInvalidArgumentException(propDef.getId() + " value is not an integer value!");
+ }
+ propertyData = new PropertyDecimalImpl(propDef.getId(), decValues);
+ break;
+ case DATETIME:
+ List<GregorianCalendar> calValues = new ArrayList<GregorianCalendar>(strValues.size());
+ try {
+ for (String s : strValues) {
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.setTimeInMillis(Long.parseLong(s));
+ calValues.add(cal);
+ }
+ } catch (NumberFormatException e) {
+ throw new CmisInvalidArgumentException(propDef.getId() + " value is not an datetime value!");
+ }
+ propertyData = new PropertyDateTimeImpl(propDef.getId(), calValues);
+ break;
+ case HTML:
+ propertyData = new PropertyHtmlImpl(propDef.getId(), strValues);
+ break;
+ case URI:
+ propertyData = new PropertyUriImpl(propDef.getId(), strValues);
+ break;
+ }
+
+ return propertyData;
+ }
+
+ public static List<String> createPolicies(ControlParser controlParser) {
+ return controlParser.getValues(CONTROL_POLICY);
+ }
+
+ public static Acl createAddAcl(ControlParser controlParser) {
+ List<String> principals = controlParser.getValues(CONTROL_ADD_ACE_PRINCIPAL);
+ if (principals == null) {
+ return null;
+ }
+
+ List<Ace> aces = new ArrayList<Ace>();
+
+ int i = 0;
+ for (String principalId : principals) {
+ aces.add(new AccessControlEntryImpl(new AccessControlPrincipalDataImpl(principalId), controlParser
+ .getValues(CONTROL_ADD_ACE_PERMISSION, i)));
+ i++;
+ }
+
+ return new AccessControlListImpl(aces);
+ }
+
+ public static Acl createRemoveAcl(ControlParser controlParser) {
+ List<String> principals = controlParser.getValues(CONTROL_REMOVE_ACE_PRINCIPAL);
+ if (principals == null) {
+ return null;
+ }
+
+ List<Ace> aces = new ArrayList<Ace>();
+
+ int i = 0;
+ for (String principalId : principals) {
+ aces.add(new AccessControlEntryImpl(new AccessControlPrincipalDataImpl(principalId), controlParser
+ .getValues(CONTROL_REMOVE_ACE_PERMISSION, i)));
+ i++;
+ }
+
+ return new AccessControlListImpl(aces);
+ }
+
+ public static ContentStream createContentStream(HttpServletRequest request) {
+ ContentStreamImpl result = null;
+
+ if (request instanceof POSTHttpServletRequestWrapper) {
+ POSTHttpServletRequestWrapper post = (POSTHttpServletRequestWrapper) request;
+ result = new ContentStreamImpl(post.getFilename(), BigInteger.valueOf(post.getSize()),
+ post.getContentType(), post.getStream());
+ }
+
+ return result;
+ }
+
+ /**
+ * Transforms the transaction into a cookie name.
+ */
+ public static String getCookieName(String transaction) {
+ if ((transaction == null) || (transaction.length() == 0)) {
+ return "cmis%";
+ }
+
+ return "cmis_" + Base64.encodeBytes(transaction.getBytes()).replace('=', '%');
+ }
+
+ /**
+ * Sets a transaction cookie.
+ */
+ public static void setCookie(HttpServletRequest request, HttpServletResponse response, String repositoryId,
+ String transaction, String value) {
+ setCookie(request, response, repositoryId, transaction, value, 3600);
+ }
+
+ /**
+ * Deletes a transaction cookie.
+ */
+ public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String repositoryId,
+ String transaction) {
+ setCookie(request, response, repositoryId, transaction, "", 0);
+ }
+
+ /**
+ * Sets a transaction cookie.
+ */
+ public static void setCookie(HttpServletRequest request, HttpServletResponse response, String repositoryId,
+ String transaction, String value, int expiry) {
+ if ((transaction != null) && (transaction.length() > 0)) {
+ Cookie tansactionCookie = new Cookie(BrowserBindingUtils.getCookieName(transaction), value);
+ tansactionCookie.setMaxAge(expiry);
+ tansactionCookie.setPath(request.getContextPath() + request.getServletPath() + "/" + repositoryId);
+ response.addCookie(tansactionCookie);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static String createCookieValue(int code, String objectId, String ex, String message) {
+ JSONObject result = new JSONObject();
+
+ result.put("code", code);
+ result.put("objectId", objectId == null ? "" : objectId);
+ result.put("exception", ex == null ? "" : ex);
+ result.put("message", message == null ? "" : message);
+
+ return result.toJSONString();
+ }
+
+ /**
+ * Writes JSON to the servlet response and adds a callback wrapper if
+ * requested.
+ */
+ public static void writeJSON(JSONStreamAware json, HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ response.setContentType(JSON_MIME_TYPE);
+ response.setCharacterEncoding("UTF-8");
+
+ String clientToken = getStringParameter(request, PARAM_CLIENTTOKEN);
+ if (clientToken != null) {
+ if (!clientToken.matches("[A-Za-z0-9._\\[\\]]*")) {
+ throw new CmisInvalidArgumentException("Invalid clientToken name!");
+ }
+ response.getWriter().print(clientToken + "(");
+ }
+
+ json.writeJSONString(response.getWriter());
+
+ if (clientToken != null) {
+ response.getWriter().print(");");
+ }
+ }
+}
Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/BrowserBindingUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/CmisBrowserBindingServlet.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/CmisBrowserBindingServlet.java?rev=1094397&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/CmisBrowserBindingServlet.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/CmisBrowserBindingServlet.java Mon Apr 18 09:29:45 2011
@@ -0,0 +1,352 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser;
+
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getStringParameter;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisFilterNotValidException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisNameConstraintViolationException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisStorageException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisStreamNotSupportedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisVersioningException;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
+import org.apache.chemistry.opencmis.commons.server.CmisServiceFactory;
+import org.apache.chemistry.opencmis.server.impl.CmisRepositoryContextListener;
+import org.apache.chemistry.opencmis.server.impl.browser.BrowserBindingUtils.CallUrl;
+import org.apache.chemistry.opencmis.server.impl.browser.json.JSONConstants;
+import org.apache.chemistry.opencmis.server.shared.CallContextHandler;
+import org.apache.chemistry.opencmis.server.shared.Dispatcher;
+import org.apache.chemistry.opencmis.server.shared.ExceptionHelper;
+import org.apache.chemistry.opencmis.server.shared.HttpUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.simple.JSONObject;
+
+public class CmisBrowserBindingServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String PARAM_CALL_CONTEXT_HANDLER = "callContextHandler";
+
+ private static final Log LOG = LogFactory.getLog(CmisBrowserBindingServlet.class.getName());
+
+ private Dispatcher repositoryDispatcher;
+ private Dispatcher rootDispatcher;
+ private CallContextHandler callContextHandler;
+
+ @Override
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+
+ // initialize the call context handler
+ callContextHandler = null;
+ String callContextHandlerClass = config.getInitParameter(PARAM_CALL_CONTEXT_HANDLER);
+ if (callContextHandlerClass != null) {
+ try {
+ callContextHandler = (CallContextHandler) Class.forName(callContextHandlerClass).newInstance();
+ } catch (Exception e) {
+ throw new ServletException("Could not load call context handler: " + e, e);
+ }
+ }
+
+ // initialize the dispatchers
+ repositoryDispatcher = new Dispatcher();
+ rootDispatcher = new Dispatcher();
+
+ try {
+ repositoryDispatcher.addResource("", Dispatcher.METHOD_GET, RepositoryService.class, "getRepositoryInfo");
+ repositoryDispatcher.addResource(BrowserBindingUtils.SELECTOR_LAST_RESULT, Dispatcher.METHOD_GET,
+ RepositoryService.class, "getLastResult");
+ repositoryDispatcher.addResource(BrowserBindingUtils.SELECTOR_TYPE_CHILDREN, Dispatcher.METHOD_GET,
+ RepositoryService.class, "getTypeChildren");
+ repositoryDispatcher.addResource(BrowserBindingUtils.SELECTOR_TYPE_DESCENDANTS, Dispatcher.METHOD_GET,
+ RepositoryService.class, "getTypeDescendants");
+ repositoryDispatcher.addResource(BrowserBindingUtils.SELECTOR_TYPE_DEFINITION, Dispatcher.METHOD_GET,
+ RepositoryService.class, "getTypeDefintion");
+ repositoryDispatcher.addResource(BrowserBindingUtils.SELECTOR_QUERY, Dispatcher.METHOD_GET,
+ DiscoveryService.class, "query");
+ repositoryDispatcher.addResource(BrowserBindingUtils.CMISACTION_QUERY, Dispatcher.METHOD_POST,
+ DiscoveryService.class, "query");
+ repositoryDispatcher.addResource(BrowserBindingUtils.CMISACTION_CREATEDOCUMENT, Dispatcher.METHOD_POST,
+ ObjectService.class, "createDocument");
+
+ rootDispatcher.addResource(BrowserBindingUtils.SELECTOR_OBJECT, Dispatcher.METHOD_GET, ObjectService.class,
+ "getObject");
+ rootDispatcher.addResource(BrowserBindingUtils.SELECTOR_CONTENT, Dispatcher.METHOD_GET,
+ ObjectService.class, "getContentStream");
+ rootDispatcher.addResource(BrowserBindingUtils.SELECTOR_CHILDREN, Dispatcher.METHOD_GET,
+ NavigationService.class, "getChildren");
+ rootDispatcher.addResource(BrowserBindingUtils.SELECTOR_DESCENDANTS, Dispatcher.METHOD_GET,
+ NavigationService.class, "getDescendants");
+ rootDispatcher.addResource(BrowserBindingUtils.SELECTOR_FOLDER_TREE, Dispatcher.METHOD_GET,
+ NavigationService.class, "getFolderTree");
+ rootDispatcher.addResource(BrowserBindingUtils.SELECTOR_PARENTS, Dispatcher.METHOD_GET,
+ NavigationService.class, "getObjectParents");
+ rootDispatcher.addResource(BrowserBindingUtils.SELECTOR_VERSIONS, Dispatcher.METHOD_GET,
+ VersioningService.class, "getAllVersions");
+ rootDispatcher.addResource(BrowserBindingUtils.CMISACTION_CREATEDOCUMENT, Dispatcher.METHOD_POST,
+ ObjectService.class, "createDocument");
+ rootDispatcher.addResource(BrowserBindingUtils.CMISACTION_CREATEFOLDER, Dispatcher.METHOD_POST,
+ ObjectService.class, "createFolder");
+ } catch (NoSuchMethodException e) {
+ LOG.error("Cannot initialize dispatcher!", e);
+ }
+ }
+
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
+ IOException {
+
+ // create a context object, dispatch and handle exceptions
+ CallContext context = null;
+ try {
+ context = HttpUtils.createContext(request, getServletContext(), CallContext.BINDING_BROWSER,
+ callContextHandler);
+ dispatch(context, request, response);
+ } catch (Exception e) {
+ if (e instanceof CmisPermissionDeniedException) {
+ if ((context == null) || (context.getUsername() == null)) {
+ response.setHeader("WWW-Authenticate", "Basic realm=\"CMIS\"");
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authorization Required");
+ } else {
+ printError(e, request, response, context);
+ }
+ } else {
+ printError(e, request, response, context);
+ }
+ }
+
+ // we are done.
+ response.flushBuffer();
+ }
+
+ // --------------------------------------------------------
+
+ private void dispatch(CallContext context, HttpServletRequest request, HttpServletResponse response)
+ throws Exception {
+ CmisService service = null;
+ try {
+ // get services factory
+ CmisServiceFactory factory = (CmisServiceFactory) getServletContext().getAttribute(
+ CmisRepositoryContextListener.SERVICES_FACTORY);
+
+ if (factory == null) {
+ throw new CmisRuntimeException("Service factory not available! Configuration problem?");
+ }
+
+ // get the service
+ service = factory.getService(context);
+
+ // analyze the path
+ String[] pathFragments = HttpUtils.splitPath(request);
+
+ if (pathFragments.length < 1) {
+ // root -> repository infos
+ RepositoryService.getRepositories(context, service, request, response);
+ return;
+ }
+
+ // select dispatcher
+
+ CallUrl callUrl = null;
+ if (pathFragments.length == 1) {
+ callUrl = CallUrl.REPOSITORY;
+ } else if (BrowserBindingUtils.ROOT_PATH_FRAGMENT.equals(pathFragments[1])) {
+ callUrl = CallUrl.ROOT;
+ }
+
+ if (callUrl == null) {
+ throw new CmisNotSupportedException("Unknown operation");
+ }
+
+ String method = request.getMethod();
+ String repositoryId = pathFragments[0];
+ boolean methodFound = false;
+
+ if (Dispatcher.METHOD_GET.equals(method)) {
+ String selector = HttpUtils.getStringParameter(request, BrowserBindingUtils.PARAM_SELECTOR);
+ String objectId = getStringParameter(request, Constants.PARAM_OBJECT_ID);
+
+ // add object id and object base type id to context
+ BrowserBindingUtils.prepareContext(context, callUrl, service, repositoryId, objectId, null, request);
+
+ // dispatch
+ if (callUrl == CallUrl.REPOSITORY) {
+ if (selector == null) {
+ selector = "";
+ }
+
+ methodFound = repositoryDispatcher.dispatch(selector, method, context, service, repositoryId,
+ request, response);
+ } else if (callUrl == CallUrl.ROOT) {
+ // set default method if necessary
+ if (selector == null) {
+ try {
+ BaseTypeId basetype = BaseTypeId.fromValue((String) context
+ .get(BrowserBindingUtils.CONTEXT_BASETYPE_ID));
+ switch (basetype) {
+ case CMIS_DOCUMENT:
+ selector = BrowserBindingUtils.SELECTOR_CONTENT;
+ break;
+ case CMIS_FOLDER:
+ selector = BrowserBindingUtils.SELECTOR_CHILDREN;
+ break;
+ default:
+ selector = BrowserBindingUtils.SELECTOR_OBJECT;
+ break;
+ }
+ } catch (Exception e) {
+ selector = BrowserBindingUtils.SELECTOR_OBJECT;
+ }
+ }
+
+ methodFound = rootDispatcher.dispatch(selector, method, context, service, repositoryId, request,
+ response);
+ }
+ } else if (Dispatcher.METHOD_POST.equals(method)) {
+ POSTHttpServletRequestWrapper postRequest = new POSTHttpServletRequestWrapper(request);
+
+ String cmisaction = HttpUtils.getStringParameter(postRequest, BrowserBindingUtils.CONTROL_CMISACTION);
+ String objectId = HttpUtils.getStringParameter(postRequest, BrowserBindingUtils.CONTROL_OBJECT_ID);
+ String transaction = HttpUtils.getStringParameter(postRequest, BrowserBindingUtils.CONTROL_TRANSACTION);
+
+ if ((cmisaction == null) || (cmisaction.length() == 0)) {
+ throw new CmisNotSupportedException("Unknown action");
+ }
+
+ // add object id and object base type id to context
+ BrowserBindingUtils.prepareContext(context, callUrl, service, repositoryId, objectId, transaction,
+ postRequest);
+
+ // dispatch
+ if (callUrl == CallUrl.REPOSITORY) {
+ methodFound = repositoryDispatcher.dispatch(cmisaction, method, context, service, repositoryId,
+ postRequest, response);
+ } else if (callUrl == CallUrl.ROOT) {
+ methodFound = rootDispatcher.dispatch(cmisaction, method, context, service, repositoryId,
+ postRequest, response);
+ }
+ }
+
+ // if the dispatcher couldn't find a matching method, return an
+ // error message
+ if (!methodFound) {
+ throw new CmisNotSupportedException("Unknown operation");
+ }
+ } finally {
+ if (service != null) {
+ service.close();
+ }
+ }
+ }
+
+ /**
+ * Translates an exception in an appropriate HTTP error code.
+ */
+ private int getErrorCode(CmisBaseException ex) {
+ if (ex instanceof CmisConstraintException) {
+ return 409;
+ } else if (ex instanceof CmisContentAlreadyExistsException) {
+ return 409;
+ } else if (ex instanceof CmisFilterNotValidException) {
+ return 400;
+ } else if (ex instanceof CmisInvalidArgumentException) {
+ return 400;
+ } else if (ex instanceof CmisNameConstraintViolationException) {
+ return 409;
+ } else if (ex instanceof CmisNotSupportedException) {
+ return 405;
+ } else if (ex instanceof CmisObjectNotFoundException) {
+ return 404;
+ } else if (ex instanceof CmisPermissionDeniedException) {
+ return 403;
+ } else if (ex instanceof CmisStorageException) {
+ return 500;
+ } else if (ex instanceof CmisStreamNotSupportedException) {
+ return 403;
+ } else if (ex instanceof CmisUpdateConflictException) {
+ return 409;
+ } else if (ex instanceof CmisVersioningException) {
+ return 409;
+ }
+
+ return 500;
+ }
+
+ /**
+ * Prints the error as JSON.
+ */
+ @SuppressWarnings("unchecked")
+ private void printError(Exception ex, HttpServletRequest request, HttpServletResponse response, CallContext context) {
+ int statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+ String exceptionName = "runtime";
+
+ if (ex instanceof CmisRuntimeException) {
+ LOG.error(ex.getMessage(), ex);
+ } else if (ex instanceof CmisBaseException) {
+ statusCode = getErrorCode((CmisBaseException) ex);
+ exceptionName = ((CmisBaseException) ex).getExceptionName();
+ } else {
+ LOG.error(ex.getMessage(), ex);
+ }
+
+ response.setStatus(statusCode);
+ response.setContentType(BrowserBindingUtils.JSON_MIME_TYPE);
+ if (context != null) {
+ BrowserBindingUtils.setCookie(request, response, context.getRepositoryId(),
+ (String) context.get(BrowserBindingUtils.CONTEXT_TRANSACTION),
+ BrowserBindingUtils.createCookieValue(statusCode, null, exceptionName, ex.getMessage()));
+ }
+
+ JSONObject jsonResponse = new JSONObject();
+ jsonResponse.put(JSONConstants.ERROR_EXCEPTION, exceptionName);
+ jsonResponse.put(JSONConstants.ERROR_MESSAGE, ex.getMessage());
+
+ String st = ExceptionHelper.getStacktraceAsString(ex);
+ if (st != null) {
+ jsonResponse.put(JSONConstants.ERROR_STACKTRACE, st);
+ }
+
+ try {
+ BrowserBindingUtils.writeJSON(jsonResponse, request, response);
+ } catch (Exception e) {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+}
Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/CmisBrowserBindingServlet.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ControlParser.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ControlParser.java?rev=1094397&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ControlParser.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ControlParser.java Mon Apr 18 09:29:45 2011
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+
+/**
+ * Parses HTML form controls.
+ */
+public class ControlParser {
+
+ private HttpServletRequest request;
+
+ private Map<String, String> zeroDim = new HashMap<String, String>();
+ private Map<String, Map<Integer, String>> oneDim = new HashMap<String, Map<Integer, String>>();
+ private Map<String, Map<Integer, Map<Integer, String>>> twoDim = new HashMap<String, Map<Integer, Map<Integer, String>>>();
+
+ public ControlParser(HttpServletRequest request) {
+ this.request = request;
+ parse();
+ }
+
+ @SuppressWarnings("unchecked")
+ private void parse() {
+ // gather all controls
+ Map<String, String[]> controls = request.getParameterMap();
+ for (Map.Entry<String, String[]> control : controls.entrySet()) {
+ String controlName = control.getKey().trim().toLowerCase();
+
+ int firstIndex = getFirstIndex(controlName);
+
+ if (firstIndex == -1) {
+ zeroDim.put(controlName, control.getValue()[0]);
+ } else {
+ String strippedControlName = controlName.substring(0, controlName.indexOf('['));
+ int secondIndex = getSecondIndex(controlName);
+
+ if (secondIndex == -1) {
+ Map<Integer, String> values = oneDim.get(strippedControlName);
+ if (values == null) {
+ values = new HashMap<Integer, String>();
+ oneDim.put(strippedControlName, values);
+ }
+
+ values.put(firstIndex, control.getValue()[0]);
+ } else {
+ Map<Integer, Map<Integer, String>> values = twoDim.get(strippedControlName);
+ if (values == null) {
+ values = new HashMap<Integer, Map<Integer, String>>();
+ twoDim.put(strippedControlName, values);
+ }
+
+ Map<Integer, String> list = values.get(firstIndex);
+ if (list == null) {
+ list = new HashMap<Integer, String>();
+ values.put(firstIndex, list);
+ }
+
+ list.put(secondIndex, control.getValue()[0]);
+ }
+ }
+ }
+ }
+
+ private int getFirstIndex(String controlName) {
+ int result = -1;
+
+ int open = controlName.indexOf('[');
+ int close = controlName.indexOf(']');
+
+ if (open == -1 || close == -1 || close < open) {
+ return result;
+ }
+
+ String indexStr = controlName.substring(open + 1, close);
+ try {
+ result = Integer.parseInt(indexStr);
+ if (result < 0) {
+ result = -1;
+ }
+ } catch (NumberFormatException e) {
+ }
+
+ return result;
+ }
+
+ private int getSecondIndex(String controlName) {
+ int result = -1;
+
+ int open = controlName.indexOf("][");
+ int close = controlName.lastIndexOf(']');
+
+ if (open == -1 || close == -1 || close < open) {
+ return result;
+ }
+
+ String indexStr = controlName.substring(open + 2, close);
+ try {
+ result = Integer.parseInt(indexStr);
+ if (result < 0) {
+ result = -1;
+ }
+ } catch (NumberFormatException e) {
+ }
+
+ return result;
+ }
+
+ private List<String> convertToList(String controlName, Map<Integer, String> map) {
+ if (map == null) {
+ return null;
+ }
+
+ int count = map.size();
+ List<String> result = new ArrayList<String>(count);
+
+ for (int i = 0; i < count; i++) {
+ String value = map.get(i);
+ if (value == null) {
+ throw new CmisInvalidArgumentException(controlName + " has gaps!");
+ }
+ result.add(value);
+ }
+
+ return result;
+ }
+
+ public String getValue(String controlName) {
+ if (controlName == null) {
+ throw new IllegalArgumentException("controlName must not be null!");
+ }
+
+ return zeroDim.get(controlName.toLowerCase());
+ }
+
+ public List<String> getValues(String controlName) {
+ if (controlName == null) {
+ throw new IllegalArgumentException("controlName must not be null!");
+ }
+
+ return convertToList(controlName, oneDim.get(controlName.toLowerCase()));
+ }
+
+ public List<String> getValues(String controlName, int index) {
+ if (controlName == null) {
+ throw new IllegalArgumentException("controlName must not be null!");
+ }
+
+ Map<Integer, Map<Integer, String>> map = twoDim.get(controlName.toLowerCase());
+ if (map == null) {
+ return null;
+ }
+
+ return convertToList(controlName, map.get(index));
+ }
+
+ public Map<Integer, String> getOneDimMap(String controlName) {
+ if (controlName == null) {
+ throw new IllegalArgumentException("controlName must not be null!");
+ }
+
+ return oneDim.get(controlName.toLowerCase());
+ }
+
+ public Map<Integer, Map<Integer, String>> getTwoDimMap(String controlName) {
+ if (controlName == null) {
+ throw new IllegalArgumentException("controlName must not be null!");
+ }
+
+ return twoDim.get(controlName.toLowerCase());
+ }
+}
Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ControlParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/DiscoveryService.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/DiscoveryService.java?rev=1094397&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/DiscoveryService.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/DiscoveryService.java Mon Apr 18 09:29:45 2011
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser;
+
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBigIntegerParameter;
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBooleanParameter;
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getEnumParameter;
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getStringParameter;
+
+import java.math.BigInteger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.chemistry.opencmis.commons.data.ObjectList;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
+import org.apache.chemistry.opencmis.server.impl.browser.json.JSONConverter;
+import org.json.simple.JSONObject;
+
+/**
+ * Discovery Service operations.
+ */
+public class DiscoveryService {
+
+ /**
+ * query.
+ */
+ public static void query(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+ HttpServletResponse response) throws Exception {
+ // get parameters
+ String statement = getStringParameter(request, Constants.PARAM_Q);
+ Boolean searchAllVersions = getBooleanParameter(request, Constants.PARAM_SEARCH_ALL_VERSIONS);
+ Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
+ IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
+ IncludeRelationships.class);
+ String renditionFilter = null;
+ BigInteger maxItems = getBigIntegerParameter(request, Constants.PARAM_MAX_ITEMS);
+ BigInteger skipCount = getBigIntegerParameter(request, Constants.PARAM_SKIP_COUNT);
+
+ // execute
+ ObjectList results = service.query(repositoryId, statement, searchAllVersions, includeAllowableActions,
+ includeRelationships, renditionFilter, maxItems, skipCount, null);
+
+ if (results == null) {
+ throw new CmisRuntimeException("Results are null!");
+ }
+
+ JSONObject jsonResults = JSONConverter.convert(results);
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ BrowserBindingUtils.writeJSON(jsonResults, request, response);
+ }
+}
Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/DiscoveryService.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/NavigationService.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/NavigationService.java?rev=1094397&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/NavigationService.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/NavigationService.java Mon Apr 18 09:29:45 2011
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser;
+
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBigIntegerParameter;
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBooleanParameter;
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getEnumParameter;
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getStringParameter;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.chemistry.opencmis.commons.data.ObjectInFolderContainer;
+import org.apache.chemistry.opencmis.commons.data.ObjectInFolderList;
+import org.apache.chemistry.opencmis.commons.data.ObjectParentData;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
+import org.apache.chemistry.opencmis.server.impl.browser.json.JSONConverter;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+
+/**
+ * Navigation Service operations.
+ */
+public final class NavigationService {
+
+ /**
+ * getChildren.
+ */
+ public static void getChildren(CallContext context, CmisService service, String repositoryId,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // get parameters
+ String folderId = (String) context.get(BrowserBindingUtils.CONTEXT_OBJECT_ID);
+ String filter = getStringParameter(request, Constants.PARAM_FILTER);
+ String orderBy = getStringParameter(request, Constants.PARAM_ORDER_BY);
+ Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
+ IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
+ IncludeRelationships.class);
+ String renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
+ Boolean includePathSegment = getBooleanParameter(request, Constants.PARAM_PATH_SEGMENT);
+ BigInteger maxItems = getBigIntegerParameter(request, Constants.PARAM_MAX_ITEMS);
+ BigInteger skipCount = getBigIntegerParameter(request, Constants.PARAM_SKIP_COUNT);
+
+ // execute
+ ObjectInFolderList children = service.getChildren(repositoryId, folderId, filter, orderBy,
+ includeAllowableActions, includeRelationships, renditionFilter, includePathSegment, maxItems,
+ skipCount, null);
+
+ if (children == null) {
+ throw new CmisRuntimeException("Children are null!");
+ }
+
+ TypeCache typeCache = new TypeCache(repositoryId, service);
+ JSONObject jsonChildren = JSONConverter.convert(children, typeCache);
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ BrowserBindingUtils.writeJSON(jsonChildren, request, response);
+ }
+
+ /**
+ * getDescendants.
+ */
+ @SuppressWarnings("unchecked")
+ public static void getDescendants(CallContext context, CmisService service, String repositoryId,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // get parameters
+ String folderId = (String) context.get(BrowserBindingUtils.CONTEXT_OBJECT_ID);
+ BigInteger depth = getBigIntegerParameter(request, Constants.PARAM_DEPTH);
+ String filter = getStringParameter(request, Constants.PARAM_FILTER);
+ Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
+ IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
+ IncludeRelationships.class);
+ String renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
+ Boolean includePathSegment = getBooleanParameter(request, Constants.PARAM_PATH_SEGMENT);
+
+ // execute
+ List<ObjectInFolderContainer> descendants = service.getDescendants(repositoryId, folderId, depth, filter,
+ includeAllowableActions, includeRelationships, renditionFilter, includePathSegment, null);
+
+ if (descendants == null) {
+ throw new CmisRuntimeException("Descendants are null!");
+ }
+
+ TypeCache typeCache = new TypeCache(repositoryId, service);
+ JSONArray jsonDescendants = new JSONArray();
+ for (ObjectInFolderContainer descendant : descendants) {
+ jsonDescendants.add(JSONConverter.convert(descendant, typeCache));
+ }
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ BrowserBindingUtils.writeJSON(jsonDescendants, request, response);
+ }
+
+ /**
+ * getFolderTree.
+ */
+ @SuppressWarnings("unchecked")
+ public static void getFolderTree(CallContext context, CmisService service, String repositoryId,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // get parameters
+ String folderId = (String) context.get(BrowserBindingUtils.CONTEXT_OBJECT_ID);
+ BigInteger depth = getBigIntegerParameter(request, Constants.PARAM_DEPTH);
+ String filter = getStringParameter(request, Constants.PARAM_FILTER);
+ Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
+ IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
+ IncludeRelationships.class);
+ String renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
+ Boolean includePathSegment = getBooleanParameter(request, Constants.PARAM_PATH_SEGMENT);
+
+ // execute
+ List<ObjectInFolderContainer> folderTree = service.getFolderTree(repositoryId, folderId, depth, filter,
+ includeAllowableActions, includeRelationships, renditionFilter, includePathSegment, null);
+
+ if (folderTree == null) {
+ throw new CmisRuntimeException("Folder Tree are null!");
+ }
+
+ TypeCache typeCache = new TypeCache(repositoryId, service);
+ JSONArray jsonDescendants = new JSONArray();
+ for (ObjectInFolderContainer descendant : folderTree) {
+ jsonDescendants.add(JSONConverter.convert(descendant, typeCache));
+ }
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ BrowserBindingUtils.writeJSON(jsonDescendants, request, response);
+ }
+
+ /**
+ * getObjectParents.
+ */
+ @SuppressWarnings("unchecked")
+ public static void getObjectParents(CallContext context, CmisService service, String repositoryId,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // get parameters
+ String objectId = (String) context.get(BrowserBindingUtils.CONTEXT_OBJECT_ID);
+ String filter = getStringParameter(request, Constants.PARAM_FILTER);
+ Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
+ IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
+ IncludeRelationships.class);
+ String renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
+ Boolean includeRelativePathSegment = getBooleanParameter(request, Constants.PARAM_RELATIVE_PATH_SEGMENT);
+
+ // execute
+ List<ObjectParentData> parents = service.getObjectParents(repositoryId, objectId, filter,
+ includeAllowableActions, includeRelationships, renditionFilter, includeRelativePathSegment, null);
+
+ if (parents == null) {
+ throw new CmisRuntimeException("Parents are null!");
+ }
+
+ TypeCache typeCache = new TypeCache(repositoryId, service);
+ JSONArray jsonParents = new JSONArray();
+ for (ObjectParentData parent : parents) {
+ jsonParents.add(JSONConverter.convert(parent, typeCache));
+ }
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ BrowserBindingUtils.writeJSON(jsonParents, request, response);
+ }
+}
Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/NavigationService.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ObjectService.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ObjectService.java?rev=1094397&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ObjectService.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ObjectService.java Mon Apr 18 09:29:45 2011
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser;
+
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBooleanParameter;
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getEnumParameter;
+import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getStringParameter;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.chemistry.opencmis.commons.data.ContentStream;
+import org.apache.chemistry.opencmis.commons.data.ObjectData;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.impl.ReturnVersion;
+import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
+import org.apache.chemistry.opencmis.commons.server.ObjectInfo;
+import org.apache.chemistry.opencmis.server.impl.browser.json.JSONConverter;
+import org.json.simple.JSONObject;
+
+/**
+ * Object Service operations.
+ */
+public final class ObjectService {
+
+ private static final int BUFFER_SIZE = 64 * 1024;
+
+ /**
+ * createDocument.
+ */
+ public static void createDocument(CallContext context, CmisService service, String repositoryId,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // get parameters
+ String folderId = (String) context.get(BrowserBindingUtils.CONTEXT_OBJECT_ID);
+ VersioningState versioningState = getEnumParameter(request, Constants.PARAM_VERSIONIG_STATE,
+ VersioningState.class);
+ String transaction = getStringParameter(request, BrowserBindingUtils.PARAM_TRANSACTION);
+
+ ControlParser cp = new ControlParser(request);
+
+ TypeCache typeCache = new TypeCache(repositoryId, service);
+
+ String newObjectId = service.createDocument(repositoryId,
+ BrowserBindingUtils.createProperties(cp, null, typeCache), folderId,
+ BrowserBindingUtils.createContentStream(request), versioningState,
+ BrowserBindingUtils.createPolicies(cp), BrowserBindingUtils.createAddAcl(cp),
+ BrowserBindingUtils.createRemoveAcl(cp), null);
+
+ ObjectInfo objectInfo = service.getObjectInfo(repositoryId, newObjectId);
+ if (objectInfo == null) {
+ throw new CmisRuntimeException("Object Info is missing!");
+ }
+
+ ObjectData object = objectInfo.getObject();
+ if (object == null) {
+ throw new CmisRuntimeException("Object is null!");
+ }
+
+ JSONObject jsonObject = JSONConverter.convert(object, typeCache);
+
+ response.setStatus(HttpServletResponse.SC_CREATED);
+ BrowserBindingUtils.setCookie(request, response, repositoryId, transaction,
+ BrowserBindingUtils.createCookieValue(HttpServletResponse.SC_CREATED, object.getId(), null, null));
+
+ BrowserBindingUtils.writeJSON(jsonObject, request, response);
+ }
+
+ /**
+ * createFolder.
+ */
+ public static void createFolder(CallContext context, CmisService service, String repositoryId,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // get parameters
+ String folderId = (String) context.get(BrowserBindingUtils.CONTEXT_OBJECT_ID);
+ String transaction = getStringParameter(request, BrowserBindingUtils.PARAM_TRANSACTION);
+
+ ControlParser cp = new ControlParser(request);
+
+ TypeCache typeCache = new TypeCache(repositoryId, service);
+
+ String newObjectId = service.createFolder(repositoryId,
+ BrowserBindingUtils.createProperties(cp, null, typeCache), folderId,
+ BrowserBindingUtils.createPolicies(cp), BrowserBindingUtils.createAddAcl(cp),
+ BrowserBindingUtils.createRemoveAcl(cp), null);
+
+ ObjectInfo objectInfo = service.getObjectInfo(repositoryId, newObjectId);
+ if (objectInfo == null) {
+ throw new CmisRuntimeException("Object Info is missing!");
+ }
+
+ ObjectData object = objectInfo.getObject();
+ if (object == null) {
+ throw new CmisRuntimeException("Object is null!");
+ }
+
+ JSONObject jsonObject = JSONConverter.convert(object, typeCache);
+
+ response.setStatus(HttpServletResponse.SC_CREATED);
+ BrowserBindingUtils.setCookie(request, response, repositoryId, transaction,
+ BrowserBindingUtils.createCookieValue(HttpServletResponse.SC_CREATED, object.getId(), null, null));
+
+ BrowserBindingUtils.writeJSON(jsonObject, request, response);
+ }
+
+ /**
+ * getObject.
+ */
+ public static void getObject(CallContext context, CmisService service, String repositoryId,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // get parameters
+ String objectId = (String) context.get(BrowserBindingUtils.CONTEXT_OBJECT_ID);
+ ReturnVersion returnVersion = getEnumParameter(request, Constants.PARAM_RETURN_VERSION, ReturnVersion.class);
+ String filter = getStringParameter(request, Constants.PARAM_FILTER);
+ Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
+ IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
+ IncludeRelationships.class);
+ String renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
+ Boolean includePolicyIds = getBooleanParameter(request, Constants.PARAM_POLICY_IDS);
+ Boolean includeAcl = getBooleanParameter(request, Constants.PARAM_ACL);
+
+ // execute
+ ObjectData object = null;
+
+ if ((returnVersion == ReturnVersion.LATEST) || (returnVersion == ReturnVersion.LASTESTMAJOR)) {
+ object = service.getObjectOfLatestVersion(repositoryId, objectId, null,
+ returnVersion == ReturnVersion.LASTESTMAJOR, filter, includeAllowableActions, includeRelationships,
+ renditionFilter, includePolicyIds, includeAcl, null);
+ } else {
+ object = service.getObject(repositoryId, objectId, filter, includeAllowableActions, includeRelationships,
+ renditionFilter, includePolicyIds, includeAcl, null);
+ }
+
+ if (object == null) {
+ throw new CmisRuntimeException("Object is null!");
+ }
+
+ TypeCache typeCache = new TypeCache(repositoryId, service);
+ JSONObject jsonObject = JSONConverter.convert(object, typeCache);
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ BrowserBindingUtils.writeJSON(jsonObject, request, response);
+ }
+
+ /**
+ * getContentStream.
+ */
+ public static void getContentStream(CallContext context, CmisService service, String repositoryId,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // get parameters
+ String objectId = (String) context.get(BrowserBindingUtils.CONTEXT_OBJECT_ID);
+ String streamId = getStringParameter(request, Constants.PARAM_STREAM_ID);
+
+ BigInteger offset = context.getOffset();
+ BigInteger length = context.getLength();
+
+ // execute
+ ContentStream content = service.getContentStream(repositoryId, objectId, streamId, offset, length, null);
+
+ if ((content == null) || (content.getStream() == null)) {
+ throw new CmisRuntimeException("Content stream is null!");
+ }
+
+ String contentType = content.getMimeType();
+ if (contentType == null) {
+ contentType = Constants.MEDIATYPE_OCTETSTREAM;
+ }
+
+ // set headers
+ if ((offset == null) && (length == null)) {
+ response.setStatus(HttpServletResponse.SC_OK);
+ } else {
+ response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
+ }
+ response.setContentType(contentType);
+
+ // send content
+ InputStream in = new BufferedInputStream(content.getStream(), BUFFER_SIZE);
+ OutputStream out = new BufferedOutputStream(response.getOutputStream());
+
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int b;
+ while ((b = in.read(buffer)) > -1) {
+ out.write(buffer, 0, b);
+ }
+
+ in.close();
+ out.flush();
+ }
+}
Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ObjectService.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/POSTHttpServletRequestWrapper.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/POSTHttpServletRequestWrapper.java?rev=1094397&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/POSTHttpServletRequestWrapper.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/POSTHttpServletRequestWrapper.java Mon Apr 18 09:29:45 2011
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.server.shared.HttpUtils;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+
+public class POSTHttpServletRequestWrapper extends HttpServletRequestWrapper {
+ private boolean isMultipart;
+ private Map<String, String[]> parameters;
+ private String filename;
+ private String contentType;
+ private long size;
+ private InputStream stream;
+
+ public POSTHttpServletRequestWrapper(HttpServletRequest request) throws Exception {
+ this(request, 4 * 1024 * 1024);
+ }
+
+ public POSTHttpServletRequestWrapper(HttpServletRequest request, int memoryThreshold) throws Exception {
+ super(request);
+
+ isMultipart = ServletFileUpload.isMultipartContent(request);
+
+ if (isMultipart) {
+ parameters = new HashMap<String, String[]>();
+
+ DiskFileItemFactory itemFactory = new DiskFileItemFactory();
+ itemFactory.setSizeThreshold(memoryThreshold);
+
+ ServletFileUpload upload = new ServletFileUpload(itemFactory);
+ @SuppressWarnings("unchecked")
+ List<FileItem> fileItems = upload.parseRequest(request);
+
+ for (FileItem item : fileItems) {
+ if (item.isFormField()) {
+ String[] values = parameters.get(item.getFieldName());
+
+ if (values == null) {
+ parameters.put(item.getFieldName(), new String[] { item.getString() });
+ } else {
+ String[] newValues = new String[values.length + 1];
+ System.arraycopy(values, 0, newValues, 0, values.length);
+ newValues[newValues.length - 1] = item.getString();
+ parameters.put(item.getFieldName(), newValues);
+ }
+ } else {
+ filename = item.getName();
+ contentType = (item.getContentType() == null ? Constants.MEDIATYPE_OCTETSTREAM : item
+ .getContentType());
+ size = item.getSize();
+ stream = item.getInputStream();
+ }
+ }
+
+ String filenameControl = HttpUtils.getStringParameter(this, BrowserBindingUtils.CONTROL_FILENAME);
+ if ((filenameControl) != null && (filenameControl.trim().length() > 0)) {
+ filename = filenameControl;
+ }
+
+ String contentTypeControl = HttpUtils.getStringParameter(this, BrowserBindingUtils.CONTROL_CONTENT_TYPE);
+ if ((contentTypeControl != null) && (contentTypeControl.trim().length() > 0)) {
+ contentType = contentTypeControl;
+ }
+ }
+ }
+
+ @Override
+ public String getParameter(String name) {
+ if (!isMultipart) {
+ return super.getParameter(name);
+ }
+
+ String[] values = parameters.get(name);
+ if ((values == null) || (values.length == 0)) {
+ return null;
+ }
+
+ return values[0];
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Map<String, String[]> getParameterMap() {
+ if (!isMultipart) {
+ return super.getParameterMap();
+ }
+
+ return parameters;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Enumeration<String> getParameterNames() {
+ if (!isMultipart) {
+ return super.getParameterNames();
+ }
+
+ return Collections.enumeration(parameters.keySet());
+ }
+
+ @Override
+ public String[] getParameterValues(String name) {
+ if (!isMultipart) {
+ return super.getParameterValues(name);
+ }
+
+ return parameters.get(name);
+ }
+
+ public String getFilename() {
+ return filename;
+ }
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public long getSize() {
+ return size;
+ }
+
+ public InputStream getStream() {
+ return stream;
+ }
+}
Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/POSTHttpServletRequestWrapper.java
------------------------------------------------------------------------------
svn:eol-style = native