blob: 3d41f1ed085d72828d4211cd18b87fdf413f88f0 [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.cocoon.transformation.helpers;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/**
* A SAX ContentHandler that builds Avalon <code>Configuration</code> objects,
* but also replaces variables of the form {var} with values from a map.
*
* @see VariableConfiguration
* @author <a href="jefft@apache.org">Jeff Turner</a>
* @version CVS $Id$
*/
public class InterpolatingConfigurationHandler extends SAXConfigurationHandler {
final private Map vars;
final private String location;
/** Constructor.
* @param vars The mappings from variable name to value.
*/
public InterpolatingConfigurationHandler(Map vars) {
this.vars = vars;
this.location = "Unknown";
}
/** Constructor.
* @param vars The mappings from variable name to value.
* @param location The origin of this configuration info.
*/
public InterpolatingConfigurationHandler(Map vars, String location) {
this.vars = vars;
this.location = location;
}
/** Replace {vars} in attributes. */
public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
AttributesImpl newAttr = new AttributesImpl(attr);
for (int i=0; i<attr.getLength(); i++) {
newAttr.setValue(i, interp(attr.getValue(i)));
}
super.startElement(uri, localName, qName, newAttr);
}
/** Replace {vars} in element bodies. */
public void characters( final char[] ch, int start, int len )
throws SAXException
{
StringBuffer buf = new StringBuffer();
if (start!=0) buf.append(ch, 0, start-1);
String newVal = interp(new String(ch,start, len));
buf.append(newVal);
buf.append(ch, start+len, ch.length-(start+len));
super.characters(buf.toString().toCharArray(), start, newVal.length());
}
protected String getLocationString() {
return this.location;
}
/**
* Interpolate variable values into a string.
*
* @param str String with {var} tokens
* @return <code>str</code>, with {variables} replaced by values. If an
* unknown variable token is encountered it is ignored.
*/
private String interp(String str) {
StringBuffer buf = new StringBuffer(str.length()*2);
StringTokenizer tok = new StringTokenizer(str, "{}", true);
int state = 0; // 0=outside, 1=inside
while (tok.hasMoreTokens()) {
String token = tok.nextToken();
if (state == 0 && "{".equals(token)) {
state = 1;
} else if (state == 1 && "}".equals(token)) {
state = 0;
} else if (state == 0) {
buf.append(token);
} else if (state == 1) {
//System.out.println("Replacing "+token+" with "+vars.get(token));
String val = (String)vars.get(token);
if (val == null) {
buf.append("{").append(token).append("}");
} else{ buf.append(val); }
}
}
return buf.toString();
}
}