View Javadoc

1   package org.apache.torque.generator.control;
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 org.apache.torque.generator.processor.string.StringProcessor;
23  
24  /**
25   * Replaces placeholder tokens like ${option:optionName} in a string by the
26   * resolved values. The escape character is the backslash (\).
27   *
28   * $Id: TokenReplacer.java 1331190 2012-04-27 02:41:35Z tfischer $
29   */
30  public class TokenReplacer implements StringProcessor
31  {
32      /** First character of a Token start. */
33      public static final char TOKEN_START_1 = '$';
34  
35      /** Second character of a Token start. */
36      public static final char TOKEN_START_2 = '{';
37  
38      /** The character ending a token. */
39      public static final char TOKEN_END = '}';
40  
41      /** The escape character. */
42      public static final char ESCAPE = '\\';
43  
44      /** The prefix for an option token. */
45      public static final String OPTION_PREFIX = "option";
46  
47      /** The separator between prefix and key. */
48      public static final char PREFIX_SEPARATOR = ':';
49  
50      /**
51       * The controller state for resolving options.
52       */
53      private ControllerState controllerState;
54  
55      public TokenReplacer(ControllerState controllerState)
56      {
57          if (controllerState == null)
58          {
59              throw new NullPointerException("controllerState must not be null");
60          }
61          this.controllerState = controllerState;
62      }
63  
64      /**
65       * Resolves all Tokens ${option:optionName} and replaces them with the
66       * appropriate value.
67       *
68       * @param toProcess the String to remove tokens from, or null.
69       */
70      public String process(String toProcess)
71      {
72          if (toProcess == null)
73          {
74              return null;
75          }
76          StringBuilder result = new StringBuilder();
77          StringBuilder tokenName = new StringBuilder();
78          boolean escape = false;
79          boolean inTokenStart = false;
80          boolean inToken = false;
81          for (char currentChar : toProcess.toCharArray())
82          {
83              if (currentChar == ESCAPE && !escape)
84              {
85                  escape = true;
86                  if (inTokenStart)
87                  {
88                      result.append(TOKEN_START_1);
89                      inTokenStart = false; // $\ is not token start
90                  }
91                  continue;
92              }
93              if (escape)
94              {
95                  if (inToken)
96                  {
97                      tokenName.append(currentChar);
98                  }
99                  else
100                 {
101                     result.append(currentChar);
102                 }
103                 escape = false;
104                 continue;
105             }
106             escape = false;
107             if (currentChar == TOKEN_START_1 && !inTokenStart && !inToken)
108             {
109                 inTokenStart = true;
110                 continue;
111             }
112             if (inTokenStart)
113             {
114                 if (currentChar == TOKEN_START_2)
115                 {
116                     inTokenStart = false;
117                     inToken = true;
118                     continue;
119                 }
120                 else
121                 {
122                     result.append(TOKEN_START_1); // did not copy that before
123                     result.append(currentChar);
124                     inTokenStart = false;
125                     continue;
126                 }
127             }
128             if (currentChar == TOKEN_END && inToken)
129             {
130                 result.append(resolveToken(tokenName.toString()));
131                 tokenName = new StringBuilder();
132                 inToken = false;
133                 continue;
134             }
135             if (inToken)
136             {
137                 tokenName.append(currentChar);
138             }
139             else
140             {
141                 result.append(currentChar);
142             }
143         }
144         if (escape)
145         {
146             throw new IllegalArgumentException("Single escape character "
147                     + ESCAPE
148                     + " encountered at end of String "
149                     + toProcess);
150         }
151         if (inTokenStart)
152         {
153             result.append(TOKEN_START_1);
154         }
155         if (inToken)
156         {
157             throw new IllegalArgumentException("Token end "
158                     + TOKEN_END
159                     + " missing at end of String "
160                     + toProcess);
161         }
162         return result.toString();
163     }
164 
165     private String resolveToken(String tokenName)
166     {
167         if (!tokenName.startsWith(OPTION_PREFIX + PREFIX_SEPARATOR))
168         {
169             throw new IllegalArgumentException("Token name must start with"
170                     + OPTION_PREFIX + PREFIX_SEPARATOR);
171         }
172         String optionName = tokenName.substring(
173                 (OPTION_PREFIX + PREFIX_SEPARATOR).length());
174         Object optionValue = controllerState.getOption(optionName);
175         if (optionValue == null)
176         {
177             return "";
178         }
179         return optionValue.toString();
180     }
181 }