View Javadoc
1   /**
2    * This file Copyright (c) 2003-2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.cms.util;
35  
36  import info.magnolia.jcr.util.NodeUtil;
37  
38  import java.io.IOException;
39  import java.io.ObjectInputStream;
40  import java.io.Serializable;
41  import java.util.Arrays;
42  import java.util.HashSet;
43  import java.util.LinkedHashSet;
44  import java.util.Set;
45  
46  import javax.jcr.Node;
47  import javax.jcr.RepositoryException;
48  
49  import org.apache.commons.lang3.StringUtils;
50  
51  /**
52   * This class defines the rules to be used by the activation content aggregator this is simply a collection of node
53   * types.
54   */
55  public class Rule implements Serializable {
56  
57      /**
58       * Generated stable serialVersionUID - we don't want to rely on a JVM generated one here, as
59       * rule instances indeed get serialized.
60       */
61      private static final long serialVersionUID = 222L;
62  
63      /**
64       * List of node types allowed.
65       */
66      private Set<String> allowedTypes = new LinkedHashSet<String>();
67  
68      /**
69       * reverse rule.
70       */
71      private boolean reverse = false;
72  
73      private final String REVERSE_LABEL = "Reverse:";
74  
75      public Rule() {
76      }
77  
78      /**
79       * Generate list from string array.
80       */
81      public Rule(String[] allowedTypes) {
82          for (int j = 0; j < allowedTypes.length; j++) {
83              this.addAllowType(allowedTypes[j]);
84          }
85      }
86  
87      /**
88       * Generate Rule from the string representation of Rule.
89       * Rule string representation can have two patterns:
90       * 1. "nodeType1,nodeType2,nodeType3,..."
91       * 2. "[nodeType1, nodeType2, ...]; Reverse:false/true". see {@link #toString()}
92       */
93      public Rule(String ruleStringRepresentation, String separator) {
94          String nodeTypes = ruleStringRepresentation;
95          if (StringUtils.contains(ruleStringRepresentation, "[") && StringUtils.contains(ruleStringRepresentation, "]")) {
96              nodeTypes = StringUtils.substringBetween(ruleStringRepresentation, "[", "]").replaceAll("\\s", "");
97              reverse = Boolean.parseBoolean(StringUtils.substringAfter(ruleStringRepresentation, REVERSE_LABEL));
98          }
99  
100         String[] types = StringUtils.split(nodeTypes, separator);
101         for (int j = 0; j < types.length; j++) {
102             this.addAllowType(types[j]);
103         }
104     }
105 
106     public void setAllowedTypes(String[] types) {
107         for (String t : types) {
108             this.addAllowType(t);
109         }
110     }
111 
112     /**
113      * Add to allow list.
114      */
115     public void addAllowType(String nodeType) {
116         if (nodeType != null) {
117             this.allowedTypes.add(nodeType);
118         }
119     }
120 
121     /**
122      * Remove from allow list.
123      */
124     public void removeAllowType(String nodeType) {
125         if (nodeType != null) {
126             this.allowedTypes.remove(nodeType);
127         }
128     }
129 
130     /**
131      * True if allowedTypes contains nodeType.
132      * Method return false also if nodeType is subtype of one of the allowedTypes.
133      *
134      * @deprecated since 4.5.5 - use {@link #isAllowed(Node)} instead.
135      */
136     @Deprecated
137     public boolean isAllowed(String nodeType) {
138         boolean allowed = this.allowedTypes.contains(nodeType);
139         if (this.reverse) {
140             return !allowed;
141         }
142 
143         return allowed;
144 
145     }
146 
147     /**
148      * True if given nodeType is allowed.
149      */
150     public boolean isAllowed(Node node) throws RepositoryException {
151         boolean allowed = false;
152 
153         for (String allowedType : this.allowedTypes) {
154             allowed |= NodeUtil.isNodeType(node, allowedType);
155         }
156 
157         if (this.reverse) {
158             return !allowed;
159         }
160 
161         return allowed;
162     }
163 
164     /**
165      * Get a string representation of this rule.
166      * Pattern is "[nodeType1, nodeType2, ...]; Reverse:false/true".
167      *
168      * @return string representation
169      */
170     @Override
171     public String toString() {
172         final StringBuilder builder = new StringBuilder();
173         builder.append(allowedTypes.toString());
174         builder.append("; ");
175         builder.append(REVERSE_LABEL);
176         builder.append(reverse);
177         return builder.toString();
178     }
179 
180     /**
181      * Set reverse.
182      */
183     public void reverse() {
184         this.reverse = true;
185     }
186 
187     private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
188         final ObjectInputStream.GetField field = ois.readFields();
189         final Object o = field.get("allowedTypes", null);
190         if (o instanceof String[]) {
191             Set<String> typesCol = new HashSet<String>();
192             typesCol.addAll(Arrays.asList((String[]) o));
193             this.allowedTypes = typesCol;
194         }
195         if (o instanceof HashSet) {
196             this.allowedTypes = (Set<String>) o;
197         }
198         this.reverse = field.get("reverse", false);
199     }
200 }