You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2006/05/19 06:54:14 UTC

svn commit: r407709 - in /jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core: NodeImpl.java PropertyImpl.java state/ItemState.java state/PropertyState.java value/BLOBFileValue.java

Author: tripod
Date: Thu May 18 21:54:13 2006
New Revision: 407709

URL: http://svn.apache.org/viewvc?rev=407709&view=rev
Log:
JCR-428 BLOBFileValues might be discarded to early

Modified:
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ItemState.java
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=407709&r1=407708&r2=407709&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Thu May 18 21:54:13 2006
@@ -3587,8 +3587,12 @@
         NodeIterator niter = getNodes();
         while (niter.hasNext()) {
             NodeImpl n = (NodeImpl) niter.nextNode();
-            // todo: does not work properly for samename siblings
-            if (!srcNode.hasNode(n.getQName())) {
+            Path.PathElement name = n.getPrimaryPath().getNameElement();
+            int idx = name.getIndex();
+            if (idx == 0) {
+                idx = 1;
+            }
+            if (!srcNode.hasNode(name.getName(), idx)) {
                 n.internalRemove(true);
             }
         }
@@ -3599,21 +3603,29 @@
             NodeImpl child = (NodeImpl) niter.nextNode();
             NodeImpl dstNode = null;
             NodeId childId = child.getNodeId();
-            if (hasNode(child.getQName())) {
-                // todo: does not work properly for samename siblings
-                dstNode = getNode(child.getQName());
-            } else if (child.isNodeType(QName.MIX_REFERENCEABLE)) {
-                // if child is referenceable, check if correspondance exist in this workspace
+            Path.PathElement name = child.getPrimaryPath().getNameElement();
+            int idx = name.getIndex();
+            if (idx == 0) {
+                idx = 1;
+            }
+
+            if (child.isNodeType(QName.MIX_REFERENCEABLE)) {
+                // check if correspondance exist in
+                // this workspace
                 try {
                     dstNode = session.getNodeById(childId);
-                    if (removeExisting) {
-                        dstNode.internalRemove(false);
-                        dstNode = null;
-                    } else if (replaceExisting) {
-                        // node exists outside of this update tree, so continue there
-                    } else {
-                        throw new ItemExistsException("Unable to update node: " + dstNode.safeGetJCRPath());
+                    // check if same parent
+                    if (!dstNode.getParent().isSame(srcNode)) {
+                        if (removeExisting) {
+                            dstNode.internalRemove(false);
+                            dstNode = null;
+                        } else if (replaceExisting) {
+                            // node exists outside of this update tree, so continue there
+                        } else {
+                            throw new ItemExistsException("Unable to update node: " + dstNode.safeGetJCRPath());
+                        }
                     }
+
                 } catch (ItemNotFoundException e) {
                     // does not exist
                 }
@@ -3621,8 +3633,13 @@
                 // if child is not referenceable, clear uuid
                 childId = null;
             }
+            if (dstNode == null && hasNode(name.getName(), idx)) {
+                // the exact behaviour for SNS is not specified by the spec
+                // so we just try to find the corresponding one.
+                dstNode = getNode(name.getName(), idx);
+            }
             if (dstNode == null) {
-                dstNode = internalAddChildNode(child.getQName(), (NodeTypeImpl) child.getPrimaryNodeType(), childId);
+                dstNode = internalAddChildNode(name.getName(), (NodeTypeImpl) child.getPrimaryNodeType(), childId);
                 // add mixins
                 NodeType[] mixins = child.getMixinNodeTypes();
                 for (int i = 0; i < mixins.length; i++) {

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java?rev=407709&r1=407708&r2=407709&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java Thu May 18 21:54:13 2006
@@ -293,10 +293,8 @@
             for (int i = 0; i < oldValues.length; i++) {
                 InternalValue old = oldValues[i];
                 if (old != null && old.getType() == PropertyType.BINARY) {
-                    // BINARY value
-                    BLOBFileValue blob = (BLOBFileValue) old.internalValue();
-                    blob.discard();
-                    blob = null; // gc hint
+                    // discard eventual temporary data before overriding
+                    ((BLOBFileValue) old.internalValue()).discard();
                 }
             }
         }

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ItemState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ItemState.java?rev=407709&r1=407708&r2=407709&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ItemState.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ItemState.java Thu May 18 21:54:13 2006
@@ -150,7 +150,7 @@
     /**
      * Pull state information from overlayed state.
      */
-    void pull() {
+    protected void pull() {
         if (overlayedState != null) {
             copy(overlayedState);
             // sync modification count

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java?rev=407709&r1=407708&r2=407709&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java Thu May 18 21:54:13 2006
@@ -108,6 +108,30 @@
         }
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    protected void pull() {
+        super.pull();
+        if (overlayedState != null && type == PropertyType.BINARY) {
+            // special treatment for blobfile values. un-temp them
+            for (int i=0; i<values.length; i++) {
+                if (values[i].internalValue() instanceof BLOBFileValue) {
+                    BLOBFileValue old = (BLOBFileValue) values[i].internalValue();
+                    BLOBFileValue val = old.copy();
+                    if (old != val) {
+                        // only override if 'copy' returned a new instance
+                        try {
+                            values[i] = InternalValue.create(val, null);
+                        } catch (RepositoryException e) {
+                            // ignore
+                        }
+                    }
+                }
+           }
+        }
+    }
+
     //-------------------------------------------------------< public methods >
     /**
      * Determines if this item state represents a node.

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java?rev=407709&r1=407708&r2=407709&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java Thu May 18 21:54:13 2006
@@ -97,6 +97,11 @@
     private final FileSystemResource fsResource;
 
     /**
+     * underlying blob file value
+     */
+    private final BLOBFileValue blob;
+
+    /**
      * converted text
      */
     private String text = null;
@@ -151,6 +156,7 @@
         // init vars
         file = spoolFile;
         fsResource = null;
+        blob = null;
         // this instance is backed by a temporarily allocated resource/buffer
         temp = true;
     }
@@ -166,6 +172,7 @@
         buffer = bytes;
         file = null;
         fsResource = null;
+        blob = null;
         // this instance is not backed by a temporarily allocated buffer
         temp = false;
     }
@@ -187,6 +194,7 @@
         this.file = file;
         // this instance is backed by a 'real' file; set virtual fs resource to null
         fsResource = null;
+        blob = null;
         // this instance is not backed by temporarily allocated resource/buffer
         temp = false;
     }
@@ -212,11 +220,28 @@
         this.fsResource = fsResource;
         // set 'real' file to null
         file = null;
+        blob = null;
         // this instance is not backed by temporarily allocated resource/buffer
         temp = false;
     }
 
     /**
+     * Creates a new <code>BLOBFileValue</code> instance from a existing blob.
+     *
+     * @param blob the existing blob
+     */
+    public BLOBFileValue(BLOBFileValue blob) {
+        // this instance is backed by a blob
+        this.blob = blob;
+        // set 'real' file to null
+        file = null;
+        fsResource = null;
+        // this instance is not backed by temporarily allocated resource/buffer
+        temp = false;
+    }
+
+
+    /**
      * Returns the length of this <code>BLOBFileValue</code>.
      *
      * @return The length, in bytes, of this <code>BLOBFileValue</code>,
@@ -237,6 +262,8 @@
             } catch (FileSystemException fse) {
                 return -1;
             }
+        } else if (blob != null) {
+            return blob.getLength();
         } else {
             // this instance is backed by an in-memory buffer
             return buffer.length;
@@ -260,6 +287,8 @@
         if (file != null) {
             // this instance is backed by a temp file
             file.delete();
+        } else if (blob != null) {
+            blob.discard();
         } else if (buffer != null) {
             // this instance is backed by an in-memory buffer
             buffer = EMPTY_BYTE_ARRAY;
@@ -306,6 +335,8 @@
                 // ignore
                 log.warn("Error while deleting BLOBFileValue: " + fse.getMessage());
             }
+        } else if (blob != null) {
+            blob.delete(pruneEmptyParentDirs);
         } else {
             // this instance is backed by an in-memory buffer
             buffer = EMPTY_BYTE_ARRAY;
@@ -322,6 +353,11 @@
      * @throws IOException         if an error occurs while while spooling
      */
     public void spool(OutputStream out) throws RepositoryException, IOException {
+        if (blob != null) {
+            blob.spool(out);
+            return;
+        }
+
         InputStream in;
         if (file != null) {
             // this instance is backed by a 'real' file
@@ -353,6 +389,7 @@
             try {
                 in.close();
             } catch (IOException ignore) {
+                // ignore
             }
         }
     }
@@ -374,6 +411,8 @@
         } else if (fsResource != null) {
             // this instance is backed by a resource in the virtual file system
             return fsResource.toString();
+        } else if (blob != null) {
+            return blob.toString();
         } else {
             // this instance is backed by an in-memory buffer
             return buffer.toString();
@@ -391,6 +430,7 @@
             BLOBFileValue other = (BLOBFileValue) obj;
             return ((file == null ? other.file == null : file.equals(other.file))
                     && (fsResource == null ? other.fsResource == null : fsResource.equals(other.fsResource))
+                    && (blob == null ? other.blob == null : blob.equals(other.blob))
                     && Arrays.equals(buffer, other.buffer));
         }
         return false;
@@ -457,6 +497,8 @@
                 throw new RepositoryException("file backing binary value not found",
                         fnfe);
             }
+        } else if (blob != null) {
+            return blob.getStream();
         } else if (fsResource != null) {
             // this instance is backed by a resource in the virtual file system
             try {
@@ -518,4 +560,14 @@
             RepositoryException {
         return Boolean.valueOf(getString()).booleanValue();
     }
-}
+
+    /**
+     * Creates a copy of this blob file value that has the 'temporary' field
+     * cleared. if the 'temp' flag is not set, <code>this</code> is returned.
+     *
+     * @return a new value based on this one.
+     */
+    public BLOBFileValue copy() {
+        return temp ? new BLOBFileValue(this) : this;
+    }
+}
\ No newline at end of file