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( 054 param, 055 (String) markers.get(i), 056 (Map) 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 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 }