Author: rhauch
Date: 2009-04-02 14:52:26 -0400 (Thu, 02 Apr 2009)
New Revision: 803
Modified:
trunk/dna-common/src/main/java/org/jboss/dna/common/util/IoUtil.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/InMemoryBinary.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrProperty.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrPropertyDefinition.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrPropertyTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java
Log:
DNA-194 Implement update JCR capability
Added more support for Node.setProperty(...), and enabled several TCK unit tests.
Modified: trunk/dna-common/src/main/java/org/jboss/dna/common/util/IoUtil.java
===================================================================
--- trunk/dna-common/src/main/java/org/jboss/dna/common/util/IoUtil.java 2009-04-02
00:03:04 UTC (rev 802)
+++ trunk/dna-common/src/main/java/org/jboss/dna/common/util/IoUtil.java 2009-04-02
18:52:26 UTC (rev 803)
@@ -34,6 +34,7 @@
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
+import java.util.Arrays;
/**
* @author Randall Hauch
@@ -352,6 +353,58 @@
}
}
+ /**
+ * Write the entire contents of the supplied string to the given stream. This method
always flushes and closes the stream when
+ * finished.
+ *
+ * @param input1 the first stream
+ * @param input2 the second stream
+ * @return true if the streams contain the same content, or false otherwise
+ * @throws IOException
+ * @throws IllegalArgumentException if the stream is null
+ */
+ public static boolean isSame( InputStream input1,
+ InputStream input2 ) throws IOException {
+ CheckArg.isNotNull(input1, "input1");
+ CheckArg.isNotNull(input2, "input2");
+ boolean error = false;
+ try {
+ byte[] buffer1 = new byte[1024];
+ byte[] buffer2 = new byte[1024];
+ try {
+ int numRead1 = 0;
+ int numRead2 = 0;
+ while (true) {
+ numRead1 = input1.read(buffer1);
+ numRead2 = input2.read(buffer2);
+ if (numRead1 > -1) {
+ if (numRead2 != numRead1) return false;
+ // Otherwise same number of bytes read
+ if (!Arrays.equals(buffer1, buffer2)) return false;
+ // Otherwise same bytes read, so continue ...
+ } else {
+ // Nothing more in stream 1 ...
+ return numRead2 < 0;
+ }
+ }
+ } finally {
+ input1.close();
+ }
+ } catch (IOException e) {
+ error = true; // this error should be thrown, even if there is an error
closing stream 2
+ throw e;
+ } catch (RuntimeException e) {
+ error = true; // this error should be thrown, even if there is an error
closing stream 2
+ throw e;
+ } finally {
+ try {
+ input2.close();
+ } catch (IOException e) {
+ if (!error) throw e;
+ }
+ }
+ }
+
private IoUtil() {
// Prevent construction
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/InMemoryBinary.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/InMemoryBinary.java 2009-04-02
00:03:04 UTC (rev 802)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/InMemoryBinary.java 2009-04-02
18:52:26 UTC (rev 803)
@@ -44,6 +44,7 @@
private final byte[] bytes;
private byte[] sha1hash;
+ private int hc;
public InMemoryBinary( byte[] bytes ) {
CheckArg.isNotNull(bytes, "bytes");
@@ -52,7 +53,22 @@
/**
* {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
*/
+ @Override
+ public int hashCode() {
+ if (sha1hash == null) {
+ // Idempotent, so doesn't matter if we recompute in concurrent threads
...
+ sha1hash = computeHash(bytes);
+ hc = sha1hash.hashCode();
+ }
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public long getSize() {
return this.bytes.length;
}
@@ -66,6 +82,7 @@
if (sha1hash == null) {
// Idempotent, so doesn't matter if we recompute in concurrent threads
...
sha1hash = computeHash(bytes);
+ hc = sha1hash.hashCode();
}
return sha1hash;
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java 2009-04-02 00:03:04
UTC (rev 802)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java 2009-04-02 18:52:26
UTC (rev 803)
@@ -24,6 +24,7 @@
package org.jboss.dna.jcr;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Iterator;
@@ -57,9 +58,12 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.i18n.I18n;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.property.Binary;
+import org.jboss.dna.graph.property.DateTime;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NamespaceRegistry;
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.jcr.SessionCache.NodeEditor;
import org.jboss.dna.jcr.cache.ChildNode;
@@ -118,6 +122,40 @@
}
}
+ final JcrValue valueFrom( int propertyType,
+ Object value ) {
+ return new JcrValue(cache.factories(), cache, propertyType, value);
+ }
+
+ final JcrValue valueFrom( Calendar value ) {
+ ValueFactories factories = cache.factories();
+ DateTime dateTime = factories.getDateFactory().create(value);
+ return new JcrValue(factories, cache, PropertyType.DATE, dateTime);
+ }
+
+ final JcrValue valueFrom( InputStream value ) {
+ ValueFactories factories = cache.factories();
+ Binary binary = factories.getBinaryFactory().create(value);
+ return new JcrValue(factories, cache, PropertyType.DATE, binary);
+ }
+
+ final JcrValue valueFrom( Node value ) throws
UnsupportedRepositoryOperationException, RepositoryException {
+ ValueFactories factories = cache.factories();
+ String uuid = factories.getStringFactory().create(value.getUUID());
+ return new JcrValue(factories, cache, PropertyType.REFERENCE, uuid);
+ }
+
+ final JcrValue[] valuesFrom( int propertyType,
+ Object[] values ) {
+ int len = values.length;
+ ValueFactories factories = cache.factories();
+ JcrValue[] results = new JcrValue[values.length];
+ for (int i = 0; i != len; ++i) {
+ results[i] = new JcrValue(factories, cache, propertyType, values[i]);
+ }
+ return results;
+ }
+
@Override
Path path() throws RepositoryException {
return cache.getPathFor(nodeInfo());
@@ -672,159 +710,184 @@
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, boolean)
*/
public final Property setProperty( String name,
- boolean value ) {
- throw new UnsupportedOperationException();
+ boolean value )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name),
valueFrom(PropertyType.BOOLEAN, value)));
+
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, java.util.Calendar)
*/
public final Property setProperty( String name,
- Calendar value ) {
- throw new UnsupportedOperationException();
+ Calendar value )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name),
valueFrom(value)));
+
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, double)
*/
public final Property setProperty( String name,
- double value ) {
- throw new UnsupportedOperationException();
+ double value )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name),
valueFrom(PropertyType.DOUBLE, value)));
+
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, java.io.InputStream)
*/
public final Property setProperty( String name,
- InputStream value ) {
- throw new UnsupportedOperationException();
+ InputStream value )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name),
valueFrom(value)));
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, long)
*/
public final Property setProperty( String name,
- long value ) {
- throw new UnsupportedOperationException();
+ long value )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name),
valueFrom(PropertyType.LONG, value)));
+
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, javax.jcr.Node)
*/
public final Property setProperty( String name,
- Node value ) {
- throw new UnsupportedOperationException();
+ Node value )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name),
valueFrom(value)));
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, java.lang.String)
*/
public final Property setProperty( String name,
- String value ) {
- throw new UnsupportedOperationException();
+ String value )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name),
valueFrom(PropertyType.STRING, value)));
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, java.lang.String, int)
*/
public final Property setProperty( String name,
String value,
- int type ) {
- throw new UnsupportedOperationException();
+ int type )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name), valueFrom(type,
value)));
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, java.lang.String[])
*/
public final Property setProperty( String name,
- String[] values ) {
- throw new UnsupportedOperationException();
+ String[] values )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name),
valuesFrom(PropertyType.STRING, values)));
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, java.lang.String[], int)
*/
public final Property setProperty( String name,
String[] values,
- int type ) {
- throw new UnsupportedOperationException();
+ int type )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name),
valuesFrom(type, values)));
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, javax.jcr.Value)
*/
public final Property setProperty( String name,
- Value value ) {
- throw new UnsupportedOperationException();
+ Value value )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name),
(JcrValue)value));
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, javax.jcr.Value, int)
*/
public final Property setProperty( String name,
Value value,
- int type ) {
- throw new UnsupportedOperationException();
+ int type )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name),
((JcrValue)value).asType(type)));
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, javax.jcr.Value[])
*/
public final Property setProperty( String name,
- Value[] values ) {
- throw new UnsupportedOperationException();
+ Value[] values )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name), values));
}
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Node#setProperty(java.lang.String, javax.jcr.Value[], int)
*/
public final Property setProperty( String name,
Value[] values,
- int type ) {
- throw new UnsupportedOperationException();
+ int type )
+ throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ int len = values.length;
+ Value[] newValues = null;
+ if (len == 0) {
+ newValues = JcrMultiValueProperty.EMPTY_VALUES;
+ } else {
+ List<Value> valuesWithDesiredType = new ArrayList<Value>(len);
+ for (int i = 0; i != len; ++i) {
+ Value value = values[i];
+ if (value == null) continue;
+ if (value.getType() != type) {
+ value = ((JcrValue)value).asType(type);
+ }
+ valuesWithDesiredType.add(value);
+ }
+ if (valuesWithDesiredType.isEmpty()) {
+ newValues = JcrMultiValueProperty.EMPTY_VALUES;
+ } else {
+ newValues = valuesWithDesiredType.toArray(new
Value[valuesWithDesiredType.size()]);
+ }
+ }
+ // Set the value, perhaps to an empty array ...
+ return cache.findJcrProperty(editor().setProperty(nameFrom(name), newValues));
}
/**
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrProperty.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrProperty.java 2009-04-02
00:03:04 UTC (rev 802)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrProperty.java 2009-04-02
18:52:26 UTC (rev 803)
@@ -23,17 +23,23 @@
*/
package org.jboss.dna.jcr;
+import javax.jcr.InvalidItemStateException;
import javax.jcr.Item;
+import javax.jcr.ItemNotFoundException;
import javax.jcr.ItemVisitor;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.version.VersionException;
import net.jcip.annotations.NotThreadSafe;
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.jcr.SessionCache.NodeEditor;
import org.jboss.dna.jcr.cache.PropertyInfo;
/**
@@ -51,6 +57,12 @@
this.propertyId = propertyId;
}
+ final NodeEditor editor() throws ItemNotFoundException, InvalidItemStateException,
RepositoryException {
+ return cache.getEditorFor(propertyId.getNodeId());
+ }
+
+ abstract boolean isMultiple();
+
/**
* {@inheritDoc}
*
@@ -179,11 +191,10 @@
/**
* {@inheritDoc}
*
- * @throws UnsupportedOperationException always
* @see javax.jcr.Item#remove()
*/
- public void remove() {
- throw new UnsupportedOperationException();
+ public void remove() throws VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ editor().removeProperty(propertyId.getPropertyName());
}
/**
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java 2009-04-02
00:03:04 UTC (rev 802)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java 2009-04-02
18:52:26 UTC (rev 803)
@@ -24,8 +24,10 @@
package org.jboss.dna.jcr;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
+import java.util.List;
import javax.jcr.Node;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
@@ -44,6 +46,8 @@
@NotThreadSafe
final class JcrMultiValueProperty extends AbstractJcrProperty {
+ static final JcrValue[] EMPTY_VALUES = new JcrValue[] {};
+
JcrMultiValueProperty( SessionCache cache,
PropertyId propertyId ) {
super(cache, propertyId);
@@ -52,6 +56,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.jcr.AbstractJcrProperty#isMultiple()
+ */
+ @Override
+ boolean isMultiple() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @throws ValueFormatException always
* @see javax.jcr.Property#getBoolean()
*/
@@ -170,16 +184,19 @@
*/
public final void setValue( Value[] values )
throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
- JcrValue[] jcrValues = null;
+ Value[] newValues = null;
if (values != null && values.length != 0) {
int numValues = values.length;
- jcrValues = new JcrValue[numValues];
+ List<Value> valuesList = new ArrayList<Value>(numValues);
ValueFactory<?> factory = null;
for (int i = 0; i != numValues; ++i) {
Value value = values[i];
- if (value instanceof JcrValue) {
+ if (value == null) {
+ // skip null values ...
+ continue;
+ } else if (value instanceof JcrValue) {
// just use the value ...
- jcrValues[i] = (JcrValue)value;
+ valuesList.add(value);
} else {
// This isn't our implementation, so create one for use
if (factory == null) {
@@ -219,11 +236,18 @@
default:
throw new RepositoryException();
}
- jcrValues[i] = createValue(factory.create(data), type);
+ valuesList.add(createValue(factory.create(data), type));
}
}
+ if (valuesList.isEmpty()) {
+ newValues = EMPTY_VALUES;
+ } else {
+ newValues = valuesList.toArray(new Value[valuesList.size()]);
+ }
+ } else {
+ newValues = EMPTY_VALUES;
}
-
cache.getEditorFor(propertyId.getNodeId()).setProperty(propertyId.getPropertyName(),
jcrValues);
+
cache.getEditorFor(propertyId.getNodeId()).setProperty(propertyId.getPropertyName(),
newValues);
}
/**
@@ -233,13 +257,23 @@
*/
public final void setValue( String[] values )
throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
- JcrValue[] jcrValues = null;
+ Value[] jcrValues = null;
if (values != null && values.length != 0) {
int numValues = values.length;
+ List<Value> valuesList = new ArrayList<Value>(numValues);
jcrValues = new JcrValue[numValues];
for (int i = 0; i != numValues; ++i) {
- jcrValues[i] = createValue(values[i], PropertyType.STRING);
+ String value = values[i];
+ if (value == null) continue; // skip null values
+ valuesList.add(createValue(values[i], PropertyType.STRING));
}
+ if (valuesList.isEmpty()) {
+ jcrValues = EMPTY_VALUES;
+ } else {
+ jcrValues = valuesList.toArray(new Value[valuesList.size()]);
+ }
+ } else {
+ jcrValues = EMPTY_VALUES;
}
cache.getEditorFor(propertyId.getNodeId()).setProperty(propertyId.getPropertyName(),
jcrValues);
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrPropertyDefinition.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrPropertyDefinition.java 2009-04-02
00:03:04 UTC (rev 802)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrPropertyDefinition.java 2009-04-02
18:52:26 UTC (rev 803)
@@ -531,7 +531,8 @@
Node node = null;
try {
- node = cache.findJcrNode((UUID)jcrValue.value());
+ UUID uuid = cache.factories().getUuidFactory().create(jcrValue.value());
+ node = cache.findJcrNode(uuid);
} catch (RepositoryException re) {
return false;
}
@@ -643,9 +644,9 @@
public boolean matches( Value valueToMatch ) {
assert valueToMatch instanceof JcrValue;
-
- JcrValue jcrValue = (JcrValue) valueToMatch;
+ JcrValue jcrValue = (JcrValue)valueToMatch;
+
/*
* Need two path factories here. One uses the permanent namespace mappings
to parse the constraints.
* The other also looks at the transient mappings to parse the checked value
@@ -658,7 +659,7 @@
for (int i = 0; i < constraints.length; i++) {
boolean matchesDescendants = constraints[i].endsWith("*");
Path constraintPath = repoPathFactory.create(matchesDescendants ?
constraints[i].substring(0,
-
constraints[i].length() - 2) : constraints[i]);
+
constraints[i].length() - 2) : constraints[i]);
if (matchesDescendants && value.isDecendantOf(constraintPath)) {
return true;
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java 2009-04-02 00:03:04 UTC
(rev 802)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java 2009-04-02 18:52:26 UTC
(rev 803)
@@ -52,6 +52,8 @@
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.property.Binary;
+import org.jboss.dna.graph.property.DateTime;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NamespaceRegistry;
import org.jboss.dna.graph.property.Path;
@@ -454,15 +456,18 @@
}
public Value createValue( Node value ) throws RepositoryException {
- return new JcrValue(valueFactories, sessionCache, PropertyType.REFERENCE,
UUID.fromString(value.getUUID()));
+ String uuid = valueFactories.getStringFactory().create(value.getUUID());
+ return new JcrValue(valueFactories, sessionCache, PropertyType.REFERENCE,
uuid);
}
public Value createValue( InputStream value ) {
- return new JcrValue(valueFactories, sessionCache, PropertyType.BINARY,
value);
+ Binary binary = valueFactories.getBinaryFactory().create(value);
+ return new JcrValue(valueFactories, sessionCache, PropertyType.BINARY,
binary);
}
public Value createValue( Calendar value ) {
- return new JcrValue(valueFactories, sessionCache, PropertyType.DATE,
value);
+ DateTime dateTime = valueFactories.getDateFactory().create(value);
+ return new JcrValue(valueFactories, sessionCache, PropertyType.DATE,
dateTime);
}
public Value createValue( boolean value ) {
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java 2009-04-02
00:03:04 UTC (rev 802)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java 2009-04-02
18:52:26 UTC (rev 803)
@@ -51,6 +51,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.jcr.AbstractJcrProperty#isMultiple()
+ */
+ @Override
+ boolean isMultiple() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see javax.jcr.Property#getBoolean()
*/
public boolean getBoolean() throws RepositoryException {
@@ -184,6 +194,11 @@
cache.getEditorFor(propertyId.getNodeId()).setProperty(propertyId.getPropertyName(),
jcrValue);
return;
}
+ if (value == null) {
+ // Then we're to delete the property ...
+
cache.getEditorFor(propertyId.getNodeId()).removeProperty(propertyId.getPropertyName());
+ return;
+ }
// We have to convert from one Value implementation to ours ...
switch (value.getType()) {
case PropertyType.STRING:
@@ -220,6 +235,7 @@
protected void setValue( JcrValue jcrValue )
throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ assert jcrValue != null;
cache.getEditorFor(propertyId.getNodeId()).setProperty(propertyId.getPropertyName(),
jcrValue);
}
@@ -230,6 +246,10 @@
*/
public void setValue( String value )
throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ if (value == null) {
+ this.remove();
+ return;
+ }
setValue(createValue(value, PropertyType.STRING));
}
@@ -240,6 +260,10 @@
*/
public void setValue( InputStream value )
throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ if (value == null) {
+ this.remove();
+ return;
+ }
setValue(createValue(context().getValueFactories().getBinaryFactory().create(value),
PropertyType.DATE));
}
@@ -270,6 +294,10 @@
*/
public void setValue( Calendar value )
throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ if (value == null) {
+ this.remove();
+ return;
+ }
setValue(createValue(context().getValueFactories().getDateFactory().create(value),
PropertyType.DATE));
}
@@ -290,6 +318,10 @@
*/
public void setValue( Node value )
throws ValueFormatException, VersionException, LockException,
ConstraintViolationException, RepositoryException {
+ if (value == null) {
+ this.remove();
+ return;
+ }
String uuid = value.getUUID();
setValue(createValue(uuid, PropertyType.REFERENCE));
}
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-04-02 00:03:04 UTC
(rev 802)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java 2009-04-02 18:52:26 UTC
(rev 803)
@@ -23,6 +23,7 @@
*/
package org.jboss.dna.jcr;
+import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import javax.jcr.Node;
@@ -31,9 +32,16 @@
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import net.jcip.annotations.NotThreadSafe;
+import org.jboss.dna.common.SystemFailureException;
+import org.jboss.dna.common.util.IoUtil;
import org.jboss.dna.graph.property.Binary;
+import org.jboss.dna.graph.property.BinaryFactory;
+import org.jboss.dna.graph.property.DateTime;
+import org.jboss.dna.graph.property.DateTimeFactory;
import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NameFactory;
import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.PathFactory;
import org.jboss.dna.graph.property.ValueFactories;
/**
@@ -211,6 +219,104 @@
return type;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ // Use the value's hash code
+ return value.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof JcrValue) {
+ JcrValue that = (JcrValue)obj;
+ if (this.type != that.type) return false;
+ try {
+ switch (this.type) {
+ case PropertyType.STRING:
+ return this.getString().equals(that.getString());
+ case PropertyType.BINARY:
+ BinaryFactory binaryFactory = valueFactories.getBinaryFactory();
+ Binary thisValue = binaryFactory.create(this.value);
+ Binary thatValue = binaryFactory.create(that.value);
+ return thisValue.equals(thatValue);
+ case PropertyType.BOOLEAN:
+ return this.getBoolean() == that.getBoolean();
+ case PropertyType.DOUBLE:
+ return this.getDouble() == that.getDouble();
+ case PropertyType.LONG:
+ return this.getLong() == that.getLong();
+ case PropertyType.DATE:
+ DateTimeFactory dateFactory = valueFactories.getDateFactory();
+ DateTime thisDateValue = dateFactory.create(this.value);
+ DateTime thatDateValue = dateFactory.create(that.value);
+ return thisDateValue.equals(thatDateValue);
+ case PropertyType.PATH:
+ PathFactory pathFactory = valueFactories.getPathFactory();
+ Path thisPathValue = pathFactory.create(this.value);
+ Path thatPathValue = pathFactory.create(that.value);
+ return thisPathValue.equals(thatPathValue);
+ case PropertyType.NAME:
+ NameFactory nameFactory = valueFactories.getNameFactory();
+ Name thisNameValue = nameFactory.create(this.value);
+ Name thatNameValue = nameFactory.create(that.value);
+ return thisNameValue.equals(thatNameValue);
+ case PropertyType.REFERENCE:
+ return this.getString().equals(that.getString());
+ default:
+ throw new SystemFailureException();
+ }
+ } catch (RepositoryException e) {
+ return false;
+ }
+ // will not get here
+ }
+ if (obj instanceof Value) {
+ Value that = (Value)obj;
+ if (this.type != that.getType()) return false;
+ try {
+ switch (this.type) {
+ case PropertyType.STRING:
+ return this.getString().equals(that.getString());
+ case PropertyType.BINARY:
+ return IoUtil.isSame(this.getStream(), that.getStream());
+ case PropertyType.BOOLEAN:
+ return this.getBoolean() == that.getBoolean();
+ case PropertyType.DOUBLE:
+ return this.getDouble() == that.getDouble();
+ case PropertyType.LONG:
+ return this.getLong() == that.getLong();
+ case PropertyType.DATE:
+ return this.getDate().equals(that.getDate());
+ case PropertyType.PATH:
+ return this.getString().equals(that.getString());
+ case PropertyType.NAME:
+ return this.getString().equals(that.getString());
+ case PropertyType.REFERENCE:
+ return this.getString().equals(that.getString());
+ default:
+ throw new SystemFailureException();
+ }
+ } catch (IOException e) {
+ return false;
+ } catch (RepositoryException e) {
+ return false;
+ }
+ // will not get here
+ }
+ return false;
+ }
+
private JcrValue withTypeAndValue( int type,
Object value ) {
return new JcrValue(this.valueFactories, this.sessionCache, type, value);
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-04-02 00:03:04
UTC (rev 802)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-04-02 18:52:26
UTC (rev 803)
@@ -127,6 +127,7 @@
private final JcrSession session;
private final String workspaceName;
protected final ExecutionContext context;
+ protected final ValueFactories factories;
protected final PathFactory pathFactory;
protected final NameFactory nameFactory;
protected final ValueFactory<String> stringFactory;
@@ -162,8 +163,9 @@
this.workspaceName = workspaceName;
this.store = store;
this.context = context;
- this.pathFactory = context.getValueFactories().getPathFactory();
- this.nameFactory = context.getValueFactories().getNameFactory();
+ this.factories = context.getValueFactories();
+ this.pathFactory = this.factories.getPathFactory();
+ this.nameFactory = this.factories.getNameFactory();
this.stringFactory = context.getValueFactories().getStringFactory();
this.namespaces = context.getNamespaceRegistry();
this.propertyFactory = context.getPropertyFactory();
@@ -196,6 +198,10 @@
return context;
}
+ ValueFactories factories() {
+ return factories;
+ }
+
PathFactory pathFactory() {
return pathFactory;
}
@@ -519,11 +525,12 @@
*
* @param name the property name; may not be null
* @param value the new property values; may not be null
+ * @return the identifier for the property; never null
* @throws ConstraintViolationException if the property could not be set because
of a node type constraint or property
* definition constraint
*/
- public void setProperty( Name name,
- JcrValue value ) throws ConstraintViolationException {
+ public PropertyId setProperty( Name name,
+ JcrValue value ) throws
ConstraintViolationException {
assert name != null;
assert value != null;
JcrPropertyDefinition definition = null;
@@ -575,7 +582,7 @@
} else {
// A cast is required ...
org.jboss.dna.graph.property.PropertyType dnaPropertyType =
PropertyTypeUtil.dnaPropertyTypeFor(propertyType);
- ValueFactory<?> factory =
context.getValueFactories().getValueFactory(dnaPropertyType);
+ ValueFactory<?> factory =
factories().getValueFactory(dnaPropertyType);
objValue = factory.create(value);
}
Property dnaProp = propertyFactory.create(name, objValue);
@@ -584,8 +591,9 @@
PropertyInfo newProperty = new PropertyInfo(id, definition.getId(),
propertyType, dnaProp, definition.isMultiple());
// Finally update the cached information and record the change ...
- node.setProperty(newProperty, context().getValueFactories());
+ node.setProperty(newProperty, factories());
operations.set(dnaProp).on(currentLocation);
+ return newProperty.getPropertyId();
}
/**
@@ -594,16 +602,16 @@
*
* @param name the property name; may not be null
* @param values new property values, all of which must have the same {@link
Value#getType() property type}; may not be
- * null or empty
+ * null but may be empty
+ * @return the identifier for the property; never null
* @throws ConstraintViolationException if the property could not be set because
of a node type constraint or property
* definition constraint
*/
- public void setProperty( Name name,
- JcrValue[] values ) throws ConstraintViolationException
{
+ public PropertyId setProperty( Name name,
+ Value[] values ) throws
ConstraintViolationException {
assert name != null;
assert values != null;
int numValues = values.length;
- assert numValues != 0;
JcrPropertyDefinition definition = null;
PropertyId id = null;
@@ -622,6 +630,7 @@
if (numValues == 0) {
// Just use the definition as is ...
} else {
+ // Use the property type for the first non-null value ...
int type = values[0].getType();
if (definition.getRequiredType() != PropertyType.UNDEFINED
&& definition.getRequiredType() != type) {
// The property type is not right, so we have to check if we
can cast.
@@ -656,15 +665,15 @@
// Can use the values as is ...
propertyType = type;
for (int i = 0; i != numValues; ++i) {
- objValues[i] = values[i].value();
+ objValues[i] = ((JcrValue)values[i]).value();
}
} else {
// A cast is required ...
assert propertyType != type;
org.jboss.dna.graph.property.PropertyType dnaPropertyType =
PropertyTypeUtil.dnaPropertyTypeFor(propertyType);
- ValueFactory<?> factory =
context.getValueFactories().getValueFactory(dnaPropertyType);
+ ValueFactory<?> factory =
factories().getValueFactory(dnaPropertyType);
for (int i = 0; i != numValues; ++i) {
- objValues[i] = factory.create(values[i].value());
+ objValues[i] = factory.create(((JcrValue)values[i]).value());
}
}
Property dnaProp = propertyFactory.create(name, objValues);
@@ -673,8 +682,9 @@
PropertyInfo newProperty = new PropertyInfo(id, definition.getId(),
propertyType, dnaProp, definition.isMultiple());
// Finally update the cached information and record the change ...
- node.setProperty(newProperty, context().getValueFactories());
+ node.setProperty(newProperty, factories());
operations.set(dnaProp).on(currentLocation);
+ return newProperty.getPropertyId();
}
/**
@@ -739,8 +749,8 @@
if (!definition.getId().equals(node.getDefinitionId())) {
// The node definition changed, so try to set the property ...
try {
- JcrValue value = new JcrValue(context().getValueFactories(),
SessionCache.this, PropertyType.STRING,
- definition.getId().getString());
+ JcrValue value = new JcrValue(factories(), SessionCache.this,
PropertyType.STRING, definition.getId()
+
.getString());
setProperty(DnaLexicon.NODE_DEFINITON, value);
} catch (ConstraintViolationException e) {
// We can't set this property on the node (according to the node
definition).
@@ -932,12 +942,15 @@
int propertyType,
boolean skipProtected ) {
JcrPropertyDefinition definition = null;
+ if (propertyType == PropertyType.UNDEFINED) {
+ propertyType = PropertyTypeUtil.jcrPropertyTypeFor(dnaProperty);
+ }
// If single-valued ...
if (dnaProperty.isSingle()) {
// Create a value for the DNA property value ...
Object value = dnaProperty.getFirstValue();
- Value jcrValue = new JcrValue(context().getValueFactories(),
SessionCache.this, propertyType, value);
+ Value jcrValue = new JcrValue(factories(), SessionCache.this, propertyType,
value);
definition = nodeTypes().findPropertyDefinition(primaryTypeNameOfParent,
mixinTypeNamesOfParent,
dnaProperty.getName(),
@@ -949,7 +962,7 @@
Value[] jcrValues = new Value[dnaProperty.size()];
int index = 0;
for (Object value : dnaProperty) {
- jcrValues[index++] = new JcrValue(context().getValueFactories(),
SessionCache.this, propertyType, value);
+ jcrValues[index++] = new JcrValue(factories(), SessionCache.this,
propertyType, value);
}
definition = nodeTypes().findPropertyDefinition(primaryTypeNameOfParent,
mixinTypeNamesOfParent,
@@ -1355,7 +1368,6 @@
NodeInfo parentInfo ) throws
RepositoryException {
// Now get the DNA node's UUID and find the DNA property containing the UUID
...
Location location = graphNode.getLocation();
- ValueFactories factories = context.getValueFactories();
UUID uuid = location.getUuid();
org.jboss.dna.graph.property.Property uuidProperty = null;
if (uuid != null) {
@@ -1537,7 +1549,7 @@
// Now add the "jcr:uuid" property if and only if referenceable ...
if (referenceable) {
// We know that this property is single-valued
- JcrValue value = new JcrValue(context.getValueFactories(), this,
PropertyType.STRING, uuid);
+ JcrValue value = new JcrValue(factories(), this, PropertyType.STRING, uuid);
PropertyDefinition propertyDefinition =
nodeTypes().findPropertyDefinition(primaryTypeName,
mixinTypeNames,
JcrLexicon.UUID,
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java 2009-04-02
00:03:04 UTC (rev 802)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java 2009-04-02
18:52:26 UTC (rev 803)
@@ -29,9 +29,7 @@
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.stub;
-import java.io.InputStream;
import java.util.Arrays;
-import java.util.Calendar;
import java.util.List;
import java.util.UUID;
import javax.jcr.Item;
@@ -729,76 +727,6 @@
node.restoreByLabel(null, false);
}
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetBooleanProperty() throws Exception {
- node.setProperty(null, false);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetCalendarProperty() throws Exception {
- node.setProperty(null, (Calendar)null);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetDoubleProperty() throws Exception {
- node.setProperty(null, 0.0);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetInputStreamProperty() throws Exception {
- node.setProperty(null, (InputStream)null);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetLongProperty() throws Exception {
- node.setProperty(null, 0L);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetNodeProperty() throws Exception {
- node.setProperty(null, (Node)null);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetStringProperty() throws Exception {
- node.setProperty(null, (String)null);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetStringsProperty() throws Exception {
- node.setProperty(null, (String[])null);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetValueProperty() throws Exception {
- node.setProperty(null, (Value)null);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetValuesProperty() throws Exception {
- node.setProperty(null, (Value[])null);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetStringPropertyWithType() throws Exception {
- node.setProperty(null, (String)null, 0);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetStringsPropertyWithType() throws Exception {
- node.setProperty(null, (String[])null, 0);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetValuePropertyWithType() throws Exception {
- node.setProperty(null, (Value)null, 0);
- }
-
- @Test( expected = UnsupportedOperationException.class )
- public void shouldNotAllowSetValuesPropertyWithType() throws Exception {
- node.setProperty(null, (Value[])null, 0);
- }
-
@Test( expected = UnsupportedRepositoryOperationException.class )
public void shouldNotAllowUnlock() throws Exception {
node.unlock();
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrPropertyTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrPropertyTest.java 2009-04-02
00:03:04 UTC (rev 802)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrPropertyTest.java 2009-04-02
18:52:26 UTC (rev 803)
@@ -286,6 +286,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.jcr.AbstractJcrProperty#isMultiple()
+ */
+ @Override
+ boolean isMultiple() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see javax.jcr.Property#getNode()
*/
@SuppressWarnings( "synthetic-access" )
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java 2009-04-02 00:03:04 UTC
(rev 802)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java 2009-04-02 18:52:26 UTC
(rev 803)
@@ -37,7 +37,13 @@
import org.apache.jackrabbit.test.RepositoryStub;
import org.apache.jackrabbit.test.api.AddNodeTest;
import org.apache.jackrabbit.test.api.NamespaceRegistryTest;
+import org.apache.jackrabbit.test.api.PropertyTest;
import org.apache.jackrabbit.test.api.RepositoryLoginTest;
+import org.apache.jackrabbit.test.api.SetValueBooleanTest;
+import org.apache.jackrabbit.test.api.SetValueDateTest;
+import org.apache.jackrabbit.test.api.SetValueDoubleTest;
+import org.apache.jackrabbit.test.api.SetValueLongTest;
+import org.apache.jackrabbit.test.api.SetValueReferenceTest;
import org.jboss.dna.graph.DnaLexicon;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Graph;
@@ -152,14 +158,14 @@
// addTestSuite(NodeTest.class);
// addTestSuite(NodeUUIDTest.class);
// addTestSuite(NodeOrderableChildNodesTest.class);
- // addTestSuite(PropertyTest.class);
+ addTestSuite(PropertyTest.class);
//
// addTestSuite(SetValueBinaryTest.class);
- // addTestSuite(SetValueBooleanTest.class);
- // addTestSuite(SetValueDateTest.class);
- // addTestSuite(SetValueDoubleTest.class);
- // addTestSuite(SetValueLongTest.class);
- // addTestSuite(SetValueReferenceTest.class);
+ addTestSuite(SetValueBooleanTest.class);
+ addTestSuite(SetValueDateTest.class);
+ addTestSuite(SetValueDoubleTest.class);
+ addTestSuite(SetValueLongTest.class);
+ addTestSuite(SetValueReferenceTest.class);
// addTestSuite(SetValueStringTest.class);
// addTestSuite(SetValueConstraintViolationExceptionTest.class);
// addTestSuite(SetValueValueFormatExceptionTest.class);