Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/RemoteValue.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/RemoteValue.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/RemoteValue.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/RemoteValue.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,1431 @@ +/* + * 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.remote; + +import java.io.InputStream; +import java.math.BigDecimal; + +/** + * Represents a value that can be assigned to a property in the repository. + * Client of the remote repository provides values as instances of this class. + */ +public class RemoteValue { + + /** + * A generic interface to represent a supplier of an item. + * <p/> + * In the specific, it is used by values whose underlying implementation is + * an {@code InputStream}. To enable multiple traversals of {@code + * InputStream}s, the value is wrapped by this interface to effectively have + * a factory over the underlying {@code InputStream}. + * + * @param <T> Type of the item this object is able to create. + */ + public static interface Supplier<T> { + + T get(); + + } + + /** + * This class helps executing logic that depends on the type of a remote + * value. Instead of manually branching code depending on the result of + * {@code isText}, {@code isBoolean} and so on, a handler can be implemented + * to provide different logic for different types. + */ + public static class TypeHandler { + + public void isBinary(Supplier<InputStream> value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiBinary(Iterable<Supplier<InputStream>> value) { + throw new IllegalStateException("case not handled"); + } + + public void isBinaryId(String value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiBinaryId(Iterable<String> value) { + throw new IllegalStateException("case not handled"); + } + + public void isBoolean(Boolean value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiBoolean(Iterable<Boolean> value) { + throw new IllegalStateException("case not handled"); + } + + public void isDate(Long value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiDate(Iterable<Long> value) { + throw new IllegalStateException("case not handled"); + } + + public void isDecimal(BigDecimal value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiDecimal(Iterable<BigDecimal> value) { + throw new IllegalStateException("case not handled"); + } + + public void isDouble(Double value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiDouble(Iterable<Double> value) { + throw new IllegalStateException("case not handled"); + } + + public void isLong(Long value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiLong(Iterable<Long> value) { + throw new IllegalStateException("case not handled"); + } + + public void isName(String value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiName(Iterable<String> value) { + throw new IllegalStateException("case not handled"); + } + + public void isPath(String value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiPath(Iterable<String> value) { + throw new IllegalStateException("case not handled"); + } + + public void isReference(String value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiReference(Iterable<String> value) { + throw new IllegalStateException("case not handled"); + } + + public void isText(String value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiText(Iterable<String> value) { + throw new IllegalStateException("case not handled"); + } + + public void isUri(String value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiUri(Iterable<String> value) { + throw new IllegalStateException("case not handled"); + } + + public void isWeakReference(String value) { + throw new IllegalStateException("case not handled"); + } + + public void isMultiWeakReference(Iterable<String> value) { + throw new IllegalStateException("case not handled"); + } + + public void isUnknown() { + throw new IllegalStateException("case not handled"); + } + } + + /** + * Create a remote value of type string. + * + * @param value The string wrapped by the remote value. + * @return A remote value of type string wrapping the provided value. + */ + public static RemoteValue toText(final String value) { + return new RemoteValue() { + + @Override + public boolean isText() { + return true; + } + + @Override + public String asText() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type string. + * + * @param value The collection of strings wrapped by the remote value. + * @return A remote multi-value of type string wrapping the provided + * collection of strings. + */ + public static RemoteValue toMultiText(final Iterable<String> value) { + return new RemoteValue() { + + @Override + public boolean isMultiText() { + return true; + } + + @Override + public Iterable<String> asMultiText() { + return value; + } + + }; + } + + /** + * Create a remote value of type binary. + * + * @param value The factory of input streams wrapped by the remote value. + * @return A remote value of type binary wrapping the provided factory of + * input streams. + */ + public static RemoteValue toBinary(final Supplier<InputStream> value) { + return new RemoteValue() { + + @Override + public boolean isBinary() { + return true; + } + + @Override + public Supplier<InputStream> asBinary() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type binary. + * + * @param value The collection of factories of input streams wrapped by the + * remote value. + * @return A remote multi-value of type binary wrapping the provided + * collection of input streams. + */ + public static RemoteValue toMultiBinary(final Iterable<Supplier<InputStream>> value) { + return new RemoteValue() { + + @Override + public boolean isMultiBinary() { + return true; + } + + @Override + public Iterable<Supplier<InputStream>> asMultiBinary() { + return value; + } + + }; + } + + /** + * Create a remote value of type binary ID. + * + * @param value The binary ID wrapped by the remote value. + * @return A remote value wrapping the provided binary ID. + */ + public static RemoteValue toBinaryId(final String value) { + return new RemoteValue() { + + @Override + public boolean isBinaryId() { + return true; + } + + @Override + public String asBinaryId() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type binary ID. + * + * @param value The collection of binary IDs wrapped by the remote value. + * @return A remote multi-value wrapping the provided collection of binary + * IDs. + */ + public static RemoteValue toMultiBinaryId(final Iterable<String> value) { + return new RemoteValue() { + + @Override + public boolean isMultiBinaryId() { + return true; + } + + @Override + public Iterable<String> asMultiBinaryId() { + return value; + } + + }; + } + + /** + * Create a remote value of type long. + * + * @param value The long to wrap in a remote value. + * @return A remote value of type long wrapping the provided long value. + */ + public static RemoteValue toLong(final long value) { + return new RemoteValue() { + + @Override + public boolean isLong() { + return true; + } + + + @Override + public Long asLong() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type long. + * + * @param value The collection of long values to wrap in a remote value. + * @return A remote multi-value of type long wrapping the provided + * collection of long values. + */ + public static RemoteValue toMultiLong(final Iterable<Long> value) { + return new RemoteValue() { + + @Override + public boolean isMultiLong() { + return true; + } + + @Override + public Iterable<Long> asMultiLong() { + return value; + } + + }; + } + + /** + * Create a remote value of type double. + * + * @param value The double value to wrap into a remote value. + * @return A remote value wrapping the provided remote value. + */ + public static RemoteValue toDouble(final double value) { + return new RemoteValue() { + + @Override + public boolean isDouble() { + return true; + } + + @Override + public Double asDouble() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type double. + * + * @param value The collection of double values to wrap into a remote + * value. + * @return A remote multi-value of type double wrapping the provided + * collection of double values. + */ + public static RemoteValue toMultiDouble(final Iterable<Double> value) { + return new RemoteValue() { + + @Override + public boolean isMultiDouble() { + return true; + } + + @Override + public Iterable<Double> asMultiDouble() { + return value; + } + + }; + } + + /** + * Create a remote value of type date. + * + * @param value The date to wrap into a remote value. The date is expressed + * in milliseconds since January 1, 1970, 00:00:00 GMT. + * @return A remote value of type date wrapping the provided date. + */ + public static RemoteValue toDate(final long value) { + return new RemoteValue() { + + @Override + public boolean isDate() { + return true; + } + + @Override + public Long asDate() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type date. + * + * @param value The collection of dates to wrap into a remote value. Every + * date is expressed in milliseconds since January 1, 1970, + * 00:00:00 GMT. + * @return A remote multi-value of type date wrapping the provided + * collection of dates. + */ + public static RemoteValue toMultiDate(final Iterable<Long> value) { + return new RemoteValue() { + + @Override + public boolean isMultiDate() { + return true; + } + + @Override + public Iterable<Long> asMultiDate() { + return value; + } + + }; + } + + /** + * Create a remote value of type boolean. + * + * @param value The boolean value to wrap into a remote value. + * @return A remote value wrapping the provided boolean value. + */ + public static RemoteValue toBoolean(final boolean value) { + return new RemoteValue() { + + @Override + public boolean isBoolean() { + return true; + } + + @Override + public Boolean asBoolean() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type boolean. + * + * @param value The collection of boolean values to wrap into a remote + * value. + * @return A remote value wrapping the provided collection of boolean + * values. + */ + public static RemoteValue toMultiBoolean(final Iterable<Boolean> value) { + return new RemoteValue() { + + @Override + public boolean isMultiBoolean() { + return true; + } + + @Override + public Iterable<Boolean> asMultiBoolean() { + return value; + } + + }; + } + + /** + * Create a remote value of type name. + * + * @param value The name to wrap into a remote value. A name is represented + * as a string. + * @return A remote value of type name wrapping the provided string. + */ + public static RemoteValue toName(final String value) { + return new RemoteValue() { + + @Override + public boolean isName() { + return true; + } + + @Override + public String asName() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type name. + * + * @param value The collection of names to wrap into a remote value. Every + * name is represented by a string. + * @return A remote multi-value of type name wrapping the provided + * collection of strings. + */ + public static RemoteValue toMultiName(final Iterable<String> value) { + return new RemoteValue() { + + @Override + public boolean isMultiName() { + return true; + } + + @Override + public Iterable<String> asMultiName() { + return value; + } + + }; + } + + /** + * Create a remote value of type path. + * + * @param value The path to wrap into the remote value. A path is + * represented by a string. + * @return A remote value of type path wrapping the provided string. + */ + public static RemoteValue toPath(final String value) { + return new RemoteValue() { + + @Override + public boolean isPath() { + return true; + } + + @Override + public String asPath() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type path. + * + * @param value The collection of paths to wrap into a remote value. Every + * path is represented by a string. + * @return A remote multi-value of type path wrapping the provided strings. + */ + public static RemoteValue toMultiPath(final Iterable<String> value) { + return new RemoteValue() { + + @Override + public boolean isMultiPath() { + return true; + } + + @Override + public Iterable<String> asMultiPath() { + return value; + } + + }; + } + + /** + * Create a remote value of type reference. + * + * @param value The reference to wrap in a remote value. The reference is + * represented by a string. + * @return A remote value of type reference wrapping the provided string. + */ + public static RemoteValue toReference(final String value) { + return new RemoteValue() { + + @Override + public boolean isReference() { + return true; + } + + @Override + public String asReference() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type reference. + * + * @param value The collection of references to wrap in a remote value. + * Every reference is represented by a string. + * @return A remote multi-value of type reference wrapping the provided + * collection of strings. + */ + public static RemoteValue toMultiReference(final Iterable<String> value) { + return new RemoteValue() { + + @Override + public boolean isMultiReference() { + return true; + } + + @Override + public Iterable<String> asMultiReference() { + return value; + } + + }; + } + + /** + * Create a remote value of type weak reference. + * + * @param value The weak reference to wrap into a remote value. The weak + * reference is represented by a string value. + * @return A remote value of type weak reference wrapping the provided + * string value. + */ + public static RemoteValue toWeakReference(final String value) { + return new RemoteValue() { + + @Override + public boolean isWeakReference() { + return true; + } + + @Override + public String asWeakReference() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type weak reference. + * + * @param value The collection of weak references to wrap into a remote + * value. Every weak reference is represented by a string. + * @return A remote multi-value of type weak reference wrapping the provided + * collection of strings. + */ + public static RemoteValue toMultiWeakReference(final Iterable<String> value) { + return new RemoteValue() { + + @Override + public boolean isMultiWeakReference() { + return true; + } + + @Override + public Iterable<String> asMultiWeakReference() { + return value; + } + + }; + } + + /** + * Create a remote value of type URI. + * + * @param value The string representation of the URI to wrap into a remote + * value. + * @return A remote value of type URI wrapping the provided string. + */ + public static RemoteValue toUri(final String value) { + return new RemoteValue() { + + @Override + public boolean isUri() { + return true; + } + + @Override + public String asUri() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type URI. + * + * @param value The collection of URIs to wrap into the remote value. Every + * URI is represented by a string. + * @return A remote multi-value of type URI wrapping the provided collection + * of strings. + */ + public static RemoteValue toMultiUri(final Iterable<String> value) { + return new RemoteValue() { + + @Override + public boolean isMultiUri() { + return true; + } + + @Override + public Iterable<String> asMultiUri() { + return value; + } + + }; + } + + /** + * Create a remote value of type decimal. + * + * @param value The decimal to wrap into a remote value. + * @return A remote value of type decimal wrapping the provided decimal + * value. + */ + public static RemoteValue toDecimal(final BigDecimal value) { + return new RemoteValue() { + + @Override + public boolean isDecimal() { + return true; + } + + @Override + public BigDecimal asDecimal() { + return value; + } + + }; + } + + /** + * Create a remote multi-value of type decimal. + * + * @param value The collection of decimals to wrap into a remote value. + * @return A remote multi-value of type decimal wrapping the provided + * collection of decimals. + */ + public static RemoteValue toMultiDecimal(final Iterable<BigDecimal> value) { + return new RemoteValue() { + + @Override + public boolean isMultiDecimal() { + return true; + } + + @Override + public Iterable<BigDecimal> asMultiDecimal() { + return value; + } + + }; + } + + private RemoteValue() { + + } + + /** + * Check if this remote value is of type string. + * + * @return {@code true} if this remote value is of type string, {@code + * false} otherwise. + */ + public boolean isText() { + return false; + } + + /** + * Read the value of this remote string value. + * + * @return The string wrapped by this remote value if this remote value is + * of type string, {@code null} otherwise. + */ + public String asText() { + return null; + } + + /** + * Check if this remote value is a multi-value of type string. + * + * @return {@code true} if this remote value is a multi-value of type + * string, {@code false} otherwise. + */ + public boolean isMultiText() { + return false; + } + + /** + * Read the value of this remote string multi-value. + * + * @return The collection of strings wrapped by this remote value if this + * remote value is a multi-value of type string, {@code null} otherwise. + */ + public Iterable<String> asMultiText() { + return null; + } + + /** + * Check if this remote value is of type binary. + * + * @return {@code true} if this remote value is of type binary, {@code + * false} otherwise. + */ + public boolean isBinary() { + return false; + } + + /** + * Read the value of this remote boolean value. + * + * @return The value of this remote value if this remote value is of type + * binary, {@code null} otherwise. + */ + public Supplier<InputStream> asBinary() { + return null; + } + + /** + * Check if this remote value is a multi-value of type binary. + * + * @return {@code true} if this remote value is a multi-value of type + * binary, {@code false} otherwise. + */ + public boolean isMultiBinary() { + return false; + } + + /** + * Read the value of this remote binary multi-value. + * + * @return The value of this remote value if this remote value is a + * multi-value of type binary, {@code null} otherwise. + */ + public Iterable<Supplier<InputStream>> asMultiBinary() { + return null; + } + + /** + * Check if this remote value is of type binary ID. + * + * @return {@code true} if this remote value is of type binary ID, {@code + * false} otherwise. + */ + public boolean isBinaryId() { + return false; + } + + /** + * Read the value of this remote binary ID multi-value. + * + * @return The value of this remote value if this remote value is of type + * binary ID, {@code null} otherwise. + */ + public String asBinaryId() { + return null; + } + + /** + * Check if this remote value is a multi-value of type binary ID. + * + * @return {@code true} if this remote value is a multi-value of type binary + * ID, {@code false} otherwise. + */ + public boolean isMultiBinaryId() { + return false; + } + + /** + * Return the value of this remote binary ID multi-value. + * + * @return The value of this remote value if this remote value is a + * multi-value of type binary ID, {@code null} otherwise. + */ + public Iterable<String> asMultiBinaryId() { + return null; + } + + /** + * Check if this remote value is of type long. + * + * @return {@code true} if this remote value is of type long, {@code false} + * otherwise. + */ + public boolean isLong() { + return false; + } + + /** + * Read the value of this remote long multi-value. + * + * @return The value of this remote value if this remote value is of type + * long, {@code null} otherwise. + */ + public Long asLong() { + return null; + } + + /** + * Check if this remote value is a multi-value of type long. + * + * @return {@code true} if this value is a multi-value of type long, {@code + * false} otherwise. + */ + public boolean isMultiLong() { + return false; + } + + /** + * Read the value of this remote multi-value of type long. + * + * @return The value of this remote value if this remote value is a + * multi-value of type long, {@code null} otherwise. + */ + public Iterable<Long> asMultiLong() { + return null; + } + + /** + * Check if this remote value is of type double. + * + * @return {@code true} if this remote value is of type long, {@code false} + * otherwise. + */ + public boolean isDouble() { + return false; + } + + /** + * Read the value of this remote value of type double. + * + * @return The value of this remote value if this remote value is of type + * double, {@code null} otherwise. + */ + public Double asDouble() { + return null; + } + + /** + * Check if this remote value is a multi-value of type double. + * + * @return {@code true} if this remote value is a multi-value of type + * double, {@code false} otherwise. + */ + public boolean isMultiDouble() { + return false; + } + + /** + * Read the value of this remote multi-value of type double. + * + * @return The value of this remote value if this remote value is a + * multi-value of type double, {@code null} otherwise. + */ + public Iterable<Double> asMultiDouble() { + return null; + } + + /** + * Check if this remote value is of type date. + * + * @return {@code true} if this remote value is of type date, {@code false} + * otherwise. + */ + public boolean isDate() { + return false; + } + + /** + * Read the value of this remote multi-value of type date. + * + * @return The value of this remote value if this remote value is of type + * date, {@code null} otherwise. + */ + public Long asDate() { + return null; + } + + /** + * Check if this remote value is a multi-value of type date. + * + * @return {@code true} if this remote value is a multi-value of type date, + * {@code false} otherwise. + */ + public boolean isMultiDate() { + return false; + } + + /** + * Read the value of this remote multi-value of type date. + * + * @return The value of this remote value if this remote value is a + * multi-value of type date, {@code null} otherwise. + */ + public Iterable<Long> asMultiDate() { + return null; + } + + /** + * Check if this remote value is of type boolean. + * + * @return {@code true} if this remote value is fo type boolean, {@code + * false} otherwise. + */ + public boolean isBoolean() { + return false; + } + + /** + * Read the value of this remote value of type boolean. + * + * @return The value of this remote value if this remote value is of type + * boolean, false otherwise. + */ + public Boolean asBoolean() { + return null; + } + + /** + * Check if this remote value is a multi-value of type boolean. + * + * @return {@code true} if this remote value is a multi-value of type + * boolean, {@code false} otherwise. + */ + public boolean isMultiBoolean() { + return false; + } + + /** + * Read the value of this remote multi-value of type boolean. + * + * @return The value of this remote value if this remote value is a + * multi-value of type boolean, {@code null} otherwise. + */ + public Iterable<Boolean> asMultiBoolean() { + return null; + } + + /** + * Check if this remote value is of type name. + * + * @return {@code true} if this remote value is of type name, {@code false} + * otherwise. + */ + public boolean isName() { + return false; + } + + /** + * Read the value of this remote value of type name. + * + * @return The value of this remote value if this remote value is of type + * name, {@code null} otherwise. + */ + public String asName() { + return null; + } + + /** + * Check if this remote value is a multi-value of type name. + * + * @return {@code true} if this remote value is a multi-value of type name, + * {@code false} otherwise. + */ + public boolean isMultiName() { + return false; + } + + /** + * Read the value of this remote multi-value of type name. + * + * @return The value of this remote value if this remote value is a + * multi-value of type name, {@code null} otherwise. + */ + public Iterable<String> asMultiName() { + return null; + } + + /** + * Check if this value is of type path. + * + * @return {@code true} if this remote value is of type path, {@code false} + * otherwise. + */ + public boolean isPath() { + return false; + } + + /** + * Read the value of this remote value of type path. + * + * @return The value of this remote value if this remote value is of type + * path, {@code null} otherwise. + */ + public String asPath() { + return null; + } + + /** + * Check if this remote value is a multi-value of type path. + * + * @return {@code true} if this remote value is a multi-value of type path, + * {@code false} otherwise. + */ + public boolean isMultiPath() { + return false; + } + + /** + * Read the value of this remote multi-value of type path. + * + * @return The value of this remote value if this remote value is a + * multi-value of type path, {@code null} otherwise. + */ + public Iterable<String> asMultiPath() { + return null; + } + + /** + * Check if this remote value is of type reference. + * + * @return {@code true} if this remote value is of type reference, {@code + * false} otherwise. + */ + public boolean isReference() { + return false; + } + + /** + * Read the value of this remote value of type reference. + * + * @return The value of this remote value if this remote value is of type + * reference, {@code null} otherwise. + */ + public String asReference() { + return null; + } + + /** + * Check if this remote value is a multi-value of type reference. + * + * @return {@code true} if this remote value is a multi-value of type + * reference, {@code false} otherwise. + */ + public boolean isMultiReference() { + return false; + } + + /** + * Read the value of this remote multi-value of type reference. + * + * @return The value of this remote value if this remote value is a + * multi-value of type reference, {@code null} otherwise. + */ + public Iterable<String> asMultiReference() { + return null; + } + + /** + * Check if this remote value is of type weak reference. + * + * @return {@code true} if this remote value is fo type weak reference, + * {@code false} otherwise. + */ + public boolean isWeakReference() { + return false; + } + + /** + * Read the value of this remote value of type weak reference. + * + * @return The value of this remote value if this remote value is of type + * weak reference, {@code null} otherwise. + */ + public String asWeakReference() { + return null; + } + + /** + * Check if this remote value is a multi-value of type weak reference. + * + * @return {@code true} if this remote value is a multi-value of type weak + * reference, {@code false} otherwise. + */ + public boolean isMultiWeakReference() { + return false; + } + + /** + * Read the value of this remote multi-value of type weak reference. + * + * @return The value of this remote value if this remote value is a + * multi-value of type weak reference, {@code null} otherwise. + */ + public Iterable<String> asMultiWeakReference() { + return null; + } + + /** + * Check if this remote value is of type decimal. + * + * @return {@code true} if this remote value is of type decimal, {@code + * false} otherwise. + */ + public boolean isDecimal() { + return false; + } + + /** + * Read the value of this remote value of type decimal. + * + * @return The value of this remote value if this remote value is of type + * decimal, {@code null} otherwise. + */ + public BigDecimal asDecimal() { + return null; + } + + /** + * Check if this remote value is a multi-value of type decimal. + * + * @return {@code true} if this remote value is a multi-value of type + * decimal, {@code false} otherwise. + */ + public boolean isMultiDecimal() { + return false; + } + + /** + * Read the value of this remote multi-value of type decimal. + * + * @return The value of this remote value if this remote value is a + * multi-value of type decimal, {@code null} otherwise. + */ + public Iterable<BigDecimal> asMultiDecimal() { + return null; + } + + /** + * Check if this remote value is of type URI. + * + * @return {@code true} if this remote value is of type URI, {@code false} + * otherwise. + */ + public boolean isUri() { + return false; + } + + /** + * Read the value of this remote value of type URI. + * + * @return The value of this remote value if this remote value is of type + * URI, {@code null} otherwise. + */ + public String asUri() { + return null; + } + + /** + * Check if this remote value is a multi-value of type URI. + * + * @return {@code true} if this remote value is a multi-value of type URI, + * {@code false} otherwise. + */ + public boolean isMultiUri() { + return false; + } + + /** + * Read the value of this remote multi-value of type URI. + * + * @return The value of this remote value if this remote value is a + * multi-value of type URI, {@code null} otherwise. + */ + public Iterable<String> asMultiUri() { + return null; + } + + /** + * Calls a method of the provided handler according to the type of this + * remote value. + * + * @param handler Handler containing logic to be executing according to the + * type of this remote value. + */ + public void whenType(TypeHandler handler) { + if (isBinary()) { + handler.isBinary(asBinary()); + return; + } + + if (isMultiBinary()) { + handler.isMultiBinary(asMultiBinary()); + return; + } + + if (isBinaryId()) { + handler.isBinaryId(asBinaryId()); + return; + } + + if (isMultiBinaryId()) { + handler.isMultiBinaryId(asMultiBinaryId()); + return; + } + + if (isBoolean()) { + handler.isBoolean(asBoolean()); + return; + } + + if (isMultiBoolean()) { + handler.isMultiBoolean(asMultiBoolean()); + return; + } + + if (isDate()) { + handler.isDate(asDate()); + return; + } + + if (isMultiDate()) { + handler.isMultiDate(asMultiDate()); + return; + } + + if (isDecimal()) { + handler.isDecimal(asDecimal()); + return; + } + + if (isMultiDecimal()) { + handler.isMultiDecimal(asMultiDecimal()); + return; + } + + if (isDouble()) { + handler.isDouble(asDouble()); + return; + } + + if (isMultiDouble()) { + handler.isMultiDouble(asMultiDouble()); + return; + } + + if (isLong()) { + handler.isLong(asLong()); + return; + } + + if (isMultiLong()) { + handler.isMultiLong(asMultiLong()); + return; + } + + if (isName()) { + handler.isName(asName()); + return; + } + + if (isMultiName()) { + handler.isMultiName(asMultiName()); + return; + } + + if (isPath()) { + handler.isPath(asPath()); + return; + } + + if (isMultiPath()) { + handler.isMultiPath(asMultiPath()); + return; + } + + if (isReference()) { + handler.isReference(asReference()); + return; + } + + if (isMultiReference()) { + handler.isMultiReference(asMultiReference()); + return; + } + + if (isText()) { + handler.isText(asText()); + return; + } + + if (isMultiText()) { + handler.isMultiText(asMultiText()); + return; + } + + if (isUri()) { + handler.isUri(asUri()); + return; + } + + if (isMultiUri()) { + handler.isMultiUri(asMultiUri()); + return; + } + + if (isWeakReference()) { + handler.isWeakReference(asWeakReference()); + return; + } + + if (isMultiWeakReference()) { + handler.isMultiWeakReference(asMultiWeakReference()); + return; + } + + handler.isUnknown(); + } + +}
Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/AddContentRemoteOperation.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/AddContentRemoteOperation.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/AddContentRemoteOperation.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/AddContentRemoteOperation.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,55 @@ +/* + * 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.remote.content; + +import org.apache.jackrabbit.oak.api.Root; +import org.apache.jackrabbit.oak.api.Tree; +import org.apache.jackrabbit.oak.remote.RemoteCommitException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class AddContentRemoteOperation implements ContentRemoteOperation { + + private static final Logger logger = LoggerFactory.getLogger(AddContentRemoteOperation.class); + + private final String path; + + public AddContentRemoteOperation(String path) { + this.path = path; + } + + @Override + public void apply(Root root) throws RemoteCommitException { + logger.debug("performing 'add' operation on path={}", path); + + Tree tree = root.getTree(path); + + if (tree.exists()) { + throw new RemoteCommitException("node already exists"); + } + + Tree parent = tree.getParent(); + + if (!parent.exists()) { + throw new RemoteCommitException("parent node does not exist"); + } + + parent.addChild(tree.getName()); + } + +} Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/AggregateContentRemoteOperation.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/AggregateContentRemoteOperation.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/AggregateContentRemoteOperation.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/AggregateContentRemoteOperation.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,40 @@ +/* + * 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.remote.content; + +import org.apache.jackrabbit.oak.api.Root; +import org.apache.jackrabbit.oak.remote.RemoteCommitException; + +import java.util.List; + +class AggregateContentRemoteOperation implements ContentRemoteOperation { + + private final List<ContentRemoteOperation> operations; + + public AggregateContentRemoteOperation(List<ContentRemoteOperation> operations) { + this.operations = operations; + } + + @Override + public void apply(Root root) throws RemoteCommitException { + for (ContentRemoteOperation operation : operations) { + operation.apply(root); + } + } + +} Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/BasicContentRemoteCredentials.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/BasicContentRemoteCredentials.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/BasicContentRemoteCredentials.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/BasicContentRemoteCredentials.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,54 @@ +/* + * 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.remote.content; + +import org.apache.jackrabbit.oak.api.ContentRepository; +import org.apache.jackrabbit.oak.api.ContentSession; +import org.apache.jackrabbit.oak.remote.RemoteLoginException; + +import javax.jcr.NoSuchWorkspaceException; +import javax.jcr.SimpleCredentials; +import javax.security.auth.login.LoginException; + +class BasicContentRemoteCredentials implements ContentRemoteCredentials { + + private final String user; + + private final char[] password; + + public BasicContentRemoteCredentials(String user, char[] password) { + this.user = user; + this.password = password; + } + + @Override + public ContentSession login(ContentRepository repository) throws RemoteLoginException { + ContentSession session; + + try { + session = repository.login(new SimpleCredentials(user, password), null); + } catch (LoginException e) { + throw new RemoteLoginException("unable to login", e); + } catch (NoSuchWorkspaceException e) { + throw new RemoteLoginException("unable to use the default workspace", e); + } + + return session; + } + +} Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteBinaries.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteBinaries.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteBinaries.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteBinaries.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,46 @@ +/* + * 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.remote.content; + +import com.google.common.collect.Maps; +import org.apache.jackrabbit.oak.api.Blob; + +import java.util.Map; +import java.util.UUID; + +class ContentRemoteBinaries { + + private Map<String, Blob> binaries; + + public ContentRemoteBinaries() { + binaries = Maps.newHashMap(); + } + + public String put(Blob blob) { + String binaryId = UUID.randomUUID().toString(); + + binaries.put(binaryId, blob); + + return binaryId; + } + + public Blob get(String binaryId) { + return binaries.get(binaryId); + } + +} Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteBinaryId.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteBinaryId.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteBinaryId.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteBinaryId.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,43 @@ +/* + * 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.remote.content; + +import org.apache.jackrabbit.oak.api.Blob; +import org.apache.jackrabbit.oak.remote.RemoteBinaryId; + +class ContentRemoteBinaryId implements RemoteBinaryId { + + private final String reference; + + private final Blob blob; + + public ContentRemoteBinaryId(String reference, Blob blob) { + this.reference = reference; + this.blob = blob; + } + + public Blob asBlob() { + return blob; + } + + @Override + public String asString() { + return reference; + } + +} Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteCredentials.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteCredentials.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteCredentials.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteCredentials.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,29 @@ +/* + * 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.remote.content; + +import org.apache.jackrabbit.oak.api.ContentRepository; +import org.apache.jackrabbit.oak.api.ContentSession; +import org.apache.jackrabbit.oak.remote.RemoteCredentials; +import org.apache.jackrabbit.oak.remote.RemoteLoginException; + +interface ContentRemoteCredentials extends RemoteCredentials { + + ContentSession login(ContentRepository repository) throws RemoteLoginException; + +} Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteInputStream.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteInputStream.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteInputStream.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteInputStream.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,72 @@ +/* + * 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.remote.content; + +import org.apache.jackrabbit.oak.remote.RemoteBinaryFilters; + +import java.io.IOException; +import java.io.InputStream; + +class ContentRemoteInputStream extends InputStream { + + private final InputStream stream; + + private final long start; + + private final long count; + + private long index = 0; + + public ContentRemoteInputStream(InputStream stream, RemoteBinaryFilters filters) { + this.stream = stream; + + long startFilter = filters.getStart(); + + if (startFilter > 0) { + this.start = startFilter; + } else { + this.start = 0; + } + + this.count = filters.getCount(); + } + + @Override + public int read() throws IOException { + while (index < start - 1) { + long skipped = stream.skip(start - index); + + if (skipped <= 0) { + return -1; + } + + index = index + skipped; + } + + if (count >= 0 && index >= start + count) { + return -1; + } + + int result = stream.read(); + + index = index + 1; + + return result; + } + +} Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteOperation.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteOperation.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteOperation.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteOperation.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,28 @@ +/* + * 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.remote.content; + +import org.apache.jackrabbit.oak.api.Root; +import org.apache.jackrabbit.oak.remote.RemoteCommitException; +import org.apache.jackrabbit.oak.remote.RemoteOperation; + +interface ContentRemoteOperation extends RemoteOperation { + + void apply(Root root) throws RemoteCommitException; + +} Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRepository.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRepository.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRepository.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRepository.java Thu Jun 11 12:09:15 2015 @@ -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.remote.content; + +import org.apache.jackrabbit.oak.Oak; +import org.apache.jackrabbit.oak.api.ContentRepository; +import org.apache.jackrabbit.oak.api.ContentSession; +import org.apache.jackrabbit.oak.remote.RemoteCredentials; +import org.apache.jackrabbit.oak.remote.RemoteLoginException; +import org.apache.jackrabbit.oak.remote.RemoteRepository; +import org.apache.jackrabbit.oak.remote.RemoteSession; + +import java.util.Set; + +public class ContentRemoteRepository implements RemoteRepository { + + private final ContentRepository contentRepository; + + private final ContentRemoteRevisions contentRemoteRevisions; + + private final ContentRemoteBinaries contentRemoteBinaries; + + public ContentRemoteRepository(ContentRepository contentRepository) { + this.contentRemoteRevisions = new ContentRemoteRevisions(); + this.contentRemoteBinaries = new ContentRemoteBinaries(); + this.contentRepository = contentRepository; + } + + @Override + public RemoteCredentials createBasicCredentials(final String user, final char[] password) { + return new BasicContentRemoteCredentials(user, password); + } + + @Override + public RemoteCredentials createImpersonationCredentials(Set<String> principals) { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + public RemoteSession login(RemoteCredentials remoteCredentials) throws RemoteLoginException { + ContentRemoteCredentials contentRemoteCredentials = null; + + if (remoteCredentials instanceof ContentRemoteCredentials) { + contentRemoteCredentials = (ContentRemoteCredentials) remoteCredentials; + } + + if (contentRemoteCredentials == null) { + throw new IllegalArgumentException("invalid credentials"); + } + + Thread thread = Thread.currentThread(); + + ClassLoader loader = thread.getContextClassLoader(); + + thread.setContextClassLoader(Oak.class.getClassLoader()); + + ContentSession session; + + try { + session = contentRemoteCredentials.login(contentRepository); + } finally { + thread.setContextClassLoader(loader); + } + + return new ContentRemoteSession(session, contentRemoteRevisions, contentRemoteBinaries); + } + +} \ No newline at end of file Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteResult.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteResult.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteResult.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteResult.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,154 @@ +/* + * 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.remote.content; + +import org.apache.jackrabbit.oak.api.Blob; +import org.apache.jackrabbit.oak.api.PropertyValue; +import org.apache.jackrabbit.oak.api.ResultRow; +import org.apache.jackrabbit.oak.api.Type; +import org.apache.jackrabbit.oak.remote.RemoteResult; +import org.apache.jackrabbit.oak.remote.RemoteValue; +import org.apache.jackrabbit.util.ISO8601; + +import javax.jcr.PropertyType; +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; + +class ContentRemoteResult implements RemoteResult { + + private final ContentRemoteBinaries binaries; + + private final ResultRow row; + + public ContentRemoteResult(ContentRemoteBinaries binaries, ResultRow row) { + this.binaries = binaries; + this.row = row; + } + + @Override + public RemoteValue getColumnValue(String column) { + return toRemoteValue(row.getValue(column)); + } + + private RemoteValue toRemoteValue(PropertyValue value) { + if (value == null) { + return null; + } + + Type<?> type = value.getType(); + + if (type.isArray()) { + return toMultiRemoteValue(value); + } else { + return toSingleRemoteValue(value); + } + } + + private RemoteValue toSingleRemoteValue(PropertyValue value) { + Type<?> type = value.getType(); + + switch (type.tag()) { + case PropertyType.STRING: + return RemoteValue.toText(value.getValue(Type.STRING)); + case PropertyType.BINARY: + return RemoteValue.toBinaryId(binaries.put(value.getValue(Type.BINARY))); + case PropertyType.LONG: + return RemoteValue.toLong(value.getValue(Type.LONG)); + case PropertyType.DOUBLE: + return RemoteValue.toDouble(value.getValue(Type.DOUBLE)); + case PropertyType.DATE: + return RemoteValue.toDate(ISO8601.parse(value.getValue(Type.DATE)).getTimeInMillis()); + case PropertyType.BOOLEAN: + return RemoteValue.toBoolean(value.getValue(Type.BOOLEAN)); + case PropertyType.NAME: + return RemoteValue.toName(value.getValue(Type.NAME)); + case PropertyType.PATH: + return RemoteValue.toPath(value.getValue(Type.PATH)); + case PropertyType.REFERENCE: + return RemoteValue.toReference(value.getValue(Type.REFERENCE)); + case PropertyType.WEAKREFERENCE: + return RemoteValue.toWeakReference(value.getValue(Type.WEAKREFERENCE)); + case PropertyType.URI: + return RemoteValue.toUri(value.getValue(Type.URI)); + case PropertyType.DECIMAL: + return RemoteValue.toDecimal(value.getValue(Type.DECIMAL)); + } + + throw new IllegalStateException("type not supported"); + } + + private RemoteValue toMultiRemoteValue(PropertyValue value) { + Type<?> type = value.getType(); + + switch (type.tag()) { + case PropertyType.STRING: + return RemoteValue.toMultiText(value.getValue(Type.STRINGS)); + case PropertyType.BINARY: + return RemoteValue.toMultiBinaryId(readBinaryValues(value)); + case PropertyType.LONG: + return RemoteValue.toMultiLong(value.getValue(Type.LONGS)); + case PropertyType.DOUBLE: + return RemoteValue.toMultiDouble(value.getValue(Type.DOUBLES)); + case PropertyType.DATE: + return RemoteValue.toMultiDate(readDateValues(value)); + case PropertyType.BOOLEAN: + return RemoteValue.toMultiBoolean(value.getValue(Type.BOOLEANS)); + case PropertyType.NAME: + return RemoteValue.toMultiName(value.getValue(Type.NAMES)); + case PropertyType.PATH: + return RemoteValue.toMultiPath(value.getValue(Type.PATHS)); + case PropertyType.REFERENCE: + return RemoteValue.toMultiReference(value.getValue(Type.REFERENCES)); + case PropertyType.WEAKREFERENCE: + return RemoteValue.toMultiWeakReference(value.getValue(Type.WEAKREFERENCES)); + case PropertyType.URI: + return RemoteValue.toMultiUri(value.getValue(Type.URIS)); + case PropertyType.DECIMAL: + return RemoteValue.toMultiDecimal(value.getValue(Type.DECIMALS)); + } + + throw new IllegalStateException("type not supported"); + } + + private Iterable<String> readBinaryValues(PropertyValue value) { + List<String> result = newArrayList(); + + for (Blob blob : value.getValue(Type.BINARIES)) { + result.add(binaries.put(blob)); + } + + return result; + } + + private Iterable<Long> readDateValues(PropertyValue value) { + List<Long> result = newArrayList(); + + for (String string : value.getValue(Type.DATES)) { + result.add(ISO8601.parse(string).getTimeInMillis()); + } + + return result; + } + + @Override + public String getSelectorPath(String selector) { + return row.getPath(selector); + } + +} Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteResults.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteResults.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteResults.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteResults.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,72 @@ +/* + * 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.remote.content; + +import org.apache.jackrabbit.oak.api.Result; +import org.apache.jackrabbit.oak.api.ResultRow; +import org.apache.jackrabbit.oak.remote.RemoteResult; +import org.apache.jackrabbit.oak.remote.RemoteResults; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; + +class ContentRemoteResults implements RemoteResults { + + private final ContentRemoteBinaries binaries; + + private final Result results; + + public ContentRemoteResults(ContentRemoteBinaries binaries, Result results) { + this.binaries = binaries; + this.results = results; + } + + @Override + public long getTotal() { + return results.getSize(); + } + + @Override + public Iterable<String> getColumns() { + return Arrays.asList(results.getColumnNames()); + } + + @Override + public Iterable<String> getSelectors() { + return Arrays.asList(results.getSelectorNames()); + } + + @Override + public Iterator<RemoteResult> iterator() { + return getResults().iterator(); + } + + private Iterable<RemoteResult> getResults() { + List<RemoteResult> results = newArrayList(); + + for (ResultRow row : this.results.getRows()) { + results.add(new ContentRemoteResult(binaries, row)); + } + + return results; + } + +} Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRevision.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRevision.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRevision.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRevision.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,43 @@ +/* + * 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.remote.content; + +import org.apache.jackrabbit.oak.api.Root; +import org.apache.jackrabbit.oak.remote.RemoteRevision; + +class ContentRemoteRevision implements RemoteRevision { + + private final String id; + + private final Root root; + + public ContentRemoteRevision(String id, Root root) { + this.id = id; + this.root = root; + } + + @Override + public String asString() { + return id; + } + + public Root getRoot() { + return root; + } + +} Added: jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRevisions.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRevisions.java?rev=1684861&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRevisions.java (added) +++ jackrabbit/oak/trunk/oak-remote/src/main/java/org/apache/jackrabbit/oak/remote/content/ContentRemoteRevisions.java Thu Jun 11 12:09:15 2015 @@ -0,0 +1,106 @@ +/* + * 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.remote.content; + +import com.google.common.base.Objects; +import com.google.common.collect.Maps; +import org.apache.jackrabbit.oak.api.AuthInfo; +import org.apache.jackrabbit.oak.api.Root; + +import java.security.Principal; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +class ContentRemoteRevisions { + + private class Key { + + private final String revisionId; + + private final Set<Principal> principals; + + private final String user; + + private Key(AuthInfo authInfo, String revisionId) { + this.user = authInfo.getUserID(); + this.principals = authInfo.getPrincipals(); + this.revisionId = revisionId; + } + + @Override + public boolean equals(Object object) { + if (object == null) { + return false; + } + + if (object == this) { + return true; + } + + if (getClass() != object.getClass()) { + return false; + } + + Key other = (Key) object; + + if (!Objects.equal(revisionId, other.revisionId)) { + return false; + } + + if (!Objects.equal(user, other.user)) { + return false; + } + + if (!Objects.equal(principals, other.principals)) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + return Objects.hashCode(revisionId, user, principals); + } + + } + + private Map<Key, Root> roots; + + public ContentRemoteRevisions() { + this.roots = Maps.newHashMap(); + } + + private Key key(AuthInfo authInfo, String revisionId) { + return new Key(authInfo, revisionId); + } + + public Root get(AuthInfo authInfo, String revisionId) { + return roots.get(key(authInfo, revisionId)); + } + + public String put(AuthInfo authInfo, Root root) { + String revisionId = UUID.randomUUID().toString(); + + roots.put(key(authInfo, revisionId), root); + + return revisionId; + } + +}
