Author: cziegeler
Date: Mon Aug 18 20:38:56 2014
New Revision: 1618724

URL: http://svn.apache.org/r1618724
Log:
SLING-3848 : JcrNodeResource takes too long and initializes too much too soon. 
Apply modified patch from Rob Ryan

Added:
    
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java
   (with props)
Modified:
    sling/trunk/bundles/jcr/resource/pom.xml
    
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResource.java
    
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
    
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResource.java

Modified: sling/trunk/bundles/jcr/resource/pom.xml
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/pom.xml?rev=1618724&r1=1618723&r2=1618724&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/pom.xml (original)
+++ sling/trunk/bundles/jcr/resource/pom.xml Mon Aug 18 20:38:56 2014
@@ -143,7 +143,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.api</artifactId>
-            <version>2.7.0</version>
+            <version>2.7.1-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>

Modified: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResource.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResource.java?rev=1618724&r1=1618723&r2=1618724&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResource.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResource.java
 Mon Aug 18 20:38:56 2014
@@ -49,23 +49,32 @@ abstract class JcrItemResource // this s
 
     private final ResourceMetadata metadata;
 
-    protected JcrItemResource(ResourceResolver resourceResolver,
-                              String path) {
+    protected JcrItemResource(final ResourceResolver resourceResolver,
+                              final String path,
+                              final ResourceMetadata metadata) {
 
         this.resourceResolver = resourceResolver;
         this.path = path;
-
-        metadata = new ResourceMetadata();
+        this.metadata = metadata;
     }
 
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceResolver()
+     */
     public ResourceResolver getResourceResolver() {
         return resourceResolver;
     }
 
+    /**
+     * @see org.apache.sling.api.resource.Resource#getPath()
+     */
     public String getPath() {
         return path;
     }
 
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceMetadata()
+     */
     public ResourceMetadata getResourceMetadata() {
         return metadata;
     }
@@ -75,15 +84,16 @@ abstract class JcrItemResource // this s
      * SLING_RESOURCE_TYPE_PROPERTY, or the node's primary node type, if the
      * property is not set
      */
-    protected String getResourceTypeForNode(Node node)
+    protected String getResourceTypeForNode(final Node node)
             throws RepositoryException {
         String result = null;
 
         if 
(node.hasProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY)) {
-            result = 
node.getProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY).getValue().getString();
+            result = 
node.getProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY).getString();
         }
 
         if (result == null || result.length() == 0) {
+            //result = node.getProperty("jcr:primaryType").getString();
             result = node.getPrimaryNodeType().getName();
         }
 

Modified: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java?rev=1618724&r1=1618723&r2=1618724&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
 Mon Aug 18 20:38:56 2014
@@ -17,11 +17,7 @@
 package org.apache.sling.jcr.resource.internal.helper.jcr;
 
 import static org.apache.jackrabbit.JcrConstants.JCR_CONTENT;
-import static org.apache.jackrabbit.JcrConstants.JCR_CREATED;
 import static org.apache.jackrabbit.JcrConstants.JCR_DATA;
-import static org.apache.jackrabbit.JcrConstants.JCR_ENCODING;
-import static org.apache.jackrabbit.JcrConstants.JCR_LASTMODIFIED;
-import static org.apache.jackrabbit.JcrConstants.JCR_MIMETYPE;
 import static org.apache.jackrabbit.JcrConstants.NT_FILE;
 
 import java.io.InputStream;
@@ -36,7 +32,6 @@ import javax.jcr.ItemNotFoundException;
 import javax.jcr.Node;
 import javax.jcr.Property;
 import javax.jcr.RepositoryException;
-import javax.jcr.ValueFormatException;
 
 import org.apache.jackrabbit.net.URLFactory;
 import org.apache.sling.adapter.annotations.Adaptable;
@@ -44,7 +39,6 @@ import org.apache.sling.adapter.annotati
 import org.apache.sling.api.resource.ModifiableValueMap;
 import org.apache.sling.api.resource.PersistableValueMap;
 import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceMetadata;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.jcr.resource.JcrModifiablePropertyMap;
@@ -72,7 +66,7 @@ class JcrNodeResource extends JcrItemRes
 
     private final String resourceType;
 
-    protected String resourceSuperType;
+    private String resourceSuperType;
 
     private final ClassLoader dynamicClassLoader;
 
