001: /* $Id: MultiVariableExpander.java 471661 2006-11-06 08:09:25Z skitching $
002: *
003: * Licensed to the Apache Software Foundation (ASF) under one or more
004: * contributor license agreements. See the NOTICE file distributed with
005: * this work for additional information regarding copyright ownership.
006: * The ASF licenses this file to You under the Apache License, Version 2.0
007: * (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: package org.apache.commons.digester.substitution;
020:
021: import java.util.Map;
022: import java.util.ArrayList;
023:
024: /**
025: * <p>Expands variable references from multiple sources.</p>
026: *
027: * @since 1.6
028: */
029:
030: public class MultiVariableExpander implements VariableExpander {
031: private int nEntries = 0;
032: private ArrayList markers = new ArrayList(2);
033: private ArrayList sources = new ArrayList(2);
034:
035: public MultiVariableExpander() {
036: }
037:
038: public void addSource(String marker, Map source) {
039: ++nEntries;
040: markers.add(marker);
041: sources.add(source);
042: }
043:
044: /*
045: * Expands any variable declarations using any of the known
046: * variable marker strings.
047: *
048: * @throws IllegalArgumentException if the input param references
049: * a variable which is not known to the specified source.
050: */
051: public String expand(String param) {
052: for (int i = 0; i < nEntries; ++i) {
053: param = expand(param, (String) markers.get(i),
054: (Map) sources.get(i));
055: }
056: return param;
057: }
058:
059: /**
060: * Replace any occurrences within the string of the form
061: * "marker{key}" with the value from source[key].
062: * <p>
063: * Commonly, the variable marker is "$", in which case variables
064: * are indicated by ${key} in the string.
065: * <p>
066: * Returns the string after performing all substitutions.
067: * <p>
068: * If no substitutions were made, the input string object is
069: * returned (not a copy).
070: *
071: * @throws IllegalArgumentException if the input param references
072: * a variable which is not known to the specified source.
073: */
074: public String expand(String str, String marker, Map source) {
075: String startMark = marker + "{";
076: int markLen = startMark.length();
077:
078: int index = 0;
079: for (;;) {
080: index = str.indexOf(startMark, index);
081: if (index == -1) {
082: return str;
083: }
084:
085: int startIndex = index + markLen;
086: if (startIndex > str.length()) {
087: throw new IllegalArgumentException(
088: "var expression starts at end of string");
089: }
090:
091: int endIndex = str.indexOf("}", index + markLen);
092: if (endIndex == -1) {
093: throw new IllegalArgumentException(
094: "var expression starts but does not end");
095: }
096:
097: String key = str.substring(index + markLen, endIndex);
098: Object value = source.get(key);
099: if (value == null) {
100: throw new IllegalArgumentException("parameter [" + key
101: + "] is not defined.");
102: }
103: String varValue = value.toString();
104:
105: str = str.substring(0, index) + varValue
106: + str.substring(endIndex + 1);
107: index += varValue.length();
108: }
109: }
110:
111: }
|