jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mdue...@apache.org
Subject svn commit: r980437 - in /jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex: QValueFactoryImpl.java ValueLoader.java
Date Thu, 29 Jul 2010 13:12:52 GMT
Author: mduerig
Date: Thu Jul 29 13:12:52 2010
New Revision: 980437

URL: http://svn.apache.org/viewvc?rev=980437&view=rev
Log:
JCR-2689: Improve equals for binary values

Modified:
    jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java
    jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ValueLoader.java

Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java?rev=980437&r1=980436&r2=980437&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java
Thu Jul 29 13:12:52 2010
@@ -16,12 +16,16 @@
  */
 package org.apache.jackrabbit.spi2davex;
 
+
+import static org.apache.jackrabbit.webdav.DavConstants.HEADER_ETAG;
+import static org.apache.jackrabbit.webdav.DavConstants.HEADER_LAST_MODIFIED;
+
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
-import org.apache.jackrabbit.spi.commons.value.ValueFactoryQImpl;
 import org.apache.jackrabbit.spi.commons.value.AbstractQValue;
+import org.apache.jackrabbit.spi.commons.value.ValueFactoryQImpl;
 import org.apache.jackrabbit.util.TransientFileFactory;
 import org.apache.jackrabbit.webdav.DavException;
 import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants;
@@ -39,6 +43,7 @@ import javax.jcr.Value;
 import javax.jcr.ValueFactory;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.ParserConfigurationException;
+
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -51,6 +56,7 @@ import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import java.io.Serializable;
 import java.util.Arrays;
+import java.util.Map;
 
 /**
  * <code>ValueFactoryImpl</code>...
@@ -142,11 +148,13 @@ class QValueFactoryImpl extends org.apac
          */
         private byte[] buffer;
 
+        private Map<String, String> headers;
+
         /**
          * URI to retrieve the value from
          */
-        private String uri;
-        private long length;
+        private final String uri;
+        private final long length;
         private int index = -1;
         private boolean initialized = true;
 
