001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.configuration2.tree; 018 019import org.apache.commons.lang3.builder.EqualsBuilder; 020import org.apache.commons.lang3.builder.HashCodeBuilder; 021import org.apache.commons.lang3.builder.ToStringBuilder; 022 023/** 024 * <p> 025 * A class representing the various symbols that are supported in keys 026 * recognized by {@link DefaultExpressionEngine}. 027 * </p> 028 * <p> 029 * An instance of this class is associated with each instance of 030 * {@code DefaultExpressionEngine}. It determines which concrete symbols are 031 * used to define elements like separators, attributes, etc. within a 032 * configuration key. 033 * </p> 034 * <p> 035 * Instances are created using the nested {@code Builder} class. They are 036 * immutable and can be shared between arbitrary components. 037 * </p> 038 * 039 * @since 2.0 040 */ 041public final class DefaultExpressionEngineSymbols 042{ 043 /** Constant for the default property delimiter. */ 044 public static final String DEFAULT_PROPERTY_DELIMITER = "."; 045 046 /** Constant for the default escaped property delimiter. */ 047 public static final String DEFAULT_ESCAPED_DELIMITER = DEFAULT_PROPERTY_DELIMITER 048 + DEFAULT_PROPERTY_DELIMITER; 049 050 /** Constant for the default attribute start marker. */ 051 public static final String DEFAULT_ATTRIBUTE_START = "[@"; 052 053 /** Constant for the default attribute end marker. */ 054 public static final String DEFAULT_ATTRIBUTE_END = "]"; 055 056 /** Constant for the default index start marker. */ 057 public static final String DEFAULT_INDEX_START = "("; 058 059 /** Constant for the default index end marker. */ 060 public static final String DEFAULT_INDEX_END = ")"; 061 062 /** 063 * An instance with default symbols. This instance is used by the default 064 * instance of {@code DefaultExpressionEngine}. 065 */ 066 public static final DefaultExpressionEngineSymbols DEFAULT_SYMBOLS = 067 createDefaultSmybols(); 068 069 /** Stores the property delimiter. */ 070 private final String propertyDelimiter; 071 072 /** Stores the escaped property delimiter. */ 073 private final String escapedDelimiter; 074 075 /** Stores the attribute start marker. */ 076 private final String attributeStart; 077 078 /** Stores the attribute end marker. */ 079 private final String attributeEnd; 080 081 /** Stores the index start marker. */ 082 private final String indexStart; 083 084 /** stores the index end marker. */ 085 private final String indexEnd; 086 087 /** 088 * Creates a new instance of {@code DefaultExpressionEngineSymbols}. 089 * 090 * @param b the builder for defining the properties of this instance 091 */ 092 private DefaultExpressionEngineSymbols(final Builder b) 093 { 094 propertyDelimiter = b.propertyDelimiter; 095 escapedDelimiter = b.escapedDelimiter; 096 indexStart = b.indexStart; 097 indexEnd = b.indexEnd; 098 attributeStart = b.attributeStart; 099 attributeEnd = b.attributeEnd; 100 } 101 102 /** 103 * Returns the string used as delimiter in property keys. 104 * 105 * @return the property delimiter 106 */ 107 public String getPropertyDelimiter() 108 { 109 return propertyDelimiter; 110 } 111 112 /** 113 * Returns the string representing an escaped property delimiter. 114 * 115 * @return the escaped property delimiter 116 */ 117 public String getEscapedDelimiter() 118 { 119 return escapedDelimiter; 120 } 121 122 /** 123 * Returns the string representing an attribute start marker. 124 * 125 * @return the attribute start marker 126 */ 127 public String getAttributeStart() 128 { 129 return attributeStart; 130 } 131 132 /** 133 * Returns the string representing an attribute end marker. 134 * 135 * @return the attribute end marker 136 */ 137 public String getAttributeEnd() 138 { 139 return attributeEnd; 140 } 141 142 /** 143 * Returns the string representing the start of an index in a property key. 144 * 145 * @return the index start marker 146 */ 147 public String getIndexStart() 148 { 149 return indexStart; 150 } 151 152 /** 153 * Returns the string representing the end of an index in a property key. 154 * 155 * @return the index end marker 156 */ 157 public String getIndexEnd() 158 { 159 return indexEnd; 160 } 161 162 /** 163 * Returns a hash code for this object. 164 * 165 * @return a hash code 166 */ 167 @Override 168 public int hashCode() 169 { 170 return new HashCodeBuilder().append(getPropertyDelimiter()) 171 .append(getEscapedDelimiter()).append(getIndexStart()) 172 .append(getIndexEnd()).append(getAttributeStart()) 173 .append(getAttributeEnd()).toHashCode(); 174 } 175 176 /** 177 * Compares this object with another one. Two instances of 178 * {@code DefaultExpressionEngineSymbols} are considered equal if all of 179 * their properties are equal. 180 * 181 * @param obj the object to compare to 182 * @return a flag whether these objects are equal 183 */ 184 @Override 185 public boolean equals(final Object obj) 186 { 187 if (this == obj) 188 { 189 return true; 190 } 191 if (!(obj instanceof DefaultExpressionEngineSymbols)) 192 { 193 return false; 194 } 195 196 final DefaultExpressionEngineSymbols c = (DefaultExpressionEngineSymbols) obj; 197 return new EqualsBuilder() 198 .append(getPropertyDelimiter(), c.getPropertyDelimiter()) 199 .append(getEscapedDelimiter(), c.getEscapedDelimiter()) 200 .append(getIndexStart(), c.getIndexStart()) 201 .append(getIndexEnd(), c.getIndexEnd()) 202 .append(getAttributeStart(), c.getAttributeStart()) 203 .append(getAttributeEnd(), c.getAttributeEnd()).isEquals(); 204 } 205 206 /** 207 * Returns a string representation for this object. This string contains the 208 * values of all properties. 209 * 210 * @return a string for this object 211 */ 212 @Override 213 public String toString() 214 { 215 return new ToStringBuilder(this) 216 .append("propertyDelimiter", getPropertyDelimiter()) 217 .append("escapedDelimiter", getEscapedDelimiter()) 218 .append("indexStart", getIndexStart()) 219 .append("indexEnd", getIndexEnd()) 220 .append("attributeStart", getAttributeStart()) 221 .append("attributeEnd", getAttributeEnd()).toString(); 222 } 223 224 /** 225 * Creates the {@code DefaultExpressionEngineSymbols} object with default 226 * symbols. 227 * 228 * @return the default symbols instance 229 */ 230 private static DefaultExpressionEngineSymbols createDefaultSmybols() 231 { 232 return new Builder().setPropertyDelimiter(DEFAULT_PROPERTY_DELIMITER) 233 .setEscapedDelimiter(DEFAULT_ESCAPED_DELIMITER) 234 .setIndexStart(DEFAULT_INDEX_START) 235 .setIndexEnd(DEFAULT_INDEX_END) 236 .setAttributeStart(DEFAULT_ATTRIBUTE_START) 237 .setAttributeEnd(DEFAULT_ATTRIBUTE_END).create(); 238 } 239 240 /** 241 * A builder class for creating instances of 242 * {@code DefaultExpressionEngineSymbols}. 243 */ 244 public static class Builder 245 { 246 /** Stores the property delimiter. */ 247 private String propertyDelimiter; 248 249 /** Stores the escaped property delimiter. */ 250 private String escapedDelimiter; 251 252 /** Stores the attribute start marker. */ 253 private String attributeStart; 254 255 /** Stores the attribute end marker. */ 256 private String attributeEnd; 257 258 /** Stores the index start marker. */ 259 private String indexStart; 260 261 /** stores the index end marker. */ 262 private String indexEnd; 263 264 /** 265 * Creates a new, uninitialized instance of {@code Builder}. All symbols 266 * are undefined. 267 */ 268 public Builder() 269 { 270 } 271 272 /** 273 * Creates a new instance of {@code Builder} whose properties are 274 * initialized from the passed in {@code DefaultExpressionEngineSymbols} 275 * object. This is useful if symbols are to be created which are similar 276 * to the passed in instance. 277 * 278 * @param c the {@code DefaultExpressionEngineSymbols} object serving as 279 * starting point for this builder 280 */ 281 public Builder(final DefaultExpressionEngineSymbols c) 282 { 283 propertyDelimiter = c.getPropertyDelimiter(); 284 escapedDelimiter = c.getEscapedDelimiter(); 285 indexStart = c.getIndexStart(); 286 indexEnd = c.getIndexEnd(); 287 attributeStart = c.getAttributeStart(); 288 attributeEnd = c.getAttributeEnd(); 289 } 290 291 /** 292 * Sets the string representing a delimiter for properties. 293 * 294 * @param d the property delimiter 295 * @return a reference to this object for method chaining 296 */ 297 public Builder setPropertyDelimiter(final String d) 298 { 299 propertyDelimiter = d; 300 return this; 301 } 302 303 /** 304 * Sets the string representing an escaped property delimiter. With this 305 * string a delimiter that belongs to the key of a property can be 306 * escaped. If for instance "." is used as property delimiter, 307 * you can set the escaped delimiter to "\." and can then 308 * escape the delimiter with a back slash. 309 * 310 * @param ed the escaped property delimiter 311 * @return a reference to this object for method chaining 312 */ 313 public Builder setEscapedDelimiter(final String ed) 314 { 315 escapedDelimiter = ed; 316 return this; 317 } 318 319 /** 320 * Sets the string representing the start of an index in a property key. 321 * Index start and end marker are used together to detect indices in a 322 * property key. 323 * 324 * @param is the index start 325 * @return a reference to this object for method chaining 326 */ 327 public Builder setIndexStart(final String is) 328 { 329 indexStart = is; 330 return this; 331 } 332 333 /** 334 * Sets the string representing the end of an index in a property key. 335 * 336 * @param ie the index end 337 * @return a reference to this object for method chaining 338 */ 339 public Builder setIndexEnd(final String ie) 340 { 341 indexEnd = ie; 342 return this; 343 } 344 345 /** 346 * Sets the string representing the start marker of an attribute in a 347 * property key. Attribute start and end marker are used together to 348 * detect attributes in a property key. 349 * 350 * @param as the attribute start marker 351 * @return a reference to this object for method chaining 352 */ 353 public Builder setAttributeStart(final String as) 354 { 355 attributeStart = as; 356 return this; 357 } 358 359 /** 360 * Sets the string representing the end marker of an attribute in a 361 * property key. 362 * 363 * @param ae the attribute end marker 364 * @return a reference to this object for method chaining 365 */ 366 public Builder setAttributeEnd(final String ae) 367 { 368 attributeEnd = ae; 369 return this; 370 } 371 372 /** 373 * Creates the {@code DefaultExpressionEngineSymbols} instance based on 374 * the properties set for this builder object. This method does not 375 * change the state of this builder. So it is possible to change 376 * properties and create another {@code DefaultExpressionEngineSymbols} 377 * instance. 378 * 379 * @return the newly created {@code DefaultExpressionEngineSymbols} 380 * instance 381 */ 382 public DefaultExpressionEngineSymbols create() 383 { 384 return new DefaultExpressionEngineSymbols(this); 385 } 386 } 387}