com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlPropertyResolverHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gemfire-core Show documentation
Show all versions of gemfire-core Show documentation
SnappyData store based off Pivotal GemFireXD
The newest version!
/*
* Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License. See accompanying
* LICENSE file.
*/
package com.gemstone.gemfire.internal.cache.xmlcache;
import java.util.HashMap;
import java.util.Set;
import com.gemstone.gemfire.i18n.LogWriterI18n;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
/**
* Helper class for CacheXmlPropertyResolver. Helps in parsing ${...${}..}..${} strings.
*
* @author Shobhit Agarwal
* @since 6.6
*/
public class CacheXmlPropertyResolverHelper {
LogWriterI18n logWriter;
public static final String DEFAULT_PROPERTY_STRING_PREFIX = "${";
public static final String DEFAULT_PROPERTY_STRING_SUFFIX = "}";
public static final String DEFAULT_PREFIX_FOR_SUFFIX = "{";
/**
* This HashMap
contains valid suffixes and prefixes to be
* parsed by {@link CacheXmlPropertyResolverHelper} like {}, [] or ().
*/
private static HashMap validSuffixAndPrefixes = new HashMap();
static {
validSuffixAndPrefixes.put("}", "{");
validSuffixAndPrefixes.put("]", "[");
validSuffixAndPrefixes.put(")", "(");
}
/* String specifying the suffice for property key prefix */
private String propertyPrefix = DEFAULT_PROPERTY_STRING_PREFIX;
/* String specifying the suffice for property key suffix */
private String propertySuffix = DEFAULT_PROPERTY_STRING_SUFFIX;
private String prefixForSuffix = DEFAULT_PREFIX_FOR_SUFFIX;
/**
* @param propPrefix
* @param propSuffix
*/
public CacheXmlPropertyResolverHelper(String propPrefix,
String propSuffix) {
if(propPrefix != null && propSuffix != null){
String validPrefix = validSuffixAndPrefixes.get(propSuffix);
if(validPrefix != null && propPrefix.endsWith(validPrefix)){
this.prefixForSuffix = validPrefix;
} else {
this.prefixForSuffix = propPrefix;
}
this.propertyPrefix = propPrefix;
this.propertySuffix = propSuffix;
}
}
/**
* Parses the given string which are supposed to be like ${} for system and/or Gemfire
* properties to be replaced. This will return property.name from ${property.name}.
* @param unparsedString
* @return parsedString
*/
protected String parseResolvablePropString(String unparsedString, PropertyResolver resolver, Set visitedReplaceableStrings){
StringBuilder buf = new StringBuilder(unparsedString);
int prefixIndex = buf.indexOf(propertyPrefix);
while(prefixIndex != -1){
int suffixIndex = findSuffixIndex(buf, prefixIndex+propertyPrefix.length());
if(suffixIndex != -1){
String replaceableString = buf.substring(prefixIndex+propertyPrefix.length(), suffixIndex);
//Check for circular references
if(!visitedReplaceableStrings.add(replaceableString)){
if(getLogWriter() != null){
logWriter.info(LocalizedStrings.CacheXmlPropertyResolverHelper_SOME_UNRESOLVED_STRING_REPLACED_CIRCULAR_ERROR__0, replaceableString);
}
throw new IllegalArgumentException("Some still unresolved string "+ replaceableString+" was replaced by resolver, leading to circular references.");
}
/** Find the replacement using given resolver
*/
replaceableString = parseResolvablePropString(replaceableString, resolver, visitedReplaceableStrings);
String replacement = resolver.resolveReplaceString(replaceableString);
if(replacement != null){
/** put replacement in unparsedString
and call parseResolvablePropString
recursively to find more
* unparsedStrings in the replaced value of given unparsedString.*/
replacement = parseResolvablePropString(replacement, resolver, visitedReplaceableStrings);
buf.replace(prefixIndex, suffixIndex+propertySuffix.length(), replacement);
prefixIndex = buf.indexOf(propertyPrefix, prefixIndex+replacement.length());
} else if(resolver.isIgnoreUnresolvedProperties()) {
/** Look for more replaceable strings in given unparsedString
. */
prefixIndex = buf.indexOf(propertyPrefix, suffixIndex+propertySuffix.length());
} else {
throw new IllegalArgumentException("No replacement found for property : "+ replaceableString);
}
//Before iterating again remove replaceable string from visitedReplaceableStrings as it can appear again.
visitedReplaceableStrings.remove(replaceableString);
} else {
prefixIndex = -1;
}
}
return buf.toString();
}
/**
* Finds index of suffix in a string from a specified index. Like finds index of
* "}" in string "${my.prop.name}" starting from index 2, which is 14.
* @param buf
* @param index
* @return suffix
*/
private int findSuffixIndex(StringBuilder buf, int index) {
int inNestedProperty = 0;
while (index < buf.length()) {
if (buf.substring(index, index+this.propertySuffix.length()).equalsIgnoreCase(this.propertySuffix)) {
if (inNestedProperty > 0) {
inNestedProperty--;
index = index + this.propertySuffix.length();
} else {
return index;
}
} else if (buf.substring(index, index+this.prefixForSuffix.length()).equalsIgnoreCase(this.prefixForSuffix)) {
inNestedProperty++;
index = index + this.prefixForSuffix.length();
} else {
index++;
}
}
return -1;
}
public LogWriterI18n getLogWriter() {
return logWriter;
}
public void setLogWriter(LogWriterI18n logWriter) {
this.logWriter = logWriter;
}
}