/** * Creates the {@code DefaultExpressionEngineSymbols} instance based on * the properties set for this builder object. This method does not * change the state of this builder. So it is possible to change * properties and create another {@code DefaultExpressionEngineSymbols} * instance. * * @return the newly created {@code DefaultExpressionEngineSymbols} * instance */ public DefaultExpressionEngineSymbols create() { return new DefaultExpressionEngineSymbols(this); } }
/** * Creates a new instance of {@code Builder} whose properties are * initialized from the passed in {@code DefaultExpressionEngineSymbols} * object. This is useful if symbols are to be created which are similar * to the passed in instance. * * @param c the {@code DefaultExpressionEngineSymbols} object serving as * starting point for this builder */ public Builder(final DefaultExpressionEngineSymbols c) { propertyDelimiter = c.getPropertyDelimiter(); escapedDelimiter = c.getEscapedDelimiter(); indexStart = c.getIndexStart(); indexEnd = c.getIndexEnd(); attributeStart = c.getAttributeStart(); attributeEnd = c.getAttributeEnd(); }
/** * Returns a flag whether attributes are marked the same way as normal * property keys. We call this the "attribute emulating mode". * When navigating through node hierarchies it might be convenient to * treat attributes the same way than other child nodes, so an * expression engine supports to set the attribute markers to the same * value than the property delimiter. If this is the case, some special * checks have to be performed. * * @return a flag if attributes and normal property keys are treated the * same way */ private boolean isAttributeEmulatingMode() { return getSymbols().getAttributeEnd() == null && StringUtils.equals(getSymbols() .getPropertyDelimiter(), getSymbols() .getAttributeStart()); } }
/** * Determines the relative offset of an escaped delimiter in relation to * a delimiter. Depending on the used delimiter and escaped delimiter * tokens the position where to search for an escaped delimiter is * different. If, for instance, the dot character (".") is * used as delimiter, and a doubled dot ("..") as escaped * delimiter, the escaped delimiter starts at the same position as the * delimiter. If the token "\." was used, it would start one * character before the delimiter because the delimiter character * "." is the second character in the escaped delimiter * string. This relation will be determined by this method. For this to * work the delimiter string must be contained in the escaped delimiter * string. * * @return the relative offset of the escaped delimiter in relation to a * delimiter */ private int escapeOffset() { return getSymbols().getEscapedDelimiter().indexOf( getSymbols().getPropertyDelimiter()); }
/** * Helper method for removing attribute markers from a key. * * @param key the key * @return the key with removed attribute markers */ private String removeAttributeMarkers(final String key) { return key .substring( getSymbols().getAttributeStart().length(), key.length() - ((getSymbols().getAttributeEnd() != null) ? getSymbols() .getAttributeEnd().length() : 0)); }
/** * Appends an index to this configuration key. * * @param index the index to be appended * @return a reference to this object */ public DefaultConfigurationKey appendIndex(final int index) { keyBuffer.append(getSymbols().getIndexStart()); keyBuffer.append(index); keyBuffer.append(getSymbols().getIndexEnd()); return this; }
.getPropertyDelimiter(), delimiterPos); if (delimiterPos < 0 || delimiterPos >= endPos)
if (getSymbols().getEscapedDelimiter() == null) .getEscapedDelimiter(), pos - escapeOffset); if (escapePos <= pos && escapePos >= 0) + getSymbols().getEscapedDelimiter().length();
/** * Helper method for extracting the next key part. Takes escaping of * delimiter characters into account. * * @return the next key part */ private String nextKeyPart() { int attrIdx = keyBuffer.toString().indexOf( getSymbols().getAttributeStart(), startIndex); if (attrIdx < 0 || attrIdx == startIndex) { attrIdx = length(); } int delIdx = nextDelimiterPos(keyBuffer.toString(), startIndex, attrIdx); if (delIdx < 0) { delIdx = attrIdx; } endIndex = Math.min(attrIdx, delIdx); return unescapeDelimiters(keyBuffer.substring(startIndex, endIndex)); }
/** * Unescapes the delimiters in the specified string. * * @param key the key to be unescaped * @return the unescaped key */ private String unescapeDelimiters(final String key) { return (getSymbols().getEscapedDelimiter() == null) ? key : StringUtils.replace(key, getSymbols() .getEscapedDelimiter(), getSymbols() .getPropertyDelimiter()); }
/** * Tests if the specified key represents an attribute according to the * current expression engine. * * @param key the key to be checked * @return <b>true</b> if this is an attribute key, <b>false</b> otherwise */ public boolean isAttributeKey(final String key) { if (key == null) { return false; } return key.startsWith(getSymbols().getAttributeStart()) && (getSymbols().getAttributeEnd() == null || key .endsWith(getSymbols().getAttributeEnd())); }
final int idx = key.lastIndexOf(getSymbols().getIndexStart()); if (idx > 0) final int endidx = key.indexOf(getSymbols().getIndexEnd(), idx);
/** * Removes trailing property delimiters from the specified key. * * @param key the key * @return the key with removed trailing property delimiters */ public String trimRight(final String key) { if (key == null) { return StringUtils.EMPTY; } String result = key; while (hasTrailingDelimiter(result)) { result = result .substring(0, result.length() - getSymbols().getPropertyDelimiter() .length()); } return result; }
/** * Returns a hash code for this object. * * @return a hash code */ @Override public int hashCode() { return new HashCodeBuilder().append(getPropertyDelimiter()) .append(getEscapedDelimiter()).append(getIndexStart()) .append(getIndexEnd()).append(getAttributeStart()) .append(getAttributeEnd()).toHashCode(); }
/** * Helper method that checks if the specified key ends with a property * delimiter. * * @param key the key to check * @return a flag if there is a trailing delimiter */ private boolean hasTrailingDelimiter(final String key) { return key.endsWith(getSymbols().getPropertyDelimiter()) && (getSymbols().getEscapedDelimiter() == null || !key .endsWith(getSymbols().getEscapedDelimiter())); }
/** * Decorates the given key so that it represents an attribute. Adds special * start and end markers. The passed in string will be modified only if does * not already represent an attribute. * * @param key the key to be decorated * @return the decorated attribute key */ public String constructAttributeKey(final String key) { if (key == null) { return StringUtils.EMPTY; } if (isAttributeKey(key)) { return key; } final StringBuilder buf = new StringBuilder(); buf.append(getSymbols().getAttributeStart()).append(key); if (getSymbols().getAttributeEnd() != null) { buf.append(getSymbols().getAttributeEnd()); } return buf.toString(); }
/** * Removes leading property delimiters from the specified key. * * @param key the key * @return the key with removed leading property delimiters */ public String trimLeft(final String key) { if (key == null) { return StringUtils.EMPTY; } String result = key; while (hasLeadingDelimiter(result)) { result = result.substring(getSymbols() .getPropertyDelimiter().length()); } return result; }
/** * Returns a string representation for this object. This string contains the * values of all properties. * * @return a string for this object */ @Override public String toString() { return new ToStringBuilder(this) .append("propertyDelimiter", getPropertyDelimiter()) .append("escapedDelimiter", getEscapedDelimiter()) .append("indexStart", getIndexStart()) .append("indexEnd", getIndexEnd()) .append("attributeStart", getAttributeStart()) .append("attributeEnd", getAttributeEnd()).toString(); }
/** * Helper method that checks if the specified key starts with a property * delimiter. * * @param key the key to check * @return a flag if there is a leading delimiter */ private boolean hasLeadingDelimiter(final String key) { return key.startsWith(getSymbols().getPropertyDelimiter()) && (getSymbols().getEscapedDelimiter() == null || !key .startsWith(getSymbols().getEscapedDelimiter())); }
/** * Helper method for determining the next indices. * * @return the next key part */ private String findNextIndices() { startIndex = endIndex; // skip empty names while (startIndex < length() && hasLeadingDelimiter(keyBuffer.substring(startIndex))) { startIndex += getSymbols().getPropertyDelimiter() .length(); } // Key ends with a delimiter? if (startIndex >= length()) { endIndex = length(); startIndex = endIndex - 1; return keyBuffer.substring(startIndex, endIndex); } return nextKeyPart(); }