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());
Show replies by date