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    *     https://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  
40      /**
41       * A builder class for creating instances of {@code DefaultExpressionEngineSymbols}.
42       */
43      public static class Builder {
44  
45          /** Stores the property delimiter. */
46          private String propertyDelimiter;
47  
48          /** Stores the escaped property delimiter. */
49          private String escapedDelimiter;
50  
51          /** Stores the attribute start marker. */
52          private String attributeStart;
53  
54          /** Stores the attribute end marker. */
55          private String attributeEnd;
56  
57          /** Stores the index start marker. */
58          private String indexStart;
59  
60          /** Stores the index end marker. */
61          private String indexEnd;
62  
63          /**
64           * Creates a new, uninitialized instance of {@code Builder}. All symbols are undefined.
65           */
66          public Builder() {
67          }
68  
69          /**
70           * Creates a new instance of {@code Builder} whose properties are initialized from the passed in
71           * {@code DefaultExpressionEngineSymbols} object. This is useful if symbols are to be created which are similar to the
72           * passed in instance.
73           *
74           * @param c the {@code DefaultExpressionEngineSymbols} object serving as starting point for this builder
75           */
76          public Builder(final DefaultExpressionEngineSymbols c) {
77              propertyDelimiter = c.getPropertyDelimiter();
78              escapedDelimiter = c.getEscapedDelimiter();
79              indexStart = c.getIndexStart();
80              indexEnd = c.getIndexEnd();
81              attributeStart = c.getAttributeStart();
82              attributeEnd = c.getAttributeEnd();
83          }
84  
85          /**
86           * Creates the {@code DefaultExpressionEngineSymbols} instance based on the properties set for this builder object. This
87           * method does not change the state of this builder. So it is possible to change properties and create another
88           * {@code DefaultExpressionEngineSymbols} instance.
89           *
90           * @return the newly created {@code DefaultExpressionEngineSymbols} instance
91           */
92          public DefaultExpressionEngineSymbols create() {
93              return new DefaultExpressionEngineSymbols(this);
94          }
95  
96          /**
97           * Sets the string representing the end marker of an attribute in a property key.
98           *
99           * @param attributeEnd the attribute end marker
100          * @return a reference to this object for method chaining
101          */
102         public Builder setAttributeEnd(final String attributeEnd) {
103             this.attributeEnd = attributeEnd;
104             return this;
105         }
106 
107         /**
108          * Sets the string representing the start marker of an attribute in a property key. Attribute start and end marker are
109          * used together to detect attributes in a property key.
110          *
111          * @param attributeStart the attribute start marker
112          * @return a reference to this object for method chaining
113          */
114         public Builder setAttributeStart(final String attributeStart) {
115             this.attributeStart = attributeStart;
116             return this;
117         }
118 
119         /**
120          * Sets the string representing an escaped property delimiter. With this string a delimiter that belongs to the key of a
121          * property can be escaped. If for instance &quot;.&quot; is used as property delimiter, you can set the escaped
122          * delimiter to &quot;\.&quot; and can then escape the delimiter with a back slash.
123          *
124          * @param escapedDelimiter the escaped property delimiter
125          * @return a reference to this object for method chaining
126          */
127         public Builder setEscapedDelimiter(final String escapedDelimiter) {
128             this.escapedDelimiter = escapedDelimiter;
129             return this;
130         }
131 
132         /**
133          * Sets the string representing the end of an index in a property key.
134          *
135          * @param indexEnd the index end
136          * @return a reference to this object for method chaining
137          */
138         public Builder setIndexEnd(final String indexEnd) {
139             this.indexEnd = indexEnd;
140             return this;
141         }
142 
143         /**
144          * Sets the string representing the start of an index in a property key. Index start and end marker are used together to
145          * detect indices in a property key.
146          *
147          * @param is the index start
148          * @return a reference to this object for method chaining
149          */
150         public Builder setIndexStart(final String is) {
151             this.indexStart = is;
152             return this;
153         }
154 
155         /**
156          * Sets the string representing a delimiter for properties.
157          *
158          * @param propertyDelimiter the property delimiter
159          * @return a reference to this object for method chaining
160          */
161         public Builder setPropertyDelimiter(final String propertyDelimiter) {
162             this.propertyDelimiter = propertyDelimiter;
163             return this;
164         }
165     }
166 
167     /** Constant for the default property delimiter. */
168     public static final String DEFAULT_PROPERTY_DELIMITER = ".";
169 
170     /** Constant for the default escaped property delimiter. */
171     public static final String DEFAULT_ESCAPED_DELIMITER = DEFAULT_PROPERTY_DELIMITER + DEFAULT_PROPERTY_DELIMITER;
172 
173     /** Constant for the default attribute start marker. */
174     public static final String DEFAULT_ATTRIBUTE_START = "[@";
175 
176     /** Constant for the default attribute end marker. */
177     public static final String DEFAULT_ATTRIBUTE_END = "]";
178 
179     /** Constant for the default index start marker. */
180     public static final String DEFAULT_INDEX_START = "(";
181 
182     /** Constant for the default index end marker. */
183     public static final String DEFAULT_INDEX_END = ")";
184 
185     /**
186      * An instance with default symbols. This instance is used by the default instance of {@code DefaultExpressionEngine}.
187      */
188     public static final DefaultExpressionEngineSymbols DEFAULT_SYMBOLS = createDefaultSmybols();
189 
190     /**
191      * Creates the {@code DefaultExpressionEngineSymbols} object with default symbols.
192      *
193      * @return the default symbols instance
194      */
195     private static DefaultExpressionEngineSymbols createDefaultSmybols() {
196         return new Builder().setPropertyDelimiter(DEFAULT_PROPERTY_DELIMITER).setEscapedDelimiter(DEFAULT_ESCAPED_DELIMITER).setIndexStart(DEFAULT_INDEX_START)
197             .setIndexEnd(DEFAULT_INDEX_END).setAttributeStart(DEFAULT_ATTRIBUTE_START).setAttributeEnd(DEFAULT_ATTRIBUTE_END).create();
198     }
199 
200     /** Stores the property delimiter. */
201     private final String propertyDelimiter;
202 
203     /** Stores the escaped property delimiter. */
204     private final String escapedDelimiter;
205 
206     /** Stores the attribute start marker. */
207     private final String attributeStart;
208 
209     /** Stores the attribute end marker. */
210     private final String attributeEnd;
211 
212     /** Stores the index start marker. */
213     private final String indexStart;
214 
215     /** Stores the index end marker. */
216     private final String indexEnd;
217 
218     /**
219      * Creates a new instance of {@code DefaultExpressionEngineSymbols}.
220      *
221      * @param b the builder for defining the properties of this instance
222      */
223     private DefaultExpressionEngineSymbols(final Builder b) {
224         propertyDelimiter = b.propertyDelimiter;
225         escapedDelimiter = b.escapedDelimiter;
226         indexStart = b.indexStart;
227         indexEnd = b.indexEnd;
228         attributeStart = b.attributeStart;
229         attributeEnd = b.attributeEnd;
230     }
231 
232     /**
233      * Compares this object with another one. Two instances of {@code DefaultExpressionEngineSymbols} are considered equal
234      * if all of their properties are equal.
235      *
236      * @param obj the object to compare to
237      * @return a flag whether these objects are equal
238      */
239     @Override
240     public boolean equals(final Object obj) {
241         if (this == obj) {
242             return true;
243         }
244         if (!(obj instanceof DefaultExpressionEngineSymbols)) {
245             return false;
246         }
247 
248         final DefaultExpressionEngineSymbols c = (DefaultExpressionEngineSymbols) obj;
249         return new EqualsBuilder().append(getPropertyDelimiter(), c.getPropertyDelimiter()).append(getEscapedDelimiter(), c.getEscapedDelimiter())
250             .append(getIndexStart(), c.getIndexStart()).append(getIndexEnd(), c.getIndexEnd()).append(getAttributeStart(), c.getAttributeStart())
251             .append(getAttributeEnd(), c.getAttributeEnd()).isEquals();
252     }
253 
254     /**
255      * Gets the string representing an attribute end marker.
256      *
257      * @return the attribute end marker
258      */
259     public String getAttributeEnd() {
260         return attributeEnd;
261     }
262 
263     /**
264      * Gets the string representing an attribute start marker.
265      *
266      * @return the attribute start marker
267      */
268     public String getAttributeStart() {
269         return attributeStart;
270     }
271 
272     /**
273      * Gets the string representing an escaped property delimiter.
274      *
275      * @return the escaped property delimiter
276      */
277     public String getEscapedDelimiter() {
278         return escapedDelimiter;
279     }
280 
281     /**
282      * Gets the string representing the end of an index in a property key.
283      *
284      * @return the index end marker
285      */
286     public String getIndexEnd() {
287         return indexEnd;
288     }
289 
290     /**
291      * Gets the string representing the start of an index in a property key.
292      *
293      * @return the index start marker
294      */
295     public String getIndexStart() {
296         return indexStart;
297     }
298 
299     /**
300      * Gets the string used as delimiter in property keys.
301      *
302      * @return the property delimiter
303      */
304     public String getPropertyDelimiter() {
305         return propertyDelimiter;
306     }
307 
308     /**
309      * Returns a hash code for this object.
310      *
311      * @return a hash code
312      */
313     @Override
314     public int hashCode() {
315         return new HashCodeBuilder().append(getPropertyDelimiter()).append(getEscapedDelimiter()).append(getIndexStart()).append(getIndexEnd())
316             .append(getAttributeStart()).append(getAttributeEnd()).toHashCode();
317     }
318 
319     /**
320      * Returns a string representation for this object. This string contains the values of all properties.
321      *
322      * @return a string for this object
323      */
324     @Override
325     public String toString() {
326         return new ToStringBuilder(this).append("propertyDelimiter", getPropertyDelimiter()).append("escapedDelimiter", getEscapedDelimiter())
327             .append("indexStart", getIndexStart()).append("indexEnd", getIndexEnd()).append("attributeStart", getAttributeStart())
328             .append("attributeEnd", getAttributeEnd()).toString();
329     }
330 }