You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2007/10/30 17:48:33 UTC

svn commit: r590140 - in /jackrabbit/trunk: jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/config/ jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/ jackrabbi...

Author: reschke
Date: Tue Oct 30 09:48:32 2007
New Revision: 590140

URL: http://svn.apache.org/viewvc?rev=590140&view=rev
Log:
JCR-1152: JCR2SPI: use own ValueFactory, wrapping the SPI's QValueFactory: spi-commons: add implementations of ValueFactory wrapping QValueFactory and Value wrapping a QValue. QValueFactoryImpl: Fix conversions that weren't called before. ValueFormat: take advantage of known ValueFactory/Value implementations.

Added:
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/QValueValue.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/ValueFactoryQImpl.java   (with props)
Modified:
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/config/RepositoryConfig.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractRepositoryConfig.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/QValueFactoryImpl.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/ValueFormat.java

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java?rev=590140&r1=590139&r2=590140&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java Tue Oct 30 09:48:32 2007
@@ -51,6 +51,7 @@
 import org.apache.jackrabbit.spi.QValueFactory;
 import org.apache.jackrabbit.spi.NameFactory;
 import org.apache.jackrabbit.spi.PathFactory;
+import org.apache.jackrabbit.value.ValueFactoryQImpl;
 import org.apache.jackrabbit.conversion.NamePathResolver;
 import org.apache.jackrabbit.conversion.NameException;
 import org.apache.jackrabbit.conversion.PathResolver;
@@ -124,6 +125,8 @@
     private final NamePathResolver npResolver;
     private final NodeTypeManagerImpl ntManager;
 
+    private final ValueFactory valueFactory;
+
     private final SessionItemStateManager itemStateManager;
     private final ItemManager itemManager;
     private final ItemStateValidator validator;
@@ -142,6 +145,9 @@
         nsMappings = new LocalNamespaceMappings(workspace.getNamespaceRegistryImpl());
         npResolver = new DefaultNamePathResolver(nsMappings, true);
 
+        // build ValueFactory
+        valueFactory = new ValueFactoryQImpl(config.getRepositoryService().getQValueFactory(), npResolver);
+
         // build nodetype manager
         ntManager = new NodeTypeManagerImpl(workspace.getNodeTypeRegistry(), this, getJcrValueFactory());
         validator = new ItemStateValidator(this, getPathFactory());
@@ -718,7 +724,7 @@
      * @see ManagerProvider#getJcrValueFactory()
      */
     public ValueFactory getJcrValueFactory() throws RepositoryException {
-        return config.getValueFactory(getNamePathResolver());
+        return valueFactory;
     }
 
     //--------------------------------------------------------------------------

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/config/RepositoryConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/config/RepositoryConfig.java?rev=590140&r1=590139&r2=590140&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/config/RepositoryConfig.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/config/RepositoryConfig.java Tue Oct 30 09:48:32 2007
@@ -16,11 +16,9 @@
  */
 package org.apache.jackrabbit.jcr2spi.config;
 
-import org.apache.jackrabbit.conversion.NamePathResolver;
-import org.apache.jackrabbit.spi.RepositoryService;
-
 import javax.jcr.RepositoryException;
-import javax.jcr.ValueFactory;
+
+import org.apache.jackrabbit.spi.RepositoryService;
 
 /**
  * This class bundles the information required by JCR2SPI to
@@ -33,8 +31,6 @@
 public interface RepositoryConfig {
 
     public RepositoryService getRepositoryService() throws RepositoryException;
-
-    public ValueFactory getValueFactory(NamePathResolver resolver) throws RepositoryException;
 
     public String getDefaultWorkspaceName();
 

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractRepositoryConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractRepositoryConfig.java?rev=590140&r1=590139&r2=590140&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractRepositoryConfig.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractRepositoryConfig.java Tue Oct 30 09:48:32 2007
@@ -18,13 +18,8 @@
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.jackrabbit.conversion.NamePathResolver;
 import org.apache.jackrabbit.jcr2spi.config.RepositoryConfig;
 import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
-import org.apache.jackrabbit.value.ValueFactoryImplEx;
-
-import javax.jcr.ValueFactory;
-import javax.jcr.RepositoryException;
 
 /**
  * <code>AbstractRepositoryConfig</code>...
@@ -32,10 +27,6 @@
 public abstract class AbstractRepositoryConfig implements RepositoryConfig {
 
     private static Logger log = LoggerFactory.getLogger(AbstractRepositoryConfig.class);
-
-    public ValueFactory getValueFactory(NamePathResolver resolver) throws RepositoryException {
-        return ValueFactoryImplEx.getInstance();
-    }
 
     public String getDefaultWorkspaceName() {
         return null;

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/QValueFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/QValueFactoryImpl.java?rev=590140&r1=590139&r2=590140&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/QValueFactoryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/QValueFactoryImpl.java Tue Oct 30 09:48:32 2007
@@ -32,6 +32,7 @@
 import javax.jcr.PropertyType;
 import java.util.Calendar;
 import java.util.Arrays;
+import java.util.TimeZone;
 import java.io.InputStream;
 import java.io.IOException;
 import java.io.File;
@@ -56,6 +57,11 @@
     private static final PathFactory PATH_FACTORY = PathFactoryImpl.getInstance();
     private static final NameFactory NAME_FACTORY = NameFactoryImpl.getInstance();
 
+    /**
+     * the default encoding
+     */
+    private static final String DEFAULT_ENCODING = "UTF-8";
+
     private QValueFactoryImpl() {
     }
 
