You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2009/05/06 18:28:21 UTC

svn commit: r772352 - in /jackrabbit/trunk: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/ jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/

Author: angela
Date: Wed May  6 16:28:21 2009
New Revision: 772352

URL: http://svn.apache.org/viewvc?rev=772352&view=rev
Log:
JCR-2061: JSR 283: References and Dereferencing of Property Values

- Dereferencing of Property Values both in jackrabbit-core and jackrabbit-jcr2spi
   > Property.getNode()
   > Property.getProperty()

- Adjusting testcases in jackrabbit-jcr-tests


TODO:

- similar testcases for the new Property types (still missing)
- new reference methods as listed in the issue
- support for weak-refs

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/BinaryPropertyTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/BooleanPropertyTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/DatePropertyTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/DoublePropertyTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/LongPropertyTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/NamePropertyTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/PathPropertyTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/ReferencePropertyTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/StringPropertyTest.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/PropertyImpl.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java?rev=772352&r1=772351&r2=772352&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java Wed May  6 16:28:21 2009
@@ -508,16 +508,48 @@
 
     public Node getNode() throws ValueFormatException, RepositoryException {
         Value value = getValue();
-        if (value.getType() == PropertyType.REFERENCE) {
-            return session.getNodeByUUID(value.getString());
-        } else {
-            // TODO: The specification suggests using value conversion
-            throw new ValueFormatException("property must be of type REFERENCE");
+        int type = value.getType();
+        switch (type) {
+            case PropertyType.REFERENCE:
+            case PropertyType.WEAKREFERENCE:
+                return session.getNodeByUUID(value.getString());
+
+            case PropertyType.PATH:
+            case PropertyType.NAME:
+                String path = value.getString();
+                Path p = session.getQPath(path);
+                boolean absolute = p.isAbsolute();
+                return (absolute) ? session.getNode(path) : getParent().getNode(path);
+
+            case PropertyType.STRING:
+                try {
+                    Value refValue = ValueHelper.convert(value, PropertyType.REFERENCE, session.getValueFactory());
+                    return session.getNodeByUUID(refValue.getString());
+                } catch (RepositoryException e) {
+                    // try if STRING value can be interpreted as PATH value
+                    Value pathValue = ValueHelper.convert(value, PropertyType.PATH, session.getValueFactory());
+                    p = session.getQPath(pathValue.getString());
+                    absolute = p.isAbsolute();
+                    return (absolute) ? session.getNode(pathValue.getString()) : getParent().getNode(pathValue.getString());
+                }
+
+            default:
+                throw new ValueFormatException("Property value cannot be converted to a PATH, REFERENCE or WEAKREFERENCE");
         }
     }
 
     public Property getProperty() throws RepositoryException {
-        throw new UnsupportedRepositoryOperationException("JCR-1609");
+        Value value = getValue();
+        Value pathValue = ValueHelper.convert(value, PropertyType.PATH, session.getValueFactory());
+        String path = pathValue.getString();
+        boolean absolute;
+        try {
+            Path p = session.getQPath(path);
+            absolute = p.isAbsolute();
+        } catch (RepositoryException e) {
+            throw new ValueFormatException("Property value cannot be converted to a PATH");
+        }
+        return (absolute) ? session.getProperty(path) : getParent().getProperty(path);
     }
 
     public BigDecimal getDecimal() throws RepositoryException {

Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/BinaryPropertyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/BinaryPropertyTest.java?rev=772352&r1=772351&r2=772352&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/BinaryPropertyTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/BinaryPropertyTest.java Wed May  6 16:28:21 2009
@@ -233,10 +233,10 @@
     }
 
     /**
-     * Tests the conversion from Binary type to Reference type. This conversion
+     * Tests the conversion from Binary type to Reference or Path type. This conversion
      * passes through previous String conversion.
      */
-    public void testAsReference() throws RepositoryException, NotExecutableException {
+    public void testGetNode() throws RepositoryException, NotExecutableException {
         if (!multiple) {
             // not testable since format of ID is implementation specific
         } else {
@@ -251,6 +251,24 @@
     }
 
     /**
+     * Tests the conversion from Binary type to Path type. This conversion
+     * passes through previous String conversion.
+     */
+    public void testGetProperty() throws RepositoryException, NotExecutableException {
+        if (!multiple) {
+            // not testable since format of ID is implementation specific
+        } else {
+            try {
+                prop.getNode();
+                fail("Property.getProperty() called on a multivalue property " +
+                        "should throw a ValueFormatException.");
+            } catch (ValueFormatException vfe) {
+                // ok
+            }
+        }
+    }
+    
+    /**
      * Tests the Property.getLength() method.
      */
     public void testGetLength() throws RepositoryException {

Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/BooleanPropertyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/BooleanPropertyTest.java?rev=772352&r1=772351&r2=772352&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/BooleanPropertyTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/BooleanPropertyTest.java Wed May  6 16:28:21 2009
@@ -180,14 +180,14 @@
     }
 
     /**
-     * Tests failure of conversion from Boolean type to Reference type.
+     * Tests failure of conversion from Boolean type to Reference or Path type.
      */
-    public void testAsReference() throws RepositoryException {
+    public void testGetNode() throws RepositoryException {
         if (!multiple) {
             try {
                 prop.getNode();
-                fail("Conversion from a Boolean value to a Reference value " +
-                        "should throw a ValueFormatException");
+                fail("Conversion from a Boolean value to a Reference or Path value " +
+                        "should throw a ValueFormatException.");
             } catch (ValueFormatException vfe) {
                 //ok
             }
@@ -197,6 +197,29 @@
                 fail("Property.getNode() called on a multivalue property " +
                         "should throw a ValueFormatException.");
             } catch (ValueFormatException vfe) {
+                //ok
+            }
+        }
+    }
+
+    /**
+     * Tests failure of conversion from Boolean type to Path type.
+     */
+    public void testGetProperty() throws RepositoryException {
+        if (!multiple) {
+            try {
+                prop.getProperty();
+                fail("Conversion from a Boolean value to a Path value " +
+                        "should throw a ValueFormatException.");
+            } catch (ValueFormatException vfe) {
+                //ok
+            }
+        } else {
+            try {
+                prop.getProperty();
+                fail("Property.getProperty() called on a multivalue property " +
+                        "should throw a ValueFormatException.");
+            } catch (ValueFormatException vfe) {
                 // ok
             }
         }

Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/DatePropertyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/DatePropertyTest.java?rev=772352&r1=772351&r2=772352&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/DatePropertyTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/DatePropertyTest.java Wed May  6 16:28:21 2009
@@ -179,13 +179,13 @@
 
 
     /**
-     * Tests failure of conversion from Date type to Reference type.
+     * Tests failure of conversion from Date type to Reference or Path type.
      */
-    public void testAsReference() throws RepositoryException {
+    public void testGetNode() throws RepositoryException {
         if (!multiple) {
             try {
                 prop.getNode();
-                fail("Conversion from a Date value to a Reference value " +
+                fail("Conversion from a Date value to a Reference or Path value " +
                         "should throw a ValueFormatException.");
             } catch (ValueFormatException vfe) {
                 //ok
@@ -202,6 +202,29 @@
     }
 
     /**
+     * Tests failure of conversion from Date type to Path type.
+     */
+    public void testGetProperty() throws RepositoryException {
+        if (!multiple) {
+            try {
+                prop.getProperty();
+                fail("Conversion from a Date value to a Path value " +
+                        "should throw a ValueFormatException.");
+            } catch (ValueFormatException vfe) {
+                //ok
+            }
+        } else {
+            try {
+                prop.getProperty();
+                fail("Property.getProperty() called on a multivalue property " +
+                        "should throw a ValueFormatException.");
+            } catch (ValueFormatException vfe) {
+                // ok
+            }
+        }
+    }
+
+    /**
      * Tests the Property.getLength() method. The length returned is either -1
      * or it is the length of the string received by conversion.
      */

Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/DoublePropertyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/DoublePropertyTest.java?rev=772352&r1=772351&r2=772352&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/DoublePropertyTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/DoublePropertyTest.java Wed May  6 16:28:21 2009
@@ -172,20 +172,43 @@
     }
 
     /**
-     * tests failure of conversion from Double type to Reference type
+     * Tests failure of conversion from Double type to Reference, WeakReference or Path type.
      */
-    public void testAsReference() throws RepositoryException {
+    public void testGetNode() throws RepositoryException {
         if (!multiple) {
             try {
                 prop.getNode();
-                fail("Conversion from a Double value to a Reference value " +
+                fail("Conversion from a Double value to a Reference or Path value " +
+                        "should throw a ValueFormatException.");
+            } catch (ValueFormatException e) {
+                // success.
+            }
+        } else {
+            try {
+                prop.getNode();
+                fail("Property.getNode() called on a multivalue property " +
                         "should throw a ValueFormatException.");
             } catch (ValueFormatException vfe) {
                 //ok
             }
+        }
+    }
+
+    /**
+     * Tests failure of conversion from Double type to Path type.
+     */
+    public void testGetProperty() throws RepositoryException {
+        if (!multiple) {
+            try {
+                prop.getProperty();
+                fail("Conversion from a Double value to a Path value " +
+                        "should throw a ValueFormatException.");
+            } catch (ValueFormatException e) {
+                // success.
+            }
         } else {
             try {
-                prop.getNode();
+                prop.getProperty();
                 fail("Property.getNode() called on a multivalue property " +
                         "should throw a ValueFormatException.");
             } catch (ValueFormatException vfe) {

Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/LongPropertyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/LongPropertyTest.java?rev=772352&r1=772351&r2=772352&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/LongPropertyTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/LongPropertyTest.java Wed May  6 16:28:21 2009
@@ -171,20 +171,43 @@
     }
 
     /**
-     * Tests failure of conversion from Long type to Reference type.
+     * Tests failure of conversion from Long type to Reference, WeakReference or Path type.
      */
-    public void testAsReference() throws RepositoryException {
+    public void testGetNode() throws RepositoryException {
         if (!multiple) {
             try {
                 prop.getNode();
-                fail("Conversion from a Double value to a Reference value " +
+                fail("Conversion from a Long value to a Reference or Path value " +
+                        "should throw a ValueFormatException.");
+            } catch (ValueFormatException e) {
+                // success.
+            }
+        } else {
+            try {
+                prop.getNode();
+                fail("Property.getNode() called on a multivalue property " +
                         "should throw a ValueFormatException.");
             } catch (ValueFormatException vfe) {
                 //ok
             }
+        }
+    }
+
+    /**
+     * Tests failure of conversion from Long type to Path type.
+     */
+    public void testGetProperty() throws RepositoryException {
+        if (!multiple) {
+            try {
+                prop.getProperty();
+                fail("Conversion from a Long value to a Path value " +
+                        "should throw a ValueFormatException.");
+            } catch (ValueFormatException e) {
+                // success.
+            }
         } else {
             try {
-                prop.getNode();
+                prop.getProperty();
                 fail("Property.getNode() called on a multivalue property " +
                         "should throw a ValueFormatException.");
             } catch (ValueFormatException vfe) {

Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/NamePropertyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/NamePropertyTest.java?rev=772352&r1=772351&r2=772352&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/NamePropertyTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/NamePropertyTest.java Wed May  6 16:28:21 2009
@@ -20,6 +20,9 @@
 import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
 import javax.jcr.PropertyType;
+import javax.jcr.Property;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Node;
 
 /**
  * Tests a date property. If the workspace does not contain a node with a date
@@ -139,22 +142,57 @@
     }
 
     /**
-     * Tests failure of conversion from Name type to Reference type.
-     *
-     * @throws RepositoryException
+     * Since JCR 2.0 a path property can be dereferenced if it points to a
+     * Node.
+     * TODO: create several tests out of this one
      */
-    public void testAsReference() throws RepositoryException {
+    public void testGetNode() throws RepositoryException {
         if (!multiple) {
+            String path = prop.getString();
+            if (prop.getParent().hasNode(path)) {
+                Node n = prop.getNode();
+                assertEquals("The path of the dereferenced property must be equal to the value", path, n.getPath());
+            } else {
+                try {
+                    prop.getNode();
+                    fail("Calling Property.getNode() for a PATH value that doesn't have a corresponding Node, PathNotFoundException is expected");
+                } catch (PathNotFoundException e) {
+                    // success.
+                }
+            }
+        } else {
             try {
                 prop.getNode();
-                fail("Conversion from a Name value to a Reference value " +
+                fail("Property.getNode() called on a multivalue property " +
                         "should throw a ValueFormatException.");
             } catch (ValueFormatException vfe) {
                 //ok
             }
+        }
+    }
+
+    /**
+     * Since JCR 2.0 a path property can be dereferenced if it points to a
+     * Property.
+     * TODO: create several tests out of this one
+     */
+    public void testGetProperty() throws RepositoryException {
+        if (!multiple) {
+            String path = prop.getString();
+            if (prop.getParent().hasProperty(path)) {
+                Property p = prop.getProperty();
+                assertEquals("The path of the dereferenced property must be equal to the value", path, p.getPath());
+            } else {
+                try {
+                    prop.getProperty();
+                    fail("Calling Property.getProperty() for a PATH value that doesn't have a corresponding Node, PathNotFoundException is expected");
+                } catch (PathNotFoundException e) {
+                    // success.
+                }
+            }
         } else {
             try {
-                prop.getNode();
+                prop.getProperty();
                 fail("Property.getNode() called on a multivalue property " +
                         "should throw a ValueFormatException.");
             } catch (ValueFormatException vfe) {

Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/PathPropertyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/PathPropertyTest.java?rev=772352&r1=772351&r2=772352&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/PathPropertyTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/PathPropertyTest.java Wed May  6 16:28:21 2009
@@ -20,6 +20,9 @@
 import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
 import javax.jcr.PropertyType;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
 
 /**
  * Tests a path property. If the workspace does not contain a node with a path
@@ -127,20 +130,89 @@
     }
 
     /**
-     * Tests failure of conversion from Path type to Reference type.
+     * Since JCR 2.0 a path property can be dereferenced if it points to a
+     * Node.
+     * TODO: create several tests out of this one
      */
-    public void testAsReference() throws RepositoryException {
+    public void testGetNode() throws RepositoryException {
         if (!multiple) {
+            String nodePath = prop.getParent().getPath();
+            String propName = prop.getName();
+
+            // absolute nodes path
+            prop.getParent().setProperty(propName, nodePath, PropertyType.PATH);
+            String value = prop.getString();
+            Node n = prop.getNode();
+            assertEquals("The path of the dereferenced property must be equal to the value", n.getPath(), value);
+            assertTrue("The property value must be resolved to the correct node.", prop.getParent().isSame(n));
+
+            // relative node path
+            prop.getParent().setProperty(propName, ".", PropertyType.PATH);
+            value = prop.getString();
+            n = prop.getNode();
+            assertEquals("The path of the dereferenced property must be equal to the value", ".", value);
+            assertTrue("The property value must be resolved to the correct node.", prop.getParent().isSame(n));
+
+            // non-existing property path
+            while (session.nodeExists(nodePath)) {
+                nodePath += "x";
+            }
+            prop.getParent().setProperty(propName, nodePath, PropertyType.PATH);
+            try {
+                prop.getProperty();
+                fail("Calling Property.getNode() for a PATH value that doesn't have a corresponding Node, PathNotFoundException is expected");
+            } catch (PathNotFoundException e) {
+                //ok
+            }
+        } else {
             try {
                 prop.getNode();
-                fail("Conversion from a Path value to a Reference value " +
+                fail("Property.getNode() called on a multivalue property " +
                         "should throw a ValueFormatException.");
             } catch (ValueFormatException vfe) {
                 //ok
             }
+        }
+    }
+
+    /**
+     * Since JCR 2.0 a path property can be dereferenced if it points to a
+     * Property.
+     * TODO: create several tests out of this one
+     */
+    public void testGetProperty() throws RepositoryException {
+        if (!multiple) {
+            String propPath = prop.getPath();
+            String propName = prop.getName();
+
+            // absolute property path
+            prop.getParent().setProperty(propName, propPath, PropertyType.PATH);
+            String path = prop.getString();
+            Property p = prop.getProperty();
+            assertEquals("The path of the dereferenced property must be equal to the value", path, p.getPath());
+            assertTrue("The property value must be resolved to the correct property.", prop.isSame(p));
+
+            // relative property path
+            prop.getParent().setProperty(propName, propName, PropertyType.PATH);
+            path = prop.getString();
+            p = prop.getProperty();
+            assertEquals("The path of the dereferenced property must be equal to the value", path, p.getName());
+            assertTrue("The property value must be resolved to the correct property.", prop.isSame(p));
+
+            // non-existing property path
+            while (session.propertyExists(propPath)) {
+                propPath += "x";
+            }
+            prop.getParent().setProperty(propName, propPath, PropertyType.PATH);
+            try {
+                prop.getProperty();
+                fail("Calling Property.getNode() for a PATH value that doesn't have a corresponding Property, PathNotFoundException is expected");
+            } catch (PathNotFoundException e) {
+                //ok
+            }
         } else {
             try {
-                prop.getNode();
+                prop.getProperty();
                 fail("Property.getNode() called on a multivalue property " +
                         "should throw a ValueFormatException.");
             } catch (ValueFormatException vfe) {

Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/ReferencePropertyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/ReferencePropertyTest.java?rev=772352&r1=772351&r2=772352&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/ReferencePropertyTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/ReferencePropertyTest.java Wed May  6 16:28:21 2009
@@ -171,6 +171,19 @@
     }
 
     /**
+     * Tests dereferencing a REFERENCE property to a Property
+     * @since JCR 2.0
+     */
+    public void testGetProperty() throws RepositoryException {
+        try {
+            prop.getProperty();
+            fail("A REFERENCE property cannot be resolved to a Property.");
+        } catch (ValueFormatException e) {
+            // ok
+        }
+    }
+
+    /**
      * Tests if Value.getType() returns the same as Property.getType() and also
      * tests that prop.getDefinition().getRequiredType() returns the same type
      * in case it is not of Undefined type.

Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/StringPropertyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/StringPropertyTest.java?rev=772352&r1=772351&r2=772352&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/StringPropertyTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/StringPropertyTest.java Wed May  6 16:28:21 2009
@@ -209,9 +209,9 @@
     }
 
     /**
-     * Tests conversion from String type to Reference type.
+     * Tests conversion from String type to Reference or Path type.
      */
-    public void testAsReference() throws RepositoryException, NotExecutableException {
+    public void testGetNode() throws RepositoryException, NotExecutableException {
         if (!multiple) {
             // not testable since format of ID is implementation specific
         } else {
@@ -226,6 +226,23 @@
     }
 
     /**
+     * Tests conversion from String type to Reference or Path type.
+     */
+    public void testGetProperty() throws RepositoryException, NotExecutableException {
+        if (!multiple) {
+            // not testable as a STRING may or may not be convertable to Path or Reference
+        } else {
+            try {
+                prop.getProperty();
+                fail("Property.getNode() called on a multivalue property " +
+                        "should throw a ValueFormatException.");
+            } catch (ValueFormatException vfe) {
+                // ok
+            }
+        }
+    }
+
+    /**
      * Tests the Property.getLength() method. The length returned is either -1
      * or it is the length of the string.
      */

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/PropertyImpl.java?rev=772352&r1=772351&r2=772352&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/PropertyImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/PropertyImpl.java Wed May  6 16:28:21 2009
@@ -40,6 +40,7 @@
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.QValue;
+import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.spi.commons.value.ValueFormat;
@@ -352,11 +353,34 @@
      * @see Property#getNode()
      */
     public Node getNode() throws ValueFormatException, RepositoryException {
-        QValue value = getQValue();
-        if (value.getType() == PropertyType.REFERENCE) {
-            return session.getNodeByUUID(value.getString());
-        } else {
-            throw new ValueFormatException("Property must be of type REFERENCE (" + safeGetJCRPath() + ")");
+        Value value = getValue();
+        int type = value.getType();
+        switch (type) {
+            case PropertyType.REFERENCE:
+            case PropertyType.WEAKREFERENCE:
+                return session.getNodeByUUID(value.getString());
+
+            case PropertyType.PATH:
+            case PropertyType.NAME:
+                String path = value.getString();
+                Path p = session.getPathResolver().getQPath(path);
+                boolean absolute = p.isAbsolute();
+                return (absolute) ? session.getNode(path) : getParent().getNode(path);
+
+            case PropertyType.STRING:
+                try {
+                    Value refValue = ValueHelper.convert(value, PropertyType.REFERENCE, session.getValueFactory());
+                    return session.getNodeByUUID(refValue.getString());
+                } catch (RepositoryException e) {
+                    // try if STRING value can be interpreted as PATH value
+                    Value pathValue = ValueHelper.convert(value, PropertyType.PATH, session.getValueFactory());
+                    p = session.getPathResolver().getQPath(pathValue.getString());
+                    absolute = p.isAbsolute();
+                    return (absolute) ? session.getNode(pathValue.getString()) : getParent().getNode(pathValue.getString());
+                }
+
+            default:
+                throw new ValueFormatException("Property value cannot be converted to a PATH, REFERENCE or WEAKREFERENCE");
         }
     }
 
@@ -364,8 +388,17 @@
      * @see Property#getProperty()
      */
     public Property getProperty() throws RepositoryException {
-        // TODO JCR-1609 - this should probably be handled a bit better...
-        return getParent().getProperty(getString());
+        Value value = getValue();
+        Value pathValue = ValueHelper.convert(value, PropertyType.PATH, session.getValueFactory());
+        String path = pathValue.getString();
+        boolean absolute;
+        try {
+            Path p = session.getPathResolver().getQPath(path);
+            absolute = p.isAbsolute();
+        } catch (RepositoryException e) {
+            throw new ValueFormatException("Property value cannot be converted to a PATH");
+        }
+        return (absolute) ? session.getProperty(path) : getParent().getProperty(path);
     }
 
     /**
@@ -583,5 +616,4 @@
             throw new ValueFormatException("Property must be of type REFERENCE.");
         }
     }
-
 }