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