Author: jsedding
Date: Mon Nov 30 14:14:52 2015
New Revision: 1717258
URL: http://svn.apache.org/viewvc?rev=1717258&view=rev
Log:
OAK-3111 - Enforce check for max node name length
- original patch from Tomek Rękawek
Added:
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/AbstractDecoratedNodeState.java
(with props)
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NameFilteringNodeState.java
(with props)
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeState.java
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeState.java
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporterTest.java
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeStateTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java?rev=1717258&r1=1717257&r2=1717258&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
Mon Nov 30 14:14:52 2015
@@ -84,7 +84,7 @@ public class Utils {
/**
* The maximum size a node name, in bytes. This is only a problem for long
path.
*/
- private static final int NODE_NAME_LIMIT =
Integer.getInteger("oak.nodeNameLimit", 150);
+ public static final int NODE_NAME_LIMIT =
Integer.getInteger("oak.nodeNameLimit", 150);
private static final Charset UTF_8 = Charset.forName("UTF-8");
Modified:
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java?rev=1717258&r1=1717257&r2=1717258&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
(original)
+++
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
Mon Nov 30 14:14:52 2015
@@ -35,6 +35,7 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import
org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade.LoggingCompositeHook;
+import org.apache.jackrabbit.oak.upgrade.nodestate.NameFilteringNodeState;
import org.apache.jackrabbit.oak.upgrade.nodestate.report.LoggingReporter;
import org.apache.jackrabbit.oak.upgrade.nodestate.report.ReportingNodeState;
import org.apache.jackrabbit.oak.upgrade.nodestate.NodeStateCopier;
@@ -79,6 +80,8 @@ public class RepositorySidegrade {
*/
private Set<String> mergePaths = DEFAULT_MERGE_PATHS;
+ private boolean skipLongNames = true;
+
private List<CommitHook> customCommitHooks = null;
VersionCopyConfiguration versionCopyConfiguration = new
VersionCopyConfiguration();
@@ -182,6 +185,14 @@ public class RepositorySidegrade {
this.mergePaths = copyOf(checkNotNull(merges));
}
+ public boolean isSkipLongNames() {
+ return skipLongNames;
+ }
+
+ public void setSkipLongNames(boolean skipLongNames) {
+ this.skipLongNames = skipLongNames;
+ }
+
/**
* Same as {@link #copy(RepositoryInitializer)}, but with no custom
initializer.
*/
@@ -205,7 +216,6 @@ public class RepositorySidegrade {
*/
public void copy(RepositoryInitializer initializer) throws
RepositoryException {
try {
- NodeState sourceRoot = source.getRoot();
NodeBuilder targetRoot = target.getRoot().builder();
new InitialContent().initialize(targetRoot);
@@ -213,10 +223,14 @@ public class RepositorySidegrade {
initializer.initialize(targetRoot);
}
- copyState(
- ReportingNodeState.wrap(sourceRoot, new
LoggingReporter(LOG, "Copying", 10000, -1)),
- targetRoot
- );
+ final NodeState reportingSourceRoot =
ReportingNodeState.wrap(source.getRoot(), new LoggingReporter(LOG, "Copying",
10000, -1));
+ final NodeState sourceRoot;
+ if (skipLongNames) {
+ sourceRoot = NameFilteringNodeState.wrap(reportingSourceRoot);
+ } else {
+ sourceRoot = reportingSourceRoot;
+ }
+ copyState(sourceRoot, targetRoot);
} catch (Exception e) {
throw new RepositoryException("Failed to copy content", e);
Modified:
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java?rev=1717258&r1=1717257&r2=1717258&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
(original)
+++
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
Mon Nov 30 14:14:52 2015
@@ -108,6 +108,7 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.upgrade.nodestate.NameFilteringNodeState;
import org.apache.jackrabbit.oak.upgrade.nodestate.report.LoggingReporter;
import org.apache.jackrabbit.oak.upgrade.nodestate.report.ReportingNodeState;
import org.apache.jackrabbit.oak.upgrade.nodestate.NodeStateCopier;
@@ -175,6 +176,8 @@ public class RepositoryUpgrade {
private List<CommitHook> customCommitHooks = null;
+ private boolean skipLongNames = true;
+
VersionCopyConfiguration versionCopyConfiguration = new
VersionCopyConfiguration();
/**
@@ -245,6 +248,14 @@ public class RepositoryUpgrade {
this.earlyShutdown = earlyShutdown;
}
+ public boolean isSkipLongNames() {
+ return skipLongNames;
+ }
+
+ public void setSkipLongNames(boolean skipLongNames) {
+ this.skipLongNames = skipLongNames;
+ }
+
/**
* Returns the list of custom CommitHooks to be applied before the final
* type validation, reference and indexing hooks.
@@ -407,13 +418,19 @@ public class RepositoryUpgrade {
new TypeEditorProvider(false).getRootEditor(
targetBuilder.getBaseState(),
targetBuilder.getNodeState(), targetBuilder, null);
- final NodeState sourceRoot = ReportingNodeState.wrap(
+ final NodeState reportingSourceRoot = ReportingNodeState.wrap(
JackrabbitNodeState.createRootNodeState(
source, workspaceName,
targetBuilder.getNodeState(),
uriToPrefix, copyBinariesByReference, skipOnError
),
new LoggingReporter(logger, "Migrating", 10000, -1)
);
+ final NodeState sourceRoot;
+ if (skipLongNames) {
+ sourceRoot = NameFilteringNodeState.wrap(reportingSourceRoot);
+ } else {
+ sourceRoot = reportingSourceRoot;
+ }
final Stopwatch watch = Stopwatch.createStarted();
Added:
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/AbstractDecoratedNodeState.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/AbstractDecoratedNodeState.java?rev=1717258&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/AbstractDecoratedNodeState.java
(added)
+++
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/AbstractDecoratedNodeState.java
Mon Nov 30 14:14:52 2015
@@ -0,0 +1,225 @@
+package org.apache.jackrabbit.oak.upgrade.nodestate;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import org.apache.jackrabbit.oak.plugins.tree.impl.TreeConstants;
+import org.apache.jackrabbit.oak.spi.state.AbstractNodeState;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
+import org.apache.jackrabbit.oak.spi.state.ReadOnlyBuilder;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import static com.google.common.base.Predicates.notNull;
+import static
org.apache.jackrabbit.oak.plugins.tree.impl.TreeConstants.OAK_CHILD_ORDER;
+
+public abstract class AbstractDecoratedNodeState extends AbstractNodeState {
+
+ protected final NodeState delegate;
+
+ protected AbstractDecoratedNodeState(@Nonnull final NodeState delegate) {
+ this.delegate = delegate;
+ }
+
+ protected boolean hideChild(@Nonnull final String name, @Nonnull final
NodeState delegateChild) {
+ return false;
+ }
+
+ @Nonnull
+ protected abstract NodeState decorateChild(@Nonnull final String name,
@Nonnull final NodeState delegateChild);
+
+ @Nonnull
+ private NodeState decorate(@Nonnull final String name, @Nonnull final
NodeState child) {
+ return hideChild(name, child) ? EmptyNodeState.MISSING_NODE :
decorateChild(name, child);
+ }
+
+ protected boolean hideProperty(@Nonnull final String name) {
+ return false;
+ }
+
+ @CheckForNull
+ protected abstract PropertyState decorateProperty(@Nonnull final
PropertyState delegatePropertyState);
+
+ @CheckForNull
+ private PropertyState decorate(@Nullable final PropertyState property) {
+ return property == null || hideProperty(property.getName()) ? null :
decorateProperty(property);
+ }
+
+ /**
+ * Convenience method to help implementations that hide nodes set the
+ * :childOrder (OAK_CHILD_ORDER) property to its correct value.
+ * <br>
+ * Intended to be used to implement {@link
#decorateProperty(PropertyState)}.
+ *
+ * @param nodeState The current node state.
+ * @param propertyState The property that chould be checked.
+ * @return The original propertyState, unless the property is called
{@code :childOrder}.
+ */
+ protected static PropertyState fixChildOrderPropertyState(NodeState
nodeState, PropertyState propertyState) {
+ if (propertyState != null &&
OAK_CHILD_ORDER.equals(propertyState.getName())) {
+ final Collection<String> childNodeNames = new ArrayList<String>();
+ Iterables.addAll(childNodeNames, nodeState.getChildNodeNames());
+ final Iterable<String> values = Iterables.filter(
+ propertyState.getValue(Type.NAMES),
Predicates.in(childNodeNames));
+ return PropertyStates.createProperty(OAK_CHILD_ORDER, values,
Type.NAMES);
+ }
+ return propertyState;
+ }
+
+ /**
+ * The AbstractDecoratedNodeState implementation returns a
ReadOnlyBuilder, which
+ * will fail for any mutable operation.
+ *
+ * This method can be overridden to return a different NodeBuilder
implementation.
+ *
+ * @return a NodeBuilder instance corresponding to this NodeState.
+ */
+ @Override
+ @Nonnull
+ public NodeBuilder builder() {
+ return new ReadOnlyBuilder(this);
+ }
+
+ @Override
+ public boolean exists() {
+ return delegate.exists();
+ }
+
+ @Override
+ public boolean hasChildNode(@Nonnull final String name) {
+ return getChildNode(name).exists();
+ }
+
+ @Override
+ @Nonnull
+ public NodeState getChildNode(@Nonnull final String name) throws
IllegalArgumentException {
+ return decorate(name, delegate.getChildNode(name));
+ }
+
+ @Override
+ @Nonnull
+ public Iterable<? extends ChildNodeEntry> getChildNodeEntries() {
+ final Iterable<ChildNodeEntry> transformed = Iterables.transform(
+ delegate.getChildNodeEntries(),
+ new Function<ChildNodeEntry, ChildNodeEntry>() {
+ @Nullable
+ @Override
+ public ChildNodeEntry apply(@Nullable final ChildNodeEntry
childNodeEntry) {
+ if (childNodeEntry != null) {
+ final String name = childNodeEntry.getName();
+ final NodeState nodeState = decorate(name,
childNodeEntry.getNodeState());
+ if (nodeState.exists()) {
+ return new MemoryChildNodeEntry(name,
nodeState);
+ }
+ }
+ return null;
+ }
+ }
+ );
+ return Iterables.filter(transformed, notNull());
+ }
+
+ @Override
+ @CheckForNull
+ public PropertyState getProperty(@Nonnull String name) {
+ return decorate(delegate.getProperty(name));
+ }
+
+ @Override
+ @Nonnull
+ public Iterable<? extends PropertyState> getProperties() {
+ final Iterable<PropertyState> propertyStates = Iterables.transform(
+ delegate.getProperties(),
+ new Function<PropertyState, PropertyState>() {
+ @Override
+ @CheckForNull
+ public PropertyState apply(@Nullable final PropertyState
propertyState) {
+ return decorate(propertyState);
+ }
+ }
+ );
+ return Iterables.filter(propertyStates, notNull());
+ }
+
+ /**
+ * Note that any implementation-specific optimizations of wrapped
NodeStates
+ * will not work if a AbstractDecoratedNodeState is passed into their
{@code #equals()}
+ * method. This implementation will compare the wrapped NodeState,
however. So
+ * optimizations work when calling {@code #equals()} on a
ReportingNodeState.
+ *
+ * @param other Object to compare with this NodeState.
+ * @return true if the given object is equal to this NodeState, false
otherwise.
+ */
+ @Override
+ public boolean equals(final Object other) {
+ if (other == null) {
+ return false;
+ }
+
+ if (this.getClass() == other.getClass()) {
+ final AbstractDecoratedNodeState o = (AbstractDecoratedNodeState)
other;
+ return delegate.equals(o.delegate);
+ }
+
+ return delegate.equals(other);
+ }
+
+ @Override
+ public boolean compareAgainstBaseState(final NodeState base, final
NodeStateDiff diff) {
+ return AbstractNodeState.compareAgainstBaseState(this, base, new
DecoratingDiff(diff, this));
+ }
+
+ private static class DecoratingDiff implements NodeStateDiff {
+
+ private final NodeStateDiff diff;
+
+ private AbstractDecoratedNodeState nodeState;
+
+ private DecoratingDiff(final NodeStateDiff diff, final
AbstractDecoratedNodeState nodeState) {
+ this.diff = diff;
+ this.nodeState = nodeState;
+ }
+
+ @Override
+ public boolean childNodeAdded(final String name, final NodeState
after) {
+ return diff.childNodeAdded(name, nodeState.decorate(name, after));
+ }
+
+ @Override
+ public boolean childNodeChanged(final String name, final NodeState
before, final NodeState after) {
+ return diff.childNodeChanged(name, before,
nodeState.decorate(name, after));
+ }
+
+ @Override
+ public boolean childNodeDeleted(final String name, final NodeState
before) {
+ return diff.childNodeDeleted(name, before);
+ }
+
+ @Override
+ public boolean propertyAdded(final PropertyState after) {
+ return diff.propertyAdded(nodeState.decorate(after));
+ }
+
+ @Override
+ public boolean propertyChanged(final PropertyState before, final
PropertyState after) {
+ return diff.propertyChanged(nodeState.decorate(before),
nodeState.decorate(after));
+ }
+
+ @Override
+ public boolean propertyDeleted(final PropertyState before) {
+ return diff.propertyDeleted(nodeState.decorate(before));
+ }
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/AbstractDecoratedNodeState.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeState.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeState.java?rev=1717258&r1=1717257&r2=1717258&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeState.java
(original)
+++
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeState.java
Mon Nov 30 14:14:52 2015
@@ -16,28 +16,15 @@
*/
package org.apache.jackrabbit.oak.upgrade.nodestate;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
-import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder;
-import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
-import org.apache.jackrabbit.oak.spi.state.AbstractNodeState;
-import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
-import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Set;
-import static
org.apache.jackrabbit.oak.plugins.tree.impl.TreeConstants.OAK_CHILD_ORDER;
-
/**
* NodeState implementation that decorates another node-state instance
* in order to hide subtrees or partial subtrees from the consumer of
@@ -68,14 +55,12 @@ import static org.apache.jackrabbit.oak.
* <li>{@link #getProperty(String)}</li>
* </ul>
*/
-public class FilteringNodeState extends AbstractNodeState {
+public class FilteringNodeState extends AbstractDecoratedNodeState {
public static final Set<String> ALL = ImmutableSet.of("/");
public static final Set<String> NONE = ImmutableSet.of();
- private final NodeState delegate;
-
private final String path;
private final Set<String> includedPaths;
@@ -114,116 +99,27 @@ public class FilteringNodeState extends
@Nonnull final Set<String> includedPaths,
@Nonnull final Set<String> excludedPaths
) {
+ super(delegate);
this.path = path;
- this.delegate = delegate;
this.includedPaths = includedPaths;
this.excludedPaths = excludedPaths;
}
- @Override
@Nonnull
- public NodeBuilder builder() {
- return new MemoryNodeBuilder(this);
- }
-
- @Override
- public boolean exists() {
- return !isHidden(path, includedPaths, excludedPaths) &&
delegate.exists();
- }
-
@Override
- @Nonnull
- public NodeState getChildNode(@Nonnull final String name) throws
IllegalArgumentException {
+ protected NodeState decorateChild(@Nonnull final String name, @Nonnull
final NodeState child) {
final String childPath = PathUtils.concat(path, name);
- return wrap(childPath, delegate.getChildNode(name), includedPaths,
excludedPaths);
- }
-
- @Override
- public boolean hasChildNode(@Nonnull final String name) {
- final String childPath = PathUtils.concat(path, name);
- return !isHidden(childPath, includedPaths, excludedPaths) &&
delegate.hasChildNode(name);
- }
-
- @Override
- @Nonnull
- public Iterable<? extends ChildNodeEntry> getChildNodeEntries() {
- final Iterable<ChildNodeEntry> transformed = Iterables.transform(
- delegate.getChildNodeEntries(),
- new Function<ChildNodeEntry, ChildNodeEntry>() {
- @Nullable
- @Override
- public ChildNodeEntry apply(@Nullable final ChildNodeEntry
childNodeEntry) {
- if (childNodeEntry != null) {
- final String name = childNodeEntry.getName();
- final String childPath = PathUtils.concat(path,
name);
- if (!isHidden(childPath, includedPaths,
excludedPaths)) {
- final NodeState nodeState =
childNodeEntry.getNodeState();
- final NodeState state = wrap(childPath,
nodeState, includedPaths, excludedPaths);
- return new MemoryChildNodeEntry(name, state);
- }
- }
- return null;
- }
- }
- );
- return Iterables.filter(transformed, new Predicate<ChildNodeEntry>() {
- @Override
- public boolean apply(@Nullable final ChildNodeEntry
childNodeEntry) {
- return childNodeEntry != null;
- }
- });
- }
-
- @Override
- public long getPropertyCount() {
- return delegate.getPropertyCount();
+ return wrap(childPath, child, includedPaths, excludedPaths);
}
@Override
- @Nonnull
- public Iterable<? extends PropertyState> getProperties() {
- return Iterables.transform(delegate.getProperties(), new
Function<PropertyState, PropertyState>() {
- @Nullable
- @Override
- public PropertyState apply(@Nullable final PropertyState
propertyState) {
- return fixChildOrderPropertyState(propertyState);
- }
- });
+ protected boolean hideChild(@Nonnull final String name, @Nonnull final
NodeState delegateChild) {
+ return isHidden(PathUtils.concat(path, name), includedPaths,
excludedPaths);
}
@Override
- public PropertyState getProperty(String name) {
- return fixChildOrderPropertyState(delegate.getProperty(name));
- }
-
- @Override
- public boolean hasProperty(String name) {
- return delegate.getProperty(name) != null;
- }
-
- /**
- * Utility method to fix the PropertyState of properties called {@code
:childOrder}.
- *
- * @param propertyState A property-state.
- * @return The original property-state or if the property name is {@code
:childOrder}, a
- * property-state with hidden child names removed from the value.
- */
- @CheckForNull
- private PropertyState fixChildOrderPropertyState(@Nullable final
PropertyState propertyState) {
- if (propertyState != null &&
OAK_CHILD_ORDER.equals(propertyState.getName())) {
- final Iterable<String> values =
Iterables.filter(propertyState.getValue(Type.NAMES), new Predicate<String>() {
- @Override
- public boolean apply(@Nullable final String name) {
- if (name == null) {
- return false;
- }
- final String childPath = PathUtils.concat(path, name);
- return !isHidden(childPath, includedPaths, excludedPaths);
- }
- });
- return PropertyStates.createProperty(OAK_CHILD_ORDER, values,
Type.NAMES);
- }
- return propertyState;
+ protected PropertyState decorateProperty(@Nonnull final PropertyState
propertyState) {
+ return fixChildOrderPropertyState(this, propertyState);
}
/**
@@ -235,7 +131,7 @@ public class FilteringNodeState extends
* @param excludes Exclude paths
* @return Whether the {@code path} is hidden or not.
*/
- public static boolean isHidden(
+ private static boolean isHidden(
@Nonnull final String path,
@Nonnull final Set<String> includes,
@Nonnull final Set<String> excludes
Added:
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NameFilteringNodeState.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NameFilteringNodeState.java?rev=1717258&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NameFilteringNodeState.java
(added)
+++
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NameFilteringNodeState.java
Mon Nov 30 14:14:52 2015
@@ -0,0 +1,64 @@
+package org.apache.jackrabbit.oak.upgrade.nodestate;
+
+import com.google.common.base.Charsets;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.plugins.document.util.Utils;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+
+public class NameFilteringNodeState extends AbstractDecoratedNodeState {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(NameFilteringNodeState.class);
+
+ private static final int NODE_NAME_LIMIT = 150;
+ /**
+ * Max character size in bytes in UTF8 = 4. Therefore if the number of
characters is smaller
+ * than NODE_NAME_LIMIT / 4 we don't need to count bytes.
+ */
+ private static final int SAFE_NODE_NAME_LENGTH = NODE_NAME_LIMIT / 4;
+
+ public static NodeState wrap(final NodeState delegate) {
+ return new NameFilteringNodeState(delegate);
+ }
+
+ private NameFilteringNodeState(final NodeState delegate) {
+ super(delegate);
+ }
+
+ @Override
+ protected boolean hideChild(@Nonnull final String name, @Nonnull final
NodeState delegateChild) {
+ if (isNameTooLong(name)) {
+ LOG.warn("Node name '{}' too long. Skipping child of {}", name,
this);
+ return true;
+ }
+ return super.hideChild(name, delegateChild);
+ }
+
+ @Override
+ @Nonnull
+ protected NodeState decorateChild(@Nonnull final String name, @Nonnull
final NodeState delegateChild) {
+ return wrap(delegateChild);
+ }
+
+ @Override
+ protected PropertyState decorateProperty(@Nonnull final PropertyState
delegatePropertyState) {
+ return fixChildOrderPropertyState(this, delegatePropertyState);
+ }
+
+ /**
+ * This method checks whether the name is no longer than the maximum node
+ * name length supported by the DocumentNodeStore.
+ *
+ * @param name
+ * to check
+ * @return true if the name is longer than {@link Utils#NODE_NAME_LIMIT}
+ */
+ private static boolean isNameTooLong(@Nonnull String name) {
+ // OAK-1589: maximum supported length of name for DocumentNodeStore
+ // is 150 bytes. Skip the sub tree if the the name is too long
+ return name.length() > SAFE_NODE_NAME_LENGTH &&
name.getBytes(Charsets.UTF_8).length > NODE_NAME_LIMIT;
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NameFilteringNodeState.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java?rev=1717258&r1=1717257&r2=1717258&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java
(original)
+++
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java
Mon Nov 30 14:14:52 2015
@@ -16,7 +16,6 @@
*/
package org.apache.jackrabbit.oak.upgrade.nodestate;
-import com.google.common.base.Charsets;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.commons.PathUtils;
@@ -187,12 +186,6 @@ public class NodeStateCopier {
for (ChildNodeEntry child : source.getChildNodeEntries()) {
final String childName = child.getName();
- // OAK-1589: maximum supported length of name for DocumentNodeStore
- // is 150 bytes. Skip the sub tree if the the name is too long
- if (childName.length() > 37 &&
childName.getBytes(Charsets.UTF_8).length > 150) {
- LOG.warn("Node name too long. Skipping {}", source);
- continue;
- }
final NodeState childSource = child.getNodeState();
if (!target.hasChildNode(childName)) {
// add new children
Modified:
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeState.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeState.java?rev=1717258&r1=1717257&r2=1717258&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeState.java
(original)
+++
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeState.java
Mon Nov 30 14:14:52 2015
@@ -18,16 +18,10 @@
*/
package org.apache.jackrabbit.oak.upgrade.nodestate.report;
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
-import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
-import org.apache.jackrabbit.oak.spi.state.ReadOnlyBuilder;
+import org.apache.jackrabbit.oak.upgrade.nodestate.AbstractDecoratedNodeState;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -52,10 +46,9 @@ import javax.annotation.Nullable;
*
* @see Reporter, PeriodicReporter, LoggingReporter
*/
-public class ReportingNodeState implements NodeState {
+public class ReportingNodeState extends AbstractDecoratedNodeState {
private final ReportingNodeState parent;
- private final NodeState delegate;
private final String name;
private final Reporter reporter;
@@ -81,13 +74,9 @@ public class ReportingNodeState implemen
return nodeState;
}
- protected NodeState wrapChild(String name, NodeState delegate) {
- return wrapAndReport(this, name, delegate, this.reporter);
- }
-
private ReportingNodeState(ReportingNodeState parent, String name,
NodeState delegate, Reporter reporter) {
+ super(delegate);
this.parent = parent;
- this.delegate = delegate;
this.name = name;
this.reporter = reporter;
}
@@ -104,203 +93,24 @@ public class ReportingNodeState implemen
if (parent == null) {
return name;
}
- return PathUtils.concat(parent.getPath(), name);
+ return PathUtils.concat(this.parent.getPath(), name);
}
- /**
- * The ReportingNodeState implementation returns a ReadOnlyBuilder, which
- * will fail for any mutable operation.
- *
- * @return a NodeBuilder instance corresponding to this NodeState.
- */
- @Override
@Nonnull
- public NodeBuilder builder() {
- return new ReadOnlyBuilder(this);
- }
-
- @Override
- public boolean compareAgainstBaseState(final NodeState base, final
NodeStateDiff diff) {
- return delegate.compareAgainstBaseState(base, new ReportingDiff(diff,
this));
- }
-
- /**
- * Note that any implementation-specific optimizations of wrapped
NodeStates
- * will not work if a ReportingNodeState is passed into their {@code
#equals()}
- * method. This implementation will compare the wrapped NodeState,
however. So
- * optimizations work when calling {@code #equals()} on a
ReportingNodeState.
- *
- * @param other Object to compare with this NodeState.
- * @return true if the given object is equal to this NodeState, false
otherwise.
- */
@Override
- public boolean equals(final Object other) {
- if (other instanceof ReportingNodeState) {
- return delegate.equals(((ReportingNodeState) other).delegate);
- } else {
- return delegate.equals(other);
- }
- }
-
- @Override
- public boolean exists() {
- return delegate.exists();
- }
-
- @Override
- public boolean hasChildNode(@Nonnull final String name) {
- return delegate.hasChildNode(name);
- }
-
- @Override
- @Nonnull
- public NodeState getChildNode(@Nonnull final String name) throws
IllegalArgumentException {
- return wrapChild(name, delegate.getChildNode(name));
- }
-
- @Override
- public long getChildNodeCount(final long max) {
- return delegate.getChildNodeCount(max);
- }
-
- @Override
- public Iterable<String> getChildNodeNames() {
- return delegate.getChildNodeNames();
- }
-
- @Override
- @Nonnull
- public Iterable<? extends ChildNodeEntry> getChildNodeEntries() {
- return Iterables.transform(
- delegate.getChildNodeEntries(),
- new Function<ChildNodeEntry, ChildNodeEntry>() {
- @Override
- @Nonnull
- public ChildNodeEntry apply(final ChildNodeEntry
childNodeEntry) {
- final String name = childNodeEntry.getName();
- return new MemoryChildNodeEntry(name, wrapChild(name,
childNodeEntry.getNodeState()));
- }
- }
- );
- }
-
- @Override
- public boolean hasProperty(@Nonnull final String name) {
- return delegate.hasProperty(name);
- }
-
- @Override
- public boolean getBoolean(@Nonnull final String name) {
- reporter.reportProperty(this, name);
- return delegate.getBoolean(name);
- }
-
- @Override
- public long getLong(final String name) {
- reporter.reportProperty(this, name);
- return delegate.getLong(name);
+ protected NodeState decorateChild(@Nonnull final String name, @Nonnull
final NodeState delegateChild) {
+ return wrapAndReport(this, name, delegateChild, reporter);
}
@Override
@CheckForNull
- public String getName(@Nonnull final String name) {
- reporter.reportProperty(this, name);
- return delegate.getName(name);
- }
-
- @Override
- @Nonnull
- public Iterable<String> getNames(@Nonnull final String name) {
- reporter.reportProperty(this, name);
- return delegate.getNames(name);
- }
-
-
- @Override
- @CheckForNull
- public String getString(final String name) {
- reporter.reportProperty(this, name);
- return delegate.getString(name);
- }
-
- @Override
- @Nonnull
- public Iterable<String> getStrings(@Nonnull final String name) {
- reporter.reportProperty(this, name);
- return delegate.getStrings(name);
- }
-
- @Override
- @CheckForNull
- public PropertyState getProperty(@Nonnull final String name) {
- reporter.reportProperty(this, name);
- return delegate.getProperty(name);
- }
-
- @Override
- public long getPropertyCount() {
- return delegate.getPropertyCount();
- }
-
- @Override
- @Nonnull
- public Iterable<? extends PropertyState> getProperties() {
- return Iterables.transform(
- delegate.getProperties(),
- new Function<PropertyState, PropertyState>() {
- @Override
- @Nonnull
- public PropertyState apply(final PropertyState
propertyState) {
- reporter.reportProperty(ReportingNodeState.this,
propertyState.getName());
- return propertyState;
- }
- }
- );
+ protected PropertyState decorateProperty(@Nonnull final PropertyState
delegatePropertyState) {
+ reporter.reportProperty(this, delegatePropertyState.getName());
+ return delegatePropertyState;
}
@Override
public String toString() {
- return "ReportingNodeState{" + getPath() + ", " + super.toString() +
"}";
- }
-
- private static class ReportingDiff implements NodeStateDiff {
-
- private final NodeStateDiff diff;
- private ReportingNodeState parent;
-
- public ReportingDiff(NodeStateDiff diff, ReportingNodeState parent) {
- this.diff = diff;
- this.parent = parent;
- }
-
- @Override
- public boolean childNodeAdded(final String name, final NodeState
after) {
- return diff.childNodeAdded(name, parent.wrapChild(name, after));
- }
-
- @Override
- public boolean childNodeChanged(final String name, final NodeState
before, final NodeState after) {
- return diff.childNodeChanged(name, before, parent.wrapChild(name,
after));
- }
-
- @Override
- public boolean childNodeDeleted(final String name, final NodeState
before) {
- return diff.childNodeDeleted(name, before);
- }
-
- @Override
- public boolean propertyAdded(final PropertyState after) {
- return diff.propertyAdded(after);
- }
-
- @Override
- public boolean propertyChanged(final PropertyState before, final
PropertyState after) {
- return diff.propertyChanged(before, after);
- }
-
- @Override
- public boolean propertyDeleted(final PropertyState before) {
- return diff.propertyDeleted(before);
- }
+ return "ReportingNodeState{" + getPath() + ", " + delegate.toString()
+ "}";
}
}
Added:
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java?rev=1717258&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java
(added)
+++
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java
Mon Nov 30 14:14:52 2015
@@ -0,0 +1,172 @@
+/*
+ * 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.upgrade;
+
+import static com.google.common.collect.Iterables.cycle;
+import static com.google.common.collect.Iterables.limit;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.core.RepositoryContext;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
+import org.apache.jackrabbit.oak.plugins.segment.memory.MemoryStore;
+import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.stats.Clock;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class LongNameTest {
+
+ public static final Credentials CREDENTIALS = new
SimpleCredentials("admin", "admin".toCharArray());
+
+ private static final String TOO_LONG_NAME = "this string is an example of
a very long node name which is approximately one hundred fifty eight bytes long
so too long for the document node store to handle";
+
+ private static final String NOT_TOO_LONG_NAME = "this string despite it is
very long as well is not too long for the document node store to handle so it
may be migrated succesfully without troubles";
+
+ private static RepositoryConfig sourceRepositoryConfig;
+
+ private static File crx2RepoDir;
+
+ @BeforeClass
+ public static void prepareSourceRepository() throws RepositoryException,
IOException, InterruptedException {
+ crx2RepoDir = new File("target", "upgrade-" +
Clock.SIMPLE.getTimeIncreasing());
+ FileUtils.deleteQuietly(crx2RepoDir);
+
+ sourceRepositoryConfig = createCrx2Config(crx2RepoDir);
+ RepositoryImpl sourceRepository =
RepositoryImpl.create(sourceRepositoryConfig);
+ Session session = sourceRepository.login(CREDENTIALS);
+ try {
+ Assert.assertTrue(TOO_LONG_NAME.getBytes().length > 150);
+ Assert.assertTrue(NOT_TOO_LONG_NAME.getBytes().length < 150);
+
+ Node longNameParent = createParent(session.getRootNode());
+ Assert.assertTrue(longNameParent.getPath().length() >= 350);
+
+ longNameParent.addNode(TOO_LONG_NAME);
+ longNameParent.addNode(NOT_TOO_LONG_NAME);
+ session.save();
+
+ Assert.assertTrue(longNameParent.hasNode(TOO_LONG_NAME));
+ Assert.assertTrue(longNameParent.hasNode(NOT_TOO_LONG_NAME));
+ } finally {
+ session.logout();
+ }
+ sourceRepository.shutdown();
+ }
+
+ private static RepositoryConfig createCrx2Config(File crx2RepoDir) throws
RepositoryException, IOException {
+ File source = new File(crx2RepoDir, "source");
+ source.mkdirs();
+ return RepositoryConfig.install(source);
+ }
+
+ @Test
+ public void longNameShouldBeSkipped() throws RepositoryException,
IOException {
+ DocumentNodeStore nodeStore = new DocumentMK.Builder().getNodeStore();
+ try {
+ upgrade(nodeStore, true);
+
+ NodeState parent = getParent(nodeStore.getRoot());
+ Assert.assertTrue(parent.hasChildNode(NOT_TOO_LONG_NAME));
+ Assert.assertEquals(1, parent.getChildNodeCount(10));
+
+ // The following throws an DocumentStoreException:
+ // Assert.assertFalse(parent.hasChildNode(TOO_LONG_NAME));
+ } finally {
+ nodeStore.dispose();
+ }
+ }
+
+ @Test(expected = RepositoryException.class)
+ @Ignore
+ public void longNameOnDocumentStoreThrowsAnException() throws
RepositoryException, IOException {
+ DocumentNodeStore nodeStore = new DocumentMK.Builder().getNodeStore();
+ try {
+ upgrade(nodeStore, false);
+ } finally {
+ nodeStore.dispose();
+ }
+ }
+
+ @Test
+ @Ignore
+ public void longNameOnSegmentStoreWorksFine() throws RepositoryException,
IOException {
+ SegmentStore memoryStore = new MemoryStore();
+ try {
+ SegmentNodeStore nodeStore =
SegmentNodeStore.newSegmentNodeStore(memoryStore).create();
+ upgrade(nodeStore, false);
+
+ NodeState parent = getParent(nodeStore.getRoot());
+ Assert.assertTrue(parent.hasChildNode(NOT_TOO_LONG_NAME));
+ Assert.assertTrue(parent.hasChildNode(TOO_LONG_NAME));
+ } finally {
+ memoryStore.close();
+ }
+ }
+
+ private static void upgrade(NodeStore target, boolean skipLongNames)
throws RepositoryException, IOException {
+ RepositoryConfig config = createCrx2Config(crx2RepoDir);
+ RepositoryContext context = RepositoryContext.create(config);
+ try {
+ RepositoryUpgrade upgrade = new RepositoryUpgrade(context, target);
+ upgrade.setSkipLongNames(skipLongNames);
+ upgrade.copy(null);
+ } finally {
+ context.getRepository().shutdown();
+ }
+ }
+
+ private static Node createParent(Node root) throws RepositoryException {
+ Node current = root;
+ for (String segment : getParentSegments()) {
+ current = current.addNode(segment);
+ }
+ return current;
+ }
+
+ private static NodeState getParent(NodeState root) throws
RepositoryException {
+ NodeState current = root;
+ for (String segment : getParentSegments()) {
+ current = current.getChildNode(segment);
+ }
+ return current;
+ }
+
+ private static Iterable<String> getParentSegments() {
+ return limit(cycle("this", "is", "a", "path"), 100); // total path
+ // length
+ // = 350
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporterTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporterTest.java?rev=1717258&r1=1717257&r2=1717258&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporterTest.java
(original)
+++
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporterTest.java
Mon Nov 30 14:14:52 2015
@@ -19,6 +19,7 @@
package org.apache.jackrabbit.oak.upgrade.nodestate.report;
import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.junit.Test;
@@ -46,8 +47,13 @@ public class PeriodicReporterTest {
@Test
public void callbackEveryTenProperties() {
+ final NodeBuilder builder = EmptyNodeState.EMPTY_NODE.builder();
+ for (int i = 1; i < 40; i++) {
+ builder.child("counter").setProperty(Integer.toString(i), i);
+ }
+
final AssertingPeriodicReporter reporter = new
AssertingPeriodicReporter(-1, 10);
- final NodeState counter =
ReportingNodeState.wrap(EmptyNodeState.EMPTY_NODE, reporter)
+ final NodeState counter =
ReportingNodeState.wrap(builder.getNodeState(), reporter)
.getChildNode("counter");
reporter.reset();
Modified:
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeStateTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeStateTest.java?rev=1717258&r1=1717257&r2=1717258&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeStateTest.java
(original)
+++
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeStateTest.java
Mon Nov 30 14:14:52 2015
@@ -30,6 +30,7 @@ import static org.apache.jackrabbit.oak.
import static
org.apache.jackrabbit.oak.upgrade.nodestate.report.AssertingPeriodicReporter.hasReportedNodes;
import static
org.apache.jackrabbit.oak.upgrade.nodestate.report.AssertingPeriodicReporter.hasReportedProperty;
import static org.hamcrest.CoreMatchers.any;
+import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
public class ReportingNodeStateTest {
@@ -73,24 +74,33 @@ public class ReportingNodeStateTest {
@Test
public void getPropertyReportsProperty() {
- final AssertingPeriodicReporter reporter = new
AssertingPeriodicReporter(10, 10);
- final NodeState nodeState =
ReportingNodeState.wrap(EmptyNodeState.EMPTY_NODE, reporter);
+ final NodeBuilder builder = EmptyNodeState.EMPTY_NODE.builder();
+ final String name = "meaningOfLife";
+ builder.setProperty(name, "42");
+
+ final AssertingPeriodicReporter reporter = new
AssertingPeriodicReporter(1, 1);
+ final NodeState nodeState =
ReportingNodeState.wrap(builder.getNodeState(), reporter);
reporter.reset();
- final String name = "a";
- for (int i = 0; i < 3; i++) {
- // 3 * 7 property requests = 21
- nodeState.getProperty(name);
- nodeState.getBoolean(name);
- nodeState.getLong(name);
- nodeState.getString(name);
- nodeState.getStrings(name);
- nodeState.getName(name);
- nodeState.getNames(name);
- }
- assertThat(reporter, hasReportedProperty(10, "/a"));
- assertThat(reporter, hasReportedProperty(20, "/a"));
+ // 7 accesses via 7 methods
+ nodeState.getProperty(name);
+ nodeState.getBoolean(name);
+ nodeState.getLong(name);
+ nodeState.getString(name);
+ nodeState.getStrings(name);
+ nodeState.getName(name);
+ nodeState.getNames(name);
+
+ assertThat(reporter, not(hasReportedProperty(0, "/meaningOfLife")));
+ assertThat(reporter, hasReportedProperty(1, "/meaningOfLife"));
+ assertThat(reporter, hasReportedProperty(2, "/meaningOfLife"));
+ assertThat(reporter, hasReportedProperty(3, "/meaningOfLife"));
+ assertThat(reporter, hasReportedProperty(4, "/meaningOfLife"));
+ assertThat(reporter, hasReportedProperty(5, "/meaningOfLife"));
+ assertThat(reporter, hasReportedProperty(6, "/meaningOfLife"));
+ assertThat(reporter, hasReportedProperty(7, "/meaningOfLife"));
+ assertThat(reporter, not(hasReportedProperty(8, "/meaningOfLife")));
}
@Test