@@ -87,20 +81,23 @@ class JcrNodeResource extends JcrItemRes
                            final Node node,
                            final ClassLoader dynamicClassLoader)
     throws RepositoryException {
-        super(resourceResolver, node.getPath());
+        super(resourceResolver, node.getPath(), new 
JcrNodeResourceMetadata(node));
         this.dynamicClassLoader = dynamicClassLoader;
         this.node = node;
-        resourceType = getResourceTypeForNode(node);
-        resourceSuperType = UNSET_RESOURCE_SUPER_TYPE;
-
-        // check for nt:file metadata
-        setMetaData(node, getResourceMetadata());
+        this.resourceType = getResourceTypeForNode(node);
+        this.resourceSuperType = UNSET_RESOURCE_SUPER_TYPE;
     }
 
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceType()
+     */
     public String getResourceType() {
         return resourceType;
     }
 
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceSuperType()
+     */
     public String getResourceSuperType() {
         // Yes, this isn't how you're supposed to compare Strings, but this is 
intentional.
         if ( resourceSuperType == UNSET_RESOURCE_SUPER_TYPE ) {
@@ -265,56 +262,4 @@ class JcrNodeResource extends JcrItemRes
 
         return Collections.<Resource> emptyList().iterator();
     }
-
-    private void setMetaData(Node node, ResourceMetadata metadata) {
-        try {
-
-            // check stuff for nt:file nodes
-            if (node.isNodeType(NT_FILE)) {
-                
metadata.setCreationTime(node.getProperty(JCR_CREATED).getLong());
-
-                // continue our stuff with the jcr:content node
-                // which might be nt:resource, which we support below
-                // if the node is new, the content node might not exist yet
-                if ( !node.isNew() || node.hasNode(JCR_CONTENT) ) {
-                    node = node.getNode(JCR_CONTENT);
-                }
-            }
-
-            // check stuff for nt:resource (or similar) nodes
-            if (node.hasProperty(JCR_MIMETYPE)) {
-                
metadata.setContentType(node.getProperty(JCR_MIMETYPE).getString());
-            }
-
-            if (node.hasProperty(JCR_ENCODING)) {
-                
metadata.setCharacterEncoding(node.getProperty(JCR_ENCODING).getString());
-            }
-
-            if (node.hasProperty(JCR_LASTMODIFIED)) {
-                // We don't check node type, so JCR_LASTMODIFIED might not be 
a long
-                final Property prop = node.getProperty(JCR_LASTMODIFIED);
-                try {
-                    metadata.setModificationTime(prop.getLong());
-                } catch(ValueFormatException vfe) {
-                    LOGGER.debug("Property {} cannot be converted to a long, 
ignored ({})",
-                            prop.getPath(), vfe);
-                }
-            }
-
-            if (node.hasProperty(JCR_DATA)) {
-                final Property prop = node.getProperty(JCR_DATA);
-                try {
-                    metadata.setContentLength(prop.getLength());
-                } catch (ValueFormatException vfe) {
-                    LOGGER.debug(
-                        "Length of Property {} cannot be retrieved, ignored 
({})",
-                        prop.getPath(), vfe);
-                }
-            }
-        } catch (RepositoryException re) {
-            LOGGER.info(
-                "setMetaData: Problem extracting metadata information for "
-                    + getPath(), re);
-        }
-    }
 }

Added: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java?rev=1618724&view=auto
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java
 (added)
+++ 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java
 Mon Aug 18 20:38:56 2014
