1. /* $Id: MultiVariableExpander.java,v 1.6 2004/05/10 06:46:30 skitching Exp $
  2. *
  3. * Copyright 2003-2004 The Apache Software Foundation.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.apache.commons.digester.substitution;
  18. import java.util.Map;
  19. import java.util.ArrayList;
  20. /**
  21. * <p>Expands variable references from multiple sources.</p>
  22. *
  23. * @since 1.6
  24. */
  25. public class MultiVariableExpander implements VariableExpander {
  26. private int nEntries = 0;
  27. private ArrayList markers = new ArrayList(2);
  28. private ArrayList sources = new ArrayList(2);
  29. public MultiVariableExpander() {
  30. }
  31. public void addSource(String marker, Map source) {
  32. ++nEntries;
  33. markers.add(marker);
  34. sources.add(source);
  35. }
  36. /*
  37. * Expands any variable declarations using any of the known
  38. * variable marker strings.
  39. *
  40. * @throws IllegalArgumentException if the input param references
  41. * a variable which is not known to the specified source.
  42. */
  43. public String expand(String param) {
  44. for(int i=0; i<nEntries; ++i) {
  45. param = expand(
  46. param,
  47. (String) markers.get(i),
  48. (Map) sources.get(i));
  49. }
  50. return param;
  51. }
  52. /**
  53. * Replace any occurrences within the string of the form
  54. * "marker{key}" with the value from source[key].
  55. * <p>
  56. * Commonly, the variable marker is "$", in which case variables
  57. * are indicated by ${key} in the string.
  58. * <p>
  59. * Returns the string after performing all substitutions.
  60. * <p>
  61. * If no substitutions were made, the input string object is
  62. * returned (not a copy).
  63. *
  64. * @throws IllegalArgumentException if the input param references
  65. * a variable which is not known to the specified source.
  66. */
  67. public String expand(String str, String marker, Map source) {
  68. String startMark = marker + "{";
  69. int markLen = startMark.length();
  70. int index = 0;
  71. for(;;)
  72. {
  73. index = str.indexOf(startMark, index);
  74. if (index == -1)
  75. {
  76. return str;
  77. }
  78. int startIndex = index + markLen;
  79. if (startIndex > str.length())
  80. {
  81. throw new IllegalArgumentException(
  82. "var expression starts at end of string");
  83. }
  84. int endIndex = str.indexOf("}", index + markLen);
  85. if (endIndex == -1)
  86. {
  87. throw new IllegalArgumentException(
  88. "var expression starts but does not end");
  89. }
  90. String key = str.substring(index+markLen, endIndex);
  91. Object value = source.get(key);
  92. if (value == null) {
  93. throw new IllegalArgumentException(
  94. "parameter [" + key + "] is not defined.");
  95. }
  96. String varValue = value.toString();
  97. str = str.substring(0, index) + varValue + str.substring(endIndex+1);
  98. index += varValue.length();
  99. }
  100. }
  101. }