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 md...@apache.org on 2012/03/23 00:22:38 UTC
svn commit: r1304130 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/
oak-core/src/main/java/org/apache/jackrabbit/oak/api/
oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/
oak-jcr/src/main/java/org/apache/jackrabbit/oa...
Author: mduerig
Date: Thu Mar 22 23:22:37 2012
New Revision: 1304130
URL: http://svn.apache.org/viewvc?rev=1304130&view=rev
Log:
OAK-33: Values in oak-core (WIP)
initial implementation of Scalar
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/ScalarImpl.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Scalar.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelPropertyState.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/state/ChangeTree.java
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/ScalarImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/ScalarImpl.java?rev=1304130&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/ScalarImpl.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/ScalarImpl.java Thu Mar 22 23:22:37 2012
@@ -0,0 +1,314 @@
+package org.apache.jackrabbit;
+
+import org.apache.jackrabbit.oak.api.Scalar;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.concurrent.Callable;
+
+public abstract class ScalarImpl implements Scalar {
+ private final int type;
+
+ public static Scalar createNumber(String value) {
+ // todo improve
+ try {
+ return createLong(Long.parseLong(value));
+ }
+ catch (NumberFormatException e) {
+ return createDouble(Double.parseDouble(value));
+ }
+ }
+
+ public static Scalar createBoolean(final boolean value) {
+ return value ? TRUE_SCALAR : FALSE_SCALAR;
+ }
+
+ public static Scalar createLong(final long value) {
+ return new LongScalar(value);
+ }
+
+ public static Scalar createDouble(final double value) {
+ return new DoubleScalar(value);
+ }
+
+ public static Scalar createString(final String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("Value must not be null");
+ }
+ return new StringScalar(value);
+ }
+
+ public static Scalar createBinary(final String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("Value must not be null");
+ }
+ return new SmallBinaryScalar(value);
+ }
+
+ public static Scalar createBinary(final Callable<InputStream> valueProvider) {
+ if (valueProvider == null) {
+ throw new IllegalArgumentException("Value must not be null");
+ }
+ return new BinaryScalar(valueProvider);
+ }
+
+ protected ScalarImpl(int type) {
+ this.type = type;
+ }
+
+ @Override
+ public int getType() {
+ return type;
+ }
+
+ @Override
+ public boolean getBoolean() {
+ return Boolean.valueOf(getString());
+ }
+
+ @Override
+ public long getLong() {
+ return Long.parseLong(getString());
+ }
+
+ @Override
+ public double getDouble() {
+ return Double.parseDouble(getString());
+ }
+
+ @Override
+ public InputStream getInputStream() {
+ try {
+ return new ByteArrayInputStream(getString().getBytes("UTF-8"));
+ }
+ catch (UnsupportedEncodingException e) {
+ // todo handle UnsupportedEncodingException
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getString() + ": " + Scalar.typeNames[type];
+ }
+
+ //------------------------------------------------------------< private >---
+
+ private static final BooleanScalar TRUE_SCALAR = new BooleanScalar(true);
+ private static final BooleanScalar FALSE_SCALAR = new BooleanScalar(false);
+
+ private static final class BooleanScalar extends ScalarImpl {
+ private final boolean value;
+
+ public BooleanScalar(boolean value) {
+ super(Scalar.BOOLEAN);
+ this.value = value;
+ }
+
+ @Override
+ public boolean getBoolean() {
+ return value;
+ }
+
+ @Override
+ public String getString() {
+ return Boolean.toString(value);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other == null || getClass() != other.getClass()) {
+ return false;
+ }
+
+ return value == ((BooleanScalar) other).value;
+ }
+
+ @Override
+ public int hashCode() {
+ return (value ? 1 : 0);
+ }
+ }
+
+ private static final class LongScalar extends ScalarImpl {
+ private final long value;
+
+ public LongScalar(long value) {
+ super(Scalar.LONG);
+ this.value = value;
+ }
+
+ @Override
+ public long getLong() {
+ return value;
+ }
+
+ @Override
+ public String getString() {
+ return Long.toString(value);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other == null || getClass() != other.getClass()) {
+ return false;
+ }
+
+ return value == ((LongScalar) other).value;
+ }
+
+ @Override
+ public int hashCode() {
+ return (int) (value ^ (value >>> 32));
+ }
+ }
+
+ private static final class DoubleScalar extends ScalarImpl {
+ private final double value;
+
+ public DoubleScalar(double value) {
+ super(Scalar.DOUBLE);
+ this.value = value;
+ }
+
+ @Override
+ public double getDouble() {
+ return value;
+ }
+
+ @Override
+ public String getString() {
+ return Double.toString(value);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other == null || getClass() != other.getClass()) {
+ return false;
+ }
+
+ return Double.compare(((DoubleScalar) other).value, value) == 0;
+
+ }
+
+ @Override
+ public int hashCode() {
+ long h = value != 0.0d ? Double.doubleToLongBits(value) : 0L;
+ return (int) (h ^ (h >>> 32));
+ }
+ }
+
+ private static final class StringScalar extends ScalarImpl {
+ private final String value;
+
+ public StringScalar(String value) {
+ super(Scalar.STRING);
+ this.value = value;
+ }
+
+ @Override
+ public String getString() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ return value.equals(((StringScalar) o).value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+ }
+
+ private static final class SmallBinaryScalar extends ScalarImpl {
+ private final String value;
+
+ public SmallBinaryScalar(String value) {
+ super(Scalar.BINARY);
+ this.value = value;
+ }
+
+ @Override
+ public String getString() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other == null || getClass() != other.getClass()) {
+ return false;
+ }
+
+ return value.equals(((SmallBinaryScalar) other).value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+ }
+
+ private static class BinaryScalar extends ScalarImpl {
+ private final Callable<InputStream> valueProvider;
+
+ public BinaryScalar(Callable<InputStream> valueProvider) {
+ super(Scalar.BINARY);
+ this.valueProvider = valueProvider;
+ }
+
+ @Override
+ public InputStream getInputStream() {
+ try {
+ return valueProvider.call();
+ }
+ catch (Exception e) {
+ // todo handle Exception
+ return null;
+ }
+ }
+
+ @Override
+ public String getString() {
+ return ""; // todo implement getString
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other == null || getClass() != other.getClass()) {
+ return false;
+ }
+
+ return getString().equals(((BinaryScalar) other).getString());
+ }
+
+ @Override
+ public int hashCode() {
+ return getString().hashCode();
+ }
+ }
+}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Scalar.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Scalar.java?rev=1304130&r1=1304129&r2=1304130&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Scalar.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Scalar.java Thu Mar 22 23:22:37 2012
@@ -22,6 +22,13 @@ import java.io.InputStream;
* An immutable, typed scalar value.
*/
public interface Scalar {
+ int BOOLEAN = 0;
+ int LONG = 1;
+ int DOUBLE = 2;
+ int BINARY = 3;
+ int STRING = 4;
+
+ String[] typeNames = {"boolean", "long", "double", "binary", "string"};
/**
* Returns the value type.
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java?rev=1304130&r1=1304129&r2=1304130&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java Thu Mar 22 23:22:37 2012
@@ -18,6 +18,7 @@
*/
package org.apache.jackrabbit.oak.kernel;
+import org.apache.jackrabbit.ScalarImpl;
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.mk.api.MicroKernelException;
import org.apache.jackrabbit.mk.json.JsopReader;
@@ -26,6 +27,7 @@ import org.apache.jackrabbit.mk.model.Ab
import org.apache.jackrabbit.mk.model.ChildNodeEntry;
import org.apache.jackrabbit.mk.model.NodeState;
import org.apache.jackrabbit.mk.model.PropertyState;
+import org.apache.jackrabbit.oak.api.Scalar;
import java.util.ArrayList;
import java.util.Iterator;
@@ -87,16 +89,16 @@ public class KernelNodeState extends Abs
kernel, childPath, revision));
} else if (reader.matches(JsopTokenizer.NUMBER)) {
properties.put(name, new KernelPropertyState(
- name, reader.getToken()));
+ name, ScalarImpl.createNumber(reader.getToken())));
} else if (reader.matches(JsopTokenizer.STRING)) {
properties.put(name, new KernelPropertyState(
- name, '"' + reader.getToken() + '"'));
+ name, ScalarImpl.createString(reader.getToken())));
} else if (reader.matches(JsopTokenizer.TRUE)) {
properties.put(name, new KernelPropertyState(
- name, "true"));
+ name, ScalarImpl.createBoolean(true)));
} else if (reader.matches(JsopTokenizer.FALSE)) {
properties.put(name, new KernelPropertyState(
- name, "false"));
+ name, ScalarImpl.createBoolean(false)));
} else if (reader.matches('[')) {
properties.put(name, new KernelPropertyState(
name, readArray(reader)));
@@ -212,30 +214,23 @@ public class KernelNodeState extends Abs
}
}
- private static String readArray(JsopReader reader) {
- StringBuilder sb = new StringBuilder("[");
- String sep = "";
+ private static List<Scalar> readArray(JsopReader reader) {
+ List<Scalar> values = new ArrayList<Scalar>();
while (!reader.matches(']')) {
- String v;
if (reader.matches(JsopTokenizer.NUMBER)) {
- v = reader.getToken();
+ values.add(ScalarImpl.createNumber(reader.getToken()));
} else if (reader.matches(JsopTokenizer.STRING)) {
- v = '"' + reader.getToken() + '"';
- }
- else if (reader.matches(JsopTokenizer.TRUE)) {
- v = "true";
+ values.add(ScalarImpl.createString(reader.getToken()));
+ } else if (reader.matches(JsopTokenizer.TRUE)) {
+ values.add(ScalarImpl.createBoolean(true));
} else if (reader.matches(JsopTokenizer.FALSE)) {
- v = "false";
+ values.add(ScalarImpl.createBoolean(false));
} else {
throw new IllegalArgumentException("Unexpected token: " + reader.getToken());
}
- sb.append(sep);
- sep = ",";
- sb.append(v);
reader.matches(',');
}
- sb.append(']');
- return sb.toString();
+ return values;
}
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelPropertyState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelPropertyState.java?rev=1304130&r1=1304129&r2=1304130&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelPropertyState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelPropertyState.java Thu Mar 22 23:22:37 2012
@@ -19,16 +19,27 @@
package org.apache.jackrabbit.oak.kernel;
import org.apache.jackrabbit.mk.model.AbstractPropertyState;
+import org.apache.jackrabbit.oak.api.Scalar;
+
+import java.util.Collections;
+import java.util.List;
public class KernelPropertyState extends AbstractPropertyState { // fixme make package private
private final String name;
+ private final Scalar value;
+ private final List<Scalar> values;
- private final String value;
-
- public KernelPropertyState(String name, String value) {
+ public KernelPropertyState(String name, Scalar value) {
this.name = name;
this.value = value;
+ this.values = null;
+ }
+
+ public KernelPropertyState(String name, List<Scalar> values) {
+ this.name = name;
+ this.value = null;
+ this.values = Collections.unmodifiableList(values);
}
@Override
@@ -38,7 +49,41 @@ public class KernelPropertyState extends
@Override
public String getEncodedValue() {
- return value;
+ if (value == null) {
+ String sep = "";
+ StringBuilder sb = new StringBuilder("[");
+ for (Scalar s : values) {
+ sb.append(sep);
+ sep = ",";
+ if (s.getType() == Scalar.STRING) {
+ sb.append('"' + s.getString() + '"');
+ }
+ else {
+ sb.append(s.getString());
+ }
+ }
+ sb.append(']');
+ return sb.toString();
+ }
+ else {
+ if (value.getType() == Scalar.STRING) {
+ return '"' + value.getString() + '"';
+ }
+ else {
+ return value.getString();
+ }
+ }
}
+ public boolean isMultiValues() {
+ return value == null;
+ }
+
+ public Scalar getValue() {
+ return value;
+ }
+
+ public List<Scalar> getValues() {
+ return values;
+ }
}
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/state/ChangeTree.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/state/ChangeTree.java?rev=1304130&r1=1304129&r2=1304130&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/state/ChangeTree.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/state/ChangeTree.java Thu Mar 22 23:22:37 2012
@@ -28,7 +28,6 @@ import org.apache.jackrabbit.oak.jcr.uti
import org.apache.jackrabbit.oak.jcr.util.Iterators;
import org.apache.jackrabbit.oak.jcr.util.Path;
import org.apache.jackrabbit.oak.jcr.util.Predicate;
-import org.apache.jackrabbit.oak.kernel.KernelPropertyState;
import javax.jcr.ItemExistsException;
import javax.jcr.ItemNotFoundException;
@@ -273,7 +272,17 @@ public class ChangeTree {
new Function1<Entry<String, JsonValue>, PropertyState>() {
@Override
public PropertyState apply(final Entry<String, JsonValue> entry) {
- return new KernelPropertyState(entry.getKey(), entry.getValue().toJson());
+ return new PropertyState() {
+ @Override
+ public String getName() {
+ return entry.getKey();
+ }
+
+ @Override
+ public String getEncodedValue() {
+ return entry.getValue().toJson();
+ }
+ };
}
});
}