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 * @version $Id: DefaultExpressionEngineSymbols.java 1624601 2014-09-12 18:04:36Z oheger $ 040 * @since 2.0 041 */ 042public final class DefaultExpressionEngineSymbols 043{ 044 /** Constant for the default property delimiter. */ 045 public static final String DEFAULT_PROPERTY_DELIMITER = "."; 046 047 /** Constant for the default escaped property delimiter. */ 048 public static final String DEFAULT_ESCAPED_DELIMITER = DEFAULT_PROPERTY_DELIMITER 049 + DEFAULT_PROPERTY_DELIMITER; 050 051 /** Constant for the default attribute start marker. */ 052 public static final String DEFAULT_ATTRIBUTE_START = "[@"; 053 054 /** Constant for the default attribute end marker. */ 055 public static final String DEFAULT_ATTRIBUTE_END = "]"; 056 057 /** Constant for the default index start marker. */ 058 public static final String DEFAULT_INDEX_START = "("; 059 060 /** Constant for the default index end marker. */ 061 public static final String DEFAULT_INDEX_END = ")"; 062 063 /** 064 * An instance with default symbols. This instance is used by the default 065 * instance of {@code DefaultExpressionEngine}. 066 */ 067 public static final DefaultExpressionEngineSymbols DEFAULT_SYMBOLS = 068 createDefaultSmybols(); 069 070 /** Stores the property delimiter. */ 071 private final String propertyDelimiter; 072 073 /** Stores the escaped property delimiter. */ 074 private final String escapedDelimiter; 075 076 /** Stores the attribute start marker. */ 077 private final String attributeStart; 078 079 /** Stores the attribute end marker. */ 080 private final String attributeEnd; 081 082 /** Stores the index start marker. */ 083 private final String indexStart; 084 085 /** stores the index end marker. */ 086 private final String indexEnd; 087 088 /** 089 * Creates a new instance of {@code DefaultExpressionEngineSymbols}. 090 * 091 * @param b the builder for defining the properties of this instance 092 */ 093 private DefaultExpressionEngineSymbols(Builder b) 094 { 095 propertyDelimiter = b.propertyDelimiter; 096 escapedDelimiter = b.escapedDelimiter; 097 indexStart = b.indexStart; 098 indexEnd = b.indexEnd; 099 attributeStart = b.attributeStart; 100 attributeEnd = b.attributeEnd; 101 } 102 103 /** 104 * Returns the string used as delimiter in property keys. 105 * 106 * @return the property delimiter 107 */ 108 public String getPropertyDelimiter() 109 { 110 return propertyDelimiter; 111 } 112 113 /** 114 * Returns the string representing an escaped property delimiter. 115 * 116 * @return the escaped property delimiter 117 */ 118 public String getEscapedDelimiter() 119 { 120 return escapedDelimiter; 121 } 122 123 /** 124 * Returns the string representing an attribute start marker. 125 * 126 * @return the attribute start marker 127 */ 128 public String getAttributeStart() 129 { 130 return attributeStart; 131 } 132 133 /** 134 * Returns the string representing an attribute end marker. 135 * 136 * @return the attribute end marker 137 */ 138 public String getAttributeEnd() 139 { 140 return attributeEnd; 141 } 142 143 /** 144 * Returns the string representing the start of an index in a property key. 145 * 146 * @return the index start marker 147 */ 148 public String getIndexStart() 149 { 150 return indexStart; 151 } 152 153 /** 154 * Returns the string representing the end of an index in a property key. 155 * 156 * @return the index end marker 157 */ 158 public String getIndexEnd() 159 { 160 return indexEnd; 161 } 162 163 /** 164 * Returns a hash code for this object. 165 * 166 * @return a hash code 167 */ 168 @Override 169 public int hashCode() 170 { 171 return new HashCodeBuilder().append(getPropertyDelimiter()) 172 .append(getEscapedDelimiter()).append(getIndexStart()) 173 .append(getIndexEnd()).append(getAttributeStart()) 174 .append(getAttributeEnd()).toHashCode(); 175 } 176 177 /** 178 * Compares this object with another one. Two instances of 179 * {@code DefaultExpressionEngineSymbols} are considered equal if all of 180 * their properties are equal. 181 * 182 * @param obj the object to compare to 183 * @return a flag whether these objects are equal 184 */ 185 @Override 186 public boolean equals(Object obj) 187 { 188 if (this == obj) 189 { 190 return true; 191 } 192 if (!(obj instanceof DefaultExpressionEngineSymbols)) 193 { 194 return false; 195 } 196 197 DefaultExpressionEngineSymbols c = (DefaultExpressionEngineSymbols) obj; 198 return new EqualsBuilder() 199 .append(getPropertyDelimiter(), c.getPropertyDelimiter()) 200 .append(getEscapedDelimiter(), c.getEscapedDelimiter()) 201 .append(getIndexStart(), c.getIndexStart()) 202 .append(getIndexEnd(), c.getIndexEnd()) 203 .append(getAttributeStart(), c.getAttributeStart()) 204 .append(getAttributeEnd(), c.getAttributeEnd()).isEquals(); 205 } 206 207 /** 208 * Returns a string representation for this object. This string contains the 209 * values of all properties. 210 * 211 * @return a string for this object 212 */ 213 @Override 214 public String toString() 215 { 216 return new ToStringBuilder(this) 217 .append("propertyDelimiter", getPropertyDelimiter()) 218 .append("escapedDelimiter", getEscapedDelimiter()) 219 .append("indexStart", getIndexStart()) 220 .append("indexEnd", getIndexEnd()) 221 .append("attributeStart", getAttributeStart()) 222 .append("attributeEnd", getAttributeEnd()).toString(); 223 } 224 225 /** 226 * Creates the {@code DefaultExpressionEngineSymbols} object with default 227 * symbols. 228 * 229 * @return the default symbols instance 230 */ 231 private static DefaultExpressionEngineSymbols createDefaultSmybols() 232 { 233 return new Builder().setPropertyDelimiter(DEFAULT_PROPERTY_DELIMITER) 234 .setEscapedDelimiter(DEFAULT_ESCAPED_DELIMITER) 235 .setIndexStart(DEFAULT_INDEX_START) 236 .setIndexEnd(DEFAULT_INDEX_END) 237 .setAttributeStart(DEFAULT_ATTRIBUTE_START) 238 .setAttributeEnd(DEFAULT_ATTRIBUTE_END).create(); 239 } 240 241 /** 242 * A builder class for creating instances of 243 * {@code DefaultExpressionEngineSymbols}. 244 */ 245 public static class Builder 246 { 247 /** Stores the property delimiter. */ 248 private String propertyDelimiter; 249 250 /** Stores the escaped property delimiter. */ 251 private String escapedDelimiter; 252 253 /** Stores the attribute start marker. */ 254 private String attributeStart; 255 256 /** Stores the attribute end marker. */ 257 private String attributeEnd; 258 259 /** Stores the index start marker. */ 260 private String indexStart; 261 262 /** stores the index end marker. */ 263 private String indexEnd; 264 265 /** 266 * Creates a new, uninitialized instance of {@code Builder}. All symbols 267 * are undefined. 268 */ 269 public Builder() 270 { 271 } 272 273 /** 274 * Creates a new instance of {@code Builder} whose properties are 275 * initialized from the passed in {@code DefaultExpressionEngineSymbols} 276 * object. This is useful if symbols are to be created which are similar 277 * to the passed in instance. 278 * 279 * @param c the {@code DefaultExpressionEngineSymbols} object serving as 280 * starting point for this builder 281 */ 282 public Builder(DefaultExpressionEngineSymbols c) 283 { 284 propertyDelimiter = c.getPropertyDelimiter(); 285 escapedDelimiter = c.getEscapedDelimiter(); 286 indexStart = c.getIndexStart(); 287 indexEnd = c.getIndexEnd(); 288 attributeStart = c.getAttributeStart(); 289 attributeEnd = c.getAttributeEnd(); 290 } 291 292 /** 293 * Sets the string representing a delimiter for properties. 294 * 295 * @param d the property delimiter 296 * @return a reference to this object for method chaining 297 */ 298 public Builder setPropertyDelimiter(String d) 299 { 300 propertyDelimiter = d; 301 return this; 302 } 303 304 /** 305 * Sets the string representing an escaped property delimiter. With this 306 * string a delimiter that belongs to the key of a property can be 307 * escaped. If for instance "." is used as property delimiter, 308 * you can set the escaped delimiter to "\." and can then 309 * escape the delimiter with a back slash. 310 * 311 * @param ed the escaped property delimiter 312 * @return a reference to this object for method chaining 313 */ 314 public Builder setEscapedDelimiter(String ed) 315 { 316 escapedDelimiter = ed; 317 return this; 318 } 319 320 /** 321 * Sets the string representing the start of an index in a property key. 322 * Index start and end marker are used together to detect indices in a 323 * property key. 324 * 325 * @param is the index start 326 * @return a reference to this object for method chaining 327 */ 328 public Builder setIndexStart(String is) 329 { 330 indexStart = is; 331 return this; 332 } 333 334 /** 335 * Sets the string representing the end of an index in a property key. 336 * 337 * @param ie the index end 338 * @return a reference to this object for method chaining 339 */ 340 public Builder setIndexEnd(String ie) 341 { 342 indexEnd = ie; 343 return this; 344 } 345 346 /** 347 * Sets the string representing the start marker of an attribute in a 348 * property key. Attribute start and end marker are used together to 349 * detect attributes in a property key. 350 * 351 * @param as the attribute start marker 352 * @return a reference to this object for method chaining 353 */ 354 public Builder setAttributeStart(String as) 355 { 356 attributeStart = as; 357 return this; 358 } 359 360 /** 361 * Sets the string representing the end marker of an attribute in a 362 * property key. 363 * 364 * @param ae the attribute end marker 365 * @return a reference to this object for method chaining 366 */ 367 public Builder setAttributeEnd(String ae) 368 { 369 attributeEnd = ae; 370 return this; 371 } 372 373 /** 374 * Creates the {@code DefaultExpressionEngineSymbols} instance based on 375 * the properties set for this builder object. This method does not 376 * change the state of this builder. So it is possible to change 377 * properties and create another {@code DefaultExpressionEngineSymbols} 378 * instance. 379 * 380 * @return the newly created {@code DefaultExpressionEngineSymbols} 381 * instance 382 */ 383 public DefaultExpressionEngineSymbols create() 384 { 385 return new DefaultExpressionEngineSymbols(this); 386 } 387 } 388}