Author: cziegeler
Date: Thu Apr 13 14:30:40 2017
New Revision: 1791259

URL: http://svn.apache.org/viewvc?rev=1791259&view=rev
Log:
SLING-6723 : Make dependency to javax.jcr, jcr.contentloader and jcr.api 
optional

Modified:
    
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/JCRSupport.java
    
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/JCRSupportImpl.java
    
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java
    
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java

Modified: 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/JCRSupport.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/JCRSupport.java?rev=1791259&r1=1791258&r2=1791259&view=diff
==============================================================================
--- 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/JCRSupport.java
 (original)
+++ 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/JCRSupport.java
 Thu Apr 13 14:30:40 2017
@@ -20,11 +20,6 @@ package org.apache.sling.servlets.post.i
 
 import java.util.List;
 
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.ValueFactory;
-
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
@@ -107,24 +102,89 @@ public class JCRSupport {
         return false;
     }
 
-    public Value parse(Session session, String value, ValueFactory factory, 
boolean weak) throws RepositoryException {
-        return ReferenceParser.parse(session, value, factory, weak);
+    public boolean isPropertyProtectedOrNewAutoCreated(final Object node, 
final String name)
+    throws PersistenceException {
+        if ( node != null && supportImpl != null ) {
+            return 
((JCRSupportImpl)supportImpl).isPropertyProtectedOrNewAutoCreated(node, name);
+        }
+        return false;
+    }
+
+    public boolean isPropertyMandatory(final Object node, final String name)
+    throws PersistenceException {
+        if ( node != null && supportImpl != null ) {
+            return ((JCRSupportImpl)supportImpl).isPropertyMandatory(node, 
name);
+        }
+        return false;
+    }
+
+    public boolean isPropertyMultiple(final Object node, final String name)
+    throws PersistenceException {
+        if ( node != null && supportImpl != null ) {
+            return ((JCRSupportImpl)supportImpl).isPropertyMultiple(node, 
name);
+        }
+        return false;
+    }
+
+    public boolean isNewNode(final Object node) {
+        if ( node != null && supportImpl != null ) {
+            return ((JCRSupportImpl)supportImpl).isNewNode(node);
+        }
+        return true;
+    }
+
+    public Integer getPropertyType(final Object node, final String name)
+    throws PersistenceException {
+        if ( node != null && supportImpl != null ) {
+            return ((JCRSupportImpl)supportImpl).getPropertyType(node, name);
+        }
+        return null;
+    }
+
+    public boolean hasSession(final ResourceResolver resolver) {
+        if ( supportImpl != null ) {
+            return ((JCRSupportImpl)supportImpl).hasSession(resolver);
+        }
+        return false;
     }
 
     /**
-     * Parses the given source strings and returns the respective reference 
value
-     * instances. If no node matches for any of the sources
-     * returns <code>null</code>.
-     * <p/>
+     * Stores property value(s) as reference(s). Will parse the reference(s) 
from the string
+     * value(s) in the {@link RequestProperty}.
      *
-     * @param values path or UUID strings
-     * @param factory the value factory
-     * @param weak true to create a WeakReference value
-     * @return the values or <code>null</code>
-     * @throws RepositoryException
+     * @return true only if parsing was successful and the property was 
actually changed
      */
-    public Value[] parse(Session session, String[] values, ValueFactory 
factory, boolean weak) throws RepositoryException {
-        return ReferenceParser.parse(session, values, factory, weak);
+    public Modification storeAsReference(
+            final Resource resource,
+            final Object node,
+            final String name,
+            final String[] values,
+            final int type,
+            final boolean multiValued)
+    throws PersistenceException {
+        if ( node != null && supportImpl != null ) {
+            return ((JCRSupportImpl)supportImpl).storeAsReference(node, name, 
values, type, multiValued);
+        }
+        throw new PersistenceException("Resource " + resource.getPath() + " 
does not support reference properties.", null, resource.getPath(), name);
     }
 
+    public void setTypedProperty(final Object n,
+            final String name,
+            final String[] values,
+            final int type,
+            final boolean multiValued)
+    throws PersistenceException {
+        if ( n != null && supportImpl != null ) {
+            ((JCRSupportImpl)supportImpl).setTypedProperty(n, name, values, 
type, multiValued);
+        } else {
+            throw new PersistenceException("Property should be stored through 
JCR but JCR support is not available");
+        }
+    }
+
+    public Object getNode(final Resource rsrc) {
+        if ( supportImpl != null ) {
+            return ((JCRSupportImpl)supportImpl).getNode(rsrc);
+        }
+        return null;
+    }
 }

Modified: 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/JCRSupportImpl.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/JCRSupportImpl.java?rev=1791259&r1=1791258&r2=1791259&view=diff
==============================================================================
--- 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/JCRSupportImpl.java
 (original)
+++ 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/JCRSupportImpl.java
 Thu Apr 13 14:30:40 2017
@@ -23,10 +23,14 @@ import java.util.List;
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import javax.jcr.Value;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.nodetype.PropertyDefinition;
 
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.sling.api.SlingHttpServletRequest;
@@ -242,4 +246,152 @@ public class JCRSupportImpl {
         }
         return false;
     }
+
+    private PropertyDefinition searchPropertyDefinition(final NodeType 
nodeType, final String name) {
+        if ( nodeType.getPropertyDefinitions() != null ) {
+            for(final PropertyDefinition pd : 
nodeType.getPropertyDefinitions()) {
+                if ( pd.getName().equals(name) ) {
+                    return pd;
+                }
+            }
+        }
+        // SLING-2877:
+        // no need to search property definitions of super types, as 
nodeType.getPropertyDefinitions()
+        // already includes those. see javadoc of {@link 
NodeType#getPropertyDefinitions()}
+        return null;
+    }
+
+    private PropertyDefinition searchPropertyDefinition(final Node node, final 
String name)
+    throws RepositoryException {
+        PropertyDefinition result = 
searchPropertyDefinition(node.getPrimaryNodeType(), name);
+        if ( result == null ) {
+            if ( node.getMixinNodeTypes() != null ) {
+                for(final NodeType mt : node.getMixinNodeTypes()) {
+                    result = this.searchPropertyDefinition(mt, name);
+                    if ( result != null ) {
+                        return result;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    public boolean isPropertyProtectedOrNewAutoCreated(final Object n, final 
String name)
+    throws PersistenceException {
+        final Node node = (Node)n;
+        try {
+            final PropertyDefinition pd = this.searchPropertyDefinition(node, 
name);
+            if ( pd != null ) {
+                // SLING-2877 (autocreated check is only required for new 
nodes)
+                if ( (node.isNew() && pd.isAutoCreated()) || pd.isProtected() 
) {
+                    return true;
+                }
+            }
+        } catch ( final RepositoryException re) {
+            throw new PersistenceException(re.getMessage(), re);
+        }
+        return false;
+    }
+
+    public boolean isNewNode(final Object node) {
+        return ((Node)node).isNew();
+    }
+
+    public boolean isPropertyMandatory(final Object node, final String name)
+    throws PersistenceException {
+        try {
+            final Property prop = ((Node)node).getProperty(name);
+            return prop.getDefinition().isMandatory();
+        } catch ( final RepositoryException re) {
+            throw new PersistenceException(re.getMessage(), re);
+        }
+    }
+
+    public boolean isPropertyMultiple(final Object node, final String name)
+    throws PersistenceException {
+        try {
+            final Property prop = ((Node)node).getProperty(name);
+            return prop.getDefinition().isMultiple();
+        } catch ( final RepositoryException re) {
+            throw new PersistenceException(re.getMessage(), re);
+        }
+    }
+
+    public Integer getPropertyType(final Object node, final String name)
+    throws PersistenceException {
+        try {
+            if ( ((Node)node).hasProperty(name) ) {
+                return ((Node)node).getProperty(name).getType();
+            }
+        } catch ( final RepositoryException re) {
+            throw new PersistenceException(re.getMessage(), re);
+        }
+        return null;
+    }
+
+    private boolean isWeakReference(int propertyType) {
+        return propertyType == PropertyType.WEAKREFERENCE;
+    }
+
+    /**
+     * Stores property value(s) as reference(s). Will parse the reference(s) 
from the string
+     * value(s) in the {@link RequestProperty}.
+     *
+     * @return A modification only if parsing was successful and the property 
was actually changed
+     */
+    public Modification storeAsReference(
+            final Object n,
+            final String name,
+            final String[] values,
+            final int type,
+            final boolean multiValued)
+    throws PersistenceException {
+        try {
+            final Node node = (Node)n;
+            if (multiValued) {
+                Value[] array = ReferenceParser.parse(node.getSession(), 
values, isWeakReference(type));
+                if (array != null) {
+                    return Modification.onModified(
+                            node.setProperty(name, array).getPath());
+                }
+            } else {
+                if (values.length >= 1) {
+                    Value v = ReferenceParser.parse(node.getSession(), 
values[0], isWeakReference(type));
+                    if (v != null) {
+                        return Modification.onModified(
+                                node.setProperty(name, v).getPath());
+                    }
+                }
+            }
+            return null;
+        } catch ( final RepositoryException re) {
+            throw new PersistenceException(re.getMessage(), re);
+        }
+    }
+
+    public boolean hasSession(final ResourceResolver resolver) {
+        return resolver.adaptTo(Session.class) != null;
+    }
+
+    public void setTypedProperty(final Object n,
+            final String name,
+            final String[] values,
+            final int type,
+            final boolean multiValued)
+    throws PersistenceException {
+        try {
+            if (multiValued) {
+                ((Node)n).setProperty(name, values, type);
+            } else if (values.length >= 1) {
+                ((Node)n).setProperty(name, values[0], type);
+            }
+        } catch ( final RepositoryException re) {
+            throw new PersistenceException(re.getMessage(), re);
+        }
+    }
+
+    public Object getNode(final Resource rsrc) {
+        return rsrc.adaptTo(Node.class);
+    }
 }

Modified: 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java?rev=1791259&r1=1791258&r2=1791259&view=diff
==============================================================================
--- 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java
 (original)
+++ 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java
 Thu Apr 13 14:30:40 2017
@@ -24,6 +24,7 @@ import javax.jcr.ValueFactory;
 
 /**
  * Takes a string representation of a node (either a path or a uuid) and tries 
to parse it.
+ * ReferenceParser is only used if JCR is available.
  */
 public class ReferenceParser {
 
@@ -33,17 +34,16 @@ public class ReferenceParser {
      * <p/>
      *
      * @param value a path or UUID
-     * @param factory the value factory
      * @param weak true to create a WeakReference value
      * @return the value or <code>null</code>
      * @throws RepositoryException
      */
-    public static Value parse(Session session, String value, ValueFactory 
factory, boolean weak) throws RepositoryException {
+    public static Value parse(Session session, String value, boolean weak) 
throws RepositoryException {
         Node n = parse(session, value);
         if (n == null) {
             return null;
         }
-        return createReferenceValue(n, factory, weak);
+        return createReferenceValue(n, session.getValueFactory(), weak);
     }
 
     /**
@@ -58,14 +58,14 @@ public class ReferenceParser {
      * @return the values or <code>null</code>
      * @throws RepositoryException
      */
-    public static Value[] parse(Session session, String[] values, ValueFactory 
factory, boolean weak) throws RepositoryException {
+    public static Value[] parse(Session session, String[] values, boolean 
weak) throws RepositoryException {
         Value ret[] = new Value[values.length];
         for (int i=0; i< values.length; i++) {
             Node n = parse(session, values[i]);
             if (n == null) {
                 return null;
             }
-            ret[i] = createReferenceValue(n, factory, weak);
+            ret[i] = createReferenceValue(n, session.getValueFactory(), weak);
         }
         return ret;
     }

Modified: 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java?rev=1791259&r1=1791258&r2=1791259&view=diff
==============================================================================
--- 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java
 (original)
+++ 
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java
 Thu Apr 13 14:30:40 2017
@@ -24,15 +24,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import javax.jcr.Node;
-import javax.jcr.Property;
 import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.ValueFactory;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.PropertyDefinition;
 
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.sling.api.resource.ModifiableValueMap;
@@ -42,9 +34,10 @@ import org.apache.sling.servlets.post.Mo
 import org.apache.sling.servlets.post.SlingPostConstants;
 
 /**
- * Sets a Property on the given Node, in some cases with a specific type and
+ * Sets a property on the given resource, in some cases with a specific type 
and
  * value. For example, "lastModified" with an empty value is stored as the
  * current Date.
+ * Special handling might apply if the resource is backed by a JCR node.
  */
 public class SlingPropertyValueHandler {
 
@@ -95,36 +88,6 @@ public class SlingPropertyValueHandler {
         return AUTO_PROPS.get(propertyName);
     }
 
-    private PropertyDefinition searchPropertyDefinition(final NodeType 
nodeType, final String name) {
-        if ( nodeType.getPropertyDefinitions() != null ) {
-            for(final PropertyDefinition pd : 
nodeType.getPropertyDefinitions()) {
-                if ( pd.getName().equals(name) ) {
-                    return pd;
-                }
-            }
-        }
-        // SLING-2877:
-        // no need to search property definitions of super types, as 
nodeType.getPropertyDefinitions()
-        // already includes those. see javadoc of {@link 
NodeType#getPropertyDefinitions()}
-        return null;
-    }
-
-    private PropertyDefinition searchPropertyDefinition(final Node node, final 
String name)
-    throws RepositoryException {
-        PropertyDefinition result = 
searchPropertyDefinition(node.getPrimaryNodeType(), name);
-        if ( result == null ) {
-            if ( node.getMixinNodeTypes() != null ) {
-                for(final NodeType mt : node.getMixinNodeTypes()) {
-                    result = this.searchPropertyDefinition(mt, name);
-                    if ( result != null ) {
-                        return result;
-                    }
-                }
-            }
-        }
-        return result;
-    }
-
     /**
      * Set property on given node, with some automatic values when user 
provides
      * the field name but no value.
@@ -139,13 +102,13 @@ public class SlingPropertyValueHandler {
      *
      * @param parent the parent node
      * @param prop the request property
-     * @throws RepositoryException if a repository error occurs
+     * @throws PersistenceException if a resource error occurs
      */
     public void setProperty(final Resource parent, final RequestProperty prop)
-            throws RepositoryException, PersistenceException {
+    throws PersistenceException {
         final Modifiable mod = new Modifiable();
         mod.resource = parent;
-        mod.node = parent.adaptTo(Node.class);
+        mod.node = jcrSupport.getNode(parent);
         mod.valueMap = parent.adaptTo(ModifiableValueMap.class);
         if ( mod.valueMap == null ) {
             throw new PersistenceException("Resource at '" + parent.getPath() 
+ "' is not modifiable.");
@@ -158,18 +121,12 @@ public class SlingPropertyValueHandler {
 
         } else if (AUTO_PROPS.containsKey(name)) {
             // check if this is a JCR resource and check node type
-            if ( mod.node != null ) {
-                final PropertyDefinition pd = 
this.searchPropertyDefinition(mod.node, name);
-                if ( pd != null ) {
-                    // SLING-2877 (autocreated check is only required for new 
nodes)
-                    if ( (mod.node.isNew() && pd.isAutoCreated()) || 
pd.isProtected() ) {
-                        return;
-                    }
-                }
+            if ( this.jcrSupport.isPropertyProtectedOrNewAutoCreated(mod.node, 
name) ) {
+                return;
             }
 
             // avoid collision with protected properties
-            final boolean isNew = (mod.node != null ? mod.node.isNew() : true);
+            final boolean isNew = jcrSupport.isNewNode(mod.node);
             switch (getAutoType(name)) {
                 case CREATED:
                     if (isNew) {
@@ -196,12 +153,12 @@ public class SlingPropertyValueHandler {
 
     /**
      * Sets the property to the given date
-     * @param parent parent node
+     * @param parent parent resource
      * @param name name of the property
-     * @throws RepositoryException if a repository error occurs
+     * @throws PersistenceException if a resource error occurs
      */
-    private void setCurrentDate(Modifiable parent, String name)
-            throws RepositoryException, PersistenceException {
+    private void setCurrentDate(final Modifiable parent, final String name)
+    throws PersistenceException {
         removePropertyIfExists(parent, name);
         parent.valueMap.put(name, now);
         changes.add(Modification.onModified(parent.resource.getPath() + '/' + 
name));
@@ -209,12 +166,12 @@ public class SlingPropertyValueHandler {
 
     /**
      * set property to the current User id
-     * @param parent parent node
+     * @param parent parent resource
      * @param name name of the property
-     * @throws RepositoryException if a repository error occurs
+     * @throws PersistenceException if a resource error occurs
      */
-    private void setCurrentUser(Modifiable parent, String name)
-            throws RepositoryException, PersistenceException {
+    private void setCurrentUser(final Modifiable parent, final String name)
+    throws PersistenceException {
         removePropertyIfExists(parent, name);
         final String user = parent.resource.getResourceResolver().getUserID();
         parent.valueMap.put(name, user);
@@ -222,29 +179,20 @@ public class SlingPropertyValueHandler {
     }
 
     /**
-     * Removes the property with the given name from the parent node if it
+     * Removes the property with the given name from the parent resource if it
      * exists and if it's not a mandatory property.
      *
-     * @param parent the parent node
+     * @param parent the parent resource
      * @param name the name of the property to remove
      * @return path of the property that was removed or <code>null</code> if
      *         it was not removed
-     * @throws RepositoryException if a repository error occurs.
+     * @throws PersistenceException if a repository error occurs.
      */
     private String removePropertyIfExists(final Modifiable parent, final 
String name)
-            throws RepositoryException, PersistenceException {
-        if (parent.valueMap.containsKey(name) ) {
-            if ( parent.node != null ) {
-                final Property prop = parent.node.getProperty(name);
-                if (!prop.getDefinition().isMandatory()) {
-                    final String path = prop.getPath();
-                    prop.remove();
-                    return path;
-                }
-            } else {
-                parent.valueMap.remove(name);
-                return parent.resource.getPath() + '/' + name;
-            }
+    throws PersistenceException {
+        if (parent.valueMap.containsKey(name) && 
!jcrSupport.isPropertyMandatory(parent.node, name)) {
+            parent.valueMap.remove(name);
+            return parent.resource.getPath() + '/' + name;
         }
         return null;
     }
@@ -252,12 +200,12 @@ public class SlingPropertyValueHandler {
     /**
      * set property without processing, except for type hints
      *
-     * @param parent the parent node
+     * @param parent the parent resource
      * @param prop the request property
-     * @throws RepositoryException if a repository error occurs.
+     * @throws PersistenceException if a resource error occurs.
      */
     private void setPropertyAsIs(final Modifiable parent, final 
RequestProperty prop)
-            throws RepositoryException, PersistenceException {
+    throws PersistenceException {
 
         String[] values = prop.getStringValues();
 
@@ -287,15 +235,13 @@ public class SlingPropertyValueHandler {
                 removeIfSingleValueProperty(parent, prop);
             }
 
-            Session s = 
parent.resource.getResourceResolver().adaptTo(Session.class);
-            if (s != null) {
-                final ValueFactory valFac = s.getValueFactory();
+            if (jcrSupport.hasSession(parent.resource.getResourceResolver())) {
                 if (type == PropertyType.DATE) {
-                    if (storeAsDate(parent, prop.getName(), values, 
multiValue, valFac)) {
+                    if (storeAsDate(parent, prop.getName(), values, 
multiValue)) {
                         return;
                     }
                 } else if (isReferencePropertyType(type)) {
-                    if (storeAsReference(parent, prop.getName(), values, type, 
multiValue, valFac)) {
+                    if (storeAsReference(parent, prop.getName(), values, type, 
multiValue)) {
                         return;
                     }
                 }
@@ -309,7 +255,7 @@ public class SlingPropertyValueHandler {
      * Patches a multi-value property using add and remove operations per 
value.
      */
     private String[] patch(final Modifiable parent, String name, String[] 
values)
-            throws RepositoryException, PersistenceException {
+    throws PersistenceException {
         // we do not use a Set here, as we want to be very restrictive in our
         // actions and avoid touching elements that are not modified through 
the
         // add/remove patch operations; e.g. if the value "foo" occurs twice
@@ -318,23 +264,16 @@ public class SlingPropertyValueHandler {
         List<String> oldValues = new ArrayList<>();
 
         if (parent.valueMap.containsKey(name)) {
-            if ( parent.node != null ) {
-                final Property p = parent.node.getProperty(name);
+            if ( parent.node != null && 
!jcrSupport.isPropertyMultiple(parent.node, name)) {
 
                 // can only patch multi-value props
-                if (!p.getDefinition().isMultiple()) {
-                    return null;
-                }
+                return null;
+            }
 
-                for (Value v : p.getValues()) {
-                    oldValues.add(v.getString());
-                }
-            } else {
-                final String[] setValues = parent.valueMap.get(name, 
String[].class);
-                if ( setValues != null ) {
-                    for(final String v : setValues) {
-                        oldValues.add(v);
-                    }
+            final String[] setValues = parent.valueMap.get(name, 
String[].class);
+            if ( setValues != null ) {
+                for(final String v : setValues) {
+                    oldValues.add(v);
                 }
             }
         }
@@ -372,16 +311,13 @@ public class SlingPropertyValueHandler {
         return propertyType == PropertyType.REFERENCE || propertyType == 
PropertyType.WEAKREFERENCE;
     }
 
-    private boolean isWeakReference(int propertyType) {
-        return propertyType == PropertyType.WEAKREFERENCE;
-    }
-
     /**
      * Returns the property type to use for the given property. This is defined
      * either by an explicit type hint in the request or simply the type of the
      * existing property.
      */
-    private int getType(final Modifiable parent, RequestProperty prop) throws 
RepositoryException {
+    private int getType(final Modifiable parent, RequestProperty prop)
+    throws PersistenceException {
         // no explicit typehint
         int type = PropertyType.UNDEFINED;
         if (prop.getTypeHint() != null) {
@@ -393,10 +329,9 @@ public class SlingPropertyValueHandler {
         }
         String[] values = prop.getStringValues();
         if ( type == PropertyType.UNDEFINED && values != null && values.length 
> 0 ) {
-            if ( parent.node != null ) {
-                if ( parent.node.hasProperty(prop.getName()) ) {
-                    type = parent.node.getProperty(prop.getName()).getType();
-                }
+            final Integer jcrType = jcrSupport.getPropertyType(parent.node, 
prop.getName());
+            if ( jcrType != null ) {
+                type = jcrType;
             }
         }
         return type;
@@ -405,7 +340,8 @@ public class SlingPropertyValueHandler {
     /**
      * Returns whether the property should be handled as multi-valued.
      */
-    private boolean isMultiValue(final Modifiable parent, RequestProperty 
prop, String[] values) throws RepositoryException {
+    private boolean isMultiValue(final Modifiable parent, RequestProperty 
prop, String[] values)
+    throws PersistenceException {
         // multiple values are provided
         if (values != null && values.length > 1) {
             return true;
@@ -419,12 +355,12 @@ public class SlingPropertyValueHandler {
             return true;
         }
         // nothing in the request, so check the current JCR property definition
+        final Object value = parent.valueMap.get(prop.getName());
         if ( parent.node != null ) {
-            if (parent.node.hasProperty(prop.getName()) ) {
-                return 
parent.node.getProperty(prop.getName()).getDefinition().isMultiple();
+            if ( value != null ) {
+                return jcrSupport.isPropertyMultiple(parent.node, 
prop.getName());
             }
         } else {
-            final Object value = parent.valueMap.get(prop.getName());
             if ( value != null && value.getClass().isArray() ) {
                 return true;
             }
@@ -437,22 +373,15 @@ public class SlingPropertyValueHandler {
      * removes multi-value properties.
      */
     private void clearProperty(final Modifiable parent, RequestProperty prop)
-            throws RepositoryException, PersistenceException {
+    throws PersistenceException {
         if (parent.valueMap.containsKey(prop.getName())) {
-            if ( parent.node != null ) {
-                if 
(parent.node.getProperty(prop.getName()).getDefinition().isMultiple()) {
-                    //the existing property is multi-valued, so just delete it?
-                    final String removePath = removePropertyIfExists(parent, 
prop.getName());
-                    if ( removePath != null ) {
-                        changes.add(Modification.onDeleted(removePath));
-                    }
-                } else {
-                    changes.add(Modification.onModified(
-                            parent.node.setProperty(prop.getName(), 
"").getPath()
-                            ));
+            if ( jcrSupport.isPropertyMultiple(parent.node, prop.getName()) ) {
+                // the existing property is multi-valued, so just delete it?
+                final String removePath = removePropertyIfExists(parent, 
prop.getName());
+                if ( removePath != null ) {
+                    changes.add(Modification.onDeleted(removePath));
                 }
             } else {
-                parent.valueMap.put(prop.getName(), "");
                 changes.add(Modification.onModified(parent.resource.getPath() 
+ '/' + prop.getName()));
             }
         }
@@ -461,8 +390,8 @@ public class SlingPropertyValueHandler {
     /**
      * Removes the property if it exists.
      */
-    private void removeProperty(final Modifiable parent, RequestProperty prop)
-            throws RepositoryException, PersistenceException {
+    private void removeProperty(final Modifiable parent, final RequestProperty 
prop)
+    throws PersistenceException {
         final String removePath = removePropertyIfExists(parent, 
prop.getName());
         if ( removePath != null ) {
             changes.add(Modification.onDeleted(removePath));
@@ -474,44 +403,36 @@ public class SlingPropertyValueHandler {
      */
     private void removeIfSingleValueProperty(final Modifiable parent,
             final RequestProperty prop)
-                    throws RepositoryException, PersistenceException {
+    throws PersistenceException {
         if (parent.valueMap.containsKey(prop.getName())) {
-            if ( parent.node != null ) {
-                if 
(!parent.node.getProperty(prop.getName()).getDefinition().isMultiple()) {
-                    // the existing property is single-valued, so we have to 
delete it before setting the
-                    // multi-value variation
-                    final String removePath = removePropertyIfExists(parent, 
prop.getName());
-                    if ( removePath != null ) {
-                        changes.add(Modification.onDeleted(removePath));
-                    }
-                }
-            } else {
-                final String removePath = removePropertyIfExists(parent, 
prop.getName());
-                if ( removePath != null ) {
-                    changes.add(Modification.onDeleted(removePath));
-                }
+            if ( jcrSupport.isPropertyMultiple(parent.node, prop.getName()) ) {
+                // do nothing, multi value
+                return;
+            }
+            final String removePath = removePropertyIfExists(parent, 
prop.getName());
+            if ( removePath != null ) {
+                changes.add(Modification.onDeleted(removePath));
             }
         }
     }
 
     /**
-     * Parses the given source strings and returns the respective jcr date 
value
+     * Parses the given source strings and returns the respective Calendar 
value
      * instances. If no format matches for any of the sources
      * returns <code>null</code>.
      * <p/>
      *
      * @param sources date time source strings
-     * @param factory the value factory
-     * @return jcr date value representations of the source or 
<code>null</code>
+     * @return Calendar value representations of the source or 
<code>null</code>
      */
-    private Value[] parse(String sources[], ValueFactory factory) {
-        Value ret[] = new Value[sources.length];
+    private Calendar[] parse(final String sources[]) {
+        final Calendar ret[] = new Calendar[sources.length];
         for (int i=0; i< sources.length; i++) {
-            Calendar c = dateParser.parse(sources[i]);
+            final Calendar c = dateParser.parse(sources[i]);
             if (c == null) {
                 return null;
             }
-            ret[i] = factory.createValue(c);
+            ret[i] = c;
         }
         return ret;
     }
@@ -523,22 +444,12 @@ public class SlingPropertyValueHandler {
      *
      * @return true only if parsing was successful and the property was 
actually changed
      */
-    private boolean storeAsDate(final Modifiable parent, String name, String[] 
values, boolean multiValued, ValueFactory valFac)
-            throws RepositoryException, PersistenceException {
+    private boolean storeAsDate(final Modifiable parent, String name, String[] 
values, boolean multiValued)
+    throws PersistenceException {
         if (multiValued) {
-            final Value[] array = parse(values, valFac);
+            final Calendar[] array = parse(values);
             if (array != null) {
-                if ( parent.node != null ) {
-                    parent.node.setProperty(name, array);
-                } else {
-                    final Calendar[] dates = new Calendar[array.length];
-                    int index = 0;
-                    for(final Value v : array) {
-                        dates[index] = v.getDate();
-                        index++;
-                    }
-                    parent.valueMap.put(name, dates);
-                }
+                parent.valueMap.put(name, array);
                 changes.add(Modification.onModified(parent.resource.getPath() 
+ '/' + name));
                 return true;
             }
@@ -566,32 +477,10 @@ public class SlingPropertyValueHandler {
             final String name,
             final String[] values,
             final int type,
-            final boolean multiValued,
-            final ValueFactory valFac)
-    throws RepositoryException, PersistenceException {
-        if ( parent.node == null ) {
-            throw new PersistenceException("Resource " + 
parent.resource.getPath() + " does not support reference properties.");
-        }
-        if (multiValued) {
-            Value[] array = this.jcrSupport.parse(parent.node.getSession(), 
values, valFac, isWeakReference(type));
-            if (array != null) {
-                changes.add(Modification.onModified(
-                        parent.node.setProperty(name, array).getPath()
-                        ));
-                return true;
-            }
-        } else {
-            if (values.length >= 1) {
-                Value v = this.jcrSupport.parse(parent.node.getSession(), 
values[0], valFac, isWeakReference(type));
-                if (v != null) {
-                    changes.add(Modification.onModified(
-                            parent.node.setProperty(name, v).getPath()
-                            ));
-                    return true;
-                }
-            }
-        }
-        return false;
+            final boolean multiValued)
+    throws PersistenceException {
+        final Modification mod = 
this.jcrSupport.storeAsReference(parent.resource, parent.node, name, values, 
type, multiValued);
+        return mod != null;
     }
 
     /**
@@ -603,36 +492,18 @@ public class SlingPropertyValueHandler {
             final String[] values,
             final int type,
             final boolean multiValued)
-                    throws RepositoryException, PersistenceException {
-        if ( parent.node != null ) {
-            Property p = null;
+    throws PersistenceException {
+        if ( parent.node != null && type != PropertyType.UNDEFINED ) {
+            jcrSupport.setTypedProperty(parent.node, name, values, type, 
multiValued);
 
-            if (multiValued) {
-                if (type == PropertyType.UNDEFINED) {
-                    p = parent.node.setProperty(name, values);
-                } else {
-                    p = parent.node.setProperty(name, values, type);
-                }
-            } else if (values.length >= 1) {
-                if (type == PropertyType.UNDEFINED) {
-                    p = parent.node.setProperty(name, values[0]);
-                } else {
-                    p = parent.node.setProperty(name, values[0], type);
-                }
-            }
-
-            if (p != null) {
-                changes.add(Modification.onModified(p.getPath()));
-            }
         } else {
             if (multiValued) {
                 parent.valueMap.put(name, toJavaObject(values, type));
-                changes.add(Modification.onModified(parent.resource.getPath() 
+ '/' + name));
             } else if (values.length >= 1) {
                 parent.valueMap.put(name, toJavaObject(values[0], type));
-                changes.add(Modification.onModified(parent.resource.getPath() 
+ '/' + name));
             }
         }
+        changes.add(Modification.onModified(parent.resource.getPath() + '/' + 
name));
     }
 
     /** Converts a value */
@@ -677,6 +548,6 @@ public class SlingPropertyValueHandler {
     public final static class Modifiable {
         public Resource resource;
         public ModifiableValueMap valueMap;
-        public Node node;
+        public Object node;
     }
 }


Reply via email to