You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by md...@apache.org on 2012/08/30 12:10:32 UTC
svn commit: r1378875 - in
/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr:
JcrConverter.java JcrNode.java JcrRepository.java
Author: mduerig
Date: Thu Aug 30 10:10:32 2012
New Revision: 1378875
URL: http://svn.apache.org/viewvc?rev=1378875&view=rev
Log:
CMIS-563: JcrConverter.setProperty escaping issues
applied slightly edited patch. Thanks Ivan Vasiliev for the patch
Modified:
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrConverter.java
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrNode.java
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrRepository.java
Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrConverter.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrConverter.java?rev=1378875&r1=1378874&r2=1378875&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrConverter.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrConverter.java Thu Aug 30 10:10:32 2012
@@ -19,6 +19,25 @@
package org.apache.chemistry.opencmis.jcr;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.ValueFormatException;
+import javax.jcr.nodetype.NodeType;
+
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.data.PropertyBoolean;
import org.apache.chemistry.opencmis.commons.data.PropertyData;
@@ -38,30 +57,23 @@ import org.apache.chemistry.opencmis.com
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyUriImpl;
import org.apache.chemistry.opencmis.jcr.util.Util;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.ValueFactory;
-import javax.jcr.ValueFormatException;
-import javax.jcr.nodetype.NodeType;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.GregorianCalendar;
-import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Utility class providing methods for converting various entities from/to their respective representation
* in JCR/CMIS.
*/
public final class JcrConverter {
+
+ private static final Logger log = LoggerFactory.getLogger(JcrConverter.class);
+ private static final Pattern QUALIFIED_NAME = Pattern.compile("\\{([^}]*)\\}(.*)");
+ private static final Pattern PREFIXED_NAME = Pattern.compile("(([^:/]+):)?([^:]*)");
+
private JcrConverter() {}
/**
- * Escapes all illegal JCR name characters of a string.
+ * Escapes all illegal for JCR local name characters of a string.
* The encoding is loosely modeled after URI encoding, but only encodes
* the characters it absolutely needs to in order to make the resulting
* string a valid JCR name.
@@ -79,9 +91,9 @@ public final class JcrConverter {
*
* @param cmisName the name to escape
* @return the escaped name
- */
- public static String toJcrName(String cmisName) {
- StringBuilder buffer = new StringBuilder(cmisName.length() * 2);
+ */
+ private static String escapeForJcr(String cmisName){
+ StringBuilder buffer = new StringBuilder(cmisName.length() * 16 + 32);
for (int i = 0; i < cmisName.length(); i++) {
char ch = cmisName.charAt(i);
if (ch == '%' || ch == '/' || ch == ':' || ch == '[' || ch == ']' || ch == '*' || ch == '|'
@@ -100,27 +112,52 @@ public final class JcrConverter {
}
/**
- * Checks if the given name is valid a valid JCR name
- *
- * @param name the name to check
- * @return <code>true</code> if the name is valid, <code>false</code> otherwise.
- */
- public static boolean isValidJcrName(String name) {
- if (name == null || name.length() == 0) {
- return false;
+ * See JSR-283, 3.2 Names
+ * A JCR name is an ordered pair of strings:
+ * (N, L) where N is a JCR namespace and L is a JCR local name.
+ * @param cmisName the name to escape
+ * @return the escaped name
+ */
+ public static String toJcrName(String cmisName) {
+ if (cmisName == null || cmisName.length()==0){
+ return null;
}
-
- for (int i = 0; i < name.length(); i++) {
- char ch = name.charAt(i);
- if (ch == '%' || ch == '/' || ch == ':' || ch == '[' || ch == ']' || ch == '*' || ch == '|'
- || ch == '\t' || ch == '\r' || ch == '\n'
- || ch == '.' && name.length() < 3
- || ch == ' ' && (i == 0 || i == name.length() - 1)) {
- return false;
+ if (cmisName.charAt(0) == '{') {
+ Matcher matcher = QUALIFIED_NAME.matcher(cmisName);
+ if (matcher.matches()) {
+ String namespaceUri = matcher.group(1);
+ String localName = matcher.group(2);
+ StringBuilder builder = new StringBuilder(cmisName.length() * 16 + 32);
+ if (namespaceUri != null && namespaceUri.length() > 0) {
+ //This must be valid URI
+ try {
+ namespaceUri = new URI(namespaceUri).toString();
+ builder.append('{');
+ builder.append(namespaceUri);
+ builder.append('}');
+ } catch (URISyntaxException e1) {
+ //Skip URI
+ log.debug(e1.getMessage(),e1);
+ }
+ }
+ builder.append(escapeForJcr(localName));
+ return builder.toString();
+ }
+ } else {
+ Matcher matcher = PREFIXED_NAME.matcher(cmisName);
+ if (matcher.matches()) {
+ String prefix = matcher.group(2);
+ String localName = matcher.group(3);
+ StringBuilder builder = new StringBuilder(cmisName.length() * 16 + 32);
+ if (prefix != null && prefix.length() > 0) {
+ builder.append(escapeForJcr(prefix));
+ builder.append(':');
+ }
+ builder.append(escapeForJcr(localName));
+ return builder.toString();
}
}
-
- return true;
+ return escapeForJcr(cmisName);
}
/**
Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrNode.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrNode.java?rev=1378875&r1=1378874&r2=1378875&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrNode.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrNode.java Thu Aug 30 10:10:32 2012
@@ -19,6 +19,24 @@
package org.apache.chemistry.opencmis.jcr;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionManager;
+
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.data.AllowableActions;
import org.apache.chemistry.opencmis.commons.data.ObjectData;
@@ -32,7 +50,6 @@ import org.apache.chemistry.opencmis.com
import org.apache.chemistry.opencmis.commons.enums.Updatability;
import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisNameConstraintViolationException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisStorageException;
@@ -52,23 +69,6 @@ import org.apache.chemistry.opencmis.jcr
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.jcr.ItemNotFoundException;
-import javax.jcr.Node;
-import javax.jcr.PathNotFoundException;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionHistory;
-import javax.jcr.version.VersionManager;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
/**
* Common base class for all JCR <code>Node</code>s to be represented as CMIS objects. Instances of this class
* are responsible for mapping from CMIS to JCR and vice versa.
@@ -319,15 +319,11 @@ public abstract class JcrNode {
*/
public JcrNode updateProperties(Properties properties) {
// get and check the new name
- String newName = PropertyHelper.getStringProperty(properties, PropertyIds.NAME);
+ String newName = JcrConverter.toJcrName(PropertyHelper.getStringProperty(properties, PropertyIds.NAME));
boolean rename = newName != null && !getName().equals(newName);
- if (rename && !JcrConverter.isValidJcrName(newName)) {
- throw new CmisNameConstraintViolationException("Name is not valid: " + newName);
- }
if (rename && isRoot()) {
throw new CmisUpdateConflictException("Cannot rename root node");
}
-
try {
// rename file or folder if necessary
Session session = getNode().getSession();
Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrRepository.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrRepository.java?rev=1378875&r1=1378874&r2=1378875&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrRepository.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-jcr/src/main/java/org/apache/chemistry/opencmis/jcr/JcrRepository.java Thu Aug 30 10:10:32 2012
@@ -18,6 +18,28 @@
*/
package org.apache.chemistry.opencmis.jcr;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.Credentials;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.LoginException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
+
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.data.AllowableActions;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
@@ -42,7 +64,6 @@ import org.apache.chemistry.opencmis.com
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
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;
@@ -65,27 +86,6 @@ import org.apache.chemistry.opencmis.jcr
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.jcr.Credentials;
-import javax.jcr.ItemNotFoundException;
-import javax.jcr.LoginException;
-import javax.jcr.NoSuchWorkspaceException;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.PathNotFoundException;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.query.Query;
-import javax.jcr.query.QueryManager;
-import javax.jcr.query.QueryResult;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
/**
* JCR back-end for CMIS server.
*/
@@ -230,16 +230,12 @@ public class JcrRepository {
throw new CmisConstraintException("Versioning required for " + typeId);
}
- // check the name
+ // get the name
String name = PropertyHelper.getStringProperty(properties, PropertyIds.NAME);
- if (!JcrConverter.isValidJcrName(name)) {
- throw new CmisNameConstraintViolationException("Name is not valid: " + name);
- }
-
// get parent Node and create child
JcrFolder parent = getJcrNode(session, folderId).asFolder();
JcrDocumentTypeHandler typeHandler = typeHandlerManager.getDocumentTypeHandler(typeId);
- JcrNode jcrNode = typeHandler.createDocument(parent, name, properties, contentStream, versioningState);
+ JcrNode jcrNode = typeHandler.createDocument(parent, JcrConverter.toJcrName(name), properties, contentStream, versioningState);
return jcrNode.getId();
}
@@ -289,16 +285,12 @@ public class JcrRepository {
throw new CmisObjectNotFoundException("Type '" + typeId + "' is unknown!");
}
- // check the name
+ // get the name
String name = PropertyHelper.getStringProperty(properties, PropertyIds.NAME);
- if (!JcrConverter.isValidJcrName(name)) {
- throw new CmisNameConstraintViolationException("Name is not valid: " + name);
- }
-
// get parent Node
JcrFolder parent = getJcrNode(session, folderId).asFolder();
JcrFolderTypeHandler typeHandler = typeHandlerManager.getFolderTypeHandler(typeId);
- JcrNode jcrNode = typeHandler.createFolder(parent, name, properties);
+ JcrNode jcrNode = typeHandler.createFolder(parent, JcrConverter.toJcrName(name), properties);
return jcrNode.getId();
}