blob: 4a07ea84e0089e400c029127dcc20bc7496101d7 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.apache.camel.component.properties;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A parser to parse a string which contains property placeholders
*
* @version
*/
public class DefaultPropertiesParser implements PropertiesParser {
protected final transient Logger log = LoggerFactory.getLogger(getClass());
public String parseUri(String text, Properties properties, String prefixToken, String suffixToken) throws IllegalArgumentException {
String answer = text;
boolean done = false;
// the placeholders can contain nested placeholders so we need to do recursive parsing
// we must therefore also do circular reference check and must keep a list of visited keys
List<String> visited = new ArrayList<String>();
while (!done) {
List<String> replaced = new ArrayList<String>();
answer = doParseUri(answer, properties, replaced, prefixToken, suffixToken);
// check the replaced with the visited to avoid circular reference
for (String replace : replaced) {
if (visited.contains(replace)) {
throw new IllegalArgumentException("Circular reference detected with key [" + replace + "] from text: " + text);
}
}
// okay all okay so add the replaced as visited
visited.addAll(replaced);
// are we done yet
done = !answer.contains(prefixToken);
}
return answer;
}
public String parseProperty(String key, String value, Properties properties) {
return value;
}
private String doParseUri(String uri, Properties properties, List<String> replaced, String prefixToken, String suffixToken) {
StringBuilder sb = new StringBuilder();
int pivot = 0;
int size = uri.length();
while (pivot < size) {
int idx = uri.indexOf(prefixToken, pivot);
if (idx < 0) {
sb.append(createConstantPart(uri, pivot, size));
break;
} else {
if (pivot < idx) {
sb.append(createConstantPart(uri, pivot, idx));
}
pivot = idx + prefixToken.length();
int endIdx = uri.indexOf(suffixToken, pivot);
if (endIdx < 0) {
throw new IllegalArgumentException("Expecting " + suffixToken + " but found end of string from text: " + uri);
}
String key = uri.substring(pivot, endIdx);
String part = createPlaceholderPart(key, properties, replaced);
if (part == null) {
throw new IllegalArgumentException("Property with key [" + key + "] not found in properties from text: " + uri);
}
sb.append(part);
pivot = endIdx + suffixToken.length();
}
}
return sb.toString();
}
private String createConstantPart(String uri, int start, int end) {
return uri.substring(start, end);
}
private String createPlaceholderPart(String key, Properties properties, List<String> replaced) {
// keep track of which parts we have replaced
replaced.add(key);
String propertyValue = System.getProperty(key);
if (propertyValue != null) {
log.debug("Found a JVM system property: {} with value: {} to be used.", key, propertyValue);
} else if (properties != null) {
propertyValue = properties.getProperty(key);
}
return parseProperty(key, propertyValue, properties);
}
}