jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r1182419 - in /jackrabbit/trunk: jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/webdav/ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/ jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/
Date Wed, 12 Oct 2011 15:13:02 GMT
Author: angela
Date: Wed Oct 12 15:13:01 2011
New Revision: 1182419

URL: http://svn.apache.org/viewvc?rev=1182419&view=rev
Log:
JCR-3093 : Inconsistency between Session.getProperty and Node.getProperty for binary values

Modified:
    jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/webdav/JcrRemotingConstants.java
    jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/webdav/ValueUtil.java
    jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DefaultItemResource.java
    jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/ItemResourceConstants.java
    jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java

Modified: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/webdav/JcrRemotingConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/webdav/JcrRemotingConstants.java?rev=1182419&r1=1182418&r2=1182419&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/webdav/JcrRemotingConstants.java
(original)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/webdav/JcrRemotingConstants.java
Wed Oct 12 15:13:01 2011
@@ -129,6 +129,7 @@ public interface JcrRemotingConstants {
     public static final String JCR_VALUES_LN = "values";
     public static final String JCR_LENGTH_LN = "length";
     public static final String JCR_LENGTHS_LN = "lengths";
+    public static final String JCR_GET_STRING_LN = "getstring";
 
     public static final String JCR_NAMESPACES_LN = "namespaces";
     public static final String JCR_NODETYPES_CND_LN = "nodetypes-cnd";

Modified: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/webdav/ValueUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/webdav/ValueUtil.java?rev=1182419&r1=1182418&r2=1182419&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/webdav/ValueUtil.java
(original)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/webdav/ValueUtil.java
Wed Oct 12 15:13:01 2011
@@ -110,4 +110,40 @@ public class ValueUtil {
         // deserialize value ->> see #valueToXml where values are serialized
         return ValueHelper.deserialize(value, type, true, valueFactory);
     }
+
+    public static long[] lengthsFromXml(Object propValue) throws RepositoryException {
+        long[] lengths;
+        // retrieve jcr-values from child 'value'-element(s)
+        List<Element> lengthElements = new ArrayList<Element>();
+        if (propValue == null) {
+            lengths = new long[0];
+        } else { /* not null propValue */
+            if (isLengthElement(propValue)) {
+                lengthElements.add((Element) propValue);
+            } else if (propValue instanceof List) {
+                for (Object el : ((List<?>) propValue)) {
+                    /* make sure, only Elements with name 'value' are used for
+                    * the 'value' field. any other content (other elements, text,
+                    * comment etc.) is ignored. NO bad-request/conflict error is
+                    * thrown.
+                    */
+                    if (isLengthElement(el)) {
+                        lengthElements.add((Element) el);
+                    }
+                }
+            }
+            /* fill the 'value' with the valid 'value' elements found before */
+            lengths = new long[lengthElements.size()];
+            int i = 0;
+            for (Element element : lengthElements) {
+                lengths[i] = Long.parseLong(XMLUtil.getText(element, "0"));
+                i++;
+            }
+        }
+        return lengths;
+    }
+
+    private static boolean isLengthElement(Object obj) {
+        return obj instanceof Element && JcrRemotingConstants.XML_LENGTH.equals(((Element)obj).getLocalName());
+    }
 }
\ No newline at end of file