@@ -0,0 +1,249 @@
+/*
+ * 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.sling.jcr.resource.internal.helper.jcr;
+
+import static org.apache.jackrabbit.JcrConstants.JCR_CONTENT;
+import static org.apache.jackrabbit.JcrConstants.JCR_CREATED;
+import static org.apache.jackrabbit.JcrConstants.JCR_DATA;
+import static org.apache.jackrabbit.JcrConstants.JCR_ENCODING;
+import static org.apache.jackrabbit.JcrConstants.JCR_LASTMODIFIED;
+import static org.apache.jackrabbit.JcrConstants.JCR_MIMETYPE;
+import static org.apache.jackrabbit.JcrConstants.NT_FILE;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.ValueFormatException;
+
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class JcrNodeResourceMetadata extends ResourceMetadata {
+
+    private static final long serialVersionUID = 1L;
+
+    /** default log */
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(JcrNodeResource.class);
+
+    private final Node node;
+    private Node contentNode;
+    private boolean nodePromotionChecked = false;
+    private long creationTime = -1;
+    private String contentType;
+    private long modificationTime = -1;
+    private long contentLength = -1;
+    private String characterEncoding;
+    private boolean populated = false;
+
+    public JcrNodeResourceMetadata(final Node inNode) {
+        this.node = inNode;
+    }
+
+    private Node getTargetNode() {
+        return contentNode != null ? contentNode : node;
+    }
+
+    private void promoteNode() {
+        // check stuff for nt:file nodes
+        try {
+            if ( (!nodePromotionChecked) && node.isNodeType(NT_FILE)) {
+                creationTime = node.getProperty(JCR_CREATED).getLong();
+
+                // continue our stuff with the jcr:content node
+                // which might be nt:resource, which we support below
+                // if the node is new, the content node might not exist yet
+                if (!node.isNew() || node.hasNode(JCR_CONTENT) ) {
+                    contentNode = node.getNode(JCR_CONTENT);
+                }
+                nodePromotionChecked = true;
+            }
+        } catch (final RepositoryException re) {
+            report(re);
+        }
+
+    }
+
+    private void report(final RepositoryException re) {
+        String nodePath = "<unknown node path>";
+        try {
+            nodePath = getTargetNode().getPath();
+        } catch (RepositoryException e) {
+            // ignore
+        }
+        LOGGER.info(
+            "setMetaData: Problem extracting metadata information for "
+                    + nodePath, re);
+    }
+
+    @Override
+    public Object get(final Object key) {
+        final Object result = super.get(key);
+        if (result != null) {
+            return result;
+        }
+
+        if (CREATION_TIME.equals(key)) {
+            promoteNode();
+            internalPut(CREATION_TIME, creationTime);
+            return creationTime;
+        } else if (CONTENT_TYPE.equals(key)) {
+            if (contentType == null) {
+                promoteNode();
+                try {
+                    if (getTargetNode().hasProperty(JCR_MIMETYPE)) {
+                        contentType = 
getTargetNode().getProperty(JCR_MIMETYPE).getString();
+                    }
+                } catch (RepositoryException re) {
+                    report(re);
+                }
+
+                internalPut(CONTENT_TYPE, contentType);
+            }
+            return contentType;
+        } else if (CHARACTER_ENCODING.equals(key)) {
+            if (characterEncoding == null) {
+                promoteNode();
+                try {
+                    if (getTargetNode().hasProperty(JCR_ENCODING)) {
+                        characterEncoding = 
getTargetNode().getProperty(JCR_ENCODING).getString();
+                    }
+                } catch (RepositoryException re) {
+                    report(re);
+                }
+                internalPut(CHARACTER_ENCODING, characterEncoding);
+            }
+            return characterEncoding;
+        } else if (MODIFICATION_TIME.equals(key)) {
+            if (modificationTime == -1) {
+                promoteNode();
+                try {
+                    if (getTargetNode().hasProperty(JCR_LASTMODIFIED)) {
+                        // We don't check node type, so JCR_LASTMODIFIED might 
not be a long
+                        final Property prop = 
getTargetNode().getProperty(JCR_LASTMODIFIED);
+                        try {
+                            modificationTime = prop.getLong();
+                        } catch(ValueFormatException vfe) {
+                            LOGGER.debug("Property {} cannot be converted to a 
long, ignored ({})",
+                                prop.getPath(), vfe);
+                        }
+                    }
+                } catch (final RepositoryException re) {
+                    report(re);
+                }
+                internalPut(MODIFICATION_TIME, modificationTime);
+            }
+            return modificationTime;
+        } else if (CONTENT_LENGTH.equals(key)) {
+            if (contentLength == -1) {
+                promoteNode();
+                try {
+                    if (getTargetNode().hasProperty(JCR_DATA)) {
+                        final Property prop = 
getTargetNode().getProperty(JCR_DATA);
+                        try {
+                            contentLength = prop.getLength();
+                        } catch (ValueFormatException vfe) {
+                            LOGGER.debug(
+                                "Length of Property {} cannot be retrieved, 
ignored ({})",
+                                prop.getPath(), vfe);
+                        }
+                    }
+                } catch (final RepositoryException re) {
+                    report(re);
+                }
+                internalPut(CONTENT_LENGTH, contentLength);
+            }
+            return contentLength;
+        }
+        return null;
+    }
+
+
+    private void populate() {
+        if (populated) {
+            return;
+        }
+        get(CREATION_TIME);
+        get(CONTENT_TYPE);
+        get(CHARACTER_ENCODING);
+        get(MODIFICATION_TIME);
+        get(CONTENT_LENGTH);
+        populated = true;
+    }
+
+    @Override
+    public Set<Map.Entry<String, Object>> entrySet() {
+        populate();
+        return super.entrySet();
+    }
+
+    @Override
+    public Set<String> keySet() {
+        populate();
+        return super.keySet();
+    }
+
+    @Override
+    public Collection<Object> values() {
+        populate();
+        return super.values();
+    }
+
+    @Override
+    public int size() {
+        populate();
+        return super.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return false;
+    }
+
+    @Override
+    public boolean containsKey(final Object key) {
+        if (super.containsKey(key)) {
+            return true;
+        }
+        if (CREATION_TIME.equals(key) ||
+            CONTENT_TYPE.equals(key) ||
+            CHARACTER_ENCODING.equals(key) ||
+            MODIFICATION_TIME.equals(key) ||
+            CONTENT_LENGTH.equals(key)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean containsValue(final Object value) {
+        if (super.containsValue(value)) {
+            return true;
+        }
+        if (!populated) {
+            populate();
+            return super.containsValue(value);
+        }
+        return false;
+    }
+}

Propchange: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResource.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResource.java?rev=1618724&r1=1618723&r2=1618724&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResource.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResource.java
 Mon Aug 18 20:38:56 2014
@@ -34,6 +34,7 @@ import javax.jcr.ValueFormatException;
 import org.apache.sling.adapter.annotations.Adaptable;
 import org.apache.sling.adapter.annotations.Adapter;
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -56,7 +57,7 @@ class JcrPropertyResource extends JcrIte
                                final String path,
                                final Property property)
     throws RepositoryException {
-        super(resourceResolver, path);
+        super(resourceResolver, path, new ResourceMetadata());
         this.property = property;
         this.resourceType = getResourceTypeForNode(property.getParent())
                 + "/" + property.getName();


Reply via email to