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