[dna-commits] DNA SVN: r770 - trunk/dna-jcr/src/main/java/org/jboss/dna/jcr.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Wed Mar 11 10:44:39 EDT 2009


Author: rhauch
Date: 2009-03-11 10:44:39 -0400 (Wed, 11 Mar 2009)
New Revision: 770

Modified:
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java
Log:
DNA-194 Implement update JCR capability

Applied the "...move_value_cast" patch, which moves the JcrNodeType logic determining whether a value can be cast to another type into the JcrValue class where it can be used to actually convert the value to a value of another type.  Also made the "createValueFormatException(...)" methods private to increase likelihood they'll be inlined. All tests pass.

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java	2009-03-10 19:43:15 UTC (rev 769)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java	2009-03-11 14:44:39 UTC (rev 770)
@@ -29,7 +29,6 @@
 import java.util.List;
 import java.util.Set;
 import java.util.Stack;
-import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 import javax.jcr.nodetype.NodeDefinition;
@@ -38,10 +37,6 @@
 import net.jcip.annotations.Immutable;
 import org.jboss.dna.common.util.CheckArg;
 import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.Path;
-import org.jboss.dna.graph.property.ValueFactories;
-import org.jboss.dna.graph.property.ValueFormatException;
-import org.jboss.dna.graph.property.Path.Segment;
 
 /**
  * DNA implementation of JCR {@link NodeType}s.
@@ -329,100 +324,16 @@
         if (value == null) {
             return !property.isMandatory();
         }
-
-        return canCastValueToType(value, property.getRequiredType());
-    }
-
-    /**
-     * Internal method to validate that a value can be cast to a given JCR property type. The values are set according to the
-     * following rules:
-     * <ol>
-     * <li>If <code>property.getRequiredType()</code> is {@link PropertyType#UNDEFINED}, return <code>true</code></li>
-     * <li>Compare the type of the given value to the required type and see if they are compatible based on the rules in the JCR
-     * 1.0 spec.</li>
-     * </ol>
-     * 
-     * @param jcrPropertyType a value from the {@link PropertyType} constants to which this value MAY be able to be casted.
-     * @param value the value to set (may not be <code>null</code>)
-     * @return whether the value can be cast to the given property type
-     */
-    private boolean canCastValueToType( Value value,
-                                        int jcrPropertyType ) {
-        assert value != null;
-
-        int valueType = value.getType();
-
-        // Trivial case - no cast required
-        if (valueType == jcrPropertyType) {
-            return true;
-        }
-
+        
         try {
-            switch (jcrPropertyType) {
-                case PropertyType.BOOLEAN:
-                    if (valueType == PropertyType.STRING) {
-                        return true;
-                    }
-
-                    if (valueType == PropertyType.BINARY) {
-                        // If the binary can be converted to a UTF-8 string, it can be set onto a boolean property
-                        value.getString();
-                        return true;
-                    }
-                    return false;
-
-                case PropertyType.DATE:
-                    if (valueType == PropertyType.DOUBLE || valueType == PropertyType.LONG) {
-                        return true;
-                    }
-
-                    if (valueType == PropertyType.STRING || valueType == PropertyType.BINARY) {
-                        // If the binary can be converted to a date, it can be set onto a date property
-                        value.getDate();
-                        return true;
-                    }
-                    return false;
-
-                case PropertyType.NAME:
-                    ValueFactories valueFactories = session.getExecutionContext().getValueFactories();
-                    if (valueType == PropertyType.STRING || valueType == PropertyType.BINARY) {
-                        valueFactories.getNameFactory().create(value.getString());
-                        return true;
-                    }
-
-                    if (valueType == PropertyType.PATH) {
-                        Path path = valueFactories.getPathFactory().create(value.getString());
-
-                        Segment[] segments = path.getSegmentsArray();
-                        return !path.isAbsolute() && segments.length == 1 && !segments[0].hasIndex();
-                    }
-
-                    return false;
-
-                case PropertyType.PATH:
-                    return value.getType() == PropertyType.STRING;
-
-                    // Nothing can be converted to these types (except themselves)
-                case PropertyType.REFERENCE:
-                case PropertyType.DOUBLE:
-                case PropertyType.LONG:
-                    return false;
-
-                    // Anything can be converted to these types
-                case PropertyType.BINARY:
-                case PropertyType.STRING:
-                case PropertyType.UNDEFINED:
-                    return true;
-                default:
-                    assert false : "Unexpected JCR property type " + jcrPropertyType;
-                    // This should still throw an exception even if assertions are turned off
-                    throw new IllegalStateException("Invalid property type " + jcrPropertyType);
-            }
-        } catch (RepositoryException re) {
+            assert value instanceof JcrValue : "Illegal implementation of Value interface";
+            ((JcrValue) value).asType(property.getRequiredType());
+        }
+        catch (javax.jcr.ValueFormatException vfe) {
+            // Cast failed
             return false;
-        } catch (ValueFormatException vfe) {
-            return false;
         }
+        return true;
     }
 
     /**
@@ -455,7 +366,12 @@
 
         for (int i = 0; i < values.length; i++) {
             if (values[i] != null) {
-                if (!canCastValueToType(values[i], property.getRequiredType())) {
+                try {
+                    assert values[i] instanceof JcrValue : "Illegal implementation of Value interface";
+                    ((JcrValue) values[i]).asType(property.getRequiredType());
+                }
+                catch (javax.jcr.ValueFormatException vfe) {
+                    // Cast failed
                     return false;
                 }
             }

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java	2009-03-10 19:43:15 UTC (rev 769)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java	2009-03-11 14:44:39 UTC (rev 770)
@@ -25,13 +25,17 @@
 
 import java.io.InputStream;
 import java.util.Calendar;
+import javax.jcr.Node;
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
 import net.jcip.annotations.NotThreadSafe;
 import org.jboss.dna.graph.property.Binary;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
 import org.jboss.dna.graph.property.ValueFactories;
+import org.jboss.dna.graph.property.Path.Segment;
 
 /**
  * @author jverhaeg
@@ -58,10 +62,14 @@
 
     private State state = State.NEVER_CONSUMED;
 
-    ValueFormatException createValueFormatException( Class<?> type ) {
+    private ValueFormatException createValueFormatException( Class<?> type ) {
         return new ValueFormatException(JcrI18n.cannotConvertValue.text(value.getClass().getSimpleName(), type.getSimpleName()));
     }
 
+    private ValueFormatException createValueFormatException( org.jboss.dna.graph.property.ValueFormatException vfe ) {
+        return new ValueFormatException(vfe);
+    }
+
     /**
      * {@inheritDoc}
      * 
@@ -177,6 +185,112 @@
         return type;
     }
 
+    /**
+     * Returns a copy of the current {@link JcrValue} cast to the JCR type specified by the <code>type</code> argument. If the
+     * value cannot be converted base don the JCR type conversion rules, a {@link ValueFormatException} will be thrown.
+     * 
+     * @param type the JCR type from {@link PropertyType} that the new {@link JcrValue} should have.
+     * @return a new {@link JcrValue} with the given JCR type and an equivalent value.
+     * @throws ValueFormatException if the value contained by this {@link JcrValue} cannot be converted to the desired type.
+     * @see PropertyType
+     */
+    JcrValue asType( int type ) throws ValueFormatException {
+
+        if (type == this.type) {
+            return new JcrValue(this.valueFactories, this.type, this.value);
+        }
+
+        switch (type) {
+            case PropertyType.BOOLEAN:
+                try {
+                    if (this.type == PropertyType.STRING || this.type == PropertyType.BINARY) {
+                        return new JcrValue(this.valueFactories, type, valueFactories.getBooleanFactory().create(value));
+                    }
+                } catch (org.jboss.dna.graph.property.ValueFormatException vfe) {
+                    throw createValueFormatException(vfe);
+                }
+                throw createValueFormatException(boolean.class);
+
+            case PropertyType.DATE:
+                try {
+                    if (this.type == PropertyType.DOUBLE || this.type == PropertyType.LONG || this.type == PropertyType.STRING
+                        || this.type == PropertyType.BINARY) {
+                        return new JcrValue(this.valueFactories, type, valueFactories.getDateFactory().create(value));
+                    }
+                } catch (org.jboss.dna.graph.property.ValueFormatException vfe) {
+                    throw createValueFormatException(vfe);
+                }
+
+                throw createValueFormatException(Calendar.class);
+
+            case PropertyType.NAME:
+                try {
+                    if (this.type == PropertyType.STRING) {
+                        return new JcrValue(this.valueFactories, type, this.valueFactories.getNameFactory().create(value));
+                    }
+
+                    String valueAsString = this.valueFactories.getStringFactory().create(value);
+                    if (this.type == PropertyType.BINARY) {
+                        return new JcrValue(this.valueFactories, type, this.valueFactories.getNameFactory().create(valueAsString));
+
+                    }
+
+                    if (this.type == PropertyType.PATH) {
+                        Path path = valueFactories.getPathFactory().create(valueAsString);
+
+                        Segment[] segments = path.getSegmentsArray();
+                        if (!path.isAbsolute() && segments.length == 1 && !segments[0].hasIndex()) {
+                            return new JcrValue(this.valueFactories, type, this.valueFactories.getNameFactory()
+                                                                                              .create(valueAsString));
+
+                        }
+                    }
+                } catch (org.jboss.dna.graph.property.ValueFormatException vfe) {
+                    throw createValueFormatException(vfe);
+                }
+
+                throw createValueFormatException(Name.class);
+
+            case PropertyType.PATH:
+                try {
+                    if (this.type == PropertyType.STRING) {
+                        return new JcrValue(this.valueFactories, type, this.valueFactories.getPathFactory().create(value));
+                    }
+                } catch (org.jboss.dna.graph.property.ValueFormatException vfe) {
+                    throw createValueFormatException(vfe);
+                }
+                throw createValueFormatException(Path.class);
+
+                // Nothing can be converted to these types (except themselves)
+            case PropertyType.REFERENCE:
+                throw createValueFormatException(Node.class);
+            case PropertyType.DOUBLE:
+                throw createValueFormatException(double.class);
+            case PropertyType.LONG:
+                throw createValueFormatException(long.class);
+
+                // Anything can be converted to these types
+            case PropertyType.BINARY:
+                try {
+                    return new JcrValue(this.valueFactories, type, valueFactories.getBinaryFactory().create(value));
+                } catch (org.jboss.dna.graph.property.ValueFormatException vfe) {
+                    throw createValueFormatException(vfe);
+                }
+            case PropertyType.STRING:
+                try {
+                    return new JcrValue(this.valueFactories, type, valueFactories.getStringFactory().create(value));
+                } catch (org.jboss.dna.graph.property.ValueFormatException vfe) {
+                    throw createValueFormatException(vfe);
+                }
+            case PropertyType.UNDEFINED:
+                return new JcrValue(this.valueFactories, this.type, this.value);
+            default:
+                assert false : "Unexpected JCR property type " + type;
+                // This should still throw an exception even if assertions are turned off
+                throw new IllegalStateException("Invalid property type " + type);
+        }
+    }
+
     void nonInputStreamConsumed() {
         if (state == State.INPUT_STREAM_CONSUMED) {
             throw new IllegalStateException(JcrI18n.inputStreamConsumed.text());




More information about the dna-commits mailing list