You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by to...@apache.org on 2017/08/24 11:22:04 UTC
svn commit: r1806028 - in /jackrabbit/oak/trunk:
oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/
oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/mount/
oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/
oak-...
Author: tomekr
Date: Thu Aug 24 11:22:04 2017
New Revision: 1806028
URL: http://svn.apache.org/viewvc?rev=1806028&view=rev
Log:
OAK-6585: Allow to use patterns in the Mount#pathSupportingFragments
Added:
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/FragmentMatcher.java
jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/mount/FragmentMatcherTest.java
jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositionContextTest.java
Modified:
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/Mount.java
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/MountInfo.java
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/Mounts.java
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/package-info.java
jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/mount/MountInfoTest.java
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositionContext.java
Added: jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/FragmentMatcher.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/FragmentMatcher.java?rev=1806028&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/FragmentMatcher.java (added)
+++ jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/FragmentMatcher.java Thu Aug 24 11:22:04 2017
@@ -0,0 +1,101 @@
+/*
+ * 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.spi.mount;
+
+import static org.apache.jackrabbit.oak.spi.mount.FragmentMatcher.Result.FULL_MATCH;
+import static org.apache.jackrabbit.oak.spi.mount.FragmentMatcher.Result.MISMATCH;
+import static org.apache.jackrabbit.oak.spi.mount.FragmentMatcher.Result.PARTIAL_MATCH;
+
+/**
+ * This utility class allows to match strings against a simple pattern language.
+ * There are two special characters:
+ * <ul>
+ * <li><code>*</code> - matches zero or more any characters different than slash</li>
+ * <li><code>$</code> - matches the end of the subject</li>
+ * </ul>
+ */
+public final class FragmentMatcher {
+
+ private FragmentMatcher() {
+ }
+
+ public enum Result {
+ FULL_MATCH, PARTIAL_MATCH, MISMATCH
+ }
+
+ /**
+ * Check if the subject starts with the pattern. See the class docs for the
+ * pattern syntax.
+ *
+ * @param pattern pattern to be matched
+ * @param subject subject
+ * @return {@link Result#FULL_MATCH} if the subject starts with the pattern,
+ * {@link Result#PARTIAL_MATCH} if the subject is shorter than the pattern,
+ * but matches it so far and {@link Result#MISMATCH} if it doesn't start with
+ * the pattern.
+ */
+ public static Result startsWith(String pattern, String subject) {
+ int i = 0, j = 0;
+ char patternChar = 0, subjectChar;
+
+ while (i < pattern.length() && j < subject.length()) {
+ patternChar = pattern.charAt(i);
+ subjectChar = subject.charAt(j);
+ switch (patternChar) {
+ case '*': // matches everything until the next slash
+ if (subjectChar == '/') {
+ i++;
+ } else {
+ j++;
+ }
+ break;
+
+ case '$':
+ return MISMATCH;
+
+ default:
+ if (patternChar != subjectChar) {
+ return MISMATCH;
+ } else {
+ i++;
+ j++;
+ break;
+ }
+ }
+ }
+ if (j == subject.length()) {
+ while (i < pattern.length()) {
+ patternChar = pattern.charAt(i);
+ switch (patternChar) {
+ case '*':
+ i++;
+ break;
+ case '$':
+ i++;
+ break;
+ default:
+ return PARTIAL_MATCH;
+ }
+ }
+ return FULL_MATCH;
+ } else {
+ return FULL_MATCH;
+ }
+ }
+}
Modified: jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/Mount.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/Mount.java?rev=1806028&r1=1806027&r2=1806028&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/Mount.java (original)
+++ jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/Mount.java Thu Aug 24 11:22:04 2017
@@ -86,6 +86,15 @@ public interface Mount {
boolean isSupportFragment(String path);
/**
+ * Checks if any path supporting the fragments falls under the specified path.
+ *
+ * @param path ancestor path
+ * @return true if the path fragment mounts are supported under some descendants
+ * of the specified path
+ */
+ boolean isSupportFragmentUnder(String path);
+
+ /**
* Checks if given path belongs to this <code>Mount</code>
*
* <p>A path belongs to a Mount in two scenarios:</p>
Modified: jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/MountInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/MountInfo.java?rev=1806028&r1=1806027&r2=1806028&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/MountInfo.java (original)
+++ jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/MountInfo.java Thu Aug 24 11:22:04 2017
@@ -23,15 +23,19 @@ import java.io.StringWriter;
import java.util.Collection;
import java.util.List;
import java.util.NavigableSet;
+import java.util.Set;
import java.util.TreeSet;
import com.google.common.base.Function;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Sets.newHashSet;
import static com.google.common.collect.Sets.newTreeSet;
import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
import static org.apache.jackrabbit.oak.commons.PathUtils.isAncestor;
+import static org.apache.jackrabbit.oak.spi.mount.FragmentMatcher.Result.FULL_MATCH;
+import static org.apache.jackrabbit.oak.spi.mount.FragmentMatcher.Result.PARTIAL_MATCH;
/**
* Default {@link Mount} implementation for non-default mounts.
@@ -51,7 +55,7 @@ final class MountInfo implements Mount {
private final String name;
private final boolean readOnly;
private final String pathFragmentName;
- private final NavigableSet<String> pathsSupportingFragments;
+ private final Set<String> pathsSupportingFragments;
private final NavigableSet<String> includedPaths;
MountInfo(String name, boolean readOnly, List<String> pathsSupportingFragments,
@@ -60,7 +64,7 @@ final class MountInfo implements Mount {
this.readOnly = readOnly;
this.pathFragmentName = "oak:mount-" + name;
this.includedPaths = cleanCopy(includedPaths);
- this.pathsSupportingFragments = cleanCopy(pathsSupportingFragments);
+ this.pathsSupportingFragments = newHashSet(pathsSupportingFragments);
}
@Override
@@ -106,9 +110,18 @@ final class MountInfo implements Mount {
@Override
public boolean isSupportFragment(String path) {
- path = SANITIZE_PATH.apply(path);
- String previousPath = pathsSupportingFragments.floor(path);
- return previousPath != null && (previousPath.equals(path) || isAncestor(previousPath, path));
+ String subject = SANITIZE_PATH.apply(path);
+ return pathsSupportingFragments.stream()
+ .map(pattern -> FragmentMatcher.startsWith(pattern, subject))
+ .anyMatch(FULL_MATCH::equals);
+ }
+
+ @Override
+ public boolean isSupportFragmentUnder(String path) {
+ String subject = SANITIZE_PATH.apply(path);
+ return pathsSupportingFragments.stream()
+ .map(pattern -> FragmentMatcher.startsWith(pattern, subject))
+ .anyMatch(r -> r == PARTIAL_MATCH || r == FULL_MATCH);
}
@Override
Modified: jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/Mounts.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/Mounts.java?rev=1806028&r1=1806027&r2=1806028&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/Mounts.java (original)
+++ jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/Mounts.java Thu Aug 24 11:22:04 2017
@@ -117,6 +117,11 @@ public final class Mounts {
}
@Override
+ public boolean isSupportFragmentUnder(String path) {
+ return false;
+ }
+
+ @Override
public boolean isMounted(String path) {
for (Mount m : mounts) {
if (m.isMounted(path)) {
Modified: jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/package-info.java?rev=1806028&r1=1806027&r2=1806028&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/mount/package-info.java Thu Aug 24 11:22:04 2017
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-@Version("3.0.0")
+@Version("3.1.0")
package org.apache.jackrabbit.oak.spi.mount;
import org.osgi.annotation.versioning.Version;
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/mount/FragmentMatcherTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/mount/FragmentMatcherTest.java?rev=1806028&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/mount/FragmentMatcherTest.java (added)
+++ jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/mount/FragmentMatcherTest.java Thu Aug 24 11:22:04 2017
@@ -0,0 +1,68 @@
+/*
+ * 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.spi.mount;
+
+import org.junit.Test;
+
+import static org.apache.jackrabbit.oak.spi.mount.FragmentMatcher.Result.FULL_MATCH;
+import static org.apache.jackrabbit.oak.spi.mount.FragmentMatcher.Result.MISMATCH;
+import static org.apache.jackrabbit.oak.spi.mount.FragmentMatcher.Result.PARTIAL_MATCH;
+import static org.junit.Assert.assertEquals;
+
+public class FragmentMatcherTest {
+
+ @Test
+ public void testMatcher() {
+ assertResult(PARTIAL_MATCH, "/content", "/");
+ assertResult(FULL_MATCH, "/content", "/content");
+ assertResult(FULL_MATCH, "/content", "/content/acme");
+ assertResult(FULL_MATCH, "/content", "/content/acme/en");
+
+ assertResult(PARTIAL_MATCH, "/content/*", "/");
+ assertResult(PARTIAL_MATCH, "/content/*", "/content");
+ assertResult(FULL_MATCH, "/content/*", "/content/acme");
+ assertResult(FULL_MATCH, "/content/*", "/content/acme/site");
+
+ assertResult(PARTIAL_MATCH, "/content$", "/");
+ assertResult(FULL_MATCH, "/content$", "/content");
+ assertResult(MISMATCH, "/content$", "/content/acme");
+
+ assertResult(PARTIAL_MATCH, "/content/*$", "/");
+ assertResult(PARTIAL_MATCH, "/content/*$", "/content");
+ assertResult(FULL_MATCH, "/content/*$", "/content/acme");
+ assertResult(MISMATCH, "/content/*$", "/content/acme/site");
+
+ assertResult(PARTIAL_MATCH, "/content/*/site", "/");
+ assertResult(PARTIAL_MATCH, "/content/*/site", "/content");
+ assertResult(PARTIAL_MATCH, "/content/*/site", "/content/acme");
+ assertResult(FULL_MATCH, "/content/*/site", "/content/acme/site");
+ assertResult(FULL_MATCH, "/content/*/site", "/content/acme/site/en");
+
+ assertResult(PARTIAL_MATCH, "/content/*/site/", "/");
+ assertResult(PARTIAL_MATCH, "/content/*/site/", "/content");
+ assertResult(PARTIAL_MATCH, "/content/*/site/", "/content/acme");
+ assertResult(FULL_MATCH, "/content/*/site/", "/content/acme/site/en");
+ assertResult(FULL_MATCH, "/content/*/site/", "/content/acme/site/en/home");
+ }
+
+ private static void assertResult(FragmentMatcher.Result expectedResult, String pattern, String subject) {
+ assertEquals(expectedResult, FragmentMatcher.startsWith(pattern, subject));
+ }
+
+}
Modified: jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/mount/MountInfoTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/mount/MountInfoTest.java?rev=1806028&r1=1806027&r2=1806028&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/mount/MountInfoTest.java (original)
+++ jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/mount/MountInfoTest.java Thu Aug 24 11:22:04 2017
@@ -62,4 +62,46 @@ public class MountInfoTest {
assertFalse(md.isDirectlyUnder("/etc/my/config"));
assertFalse(md.isDirectlyUnder("/libs"));
}
+
+ @Test
+ public void testSupportFragment() {
+ MountInfo md = new MountInfo("foo", false, of("/apps", "/libs/*/site", "/content/*$", "/var$"), Collections.emptyList());
+
+ assertFalse(md.isSupportFragment("/"));
+ assertTrue(md.isSupportFragment("/apps"));
+ assertTrue(md.isSupportFragment("/apps/acme"));
+
+ assertFalse(md.isSupportFragment("/libs"));
+ assertFalse(md.isSupportFragment("/libs/acme"));
+ assertTrue(md.isSupportFragment("/libs/acme/site"));
+ assertTrue(md.isSupportFragment("/libs/acme/site/abc"));
+
+ assertFalse(md.isSupportFragment("/content"));
+ assertTrue(md.isSupportFragment("/content/site"));
+ assertFalse(md.isSupportFragment("/content/site/abc"));
+
+ assertTrue(md.isSupportFragment("/var"));
+ assertFalse(md.isSupportFragment("/var/abc"));
+ }
+
+ @Test
+ public void testSupportFragmentUnder() {
+ MountInfo md = new MountInfo("foo", false, of("/apps", "/libs/*/site", "/content/*$", "/var$"), Collections.emptyList());
+
+ assertTrue(md.isSupportFragmentUnder("/"));
+ assertTrue(md.isSupportFragmentUnder("/apps"));
+ assertTrue(md.isSupportFragmentUnder("/apps/acme"));
+
+ assertTrue(md.isSupportFragmentUnder("/libs"));
+ assertTrue(md.isSupportFragmentUnder("/libs/acme"));
+ assertTrue(md.isSupportFragmentUnder("/libs/acme/site"));
+ assertTrue(md.isSupportFragmentUnder("/libs/acme/site/abc"));
+
+ assertTrue(md.isSupportFragmentUnder("/content"));
+ assertTrue(md.isSupportFragmentUnder("/content/site"));
+ assertFalse(md.isSupportFragmentUnder("/content/site/abc"));
+
+ assertTrue(md.isSupportFragmentUnder("/var"));
+ assertFalse(md.isSupportFragmentUnder("/var/abc"));
+ }
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositionContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositionContext.java?rev=1806028&r1=1806027&r2=1806028&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositionContext.java (original)
+++ jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositionContext.java Thu Aug 24 11:22:04 2017
@@ -91,9 +91,7 @@ class CompositionContext {
boolean shouldBeComposite(final String path) {
boolean supportMounts = false;
- if (nonDefaultStores.stream()
- .map(MountedNodeStore::getMount)
- .anyMatch(m -> m.isSupportFragment(path))) {
+ if (mip.getNonDefaultMounts().stream().anyMatch(m -> m.isSupportFragmentUnder(path))) {
supportMounts = true;
} else if (!mip.getMountsPlacedUnder(path).isEmpty()) {
supportMounts = true;
Added: jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositionContextTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositionContextTest.java?rev=1806028&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositionContextTest.java (added)
+++ jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositionContextTest.java Thu Aug 24 11:22:04 2017
@@ -0,0 +1,65 @@
+/*
+ * 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.composite;
+
+import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
+import org.apache.jackrabbit.oak.spi.mount.Mounts;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class CompositionContextTest {
+
+ @Test
+ public void testShouldBeComposite() {
+ MountInfoProvider mip = Mounts.newBuilder()
+ .mount("libs", true,
+ Arrays.asList(
+ "/oak:index/*$"
+ ),
+ Arrays.asList(
+ "/apps",
+ "/libs",
+ "/jcr:system/rep:permissionStore/oak:mount-libs-crx.default")
+ )
+ .build();
+ CompositionContext ctx = new CompositionContext(mip, null, Collections.emptyList());
+
+ assertTrue(ctx.shouldBeComposite("/"));
+ assertTrue(ctx.shouldBeComposite("/oak:index"));
+ assertTrue(ctx.shouldBeComposite("/oak:index/lucene"));
+ assertTrue(ctx.shouldBeComposite("/jcr:system"));
+ assertTrue(ctx.shouldBeComposite("/jcr:system/rep:permissionStore"));
+
+ assertFalse(ctx.shouldBeComposite("/apps"));
+ assertFalse(ctx.shouldBeComposite("/apps/acme"));
+ assertFalse(ctx.shouldBeComposite("/libs"));
+ assertFalse(ctx.shouldBeComposite("/libs/acme"));
+ assertFalse(ctx.shouldBeComposite("/oak:index/lucene/:data"));
+ assertFalse(ctx.shouldBeComposite("/oak:index/lucene/:oak:mount-libs-data"));
+ assertFalse(ctx.shouldBeComposite("/jcr:system/rep:permissionStore/oak:mount-libs-crx.default"));
+ assertFalse(ctx.shouldBeComposite("/jcr:system/rep:permissionStore/oak:mount-libs-crx.default/123"));
+ assertFalse(ctx.shouldBeComposite("/jcr:system/rep:permissionStore/crx.default"));
+ assertFalse(ctx.shouldBeComposite("/content"));
+ assertFalse(ctx.shouldBeComposite("/jcr:system/rep:versionStorage"));
+ }
+
+}