View Javadoc

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