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/07 18:03:04 UTC

[jackrabbit-filevault] branch bugfix/JCRVLT-514 created (now 1955fed)

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a change to branch bugfix/JCRVLT-514
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git.


      at 1955fed  JCRVLT-514 (de-)serialize property filters in JcrWorkspaceFilter

This branch includes the following new commits:

     new 1955fed  JCRVLT-514 (de-)serialize property filters in JcrWorkspaceFilter

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[jackrabbit-filevault] 01/01: JCRVLT-514 (de-)serialize property filters in JcrWorkspaceFilter

Posted by kw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch bugfix/JCRVLT-514
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git

commit 1955fed71e54e2d216d81b8d477a5f0f6c84cdd9
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Wed Apr 7 20:02:52 2021 +0200

    JCRVLT-514 (de-)serialize property filters in JcrWorkspaceFilter
---
 .../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 +++++++++++++++------
 .../vault/packaging/impl/JcrWorkspaceFilterIT.java |  55 +++++++++
 5 files changed, 164 insertions(+), 43 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/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));
+    }
+    
+}