Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java (revision 769) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java (working copy) @@ -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: - *
property.getRequiredType()
is {@link PropertyType#UNDEFINED}, return true
null
)
- * @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;
}
}
Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java
===================================================================
--- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java (revision 769)
+++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java (working copy)
@@ -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
@@ -62,6 +66,10 @@
return new ValueFormatException(JcrI18n.cannotConvertValue.text(value.getClass().getSimpleName(), type.getSimpleName()));
}
+ 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 type
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());