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