blob: 68d01a9dc294e352a9524ee2a15f50df052f2693 [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.fulcrum.yaafi.framework.util;
import java.util.Map;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.logger.Logger;
/**
* Helper class to expand the value and all attributes.
*
* @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
*/
public class ConfigurationUtil
{
/**
* Expand place holders found in values or attrbute values with the
* content of the given variables. The implementation assumes that
* the given configuration can be cast to a DefaultConfiguration
* otherwise we can't use any setters.
*
* @param logger the logger to write diagnostic messages
* @param defaultConfiguration the configuration
* @param vars the map holding the variables
* @throws ConfigurationException parsing the configuration failed
*/
public static void expand(Logger logger, DefaultConfiguration defaultConfiguration, Map vars) throws ConfigurationException
{
if((vars == null) || (vars.size() == 0))
{
return;
}
// update the value of the configuration element
if(defaultConfiguration.getValue(null) != null)
{
String oldValue = defaultConfiguration.getValue();
String newValue = ConfigurationUtil.expand(oldValue, vars);
defaultConfiguration.setValue(newValue);
if(oldValue.equals(newValue) == false)
{
logger.debug("Changed element <"
+ defaultConfiguration.getName()
+ "> from '"
+ oldValue
+ "' ==> '"
+ newValue
+ "'"
);
}
}
// update all attributes
String attributeName = null;
String[] attributeNames = defaultConfiguration.getAttributeNames();
for(int i=0; i<attributeNames.length; i++)
{
attributeName = attributeNames[i];
String oldAttributeValue = defaultConfiguration.getAttribute(attributeName);
String newAttributeValue = ConfigurationUtil.expand(oldAttributeValue, vars);
defaultConfiguration.setAttribute(attributeName, newAttributeValue);
if(oldAttributeValue.equals(newAttributeValue) == false)
{
logger.debug("Changed attribute '"
+ defaultConfiguration.getName() + "@" + attributeName
+ "' from '"
+ oldAttributeValue
+ "' ==> '"
+ newAttributeValue
+ "'"
);
}
}
// and now recurse through all children (children are in general a lot of work)
Configuration[] children = defaultConfiguration.getChildren();
for(int i=0; i<children.length; i++)
{
ConfigurationUtil.expand(logger, ((DefaultConfiguration) children[i]), vars);
}
}
/**
* Perform a series of substitutions. The substitutions
* are performed by replacing ${variable} in the target
* string with the value of provided by the key "variable"
* in the provided hashtable.
*
* The unexpanded ${variable} is always written to
* the string buffer.
*
* @param argStr target string
* @param vars name/value pairs used for substitution
* @return String target string with replacements.
*/
private static String expand(String argStr, Map vars)
{
// ignore failures
boolean isLenient = true;
StringBuilder argBuf = new StringBuilder();
int argStrLength = argStr.length();
for (int cIdx = 0 ; cIdx < argStrLength;)
{
char ch = argStr.charAt(cIdx);
char del = ' ';
switch (ch)
{
case '$':
StringBuilder nameBuf = new StringBuilder();
del = argStr.charAt(cIdx+1);
if( del == '{')
{
cIdx++;
for (++cIdx ; cIdx < argStr.length(); ++cIdx)
{
ch = argStr.charAt(cIdx);
if (ch != '}')
nameBuf.append(ch);
else
break;
}
if (nameBuf.length() > 0)
{
Object value = vars.get(nameBuf.toString());
if (value != null)
{
argBuf.append(value.toString());
}
else
{
if (!isLenient)
{
throw new RuntimeException("No value found for : " + nameBuf );
}
else
{
argBuf.append("${").append(nameBuf).append("}");
}
}
del = argStr.charAt(cIdx);
if( del != '}')
{
throw new RuntimeException("Delimineter not found for : " + nameBuf );
}
}
cIdx++;
}
else
{
argBuf.append(ch);
++cIdx;
}
break;
default:
argBuf.append(ch);
++cIdx;
break;
}
}
return argBuf.toString();
}
}