
org.apache.jackrabbit.oak.remote.content.ContentRemoteTree Maven / Gradle / Ivy
The newest version!
/*
* 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.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.remote.RemoteTree;
import org.apache.jackrabbit.oak.remote.RemoteTreeFilters;
import org.apache.jackrabbit.oak.remote.RemoteValue;
import org.apache.jackrabbit.oak.remote.RemoteValue.Supplier;
import org.apache.jackrabbit.oak.remote.filter.Filters;
import org.apache.jackrabbit.util.ISO8601;
import java.io.InputStream;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
class ContentRemoteTree implements RemoteTree {
private final Tree tree;
private final int depth;
private final RemoteTreeFilters filters;
private final ContentRemoteBinaries contentRemoteBinaries;
public ContentRemoteTree(Tree tree, int depth, RemoteTreeFilters filters, ContentRemoteBinaries contentRemoteBinaries) {
this.tree = tree;
this.depth = depth;
this.filters = filters;
this.contentRemoteBinaries = contentRemoteBinaries;
}
@Override
public Map getProperties() {
Map properties = new HashMap();
for (PropertyState property : getFilteredProperties()) {
properties.put(property.getName(), getRemoteValue(property));
}
return properties;
}
private Iterable extends PropertyState> getFilteredProperties() {
return Iterables.filter(tree.getProperties(), getPropertyFilters());
}
private Predicate super PropertyState> getPropertyFilters() {
return new Predicate() {
@Override
public boolean apply(PropertyState property) {
return new Filters(filters.getPropertyFilters()).matches(property.getName());
}
};
}
private RemoteValue getRemoteValue(PropertyState property) {
Type> type = property.getType();
if (type == Type.DATE) {
return RemoteValue.toDate(getDate(property.getValue(Type.DATE)));
}
if (type == Type.DATES) {
return RemoteValue.toMultiDate(getDates(property.getValue(Type.DATES)));
}
if (type == Type.BINARY) {
return getBinaryRemoteValue(property.getValue(Type.BINARY));
}
if (type == Type.BINARIES) {
return getBinaryRemoteValues(property.getValue(Type.BINARIES));
}
if (type == Type.BOOLEAN) {
return RemoteValue.toBoolean(property.getValue(Type.BOOLEAN));
}
if (type == Type.BOOLEANS) {
return RemoteValue.toMultiBoolean(property.getValue(Type.BOOLEANS));
}
if (type == Type.DECIMAL) {
return RemoteValue.toDecimal(property.getValue(Type.DECIMAL));
}
if (type == Type.DECIMALS) {
return RemoteValue.toMultiDecimal(property.getValue(Type.DECIMALS));
}
if (type == Type.DOUBLE) {
return RemoteValue.toDouble(property.getValue(Type.DOUBLE));
}
if (type == Type.DOUBLES) {
return RemoteValue.toMultiDouble(property.getValue(Type.DOUBLES));
}
if (type == Type.LONG) {
return RemoteValue.toLong(property.getValue(Type.LONG));
}
if (type == Type.LONGS) {
return RemoteValue.toMultiLong(property.getValue(Type.LONGS));
}
if (type == Type.NAME) {
return RemoteValue.toName(property.getValue(Type.NAME));
}
if (type == Type.NAMES) {
return RemoteValue.toMultiName(property.getValue(Type.NAMES));
}
if (type == Type.PATH) {
return RemoteValue.toPath(property.getValue(Type.PATH));
}
if (type == Type.PATHS) {
return RemoteValue.toMultiPath(property.getValue(Type.PATHS));
}
if (type == Type.REFERENCE) {
return RemoteValue.toReference(property.getValue(Type.REFERENCE));
}
if (type == Type.REFERENCES) {
return RemoteValue.toMultiReference(property.getValue(Type.REFERENCES));
}
if (type == Type.STRING) {
return RemoteValue.toText(property.getValue(Type.STRING));
}
if (type == Type.STRINGS) {
return RemoteValue.toMultiText(property.getValue(Type.STRINGS));
}
if (type == Type.URI) {
return RemoteValue.toUri(property.getValue(Type.URI));
}
if (type == Type.URIS) {
return RemoteValue.toMultiUri(property.getValue(Type.URIS));
}
if (type == Type.WEAKREFERENCE) {
return RemoteValue.toWeakReference(property.getValue(Type.WEAKREFERENCE));
}
if (type == Type.WEAKREFERENCES) {
return RemoteValue.toMultiWeakReference(property.getValue(Type.WEAKREFERENCES));
}
throw new IllegalArgumentException("unrecognized property type");
}
private long getDate(String date) {
Calendar calendar = ISO8601.parse(date);
if (calendar == null) {
throw new IllegalStateException("invalid date format");
}
return calendar.getTimeInMillis();
}
private Iterable getDates(Iterable dates) {
return Iterables.transform(dates, new Function() {
@Override
public Long apply(String date) {
return getDate(date);
}
});
}
private RemoteValue getBinaryRemoteValue(Blob blob) {
if (getLength(blob) < filters.getBinaryThreshold()) {
return RemoteValue.toBinary(getBinary(blob));
} else {
return RemoteValue.toBinaryId(getBinaryId(blob));
}
}
private RemoteValue getBinaryRemoteValues(Iterable blobs) {
if (getLength(blobs) < filters.getBinaryThreshold()) {
return RemoteValue.toMultiBinary(getBinaries(blobs));
} else {
return RemoteValue.toMultiBinaryId(getBinaryIds(blobs));
}
}
private long getLength(Blob blob) {
return blob.length();
}
private long getLength(Iterable blobs) {
long length = 0;
for (Blob blob : blobs) {
length = length + blob.length();
}
return length;
}
private Supplier getBinary(final Blob blob) {
return new Supplier() {
@Override
public InputStream get() {
return blob.getNewStream();
}
};
}
private Iterable> getBinaries(Iterable blobs) {
return Iterables.transform(blobs, new Function>() {
@Override
public Supplier apply(Blob blob) {
return getBinary(blob);
}
});
}
private String getBinaryId(Blob blob) {
return contentRemoteBinaries.put(blob);
}
private Iterable getBinaryIds(Iterable blobs) {
return Iterables.transform(blobs, new Function() {
@Override
public String apply(Blob blob) {
return getBinaryId(blob);
}
});
}
@Override
public Map getChildren() {
Map children = new HashMap();
for (Tree child : getFilteredChildren()) {
if (depth < filters.getDepth()) {
children.put(child.getName(), new ContentRemoteTree(child, depth + 1, filters, contentRemoteBinaries));
} else {
children.put(child.getName(), null);
}
}
return children;
}
private Iterable getFilteredChildren() {
Iterable result = tree.getChildren();
if (filters.getChildrenStart() > 0) {
result = Iterables.skip(result, filters.getChildrenStart());
}
if (filters.getChildrenCount() >= 0) {
result = Iterables.limit(result, filters.getChildrenCount());
}
return Iterables.filter(result, getNodeFilters());
}
private Predicate getNodeFilters() {
return new Predicate() {
@Override
public boolean apply(Tree child) {
return new Filters(filters.getNodeFilters()).matches(child.getName());
}
};
}
@Override
public boolean hasMoreChildren() {
if (filters.getChildrenCount() < 0) {
return false;
}
int start = filters.getChildrenStart();
if (start < 0) {
start = 0;
}
int count = filters.getChildrenCount();
if (count < 0) {
count = 0;
}
int max = start + count;
return tree.getChildrenCount(max) > max;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy