You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by kw...@apache.org on 2021/04/08 07:10:17 UTC
[jackrabbit-filevault] branch master updated: JCRVLT-514
(de-)serialize property filters in JcrWorkspaceFilter (#133)
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git
The following commit(s) were added to refs/heads/master by this push:
new e730ef9 JCRVLT-514 (de-)serialize property filters in JcrWorkspaceFilter (#133)
e730ef9 is described below
commit e730ef9c999ac69b477675cd2671ff6ab5167d4d
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Thu Apr 8 09:10:11 2021 +0200
JCRVLT-514 (de-)serialize property filters in JcrWorkspaceFilter (#133)
---
.../apache/jackrabbit/vault/fs/api/FilterSet.java | 6 +-
.../vault/fs/config/DefaultWorkspaceFilter.java | 11 +-
.../vault/packaging/JcrPackageDefinition.java | 7 +-
.../vault/packaging/impl/JcrWorkspaceFilter.java | 128 +++++++++++++++------
.../jackrabbit/vault/packaging/package-info.java | 2 +-
.../vault/packaging/impl/JcrWorkspaceFilterIT.java | 55 +++++++++
6 files changed, 165 insertions(+), 44 deletions(-)
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/FilterSet.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/FilterSet.java
index eea59e3..8d8994e 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/FilterSet.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/FilterSet.java
@@ -252,11 +252,11 @@ public abstract class FilterSet<E extends Filter> implements Dumpable {
*/
@Override
public void dump(@NotNull DumpContext ctx, boolean isLast) {
- ctx.printf(false, "root: %s", getRoot());
+ ctx.printf(false, "root: %s, mode %s", getRoot(), getImportMode());
if (entries != null) {
Iterator<Entry<E>> iter = entries.iterator();
while (iter.hasNext()) {
- Entry e = iter.next();
+ Entry<E> e = iter.next();
e.dump(ctx, !iter.hasNext());
}
}
@@ -280,7 +280,7 @@ public abstract class FilterSet<E extends Filter> implements Dumpable {
if (this == o) return true;
if (!(o instanceof FilterSet)) return false;
- FilterSet filterSet = (FilterSet) o;
+ FilterSet<E> filterSet = (FilterSet<E>) o;
if (entries != null ? !entries.equals(filterSet.entries) : filterSet.entries != null) return false;
return root.equals(filterSet.root);
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/DefaultWorkspaceFilter.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/DefaultWorkspaceFilter.java
index 2832e2c..02047e0 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/DefaultWorkspaceFilter.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/DefaultWorkspaceFilter.java
@@ -488,7 +488,16 @@ public class DefaultWorkspaceFilter implements Dumpable, WorkspaceFilter {
Iterator<PathFilterSet> iter = nodesFilterSets.iterator();
while (iter.hasNext()) {
PathFilterSet set = iter.next();
- ctx.println(!iter.hasNext(), "ItemFilterSet");
+ ctx.println(!iter.hasNext(), "NodeFilterSet");
+ ctx.indent(!iter.hasNext());
+ set.dump(ctx, false);
+ ctx.outdent();
+ }
+
+ iter = propsFilterSets.iterator();
+ while (iter.hasNext()) {
+ PathFilterSet set = iter.next();
+ ctx.println(!iter.hasNext(), "PropertyFilterSet");
ctx.indent(!iter.hasNext());
set.dump(ctx, false);
ctx.outdent();
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/JcrPackageDefinition.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/JcrPackageDefinition.java
index 3c157e7..6ee6b87 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/JcrPackageDefinition.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/JcrPackageDefinition.java
@@ -162,11 +162,16 @@ public interface JcrPackageDefinition extends PackageProperties {
String PN_MODE = "mode";
/**
- * Property name of the filter rules
+ * Property name of the path filter rules
*/
String PN_RULES = "rules";
/**
+ * Property name of the property filter rules
+ */
+ String PN_PROPERTY_RULES = "propertyRules";
+
+ /**
* Property name of the rule type
*/
String PN_TYPE = "type";
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrWorkspaceFilter.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrWorkspaceFilter.java
index 9f15ed1..1919706 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrWorkspaceFilter.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrWorkspaceFilter.java
@@ -25,9 +25,14 @@ import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.version.VersionException;
+import org.apache.jackrabbit.vault.fs.api.FilterSet;
import org.apache.jackrabbit.vault.fs.api.ImportMode;
-import org.apache.jackrabbit.vault.fs.api.ItemFilterSet;
+import org.apache.jackrabbit.vault.fs.api.PathFilter;
import org.apache.jackrabbit.vault.fs.api.PathFilterSet;
import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
@@ -53,35 +58,31 @@ public class JcrWorkspaceFilter {
if (root.length() == 0) {
continue;
}
+ boolean isPropertyFilter = false;
+ if (filter.getName().startsWith("p")) {
+ isPropertyFilter = true;
+ }
String mode = filter.hasProperty(JcrPackageDefinitionImpl.PN_MODE)
? filter.getProperty(JcrPackageDefinitionImpl.PN_MODE).getString()
: "";
PathFilterSet set = new PathFilterSet(root);
+ PathFilterSet propertySet = new PathFilterSet(root);
if (mode.length() > 0) {
set.setImportMode(ImportMode.valueOf(mode.toUpperCase()));
+ propertySet.setImportMode(ImportMode.valueOf(mode.toUpperCase()));
}
+
if (filter.hasProperty(JcrPackageDefinitionImpl.PN_RULES)) {
- // new version with mv rules property
- Property p = filter.getProperty(JcrPackageDefinitionImpl.PN_RULES);
- Value[] values = p.getDefinition().isMultiple() ? p.getValues() : new Value[]{p.getValue()};
- for (Value value: values) {
- String rule = value.getString();
- int idx = rule.indexOf(':');
- String type = idx > 0 ? rule.substring(0, idx) : "include";
- String patt = idx > 0 ? rule.substring(idx + 1) : "";
- DefaultPathFilter pf;
- try {
- pf = new DefaultPathFilter(patt);
- } catch (ConfigurationException e) {
- throw new RepositoryException("Can not load filter from node " + defNode.getPath(), e);
- }
- if ("include".equals(type)) {
- set.addInclude(pf);
- } else {
- set.addExclude(pf);
+ try {
+ loadRules(set, filter, JcrPackageDefinitionImpl.PN_RULES);
+ if (!loadRules(propertySet, filter, JcrPackageDefinitionImpl.PN_PROPERTY_RULES)) {
+ propertySet = null;
}
+ } catch (ConfigurationException e) {
+ throw new RepositoryException("Can not load filter from node " + defNode.getPath(), e);
}
} else {
+ // this is the legacy format
for (NodeIterator rules = filter.getNodes(); rules.hasNext();) {
Node rule = rules.nextNode();
String type = rule.getProperty(JcrPackageDefinitionImpl.PN_TYPE).getString();
@@ -98,12 +99,40 @@ public class JcrWorkspaceFilter {
set.addExclude(pf);
}
}
+ propertySet = null;
+ }
+ if (propertySet != null) {
+ wsp.add(set, propertySet);
+ } else {
+ wsp.add(set);
}
- wsp.add(set);
}
return wsp;
}
+ private static boolean loadRules(PathFilterSet set, Node filterNode, String propertyName) throws ConfigurationException, RepositoryException {
+ if (!filterNode.hasProperty(propertyName)) {
+ return false;
+ }
+ Property p = filterNode.getProperty(propertyName);
+ Value[] values = p.getDefinition().isMultiple() ? p.getValues() : new Value[]{p.getValue()};
+ for (Value value: values) {
+ String rule = value.getString();
+ int idx = rule.indexOf(':');
+ String type = idx > 0 ? rule.substring(0, idx) : "include";
+ String patt = idx > 0 ? rule.substring(idx + 1) : "";
+ DefaultPathFilter pf = new DefaultPathFilter(patt);
+
+ if ("include".equals(type)) {
+ set.addInclude(pf);
+ } else {
+ set.addExclude(pf);
+ }
+ }
+ return true;
+ }
+
+ @Deprecated
public static void saveLegacyFilter(WorkspaceFilter filter, Node defNode, boolean save)
throws RepositoryException {
// delete all nodes first
@@ -115,7 +144,7 @@ public class JcrWorkspaceFilter {
Node setNode = defNode.addNode("f" + nr);
setNode.setProperty(JcrPackageDefinitionImpl.PN_ROOT, set.getRoot());
int eNr = 0;
- for (ItemFilterSet.Entry e: set.getEntries()) {
+ for (FilterSet.Entry<PathFilter> e: set.getEntries()) {
// expect path filter
if (!(e.getFilter() instanceof DefaultPathFilter)) {
throw new IllegalArgumentException("Can only handle default path filters.");
@@ -139,28 +168,51 @@ public class JcrWorkspaceFilter {
defNode.getNode(JcrPackageDefinitionImpl.NN_FILTER).remove();
}
Node filterNode = defNode.addNode(JcrPackageDefinitionImpl.NN_FILTER);
- int nr = 0;
- for (PathFilterSet set: filter.getFilterSets()) {
- Node setNode = filterNode.addNode("f" + nr);
+ savePathFilterSet(filter.getFilterSets(), filter.getPropertyFilterSets(), filterNode);
+
+ if (save) {
+ defNode.getSession().save();
+ }
+ }
+
+
+ private static void savePathFilterSet(List<PathFilterSet> pathFilterSets, List<PathFilterSet> propertyFilterSets, Node filterNode) throws RepositoryException {
+ int no = 0;
+ for (PathFilterSet set: pathFilterSets) {
+ Node setNode = filterNode.addNode("f" + no);
setNode.setProperty(JcrPackageDefinitionImpl.PN_ROOT, set.getRoot());
setNode.setProperty(JcrPackageDefinitionImpl.PN_MODE, set.getImportMode().name().toLowerCase());
- List<String> rules = new LinkedList<String>();
- for (ItemFilterSet.Entry e: set.getEntries()) {
- // expect path filter
- if (!(e.getFilter() instanceof DefaultPathFilter)) {
- throw new IllegalArgumentException("Can only handle default path filters.");
- }
- String type = e.isInclude() ? "include" : "exclude";
- String patt = ((DefaultPathFilter) e.getFilter()).getPattern();
- rules.add(type + ":" + patt);
+
+ saveRules(setNode, set.getEntries(), JcrPackageDefinitionImpl.PN_RULES);
+ // find property filter for same root
+ PathFilterSet propertyFilterSet = getSetForRoot(propertyFilterSets, set.getRoot());
+ if (propertyFilterSet != null) {
+ saveRules(setNode, propertyFilterSet.getEntries(), JcrPackageDefinitionImpl.PN_PROPERTY_RULES);
}
- setNode.setProperty(JcrPackageDefinitionImpl.PN_RULES, rules.toArray(new String[rules.size()]));
- nr++;
- }
- if (save) {
- defNode.getSession().save();
+ no++;
}
}
+ private static PathFilterSet getSetForRoot(List<PathFilterSet> filterSets, String root) {
+ for (PathFilterSet set : filterSets) {
+ if (set.getRoot().equals(root)) {
+ return set;
+ }
+ }
+ return null;
+ }
+ private static void saveRules(Node setNode, List<FilterSet.Entry<PathFilter>> entries, String propertyName) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+ List<String> rules = new LinkedList<>();
+ for (FilterSet.Entry<PathFilter> e: entries) {
+ // expect path filter
+ if (!(e.getFilter() instanceof DefaultPathFilter)) {
+ throw new IllegalArgumentException("Can only handle default path filters.");
+ }
+ String type = e.isInclude() ? "include" : "exclude";
+ String patt = ((DefaultPathFilter) e.getFilter()).getPattern();
+ rules.add(type + ":" + patt);
+ }
+ setNode.setProperty(propertyName, rules.toArray(new String[rules.size()]));
+ }
}
\ No newline at end of file
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/package-info.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/package-info.java
index 8ba3eea..0c8c0f8 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/package-info.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/package-info.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-@Version("2.12.0")
+@Version("2.13.0")
package org.apache.jackrabbit.vault.packaging;
import org.osgi.annotation.versioning.Version;
diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/impl/JcrWorkspaceFilterIT.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/impl/JcrWorkspaceFilterIT.java
new file mode 100644
index 0000000..74d0d43
--- /dev/null
+++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/impl/JcrWorkspaceFilterIT.java
@@ -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.vault.packaging.impl;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.jackrabbit.vault.fs.api.ImportMode;
+import org.apache.jackrabbit.vault.fs.api.PathFilterSet;
+import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.filter.DefaultPathFilter;
+import org.apache.jackrabbit.vault.packaging.integration.IntegrationTestBase;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class JcrWorkspaceFilterIT extends IntegrationTestBase {
+
+ @Test
+ public void testComplexFilterRoundtrip() throws RepositoryException, ConfigurationException {
+ DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+ PathFilterSet pathFilterSet = new PathFilterSet("/my/root");
+ pathFilterSet.setImportMode(ImportMode.MERGE);
+ pathFilterSet.setType("cleanup");
+ pathFilterSet.addInclude(new DefaultPathFilter("/my/root/include.*"));
+ pathFilterSet.addExclude(new DefaultPathFilter("/my/root/exclude.*"));
+
+ PathFilterSet propertyFilterSet = new PathFilterSet("/my/root");
+ propertyFilterSet.setImportMode(ImportMode.MERGE);
+ propertyFilterSet.setType("cleanup");
+ propertyFilterSet.addInclude(new DefaultPathFilter("/my/root/myprops.*"));
+ propertyFilterSet.addExclude(new DefaultPathFilter("/my/root/notmyprops.*"));
+ filter.add(pathFilterSet, propertyFilterSet);
+ Node defNode = JcrUtils.getOrCreateByPath("/etc/packages/mypackage/jcr:content/vlt:definition", "vlt:PackageDefinition", admin);
+ JcrWorkspaceFilter.saveFilter(filter, defNode, false);
+ Assert.assertEquals(filter, JcrWorkspaceFilter.loadFilter(defNode));
+ }
+
+}