@@ -67,30 +73,42 @@
     /**
      * @see QValueFactory#create(String, int)
      */
-    public QValue create(String value, int type) {
+    public QValue create(String value, int type) throws RepositoryException {
         if (value == null) {
             throw new IllegalArgumentException("Cannot create QValue from null value.");
         }
-        switch (type) {
-            case PropertyType.BOOLEAN:
-                return new QValueImpl(Boolean.valueOf(value));
-            case PropertyType.DATE:
-                return new DateQValue(value);
-            case PropertyType.DOUBLE:
-                return new QValueImpl(Double.valueOf(value));
-            case PropertyType.LONG:
-                return new QValueImpl(Long.valueOf(value));
-            case PropertyType.PATH:
-                return new QValueImpl(PATH_FACTORY.create(value));
-            case PropertyType.NAME:
-                return new QValueImpl(NAME_FACTORY.create(value));
-            case PropertyType.STRING:
-            case PropertyType.REFERENCE:
-                return new QValueImpl(value, type);
-            case PropertyType.BINARY:
-                throw new IllegalArgumentException("this method does not support the type PropertyType.BINARY");
-            default:
-                throw new IllegalArgumentException("illegal type");
+        
+        try {
+            switch (type) {
+                case PropertyType.BOOLEAN:
+                    return new QValueImpl(Boolean.valueOf(value));
+                case PropertyType.DATE: {
+                        Calendar cal = ISO8601.parse(value);
+                        if (cal == null) {
+                            throw new ValueFormatException("not a valid date: " + value);
+                        }
+                        return new DateQValue(cal);
+                    }
+                case PropertyType.DOUBLE:
+                    return new QValueImpl(Double.valueOf(value));
+                case PropertyType.LONG:
+                    return new QValueImpl(Long.valueOf(value));
+                case PropertyType.PATH:
+                    return new QValueImpl(PATH_FACTORY.create(value));
+                case PropertyType.NAME:
+                    return new QValueImpl(NAME_FACTORY.create(value));
+                case PropertyType.STRING:
+                case PropertyType.REFERENCE:
+                    return new QValueImpl(value, type);
+                case PropertyType.BINARY:
+                    return new BinaryQValue(value.getBytes(DEFAULT_ENCODING));
+                default:
+                    throw new IllegalArgumentException("illegal type");
+            }
+        } catch (NumberFormatException ex) {
+            throw new ValueFormatException(ex);
+        } catch (UnsupportedEncodingException ex) {
+            throw new RepositoryException(ex);
         }
     }
 
@@ -176,10 +194,6 @@
      * @see QValueFactoryImpl.BinaryQValue
      */
     private static class QValueImpl implements QValue, Serializable {
-        /**
-         * the default encoding
-         */
-        private static final String DEFAULT_ENCODING = "UTF-8";
 
         private final Object val;
         private final int type;
@@ -250,9 +264,9 @@
         public InputStream getStream() throws RepositoryException {
             try {
                 // convert via string
-                return new ByteArrayInputStream(getString().getBytes(QValueImpl.DEFAULT_ENCODING));
+                return new ByteArrayInputStream(getString().getBytes(QValueFactoryImpl.DEFAULT_ENCODING));
             } catch (UnsupportedEncodingException e) {
-                throw new RepositoryException(QValueImpl.DEFAULT_ENCODING + " is not supported encoding on this platform", e);
+                throw new RepositoryException(QValueFactoryImpl.DEFAULT_ENCODING + " is not supported encoding on this platform", e);
             }
         }
 
@@ -273,8 +287,22 @@
         public Calendar getCalendar() throws RepositoryException {
             if (type == PropertyType.DATE) {
                 return (Calendar) ((Calendar) val).clone();
+            } else if (type == PropertyType.DOUBLE) {
+                Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+00:00"));
+                cal.setTimeInMillis(((Double) val).longValue());
+                return cal;
+            } else if (type == PropertyType.LONG) {
+                Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+00:00"));
+                cal.setTimeInMillis(((Long) val).longValue());
+                return cal;
             } else {
-                return ISO8601.parse(getString());
+                Calendar cal = ISO8601.parse(getString());
+                if (cal == null) {
+                    throw new ValueFormatException("not a date string: " + getString());
+                }
+                else {
+                    return cal;
+                }
             }
         }
 
@@ -284,8 +312,14 @@
         public double getDouble() throws RepositoryException {
             if (type == PropertyType.DOUBLE) {
                 return ((Double) val).doubleValue();
+            } else if (type == PropertyType.DATE) {
+                return ((Calendar) val).getTimeInMillis(); 
             } else {
-                return Double.parseDouble(getString());
+                try {
+                    return Double.parseDouble(getString());
+                } catch (NumberFormatException ex) {
+                    throw new ValueFormatException("not a double: " + getString(), ex);
+                }
             }
         }
 
@@ -295,8 +329,16 @@
         public long getLong() throws RepositoryException {
             if (type == PropertyType.LONG) {
                 return ((Long) val).longValue();
+            } else if (type == PropertyType.DOUBLE) {
+                return ((Double) val).longValue();
+            } else if (type == PropertyType.DATE) {
+                return ((Calendar) val).getTimeInMillis(); 
             } else {
-                return Long.parseLong(getString());
+                try {
+                    return Long.parseLong(getString());
+                } catch (NumberFormatException ex) {
+                    throw new ValueFormatException("not a long: " + getString(), ex);
+                }
             }
         }
 
@@ -331,7 +373,6 @@
         /**
          *
          * @param obj
-         * @return
          * @see Object#equals(Object)
          */
         public boolean equals(Object obj) {
@@ -362,11 +403,6 @@
 
         private final String formattedStr;
 
-        private DateQValue(String value) {
-            super(ISO8601.parse(value), PropertyType.DATE);
-            formattedStr = value;
-        }
-
         private DateQValue(Calendar value) {
             super(value, PropertyType.DATE);
             formattedStr = ISO8601.format(value);
@@ -599,9 +635,9 @@
                 try {
                     spool(out);
                     byte[] data = out.toByteArray();
-                    text = new String(data, QValueImpl.DEFAULT_ENCODING);
+                    text = new String(data, QValueFactoryImpl.DEFAULT_ENCODING);
                 } catch (UnsupportedEncodingException e) {
-                    throw new RepositoryException(QValueImpl.DEFAULT_ENCODING
+                    throw new RepositoryException(QValueFactoryImpl.DEFAULT_ENCODING
                         + " not supported on this platform", e);
                 } catch (IOException e) {
                     throw new ValueFormatException("conversion from stream to string failed", e);
@@ -645,21 +681,34 @@
          * @see QValue#getCalendar()
          */
         public Calendar getCalendar() throws RepositoryException {
-           throw new UnsupportedOperationException();
+             Calendar cal = ISO8601.parse(getString());
+             if (cal == null) {
+                 throw new ValueFormatException("not a date string: " + getString());
+             } else {
+                 return cal;
+             }
         }
 
         /**
          * @see QValue#getDouble()
          */
         public double getDouble() throws RepositoryException {
-            return Double.parseDouble(getString());
+            try {
+                return Double.parseDouble(getString());
+            } catch (NumberFormatException ex) {
+                throw new ValueFormatException(ex);
+            }
         }
 
         /**
          * @see QValue#getLong()
          */
         public long getLong() throws RepositoryException {
-            return Long.parseLong(getString());
+            try {
+                return Long.parseLong(getString());
+            } catch (NumberFormatException ex) {
+                throw new ValueFormatException(ex);
+            }
         }
 
         /**

Added: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/QValueValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/QValueValue.java?rev=590140&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/QValueValue.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/QValueValue.java Tue Oct 30 09:48:32 2007
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.value;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Calendar;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+
+import org.apache.jackrabbit.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.QValue;
+
+/**
+ * A <code>QValueValue</code> provides an implementation
+ * of the <code>Value</code> interface representing an SPI
+ * <code>QValue</code>.
+ */
+public final class QValueValue implements Value {
+
+    // wrapped QValue
+    private final QValue qvalue;
+
+    // used for keeping track of input streams that have already been passed back
+    private InputStream stream = null;
+
+    // for converting the internal NAME/PATH format to JCR format
+    private final NamePathResolver resolver;
+
+    /**
+     * Constructs a <code>QValueValue</code> object representing an SPI
+     * <codeQValue</code>.
+     *
+     * @param qvalue the QValue this <code>QValueValue</code> should represent
+     * @param resolver fore resolving namespace URIs to prefixes in NAME/PATH properties
+     */
+    public QValueValue(QValue qvalue, NamePathResolver resolver) {
+        this.qvalue = qvalue;
+        this.resolver = resolver;
+    }
+
+    /**
+     * Returns the embedded <code>QValue</code>.
+     *
+     * @return the embedded <code>QValue</code>
+     */
+    public QValue getQValue() {
+        return qvalue;
+    }
+
+    //----------------------------------------------------------------< Value >
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean getBoolean() throws RepositoryException {
+        setValueConsumed();
+        if (getType() == PropertyType.STRING || getType() == PropertyType.BINARY || getType() == PropertyType.BOOLEAN) {
+            return Boolean.valueOf(qvalue.getString()).booleanValue();
+        } else {
+            throw new ValueFormatException("incompatible type " + PropertyType.nameFromValue(qvalue.getType()));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Calendar getDate() throws RepositoryException {
+        setValueConsumed();
+        return qvalue.getCalendar();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double getDouble() throws RepositoryException {
+        setValueConsumed();
+        return qvalue.getDouble();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getLong() throws RepositoryException {
+        setValueConsumed();
+        return qvalue.getLong();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InputStream getStream() throws IllegalStateException, RepositoryException {
+        setStreamConsumed();
+        if (stream == null) {
+            if (getType() == PropertyType.NAME || getType() == PropertyType.PATH) {
+                // needs namespace mapping
+                try {
+                    String l_s = getType() == PropertyType.NAME
+                      ? resolver.getJCRName(qvalue.getName())
+                      : resolver.getJCRPath(qvalue.getPath());
+                    stream = new ByteArrayInputStream(l_s.getBytes("UTF-8"));
+                } catch (UnsupportedEncodingException ex) {
+                    throw new RepositoryException(ex);
+                }
+            } else {
+                stream = qvalue.getStream();
+            }
+        }
+        return stream;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getString() throws RepositoryException {
+        setValueConsumed();
+        if (getType() == PropertyType.NAME) {
+            // needs formatting
+            return resolver.getJCRName(qvalue.getName());
+        } else if (getType() == PropertyType.PATH) {
+            // needs formatting
+            return resolver.getJCRPath(qvalue.getPath());
+        } else {
+            return qvalue.getString();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getType() {
+        return qvalue.getType();
+    }
+
+    public boolean equals(Object p_obj) {
+        if (p_obj instanceof QValueValue) {
+            return qvalue.equals(((QValueValue)p_obj).qvalue);
+        }
+        else {
+            return false;
+        }
+    }
+
+    public int hashCode() {
+        return qvalue.hashCode();
+    }
+
+    private static final short STATE_UNDEFINED = 0;
+  
+    private static final short STATE_VALUE_CONSUMED = 1;
+  
+    private static final short STATE_STREAM_CONSUMED = 2;
+  
+    private short state = STATE_UNDEFINED;
+
+    /**
+     * Checks if the non-stream value of this instance has already been
+     * consumed (if any getter methods except <code>{@link #getStream()}</code> and
+     * <code>{@link #getType()}</code> have been previously called at least once) and
+     * sets the state to <code>STATE_STREAM_CONSUMED</code>.
+     *
+     * @throws IllegalStateException if any getter methods other than
+     *                               <code>getStream()</code> and
+     *                               <code>getType()</code> have been
+     *                               previously called at least once.
+     */
+    private void setStreamConsumed() throws IllegalStateException {
+        if (state == STATE_VALUE_CONSUMED) {
+            throw new IllegalStateException("non-stream value has already been consumed");
+        }
+        state = STATE_STREAM_CONSUMED;
+    }
+
+    /**
+     * Checks if the stream value of this instance has already been
+     * consumed (if {@link #getStream()} has been previously called
+     * at least once) and sets the state to <code>STATE_VALUE_CONSUMED</code>.
+     *
+     * @throws IllegalStateException if <code>getStream()</code> has been
+     *                               previously called at least once.
+     */
+    private void setValueConsumed() throws IllegalStateException {
+        if (state == STATE_STREAM_CONSUMED) {
+            throw new IllegalStateException("stream value has already been consumed");
+        }
+        state = STATE_VALUE_CONSUMED;
+    }
+}

Added: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/ValueFactoryQImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/ValueFactoryQImpl.java?rev=590140&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/ValueFactoryQImpl.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/ValueFactoryQImpl.java Tue Oct 30 09:48:32 2007
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.value;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+
+import javax.jcr.NamespaceException;
+import javax.jcr.Node;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.ValueFormatException;
+
+import org.apache.jackrabbit.conversion.IllegalNameException;
+import org.apache.jackrabbit.conversion.MalformedPathException;
+import org.apache.jackrabbit.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.QValue;
+import org.apache.jackrabbit.spi.QValueFactory;
+
+/**
+ * This class implements the <code>ValueFactory</code> interface,
+ * wrapping an existing SPI <code>QValueFactory</code> and a
+ * <code>NamePathResolver</code>.
+ *
+ * @see ValueFactory
+ * @see QValueFactory
+ */
+public class ValueFactoryQImpl implements ValueFactory {
+  
+    private final QValueFactory qfactory;
+    private final NamePathResolver resolver;
+  
+    /**
+     * Constructs a new <code>ValueFactoryQImpl</code> based
+     * on an existing SPI <code>QValueFactory</code> and a
+     * <code>NamePathResolver</code>.
+     * @param qfactory wrapped <code>QValueFactory</code>
+     * @param resolver wrapped <code>NamePathResolver</code>
+     */
+    public ValueFactoryQImpl(QValueFactory qfactory, NamePathResolver resolver) {
+        this.qfactory = qfactory;
+        this.resolver = resolver;
+    }
+  
+    /**
+     * Create a new <code>Value</code> based on an existing
+     * <code>QValue</code>
+     * @param qvalue existing <code>QValue</code>
+     * @return a <code>Value</code> representing the <code>QValue</code>
+     */
+    public Value createValue(QValue qvalue) {
+        return new QValueValue(qvalue, resolver);
+    }
+  
+    //---------------------------------------------------------< ValueFactory >
+
+    /**
+     * {@inheritDoc}
+     */
+    public Value createValue(String value) {
+        try {
+            QValue qvalue = qfactory.create(value, PropertyType.STRING);
+            return new QValueValue(qvalue, resolver);
+        } catch (RepositoryException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Value createValue(long value) {
+        try {
+            QValue qvalue = qfactory.create(value);
+            return new QValueValue(qvalue, resolver);
+        } catch (RepositoryException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Value createValue(double value) {
+        try {
+            QValue qvalue = qfactory.create(value);
+            return new QValueValue(qvalue, resolver);
+        } catch (RepositoryException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Value createValue(boolean value) {
+        try {
+            QValue qvalue = qfactory.create(Boolean.toString(value), PropertyType.BOOLEAN);
+            return new QValueValue(qvalue, resolver);
+        } catch (RepositoryException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Value createValue(Calendar value) {
+        try {
+            QValue qvalue = qfactory.create(value);
+            return new QValueValue(qvalue, resolver);
+        } catch (RepositoryException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Value createValue(InputStream value) {
+        try {
+            QValue qvalue = qfactory.create(value);
+            return new QValueValue(qvalue, resolver);
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        } catch (RepositoryException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Value createValue(Node value) throws RepositoryException {
+        QValue qvalue = qfactory.create(value.getUUID(), PropertyType.REFERENCE);
+        return new QValueValue(qvalue, resolver);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Value createValue(String value, int type) throws ValueFormatException {
+        try {
+            QValue qvalue;
+      
+            if (type == PropertyType.NAME) {
+                Name name = resolver.getQName(value);
+                qvalue = qfactory.create(name);
+            } else if (type == PropertyType.PATH) {
+                Path path = resolver.getQPath(value);
+                qvalue = qfactory.create(path);
+            } else {
+                qvalue = qfactory.create(value, type);
+            }
+      
+            return new QValueValue(qvalue, resolver);
+        } catch (IllegalNameException ex) {
+            throw new ValueFormatException(ex);
+        } catch (MalformedPathException ex) {
+            throw new ValueFormatException(ex);
+        } catch (NamespaceException ex) {
+            throw new ValueFormatException(ex);
+        } catch (ValueFormatException ex) {
+            throw ex;
+        } catch (RepositoryException ex) {
+            throw new ValueFormatException(ex);
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/ValueFactoryQImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/ValueFormat.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/ValueFormat.java?rev=590140&r1=590139&r2=590140&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/ValueFormat.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/value/ValueFormat.java Tue Oct 30 09:48:32 2007
@@ -48,8 +48,9 @@
                                    QValueFactory factory) throws RepositoryException {
         if (jcrValue == null) {
             throw new IllegalArgumentException("null value");
-        }
-        if (jcrValue.getType() == PropertyType.BINARY) {
+        } else if (jcrValue instanceof QValueValue) {
+            return ((QValueValue)jcrValue).getQValue();
+        } else if (jcrValue.getType() == PropertyType.BINARY) {
             try {
                 return factory.create(jcrValue.getStream());
             } catch (IOException e) {
@@ -145,37 +146,42 @@
     public static Value getJCRValue(QValue qualifiedValue,
                                     NamePathResolver resolver,
                                     ValueFactory factory) throws RepositoryException {
-        Value jcrValue;
-        int propertyType = qualifiedValue.getType();
-        switch (propertyType) {
-            case PropertyType.STRING:
-            case PropertyType.BOOLEAN:
-            case PropertyType.REFERENCE:
-                jcrValue = factory.createValue(qualifiedValue.getString(), propertyType);
-                break;
-            case PropertyType.PATH:
-                Path qPath = qualifiedValue.getPath();
-                jcrValue = factory.createValue(resolver.getJCRPath(qPath), propertyType);
-                break;
-            case PropertyType.NAME:
-                Name qName = qualifiedValue.getName();
-                jcrValue = factory.createValue(resolver.getJCRName(qName), propertyType);
-                break;
-            case PropertyType.BINARY:
-                jcrValue = factory.createValue(qualifiedValue.getStream());
-                break;
-            case PropertyType.DATE:
-                jcrValue = factory.createValue(qualifiedValue.getCalendar());
-                break;
-            case PropertyType.DOUBLE:
-              jcrValue = factory.createValue(qualifiedValue.getDouble());
-              break;
-            case PropertyType.LONG:
-                jcrValue = factory.createValue(qualifiedValue.getLong());
-                break;
-            default:
-                throw new RepositoryException("illegal internal value type");
+        if (factory instanceof ValueFactoryQImpl) {
+            return ((ValueFactoryQImpl)factory).createValue(qualifiedValue);
+        }
+        else {
+            Value jcrValue;
+            int propertyType = qualifiedValue.getType();
+            switch (propertyType) {
+                case PropertyType.STRING:
+                case PropertyType.BOOLEAN:
+                case PropertyType.REFERENCE:
+                    jcrValue = factory.createValue(qualifiedValue.getString(), propertyType);
+                    break;
+                case PropertyType.PATH:
+                    Path qPath = qualifiedValue.getPath();
+                    jcrValue = factory.createValue(resolver.getJCRPath(qPath), propertyType);
+                    break;
+                case PropertyType.NAME:
+                    Name qName = qualifiedValue.getName();
+                    jcrValue = factory.createValue(resolver.getJCRName(qName), propertyType);
+                    break;
+                case PropertyType.BINARY:
+                    jcrValue = factory.createValue(qualifiedValue.getStream());
+                    break;
+                case PropertyType.DATE:
+                    jcrValue = factory.createValue(qualifiedValue.getCalendar());
+                    break;
+                case PropertyType.DOUBLE:
+                  jcrValue = factory.createValue(qualifiedValue.getDouble());
+                  break;
+                case PropertyType.LONG:
+                    jcrValue = factory.createValue(qualifiedValue.getLong());
+                    break;
+                default:
+                    throw new RepositoryException("illegal internal value type");
+            }
+            return jcrValue;
         }
-        return jcrValue;
     }
 }