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 "." is used as property delimiter, you can set the escaped 120 * delimiter to "\." 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 }