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 /** 040 * A builder class for creating instances of {@code DefaultExpressionEngineSymbols}. 041 */ 042 public static class Builder { 043 /** Stores the property delimiter. */ 044 private String propertyDelimiter; 045 046 /** Stores the escaped property delimiter. */ 047 private String escapedDelimiter; 048 049 /** Stores the attribute start marker. */ 050 private String attributeStart; 051 052 /** Stores the attribute end marker. */ 053 private String attributeEnd; 054 055 /** Stores the index start marker. */ 056 private String indexStart; 057 058 /** Stores the index end marker. */ 059 private String indexEnd; 060 061 /** 062 * Creates a new, uninitialized instance of {@code Builder}. All symbols are undefined. 063 */ 064 public Builder() { 065 } 066 067 /** 068 * Creates a new instance of {@code Builder} whose properties are initialized from the passed in 069 * {@code DefaultExpressionEngineSymbols} object. This is useful if symbols are to be created which are similar to the 070 * passed in instance. 071 * 072 * @param c the {@code DefaultExpressionEngineSymbols} object serving as starting point for this builder 073 */ 074 public Builder(final DefaultExpressionEngineSymbols c) { 075 propertyDelimiter = c.getPropertyDelimiter(); 076 escapedDelimiter = c.getEscapedDelimiter(); 077 indexStart = c.getIndexStart(); 078 indexEnd = c.getIndexEnd(); 079 attributeStart = c.getAttributeStart(); 080 attributeEnd = c.getAttributeEnd(); 081 } 082 083 /** 084 * Creates the {@code DefaultExpressionEngineSymbols} instance based on the properties set for this builder object. This 085 * method does not change the state of this builder. So it is possible to change properties and create another 086 * {@code DefaultExpressionEngineSymbols} instance. 087 * 088 * @return the newly created {@code DefaultExpressionEngineSymbols} instance 089 */ 090 public DefaultExpressionEngineSymbols create() { 091 return new DefaultExpressionEngineSymbols(this); 092 } 093 094 /** 095 * Sets the string representing the end marker of an attribute in a property key. 096 * 097 * @param attributeEnd the attribute end marker 098 * @return a reference to this object for method chaining 099 */ 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}