001 /* $Id: MultiVariableExpander.java 992060 2010-09-02 19:09:47Z simonetripodi $
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<String> markers = new ArrayList<String>(2);
033 private ArrayList<Map<String, Object>> sources = new ArrayList<Map<String, Object>>(2);
034
035 public MultiVariableExpander() {
036 }
037
038 public void addSource(String marker, Map<String, Object> 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(
054 param,
055 markers.get(i),
056 sources.get(i));
057 }
058 return param;
059 }
060
061 /**
062 * Replace any occurrences within the string of the form
063 * "marker{key}" with the value from source[key].
064 * <p>
065 * Commonly, the variable marker is "$", in which case variables
066 * are indicated by ${key} in the string.
067 * <p>
068 * Returns the string after performing all substitutions.
069 * <p>
070 * If no substitutions were made, the input string object is
071 * returned (not a copy).
072 *
073 * @throws IllegalArgumentException if the input param references
074 * a variable which is not known to the specified source.
075 */
076 public String expand(String str, String marker, Map<String, Object> source) {
077 String startMark = marker + "{";
078 int markLen = startMark.length();
079
080 int index = 0;
081 for(;;)
082 {
083 index = str.indexOf(startMark, index);
084 if (index == -1)
085 {
086 return str;
087 }
088
089 int startIndex = index + markLen;
090 if (startIndex > str.length())
091 {
092 throw new IllegalArgumentException(
093 "var expression starts at end of string");
094 }
095
096 int endIndex = str.indexOf("}", index + markLen);
097 if (endIndex == -1)
098 {
099 throw new IllegalArgumentException(
100 "var expression starts but does not end");
101 }
102
103 String key = str.substring(index+markLen, endIndex);
104 Object value = source.get(key);
105 if (value == null) {
106 throw new IllegalArgumentException(
107 "parameter [" + key + "] is not defined.");
108 }
109 String varValue = value.toString();
110
111 str = str.substring(0, index) + varValue + str.substring(endIndex+1);
112 index += varValue.length();
113 }
114 }
115
116 }