View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.configuration2.tree;
18  
19  import org.apache.commons.lang3.builder.EqualsBuilder;
20  import org.apache.commons.lang3.builder.HashCodeBuilder;
21  import org.apache.commons.lang3.builder.ToStringBuilder;
22  
23  /**
24   * <p>
25   * A class representing the various symbols that are supported in keys recognized by {@link DefaultExpressionEngine}.
26   * </p>
27   * <p>
28   * An instance of this class is associated with each instance of {@code DefaultExpressionEngine}. It determines which
29   * concrete symbols are used to define elements like separators, attributes, etc. within a configuration key.
30   * </p>
31   * <p>
32   * Instances are created using the nested {@code Builder} class. They are immutable and can be shared between arbitrary
33   * components.
34   * </p>
35   *
36   * @since 2.0
37   */
38  public final class DefaultExpressionEngineSymbols {
39      /** Constant for the default property delimiter. */
40      public static final String DEFAULT_PROPERTY_DELIMITER = ".";
41  
42      /** Constant for the default escaped property delimiter. */
43      public static final String DEFAULT_ESCAPED_DELIMITER = DEFAULT_PROPERTY_DELIMITER + DEFAULT_PROPERTY_DELIMITER;
44  
45      /** Constant for the default attribute start marker. */
46      public static final String DEFAULT_ATTRIBUTE_START = "[@";
47  
48      /** Constant for the default attribute end marker. */
49      public static final String DEFAULT_ATTRIBUTE_END = "]";
50  
51      /** Constant for the default index start marker. */
52      public static final String DEFAULT_INDEX_START = "(";
53  
54      /** Constant for the default index end marker. */
55      public static final String DEFAULT_INDEX_END = ")";
56  
57      /**
58       * An instance with default symbols. This instance is used by the default instance of {@code DefaultExpressionEngine}.
59       */
60      public static final DefaultExpressionEngineSymbols DEFAULT_SYMBOLS = createDefaultSmybols();
61  
62      /** Stores the property delimiter. */
63      private final String propertyDelimiter;
64  
65      /** Stores the escaped property delimiter. */
66      private final String escapedDelimiter;
67  
68      /** Stores the attribute start marker. */
69      private final String attributeStart;
70  
71      /** Stores the attribute end marker. */
72      private final String attributeEnd;
73  
74      /** Stores the index start marker. */
75      private final String indexStart;
76  
77      /** Stores the index end marker. */
78      private final String indexEnd;
79  
80      /**
81       * Creates a new instance of {@code DefaultExpressionEngineSymbols}.
82       *
83       * @param b the builder for defining the properties of this instance
84       */
85      private DefaultExpressionEngineSymbols(final Builder b) {
86          propertyDelimiter = b.propertyDelimiter;
87          escapedDelimiter = b.escapedDelimiter;
88          indexStart = b.indexStart;
89          indexEnd = b.indexEnd;
90          attributeStart = b.attributeStart;
91          attributeEnd = b.attributeEnd;
92      }
93  
94      /**
95       * Gets the string used as delimiter in property keys.
96       *
97       * @return the property delimiter
98       */
99      public String getPropertyDelimiter() {
100         return propertyDelimiter;
101     }
102 
103     /**
104      * Gets the string representing an escaped property delimiter.
105      *
106      * @return the escaped property delimiter
107      */
108     public String getEscapedDelimiter() {
109         return escapedDelimiter;
110     }
111 
112     /**
113      * Gets the string representing an attribute start marker.
114      *
115      * @return the attribute start marker
116      */
117     public String getAttributeStart() {
118         return attributeStart;
119     }
120 
121     /**
122      * Gets the string representing an attribute end marker.
123      *
124      * @return the attribute end marker
125      */
126     public String getAttributeEnd() {
127         return attributeEnd;
128     }
129 
130     /**
131      * Gets the string representing the start of an index in a property key.
132      *
133      * @return the index start marker
134      */
135     public String getIndexStart() {
136         return indexStart;
137     }
138 
139     /**
140      * Gets the string representing the end of an index in a property key.
141      *
142      * @return the index end marker
143      */
144     public String getIndexEnd() {
145         return indexEnd;
146     }
147 
148     /**
149      * Returns a hash code for this object.
150      *
151      * @return a hash code
152      */
153     @Override
154     public int hashCode() {
155         return new HashCodeBuilder().append(getPropertyDelimiter()).append(getEscapedDelimiter()).append(getIndexStart()).append(getIndexEnd())
156             .append(getAttributeStart()).append(getAttributeEnd()).toHashCode();
157     }
158 
159     /**
160      * Compares this object with another one. Two instances of {@code DefaultExpressionEngineSymbols} are considered equal
161      * if all of their properties are equal.
162      *
163      * @param obj the object to compare to
164      * @return a flag whether these objects are equal
165      */
166     @Override
167     public boolean equals(final Object obj) {
168         if (this == obj) {
169             return true;
170         }
171         if (!(obj instanceof DefaultExpressionEngineSymbols)) {
172             return false;
173         }
174 
175         final DefaultExpressionEngineSymbols c = (DefaultExpressionEngineSymbols) obj;
176         return new EqualsBuilder().append(getPropertyDelimiter(), c.getPropertyDelimiter()).append(getEscapedDelimiter(), c.getEscapedDelimiter())
177             .append(getIndexStart(), c.getIndexStart()).append(getIndexEnd(), c.getIndexEnd()).append(getAttributeStart(), c.getAttributeStart())
178             .append(getAttributeEnd(), c.getAttributeEnd()).isEquals();
179     }
180 
181     /**
182      * Returns a string representation for this object. This string contains the values of all properties.
183      *
184      * @return a string for this object
185      */
186     @Override
187     public String toString() {
188         return new ToStringBuilder(this).append("propertyDelimiter", getPropertyDelimiter()).append("escapedDelimiter", getEscapedDelimiter())
189             .append("indexStart", getIndexStart()).append("indexEnd", getIndexEnd()).append("attributeStart", getAttributeStart())
190             .append("attributeEnd", getAttributeEnd()).toString();
191     }
192 
193     /**
194      * Creates the {@code DefaultExpressionEngineSymbols} object with default symbols.
195      *
196      * @return the default symbols instance
197      */
198     private static DefaultExpressionEngineSymbols createDefaultSmybols() {
199         return new Builder().setPropertyDelimiter(DEFAULT_PROPERTY_DELIMITER).setEscapedDelimiter(DEFAULT_ESCAPED_DELIMITER).setIndexStart(DEFAULT_INDEX_START)
200             .setIndexEnd(DEFAULT_INDEX_END).setAttributeStart(DEFAULT_ATTRIBUTE_START).setAttributeEnd(DEFAULT_ATTRIBUTE_END).create();
201     }
202 
203     /**
204      * A builder class for creating instances of {@code DefaultExpressionEngineSymbols}.
205      */
206     public static class Builder {
207         /** Stores the property delimiter. */
208         private String propertyDelimiter;
209 
210         /** Stores the escaped property delimiter. */
211         private String escapedDelimiter;
212 
213         /** Stores the attribute start marker. */
214         private String attributeStart;
215 
216         /** Stores the attribute end marker. */
217         private String attributeEnd;
218 
219         /** Stores the index start marker. */
220         private String indexStart;
221 
222         /** Stores the index end marker. */
223         private String indexEnd;
224 
225         /**
226          * Creates a new, uninitialized instance of {@code Builder}. All symbols are undefined.
227          */
228         public Builder() {
229         }
230 
231         /**
232          * Creates a new instance of {@code Builder} whose properties are initialized from the passed in
233          * {@code DefaultExpressionEngineSymbols} object. This is useful if symbols are to be created which are similar to the
234          * passed in instance.
235          *
236          * @param c the {@code DefaultExpressionEngineSymbols} object serving as starting point for this builder
237          */
238         public Builder(final DefaultExpressionEngineSymbols c) {
239             propertyDelimiter = c.getPropertyDelimiter();
240             escapedDelimiter = c.getEscapedDelimiter();
241             indexStart = c.getIndexStart();
242             indexEnd = c.getIndexEnd();
243             attributeStart = c.getAttributeStart();
244             attributeEnd = c.getAttributeEnd();
245         }
246 
247         /**
248          * Sets the string representing a delimiter for properties.
249          *
250          * @param propertyDelimiter the property delimiter
251          * @return a reference to this object for method chaining
252          */
253         public Builder setPropertyDelimiter(final String propertyDelimiter) {
254             this.propertyDelimiter = propertyDelimiter;
255             return this;
256         }
257 
258         /**
259          * Sets the string representing an escaped property delimiter. With this string a delimiter that belongs to the key of a
260          * property can be escaped. If for instance &quot;.&quot; is used as property delimiter, you can set the escaped
261          * delimiter to &quot;\.&quot; and can then escape the delimiter with a back slash.
262          *
263          * @param escapedDelimiter the escaped property delimiter
264          * @return a reference to this object for method chaining
265          */
266         public Builder setEscapedDelimiter(final String escapedDelimiter) {
267             this.escapedDelimiter = escapedDelimiter;
268             return this;
269         }
270 
271         /**
272          * Sets the string representing the start of an index in a property key. Index start and end marker are used together to
273          * detect indices in a property key.
274          *
275          * @param is the index start
276          * @return a reference to this object for method chaining
277          */
278         public Builder setIndexStart(final String is) {
279             this.indexStart = is;
280             return this;
281         }
282 
283         /**
284          * Sets the string representing the end of an index in a property key.
285          *
286          * @param indexEnd the index end
287          * @return a reference to this object for method chaining
288          */
289         public Builder setIndexEnd(final String indexEnd) {
290             this.indexEnd = indexEnd;
291             return this;
292         }
293 
294         /**
295          * Sets the string representing the start marker of an attribute in a property key. Attribute start and end marker are
296          * used together to detect attributes in a property key.
297          *
298          * @param attributeStart the attribute start marker
299          * @return a reference to this object for method chaining
300          */
301         public Builder setAttributeStart(final String attributeStart) {
302             this.attributeStart = attributeStart;
303             return this;
304         }
305 
306         /**
307          * Sets the string representing the end marker of an attribute in a property key.
308          *
309          * @param attributeEnd the attribute end marker
310          * @return a reference to this object for method chaining
311          */
312         public Builder setAttributeEnd(final String attributeEnd) {
313             this.attributeEnd = attributeEnd;
314             return this;
315         }
316 
317         /**
318          * Creates the {@code DefaultExpressionEngineSymbols} instance based on the properties set for this builder object. This
319          * method does not change the state of this builder. So it is possible to change properties and create another
320          * {@code DefaultExpressionEngineSymbols} instance.
321          *
322          * @return the newly created {@code DefaultExpressionEngineSymbols} instance
323          */
324         public DefaultExpressionEngineSymbols create() {
325             return new DefaultExpressionEngineSymbols(this);
326         }
327     }
328 }