Modified: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DefaultItemResource.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DefaultItemResource.java?rev=1182419&r1=1182418&r2=1182419&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DefaultItemResource.java
(original)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DefaultItemResource.java
Wed Oct 12 15:13:01 2011
@@ -184,11 +184,19 @@ public class DefaultItemResource extends
         if (prop == null && exists()) {
             try {
                 Property p = (Property) item;
-                if (JCR_LENGTH.equals(name) && !isMultiple()) {
-                    long length = p.getLength();
-                    prop = new DefaultDavProperty<String>(JCR_LENGTH, String.valueOf(length),
true);
-                } else if (JCR_LENGTHS.equals(name) && isMultiple()) {
-                    prop = new LengthsProperty(p.getLengths());
+                if (isMultiple()) {
+                    if (JCR_LENGTHS.equals(name)) {
+                        prop = new LengthsProperty(p.getLengths());
+                    }
+                } else {
+                    if (JCR_LENGTH.equals(name)) {
+                        long length = p.getLength();
+                        prop = new DefaultDavProperty<String>(JCR_LENGTH, String.valueOf(length),
true);
+                    } else if (JCR_GET_STRING.equals(name) && p.getType() != PropertyType.BINARY)
{
+                        // getstring property is only created for single value
+                        // non-binary jcr properties
+                        prop = new DefaultDavProperty<String>(JCR_GET_STRING, p.getString(),
true);
+                    }
                 }
             } catch (RepositoryException e) {
                 log.error("Failed to retrieve resource properties: "+e.getMessage());

Modified: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/ItemResourceConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/ItemResourceConstants.java?rev=1182419&r1=1182418&r2=1182419&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/ItemResourceConstants.java
(original)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/ItemResourceConstants.java
Wed Oct 12 15:13:01 2011
@@ -81,6 +81,7 @@ public interface ItemResourceConstants e
     public static final DavPropertyName JCR_VALUES = DavPropertyName.create(JCR_VALUES_LN,
NAMESPACE);
     public static final DavPropertyName JCR_LENGTH = DavPropertyName.create(JCR_LENGTH_LN,
NAMESPACE);
     public static final DavPropertyName JCR_LENGTHS = DavPropertyName.create(JCR_LENGTHS_LN,
NAMESPACE);
+    public static final DavPropertyName JCR_GET_STRING = DavPropertyName.create(JCR_GET_STRING_LN,
NAMESPACE);
 
     // property names used for resource representing a workspace
     public static final DavPropertyName JCR_NAMESPACES = DavPropertyName.create(JCR_NAMESPACES_LN,
NAMESPACE);

Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java?rev=1182419&r1=1182418&r2=1182419&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java
Wed Oct 12 15:13:01 2011
@@ -16,19 +16,6 @@
  */
 package org.apache.jackrabbit.spi2davex;
 
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.Credentials;
-import javax.jcr.ItemNotFoundException;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.HttpException;
 import org.apache.commons.httpclient.HttpMethod;
@@ -41,6 +28,7 @@ import org.apache.jackrabbit.commons.jso
 import org.apache.jackrabbit.commons.json.JsonUtil;
 import org.apache.jackrabbit.commons.webdav.JcrRemotingConstants;
 import org.apache.jackrabbit.commons.webdav.JcrValueType;
+import org.apache.jackrabbit.commons.webdav.ValueUtil;
 import org.apache.jackrabbit.spi.Batch;
 import org.apache.jackrabbit.spi.ItemId;
 import org.apache.jackrabbit.spi.ItemInfo;
@@ -61,14 +49,35 @@ import org.apache.jackrabbit.spi.commons
 import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
 import org.apache.jackrabbit.spi.commons.name.PathBuilder;
 import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
+import org.apache.jackrabbit.spi.commons.value.ValueFormat;
 import org.apache.jackrabbit.spi2dav.ExceptionConverter;
+import org.apache.jackrabbit.spi2dav.ItemResourceConstants;
 import org.apache.jackrabbit.util.Text;
+import org.apache.jackrabbit.webdav.DavConstants;
 import org.apache.jackrabbit.webdav.DavException;
 import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.MultiStatusResponse;
+import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
 import org.apache.jackrabbit.webdav.header.IfHeader;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
+import org.apache.jackrabbit.webdav.property.DavPropertySet;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.jcr.Credentials;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
 /**
  * <code>RepositoryServiceImpl</code>...
  */
@@ -90,6 +99,25 @@ public class RepositoryServiceImpl exten
 
     private static final String DEFAULT_CHARSET = "UTF-8";
 
+    private static final DavPropertyName JCR_TYPE =
+            DavPropertyName.create(ItemResourceConstants.JCR_TYPE_LN, ItemResourceConstants.NAMESPACE);
+
+    private static final DavPropertyName JCR_LENGTH =
+            DavPropertyName.create(ItemResourceConstants.JCR_LENGTH_LN, ItemResourceConstants.NAMESPACE);
+
+    private static final DavPropertyName JCR_LENGTHS =
+            DavPropertyName.create(ItemResourceConstants.JCR_LENGTHS_LN, ItemResourceConstants.NAMESPACE);
+
+    private static final DavPropertyName JCR_GET_STRING =
+            DavPropertyName.create(ItemResourceConstants.JCR_GET_STRING_LN, ItemResourceConstants.NAMESPACE);
+
+    private static final DavPropertyNameSet LAZY_PROPERTY_NAME_SET = new DavPropertyNameSet(){{
+        add(JCR_TYPE);
+        add(JCR_LENGTH);
+        add(JCR_LENGTHS);
+        add(JCR_GET_STRING);
+    }};
+
     /**
      * base uri to the extended jcr-server that can handle the GET and POST
      * (or PATCH) requests sent by this service implementation.
@@ -211,7 +239,7 @@ public class RepositoryServiceImpl exten
     }
 
     private String getURI(Path path, SessionInfo sessionInfo) throws RepositoryException
{
-        StringBuffer sb = new StringBuffer(getRootURI(sessionInfo));
+        StringBuilder sb = new StringBuilder(getRootURI(sessionInfo));
         String jcrPath = getNamePathResolver(sessionInfo).getJCRPath(path);
         sb.append(Text.escapePath(jcrPath));
         return sb.toString();
@@ -227,13 +255,13 @@ public class RepositoryServiceImpl exten
     }
 
     private String getRootURI(SessionInfo sessionInfo) {
-        StringBuffer sb = new StringBuffer(getWorkspaceURI(sessionInfo));
+        StringBuilder sb = new StringBuilder(getWorkspaceURI(sessionInfo));
         sb.append(Text.escapePath(JcrRemotingConstants.ROOT_ITEM_RESOURCEPATH));
         return sb.toString();
     }
 
     private String getWorkspaceURI(SessionInfo sessionInfo) {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         sb.append(jcrServerURI);
         sb.append(Text.escape(sessionInfo.getWorkspaceName()));
         return sb.toString();
@@ -304,7 +332,7 @@ public class RepositoryServiceImpl exten
     @Override
     public Iterator<? extends ItemInfo> getItemInfos(SessionInfo sessionInfo, ItemId
itemId) throws ItemNotFoundException, RepositoryException {
         if (!itemId.denotesNode()) {
-            PropertyInfo propertyInfo = super.getPropertyInfo(sessionInfo, (PropertyId) itemId);
+            PropertyInfo propertyInfo = getPropertyInfo(sessionInfo, (PropertyId) itemId);
             return Iterators.singleton(propertyInfo);
         } else {
             NodeId nodeId = (NodeId) itemId;
@@ -347,6 +375,66 @@ public class RepositoryServiceImpl exten
         }
     }
 
+    /**
+     * @see RepositoryService#getPropertyInfo(SessionInfo, PropertyId)
+     */
+    @Override
+    public PropertyInfo getPropertyInfo(SessionInfo sessionInfo, PropertyId propertyId) throws
RepositoryException {
+        Path p = getPath(propertyId, sessionInfo);
+        String uri = getURI(p, sessionInfo);
+        PropFindMethod method = null;
+        try {
+            method = new PropFindMethod(uri, LAZY_PROPERTY_NAME_SET, DavConstants.DEPTH_0);
+            getClient(sessionInfo).executeMethod(method);
+            method.checkSuccess();
+
+            MultiStatusResponse[] responses = method.getResponseBodyAsMultiStatus().getResponses();
+            if (responses.length != 1) {
+                throw new ItemNotFoundException("Unable to retrieve the PropertyInfo. No
such property " + uri);
+            }
+
+            MultiStatusResponse response = responses[0];
+            DavPropertySet props = response.getProperties(DavServletResponse.SC_OK);
+            int propertyType = PropertyType.valueFromName(props.get(JCR_TYPE).getValue().toString());
+
+            if (propertyType == PropertyType.BINARY) {
+                DavProperty<?> lengthsProp = props.get(JCR_LENGTHS);
+                if (lengthsProp != null) {
+                    // multivalued binary property
+                    long[] lengths = ValueUtil.lengthsFromXml(lengthsProp.getValue());
+                    QValue[] qValues = new QValue[lengths.length];
+                    for (int i = 0 ; i < lengths.length ; i ++) {
+                        qValues[i] = getQValueFactory(sessionInfo).create(lengths[i], uri,
i);
+                    }
+                    return new PropertyInfoImpl(propertyId, p, propertyType, qValues);
+                } else {
+                    // single valued binary property
+                    long length = Long.parseLong(props.get(JCR_LENGTH).getValue().toString());
+                    QValue qValue = getQValueFactory(sessionInfo).create(length, uri, 0)
;
+                    return new PropertyInfoImpl(propertyId, p, propertyType, qValue);
+                }
+            } else if (props.contains(JCR_GET_STRING)) {
+                // single valued non-binary property
+                String str = props.get(JCR_GET_STRING).getValue().toString();
+                QValue qValue = ValueFormat.getQValue(str, propertyType, getNamePathResolver(sessionInfo),
getQValueFactory(sessionInfo));
+                return new PropertyInfoImpl(propertyId, p, propertyType, qValue);
+            } else {
+                // multivalued non-binary property or some other property that
+                // didn't expose the JCR_GET_STRING dav property.
+                return super.getPropertyInfo(sessionInfo, propertyId);
+            }
+        } catch (IOException e) {
+            log.error("Internal error while retrieving ItemInfo.",e);
+            throw new RepositoryException(e.getMessage());
+        } catch (DavException e) {
+            throw ExceptionConverter.generate(e);
+        } finally {
+            if (method != null) {
+                method.releaseConnection();
+            }
+        }
+    }
+
     @Override
     public Batch createBatch(SessionInfo sessionInfo, ItemId itemId) throws RepositoryException
{
         return new BatchImpl(itemId, sessionInfo);
@@ -378,7 +466,7 @@ public class RepositoryServiceImpl exten
             method = new PostMethod(getWorkspaceURI(sessionInfo));
             NamePathResolver resolver = getNamePathResolver(sessionInfo);
 
-            StringBuffer args = new StringBuffer();
+            StringBuilder args = new StringBuilder();
             args.append(srcWorkspaceName);
             args.append(",");
             args.append(resolver.getJCRPath(getPath(srcNodeId, sessionInfo, srcWorkspaceName)));
@@ -412,7 +500,7 @@ public class RepositoryServiceImpl exten
             method = new PostMethod(getWorkspaceURI(sessionInfo));
 
             NamePathResolver resolver = getNamePathResolver(sessionInfo);
-            StringBuffer args = new StringBuffer();
+            StringBuilder args = new StringBuilder();
             args.append(srcWorkspaceName);
             args.append(",");
             args.append(resolver.getJCRPath(getPath(srcNodeId, sessionInfo, srcWorkspaceName)));
@@ -489,7 +577,7 @@ public class RepositoryServiceImpl exten
 
             // insert the content of 'batchMap' part containing the ordered list
             // of methods to be executed:
-            StringBuffer buf = new StringBuffer();
+            StringBuilder buf = new StringBuilder();
             for (Iterator<String> it = diff.iterator(); it.hasNext();) {
                 buf.append(it.next());
                 if (it.hasNext()) {
@@ -651,7 +739,7 @@ public class RepositoryServiceImpl exten
             // TODO: multiple reorder of SNS nodes requires readjustment of path -> see
remove()
             String srcPath = getNamePathResolver(sessionInfo).getJCRPath(getPath(srcNodeId,
sessionInfo));
 
-            StringBuffer val = new StringBuffer();
+            StringBuilder val = new StringBuilder();
             if (beforeNodeId != null) {
                 Path beforePath = getPath(beforeNodeId, sessionInfo);
                 String beforeJcrPath = getNamePathResolver(sessionInfo).getJCRPath(beforePath);
@@ -719,7 +807,7 @@ public class RepositoryServiceImpl exten
          * @param value
          */
         private void appendDiff(char symbol, String targetPath, String value) {
-            StringBuffer bf = new StringBuffer();
+            StringBuilder bf = new StringBuilder();
             bf.append(symbol).append(targetPath).append(" : ");
             if (value != null) {
                 bf.append(value);
@@ -754,7 +842,7 @@ public class RepositoryServiceImpl exten
                 clearPreviousSetProperty(jcrPropPath);
             }
 
-            StringBuffer strVal = new StringBuffer("[");
+            StringBuilder strVal = new StringBuilder("[");
             for (int i = 0; i < values.length; i++) {
                 String str = getJsonString(values[i]);
                 if (str == null) {



Mime
View raw message