@@ -378,29 +386,58 @@ class QValueFactoryImpl extends org.apac
             }
             if (obj instanceof BinaryQValue) {
                 BinaryQValue other = (BinaryQValue) obj;
-                // for both the value has not been loaded yet
-                if (!initialized) {
-                    if (other.uri != null) {
-                        return other.uri.equals(uri);
-                    } else {
-                        // need to load the binary value in order to be able
-                        // to compare the 2 values.
-                        try {
-                            loadBinary();
-                        } catch (RepositoryException e) {
-                            return false;
-                        } catch (IOException e) {
+
+                // Consider unequal urls as unequal values and both urls null as equal values
+                if (this.uri == null) {
+                    return other.uri == null;
+                }
+                if (!this.uri.equals(other.uri)) {
+                    return false;
+                }
+
+                // Consider both uninitialized as equal values
+                if (!this.preInitialized() && !other.preInitialized()) {
+                    return true;
+                }
+
+                try {
+                    // Initialized the one which is not
+                    if (!this.preInitialized()) {
+                        this.preInitialize(new String[] {HEADER_ETAG, HEADER_LAST_MODIFIED});
+                    } else if (!other.preInitialized()) {
+                        other.preInitialize(new String[] {HEADER_ETAG, HEADER_LAST_MODIFIED});
+                    }
+                } catch (RepositoryException e) {
+                    return false;
+                } catch (IOException e) {
+                    return false;
+                }
+
+                // If we have headers try to determine equality from them
+                if (headers != null && !headers.isEmpty()) {
+
+                    // Values are (un)equal if we have equal Etags
+                    if (containKey(HEADER_ETAG, this.headers, other.headers)) {
+                        return equalValue(HEADER_ETAG, this.headers, other.headers);
+                    }
+
+                    // Values are unequal if we have different Last-modified values
+                    if (containKey(HEADER_LAST_MODIFIED, this.headers, other.headers)) {
+                        if (!equalValue(HEADER_LAST_MODIFIED, this.headers, other.headers))
{
                             return false;
                         }
                     }
+
+                // Otherwise compare binaries
+                } else {
+                    return ((file == null ? other.file == null : file.equals(other.file))
+                        && Arrays.equals(buffer, other.buffer));
                 }
-                // both have been loaded
-                return ((file == null ? other.file == null : file.equals(other.file))
-                    && Arrays.equals(buffer, other.buffer));
             }
             return false;
         }
 
+
         /**
          * Returns zero to satisfy the Object equals/hashCode contract.
          * This class is mutable and not meant to be used as a hash key.
@@ -422,6 +459,42 @@ class QValueFactoryImpl extends org.apac
             loader.loadBinary(uri, index, this);
         }
 
+        /**
+         * Load the header with the given names. If none of the named headers exist, load
binary.
+         */
+        private void preInitialize(String[] headerNames) throws IOException, RepositoryException
{
+            headers = loader.loadHeaders(uri, headerNames);
+            if (headers.isEmpty()) {
+                loadBinary();
+            }
+        }
+
+        /**
+         * @return <code>true</code> if either initialized or headers have been
+         *         loaded, <code>false</code> otherwise.
+         */
+        private boolean preInitialized() {
+            return initialized || headers != null;
+        }
+
+        /**
+         * @return <code>true</code> if both maps contain the same value for
+         *         <code>key</code>, <code>false</code> otherwise.
The
+         *         <code>key</code> must not map to <code>null</code>
in either
+         *         map.
+         */
+        private boolean equalValue(String key, Map<String, String> map1, Map<String,
String> map2) {
+            return map1.get(key).equals(map2.get(key));
+        }
+
+        /**
+         * @return <code>true</code> if both maps contains the <code>key</code>,
+         *         <code>false</code> otherwise.
+         */
+        private boolean containKey(String key, Map<String, String> map1, Map<String,
String> map2) {
+            return map1.containsKey(key) && map2.containsKey(key);
+        }
+
         //-----------------------------< Serializable >-------------------------
         private void writeObject(ObjectOutputStream out)
                 throws IOException {

Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ValueLoader.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ValueLoader.java?rev=980437&r1=980436&r2=980437&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ValueLoader.java
(original)
+++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ValueLoader.java
Thu Jul 29 13:12:52 2010
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.spi2davex;
 
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.HeadMethod;
 import org.apache.jackrabbit.spi2dav.ExceptionConverter;
 import org.apache.jackrabbit.webdav.DavConstants;
 import org.apache.jackrabbit.webdav.DavException;
@@ -33,8 +34,11 @@ import org.apache.jackrabbit.webdav.prop
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
+
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * <code>ValueLoader</code>...
@@ -61,6 +65,25 @@ class ValueLoader {
         }
     }
 
+    public Map<String, String> loadHeaders(String uri, String[] headerNames) throws
IOException,
+            RepositoryException {
+        HeadMethod method = new HeadMethod(uri);
+        try {
+            int statusCode = client.executeMethod(method);
+            if (statusCode == DavServletResponse.SC_OK) {
+                Map<String, String> headers = new HashMap<String, String>();
+                for (String name : headerNames) {
+                    headers.put(name, method.getResponseHeader(name).getValue());
+                }
+                return headers;
+            } else {
+                throw ExceptionConverter.generate(new DavException(statusCode, ("Unable to
load headers at " + uri + " - Status line = " + method.getStatusLine().toString())));
+            }
+        } finally {
+            method.releaseConnection();
+        }
+    }
+
     int loadType(String uri) throws RepositoryException, IOException {
         DavPropertyNameSet nameSet = new DavPropertyNameSet();
         nameSet.add(ItemResourceConstants.JCR_TYPE);
@@ -109,4 +132,5 @@ class ValueLoader {
          */
         void reset();
     }
+
 }



Mime
View raw message