You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2012/04/23 17:22:24 UTC
svn commit: r1329281 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/api/
oak-core/src/main/java/org/apache/jackrabbit/oak/core/ oak-jcr/
oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/
Author: angela
Date: Mon Apr 23 15:22:24 2012
New Revision: 1329281
URL: http://svn.apache.org/viewvc?rev=1329281&view=rev
Log:
OAK-16 : Proper ValueFactory implementation and Value handling (WIP)
NOTE: this is a proposal drafting how we could combine a reasonable
implementation of the JCR value handling with the needs we have within oak-core. i tried to take the work thomas made with his corevalue into account. however, i didn't yet remove those nor did i touch the Scalar interface so far.
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/BinaryValue.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/CoreValueFactoryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/CoreValueImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ValueImpl.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/KernelContentRepository.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/KernelContentSession.java
jackrabbit/oak/trunk/oak-jcr/pom.xml
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ValueFactoryImpl.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java?rev=1329281&r1=1329280&r2=1329281&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java Mon Apr 23 15:22:24 2012
@@ -94,6 +94,8 @@ public interface ContentSession extends
*/
QueryEngine getQueryEngine();
+ CoreValueFactory getCoreValueFactory();
+
// TODO : add versioning operations
}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/BinaryValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/BinaryValue.java?rev=1329281&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/BinaryValue.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/BinaryValue.java Mon Apr 23 15:22:24 2012
@@ -0,0 +1,51 @@
+/*
+ * 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.oak.core;
+
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.util.MicroKernelInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+
+/**
+ * BinaryValue... TODO: review name (BlobValue? BlobCoreValue? BinaryCoreValue?)
+ */
+public class BinaryValue {
+
+ /**
+ * logger instance
+ */
+ private static final Logger log = LoggerFactory.getLogger(BinaryValue.class);
+
+ private String binaryID;
+ private MicroKernel mk;
+
+ BinaryValue(String binaryID, MicroKernel mk) {
+ this.binaryID = binaryID;
+ this.mk = mk;
+ }
+
+ InputStream getStream() {
+ return new MicroKernelInputStream(mk, binaryID);
+ }
+
+ long length() {
+ return mk.getLength(binaryID);
+ }
+}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/CoreValueFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/CoreValueFactoryImpl.java?rev=1329281&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/CoreValueFactoryImpl.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/CoreValueFactoryImpl.java Mon Apr 23 15:22:24 2012
@@ -0,0 +1,83 @@
+/*
+ * 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.oak.core;
+
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.CoreValueFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.PropertyType;
+import java.io.InputStream;
+import java.math.BigDecimal;
+
+/**
+ * CoreValueFactoryImpl... TODO javadoc
+ */
+public class CoreValueFactoryImpl implements CoreValueFactory {
+
+ /**
+ * logger instance
+ */
+ private static final Logger log = LoggerFactory.getLogger(CoreValueFactoryImpl.class);
+
+ private final MicroKernel mk;
+
+ CoreValueFactoryImpl(MicroKernel mk) {
+ this.mk = mk;
+ }
+
+ //-----------------------------------------< javax.jcr.CoreValueFactory >---
+ @Override
+ public CoreValue createValue(String value) {
+ return new CoreValueImpl(value, PropertyType.STRING);
+ }
+
+ @Override
+ public CoreValue createValue(double value) {
+ return new CoreValueImpl(value);
+ }
+
+ @Override
+ public CoreValue createValue(long value) {
+ return new CoreValueImpl(value);
+ }
+
+ @Override
+ public CoreValue createValue(boolean value) {
+ return new CoreValueImpl(value);
+ }
+
+ @Override
+ public CoreValue createValue(BigDecimal value) {
+ return new CoreValueImpl(value);
+ }
+
+ @Override
+ public CoreValue createValue(InputStream value) {
+ String binaryID = mk.write(value);
+ return new CoreValueImpl(new BinaryValue(binaryID, mk));
+ }
+
+ @Override
+ public CoreValue createValue(String value, int type) {
+ return new CoreValueImpl(value, type);
+ }
+
+
+}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/CoreValueImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/CoreValueImpl.java?rev=1329281&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/CoreValueImpl.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/CoreValueImpl.java Mon Apr 23 15:22:24 2012
@@ -0,0 +1,308 @@
+/*
+ * 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.oak.core;
+
+import org.apache.jackrabbit.oak.api.CoreValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.PropertyType;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+
+/**
+ * CoreValueImpl... TODO: javadoc
+ */
+class CoreValueImpl implements CoreValue, Comparable<CoreValue>{
+
+ /**
+ * logger instance
+ */
+ private static final Logger log = LoggerFactory.getLogger(CoreValueImpl.class);
+
+ private final Object value;
+ private final int type;
+
+ /**
+ * Create a new instance.
+ *
+ * @param value The value.
+ * @param type The property type.
+ * @throws IllegalArgumentException if the passed {@code value} is {@code null}.
+ */
+ private CoreValueImpl(Object value, int type) {
+ if (value == null) {
+ throw new IllegalArgumentException("null value");
+ }
+ this.value = value;
+ this.type = type;
+ }
+
+ /**
+ * Create a new instance.
+ *
+ * @param value
+ * @param type
+ * @throws IllegalArgumentException if the specified type cannot be created
+ * from a string value.
+ */
+ CoreValueImpl(String value, int type) {
+ if (value == null) {
+ throw new IllegalArgumentException("null value");
+ }
+ switch (type) {
+ case PropertyType.STRING:
+ case PropertyType.NAME:
+ case PropertyType.PATH:
+ case PropertyType.DATE:
+ case PropertyType.REFERENCE:
+ case PropertyType.WEAKREFERENCE:
+ case PropertyType.URI:
+ this.value = value;
+ this.type = type;
+ break;
+
+ default:
+ throw new IllegalArgumentException("Illegal type " + PropertyType.nameFromValue(type));
+ }
+
+ }
+
+ /**
+ * Create a new instance.
+ *
+ * @param value
+ * @throws IllegalArgumentException if the passed {@code value}
+ * is {@code null}.
+ */
+ CoreValueImpl(Long value) {
+ this(value, PropertyType.LONG);
+ }
+
+ /**
+ * Create a new instance.
+ *
+ * @param value
+ * @throws IllegalArgumentException if the passed {@code value}
+ * is {@code null}.
+ */
+ CoreValueImpl(Double value) {
+ this(value, PropertyType.DOUBLE);
+ }
+
+ /**
+ * Create a new instance.
+ *
+ * @param value
+ * @throws IllegalArgumentException if the passed {@code value}
+ * is {@code null}.
+ */
+ CoreValueImpl(Boolean value) {
+ this(value, PropertyType.BOOLEAN);
+ }
+
+ /**
+ * Create a new instance.
+ *
+ * @param value
+ * @throws IllegalArgumentException if the passed {@code value}
+ * is {@code null}.
+ */
+ CoreValueImpl(BigDecimal value) {
+ this(value, PropertyType.DECIMAL);
+ }
+
+ /**
+ * Create a new instance.
+ *
+ * @param value
+ * @throws IllegalArgumentException if the passed {@code value}
+ * is {@code null}.
+ */
+ CoreValueImpl(BinaryValue value) {
+ this(value, PropertyType.BINARY);
+ }
+
+ //----------------------------------------------------------< CoreValue >---
+ @Override
+ public int getType() {
+ return type;
+ }
+
+ @Override
+ public String getString() {
+ return value.toString();
+ }
+
+ @Override
+ public long getLong() {
+ long l;
+ switch (getType()) {
+ case PropertyType.LONG:
+ l = (Long) value;
+ break;
+ case PropertyType.DOUBLE:
+ l = ((Double) value).longValue();
+ break;
+ case PropertyType.DECIMAL:
+ l = ((BigDecimal) value).longValue();
+ break;
+ default:
+ l = Long.parseLong(getString());
+ }
+ return l;
+ }
+
+ @Override
+ public double getDouble() {
+ double d;
+ switch (getType()) {
+ case PropertyType.DOUBLE:
+ d = (Double) value;
+ break;
+ case PropertyType.LONG:
+ d = ((Long) value).doubleValue();
+ break;
+ case PropertyType.DECIMAL:
+ d = ((BigDecimal) value).doubleValue();
+ break;
+ default:
+ d = Double.parseDouble(getString());
+ }
+ return d;
+ }
+
+ @Override
+ public boolean getBoolean() {
+ boolean b;
+ switch (getType()) {
+ case PropertyType.BOOLEAN:
+ b = (Boolean) value;
+ break;
+ case PropertyType.STRING:
+ case PropertyType.BINARY:
+ b = Boolean.parseBoolean(getString());
+ break;
+ default:
+ throw new UnsupportedOperationException("Unsupported conversion.");
+
+ }
+ return b;
+ }
+
+ @Override
+ public BigDecimal getDecimal() {
+ BigDecimal decimal;
+ switch (getType()) {
+ case PropertyType.DECIMAL:
+ decimal = (BigDecimal) value;
+ break;
+ case PropertyType.DOUBLE:
+ decimal = new BigDecimal(getDouble());
+ break;
+ case PropertyType.LONG:
+ decimal = new BigDecimal(getLong());
+ break;
+ default:
+ decimal = new BigDecimal(getString());
+ }
+ return decimal;
+ }
+
+ @Override
+ public InputStream getNewStream() {
+ InputStream in;
+ switch (type) {
+ case PropertyType.BINARY:
+ in = ((BinaryValue) value).getStream();
+ break;
+ default:
+ try {
+ in = new ByteArrayInputStream(getString().getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ // TODO: proper log output and exception handling
+ throw new RuntimeException(e);
+ }
+ }
+ return in;
+ }
+
+ @Override
+ public long length() {
+ long length;
+ switch (type) {
+ case PropertyType.BINARY:
+ length = ((BinaryValue) value).length();
+ break;
+ default:
+ length = getString().length();
+ }
+ return length;
+ }
+
+ //---------------------------------------------------------< Comparable >---
+ @Override
+ public int compareTo(CoreValue o) {
+ if (this == o) {
+ return 0;
+ }
+ if (type != o.getType()) {
+ // TODO convert?
+ return type - o.getType();
+ }
+ switch (type) {
+ case PropertyType.LONG:
+ return ((Long) value).compareTo(o.getLong());
+ case PropertyType.DOUBLE:
+ return ((Double) value).compareTo(o.getDouble());
+ case PropertyType.DECIMAL:
+ return ((BigDecimal) value).compareTo(o.getDecimal());
+ case PropertyType.BOOLEAN:
+ return ((Boolean) value).compareTo(o.getBoolean());
+ default:
+ return value.toString().compareTo(o.toString());
+ }
+
+ }
+
+ //-------------------------------------------------------------< Object >---
+ @Override
+ public int hashCode() {
+ return type ^ value.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+
+ if (o instanceof CoreValueImpl) {
+ CoreValueImpl other = (CoreValueImpl) o;
+ return type == other.type && value.equals(other.value);
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return value.toString();
+ }
+}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/KernelContentRepository.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/KernelContentRepository.java?rev=1329281&r1=1329280&r2=1329281&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/KernelContentRepository.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/KernelContentRepository.java Mon Apr 23 15:22:24 2012
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.core;
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.CoreValueFactory;
import org.apache.jackrabbit.oak.kernel.NodeState;
import org.apache.jackrabbit.oak.api.Branch;
import org.apache.jackrabbit.oak.api.QueryEngine;
@@ -93,8 +94,10 @@ public class KernelContentRepository imp
throw new NoSuchWorkspaceException(workspaceName);
}
+ CoreValueFactory valueFactory = new CoreValueFactoryImpl(microKernel);
+
return new KernelContentSession(
- sc, workspaceName, nodeStore, wspRoot, queryEngine);
+ sc, workspaceName, nodeStore, wspRoot, queryEngine, valueFactory);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/KernelContentSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/KernelContentSession.java?rev=1329281&r1=1329280&r2=1329281&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/KernelContentSession.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/KernelContentSession.java Mon Apr 23 15:22:24 2012
@@ -21,6 +21,7 @@ import org.apache.jackrabbit.mk.api.Micr
import org.apache.jackrabbit.oak.api.AuthInfo;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.CoreValueFactory;
import org.apache.jackrabbit.oak.kernel.NodeState;
import org.apache.jackrabbit.oak.api.Branch;
import org.apache.jackrabbit.oak.kernel.NodeStore;
@@ -45,17 +46,20 @@ class KernelContentSession implements Co
private final String workspaceName;
private final NodeStore store;
private final QueryEngine queryEngine;
+ private final CoreValueFactory valueFactory;
private NodeState root;
public KernelContentSession(
SimpleCredentials credentials, String workspaceName,
- NodeStore store, NodeState root, QueryEngine queryEngine) {
+ NodeStore store, NodeState root, QueryEngine queryEngine,
+ CoreValueFactory valueFactory) {
this.credentials = credentials;
this.workspaceName = workspaceName;
this.store = store;
this.queryEngine = queryEngine;
this.root = root;
+ this.valueFactory = valueFactory;
}
@Override
@@ -113,4 +117,9 @@ class KernelContentSession implements Co
return queryEngine;
}
+ @Override
+ public CoreValueFactory getCoreValueFactory() {
+ return valueFactory;
+ }
+
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-jcr/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/pom.xml?rev=1329281&r1=1329280&r2=1329281&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-jcr/pom.xml Mon Apr 23 15:22:24 2012
@@ -59,6 +59,11 @@
<version>3.2.1</version>
</dependency>
<dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java?rev=1329281&r1=1329280&r2=1329281&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java Mon Apr 23 15:22:24 2012
@@ -69,7 +69,7 @@ public class SessionImpl extends Abstrac
SessionImpl(GlobalContext globalContext, ContentSession contentSession) {
this.globalContext = globalContext;
this.contentSession = contentSession;
- this.valueFactory = new ValueFactoryImpl();
+ this.valueFactory = new ValueFactoryImpl(contentSession.getCoreValueFactory());
workspace = new WorkspaceImpl(sessionContext);
this.branch = contentSession.branchRoot();
}
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ValueFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ValueFactoryImpl.java?rev=1329281&r1=1329280&r2=1329281&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ValueFactoryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ValueFactoryImpl.java Mon Apr 23 15:22:24 2012
@@ -16,34 +16,163 @@
*/
package org.apache.jackrabbit.oak.jcr;
-import org.apache.jackrabbit.value.AbstractValueFactory;
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.CoreValueFactory;
+import org.apache.jackrabbit.util.ISO8601;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.jcr.Binary;
+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 java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.Calendar;
/**
- * ValueFactoryImpl...
+ * CoreValueFactoryImpl...
*/
-class ValueFactoryImpl extends AbstractValueFactory {
+class ValueFactoryImpl implements ValueFactory {
/**
* logger instance
*/
private static final Logger log = LoggerFactory.getLogger(ValueFactoryImpl.class);
- ValueFactoryImpl() {
+ private final CoreValueFactory factory;
+ private final DummyNamePathResolver resolver; // TODO: add proper name/path conversion
+ /**
+ *
+ * @param factory
+ */
+ public ValueFactoryImpl(CoreValueFactory factory/*, NamePathResolver resolver*/) {
+ this.factory = factory;
+ this.resolver = new DummyNamePathResolver();
+ }
+
+ //-------------------------------------------------------< ValueFactory >---
+ @Override
+ public Value createValue(String value) {
+ CoreValue cv = factory.createValue(value, PropertyType.STRING);
+ return new ValueImpl(cv, resolver);
+ }
+
+ @Override
+ public Value createValue(long value) {
+ CoreValue cv = factory.createValue(value);
+ return new ValueImpl(cv, resolver);
+ }
+
+ @Override
+ public Value createValue(double value) {
+ CoreValue cv = factory.createValue(value);
+ return new ValueImpl(cv, resolver);
}
@Override
- protected void checkPathFormat(String s) throws ValueFormatException {
- // TODO : path validation
+ public Value createValue(boolean value) {
+ CoreValue cv = factory.createValue(value);
+ return new ValueImpl(cv, resolver);
+ }
+ @Override
+ public Value createValue(Calendar value) {
+ String dateStr = ISO8601.format(value);
+ CoreValue cv = factory.createValue(dateStr, PropertyType.DATE);
+ return new ValueImpl(cv, resolver);
}
@Override
- protected void checkNameFormat(String s) throws ValueFormatException {
- // TODO : name validation
+ public Value createValue(InputStream value) {
+ try {
+ CoreValue cv = factory.createValue(value);
+ return new ValueImpl(cv, resolver);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ } finally {
+ // JCR-2903
+ IOUtils.closeQuietly(value);
+ }
+ }
+
+ @Override
+ public Value createValue(Node value) throws RepositoryException {
+ return createValue(value, false);
+ }
+
+ @Override
+ public Value createValue(String value, int type) throws ValueFormatException {
+ CoreValue cv;
+ if (type == PropertyType.NAME) {
+ cv = factory.createValue(resolver.getInternalName(value), type);
+ } else if (type == PropertyType.PATH) {
+ cv = factory.createValue(resolver.getInternalPath(value), type);
+ } else {
+ cv = factory.createValue(value, type);
+ }
+
+ return new ValueImpl(cv, resolver);
+ }
+
+ @Override
+ public Binary createBinary(InputStream stream) throws RepositoryException {
+ try {
+ CoreValue value = factory.createValue(stream);
+ // TODO: BINARY implementation missing
+ throw new UnsupportedOperationException("BINARY handling");
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ } finally {
+ IOUtils.closeQuietly(stream);
+ }
+ }
+
+ @Override
+ public Value createValue(Binary value) {
+ try {
+ return createValue(value.getStream());
+ } catch (RepositoryException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ @Override
+ public Value createValue(BigDecimal value) {
+ CoreValue cv = factory.createValue(value);
+ return new ValueImpl(cv, resolver);
+ }
+
+ @Override
+ public Value createValue(Node value, boolean weak) throws RepositoryException {
+ CoreValue cv = factory.createValue(value.getUUID(), weak ? PropertyType.WEAKREFERENCE : PropertyType.REFERENCE);
+ return new ValueImpl(cv, resolver);
+ }
+
+
+ //--------------------------------------------------------------------------
+ // TODO: replace by reasonable implementation taking namespace mappings etc. into account.
+ public class DummyNamePathResolver {
+ String getJCRPath(String internalPath) {
+ return internalPath;
+ }
+
+ String getInternalPath(String jcrPath) {
+ return jcrPath;
+ }
+
+ String getJCRName(String internalName) {
+ return internalName;
+ }
+
+ String getInternalName(String jcrName) {
+ return jcrName;
+ }
}
}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ValueImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ValueImpl.java?rev=1329281&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ValueImpl.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ValueImpl.java Mon Apr 23 15:22:24 2012
@@ -0,0 +1,253 @@
+/*
+ * 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.oak.jcr;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.util.ISO8601;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Binary;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+/**
+ * ValueImpl...
+ */
+public class ValueImpl implements Value {
+
+ /**
+ * logger instance
+ */
+ private static final Logger log = LoggerFactory.getLogger(ValueImpl.class);
+
+ private final CoreValue value;
+
+ // TODO need utility to convert the internal NAME/PATH format to JCR format
+ private final ValueFactoryImpl.DummyNamePathResolver resolver;
+
+ /**
+ * Constructs a <code>ValueImpl</code> object representing an SPI
+ * <codeQValue</code>.
+ *
+ * @param value the value object this <code>ValueImpl</code> should represent
+ * @param resolver
+ */
+ public ValueImpl(CoreValue value, ValueFactoryImpl.DummyNamePathResolver resolver) {
+ this.value = value;
+ this.resolver = resolver;
+ }
+
+ //--------------------------------------------------------------< Value >---
+ /**
+ * @see javax.jcr.Value#getType()
+ */
+ public int getType() {
+ return value.getType();
+ }
+
+ /**
+ * @see javax.jcr.Value#getBoolean()
+ */
+ public boolean getBoolean() throws RepositoryException {
+ if (getType() == PropertyType.STRING || getType() == PropertyType.BINARY || getType() == PropertyType.BOOLEAN) {
+ return value.getBoolean();
+ } else {
+ throw new ValueFormatException("Incompatible type " + PropertyType.nameFromValue(getType()));
+ }
+ }
+
+ /**
+ * @see javax.jcr.Value#getDate()
+ */
+ public Calendar getDate() throws RepositoryException {
+ Calendar cal;
+ switch (getType()) {
+ case PropertyType.DOUBLE:
+ case PropertyType.LONG:
+ case PropertyType.DECIMAL:
+ cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+00:00"));
+ cal.setTimeInMillis(getLong());
+ break;
+ default:
+ cal = ISO8601.parse(getString());
+ if (cal == null) {
+ throw new ValueFormatException("Not a date string: " + getString());
+ }
+ }
+ return cal;
+ }
+
+ /**
+ * @see javax.jcr.Value#getDecimal()
+ */
+ public BigDecimal getDecimal() throws RepositoryException {
+ try {
+ return value.getDecimal();
+ } catch (NumberFormatException e) {
+ throw new ValueFormatException("Incompatible type " + PropertyType.nameFromValue(getType()));
+ }
+ }
+
+ /**
+ * @see javax.jcr.Value#getDouble()
+ */
+ public double getDouble() throws RepositoryException {
+ try {
+ return value.getDouble();
+ } catch (NumberFormatException e) {
+ throw new ValueFormatException("Incompatible type " + PropertyType.nameFromValue(getType()));
+ }
+ }
+
+ /**
+ * @see javax.jcr.Value#getLong()
+ */
+ public long getLong() throws RepositoryException {
+ try {
+ return value.getLong();
+ } catch (NumberFormatException e) {
+ throw new ValueFormatException("Incompatible type " + PropertyType.nameFromValue(getType()));
+ }
+ }
+
+ /**
+ * @see javax.jcr.Value#getString()
+ */
+ public String getString() throws RepositoryException {
+ switch (getType()) {
+ case PropertyType.NAME :
+ return resolver.getJCRName(value.toString());
+ case PropertyType.PATH:
+ return resolver.getJCRPath(value.toString());
+ case PropertyType.BINARY:
+ InputStream stream = getStream();
+ try {
+ return IOUtils.toString(stream, "UTF-8");
+ } catch (IOException e) {
+ throw new RepositoryException("conversion from stream to string failed", e);
+ } finally {
+ IOUtils.closeQuietly(stream);
+ }
+ default:
+ return value.toString();
+ }
+ }
+
+
+ /**
+ * @see javax.jcr.Value#getStream()
+ */
+ public InputStream getStream() throws IllegalStateException, RepositoryException {
+ InputStream stream;
+ switch (getType()) {
+ case PropertyType.NAME:
+ case PropertyType.PATH:
+ try {
+ stream = new ByteArrayInputStream(getString().getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException ex) {
+ throw new RepositoryException("UTF-8 is not supported", ex);
+ }
+ break;
+ default:
+ stream = value.getNewStream();
+ }
+ return stream;
+ }
+
+ /**
+ * @see javax.jcr.Value#getBinary()
+ */
+ public Binary getBinary() throws RepositoryException {
+ return new BinaryImpl();
+ }
+
+ //-------------------------------------------------------------< Object >---
+ /**
+ * @see Object#equals(Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ValueImpl) {
+ return value.equals(((ValueImpl) obj).value);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @see Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ //------------------------------------------------------------< Binary >----
+ private class BinaryImpl implements Binary {
+
+ @Override
+ public InputStream getStream() throws RepositoryException {
+ switch (value.getType()) {
+ case PropertyType.NAME:
+ case PropertyType.PATH:
+ // need to respect namespace remapping
+ try {
+ final String strValue = getString();
+ return new ByteArrayInputStream(strValue.getBytes("utf-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new RepositoryException(e.getMessage());
+ }
+ default:
+ return value.getNewStream();
+ }
+ }
+
+ @Override
+ public int read(byte[] b, long position) throws IOException, RepositoryException {
+ // TODO
+ throw new UnsupportedOperationException("implementation missing");
+ }
+
+ @Override
+ public long getSize() throws RepositoryException {
+ switch (value.getType()) {
+ case PropertyType.NAME:
+ case PropertyType.PATH:
+ // need to respect namespace remapping
+ return getString().length();
+ default:
+ return value.length();
+ }
+ }
+
+ @Override
+ public void dispose() {
+ // nothing to do
+ }
+ }
+}
\ No newline at end of file