1 15 package org.apache.hivemind.impl; 16 17 import java.util.Iterator ; 18 import java.util.List ; 19 20 import org.apache.commons.logging.Log; 21 import org.apache.commons.logging.LogFactory; 22 import org.apache.hivemind.ErrorHandler; 23 import org.apache.hivemind.Location; 24 import org.apache.hivemind.SymbolExpander; 25 import org.apache.hivemind.SymbolSource; 26 import org.apache.hivemind.order.Orderer; 27 28 34 public class SymbolExpanderImpl implements SymbolExpander 35 { 36 private static final Log LOG = LogFactory.getLog(SymbolExpanderImpl.class); 37 38 private static final int STATE_START = 0; 39 40 private static final int STATE_DOLLAR = 1; 41 42 private static final int STATE_COLLECT_SYMBOL_NAME = 2; 43 44 private ErrorHandler _errorHandler; 45 46 private SymbolSource[] _symbolSources; 47 48 private List _contributedSymbolSources; 49 50 public SymbolExpanderImpl(ErrorHandler handler, List symbolSourceContributions) 51 { 52 _errorHandler = handler; 53 _contributedSymbolSources = symbolSourceContributions; 54 } 55 56 public SymbolExpanderImpl(ErrorHandler handler, SymbolSource[] symbolSources) 57 { 58 _errorHandler = handler; 59 _symbolSources = symbolSources; 60 } 61 62 private synchronized SymbolSource[] initContributedSymbolSources(List contributions) 63 { 64 SymbolSource[] symbolSources; 65 66 Orderer o = new Orderer(LogFactory.getLog(SymbolExpander.class), _errorHandler, XmlImplMessages 67 .symbolSourceContribution()); 68 69 Iterator i = contributions.iterator(); 70 while (i.hasNext()) 71 { 72 SymbolSourceContribution c = (SymbolSourceContribution) i.next(); 73 74 o.add(c, c.getName(), c.getPrecedingNames(), c.getFollowingNames()); 75 } 76 77 List sources = o.getOrderedObjects(); 78 79 int count = sources.size(); 80 81 symbolSources = new SymbolSource[count]; 82 83 for (int j = 0; j < count; j++) 84 { 85 SymbolSourceContribution c = (SymbolSourceContribution) sources.get(j); 86 symbolSources[j] = c.getSource(); 87 } 88 89 return symbolSources; 90 } 91 92 public String valueForSymbol(String name) 93 { 94 if (_symbolSources == null && _contributedSymbolSources != null) { 95 _symbolSources = initContributedSymbolSources(_contributedSymbolSources); 98 _contributedSymbolSources = null; 99 } 100 101 for (int i = 0; i < _symbolSources.length; i++) 102 { 103 String value = _symbolSources[i].valueForSymbol(name); 104 105 if (value != null) 106 return value; 107 } 108 109 return null; 110 } 111 112 115 public String expandSymbols(String text, Location location) 116 { 117 StringBuffer result = new StringBuffer (text.length()); 118 char[] buffer = text.toCharArray(); 119 int state = STATE_START; 120 int blockStart = 0; 121 int blockLength = 0; 122 int symbolStart = -1; 123 int symbolLength = 0; 124 int i = 0; 125 int braceDepth = 0; 126 boolean anySymbols = false; 127 128 while (i < buffer.length) 129 { 130 char ch = buffer[i]; 131 132 switch (state) 133 { 134 case STATE_START: 135 136 if (ch == '$') 137 { 138 state = STATE_DOLLAR; 139 i++; 140 continue; 141 } 142 143 blockLength++; 144 i++; 145 continue; 146 147 case STATE_DOLLAR: 148 149 if (ch == '{') 150 { 151 state = STATE_COLLECT_SYMBOL_NAME; 152 i++; 153 154 symbolStart = i; 155 symbolLength = 0; 156 braceDepth = 1; 157 158 continue; 159 } 160 161 165 if (ch == '$') 166 { 167 170 anySymbols = true; 171 172 if (blockLength > 0) 173 result.append(buffer, blockStart, blockLength); 174 175 result.append(ch); 176 177 i++; 178 blockStart = i; 179 blockLength = 0; 180 state = STATE_START; 181 182 continue; 183 } 184 185 188 blockLength++; 189 190 state = STATE_START; 191 continue; 192 193 case STATE_COLLECT_SYMBOL_NAME: 194 195 if (ch != '}') 196 { 197 if (ch == '{') 198 braceDepth++; 199 200 i++; 201 symbolLength++; 202 continue; 203 } 204 205 braceDepth--; 206 207 if (braceDepth > 0) 208 { 209 i++; 210 symbolLength++; 211 continue; 212 } 213 214 216 218 if (symbolLength == 0) 219 blockLength += 3; 220 221 224 if (blockLength > 0) 225 result.append(buffer, blockStart, blockLength); 226 227 if (symbolLength > 0) 228 { 229 String variableName = text.substring(symbolStart, symbolStart 230 + symbolLength); 231 232 result.append(expandSymbol(variableName, location)); 233 234 anySymbols = true; 235 } 236 237 i++; 238 blockStart = i; 239 blockLength = 0; 240 241 243 state = STATE_START; 244 245 continue; 246 } 247 248 } 249 250 253 if (!anySymbols) 254 return text; 255 256 259 if (state == STATE_DOLLAR) 260 blockLength++; 261 262 if (state == STATE_COLLECT_SYMBOL_NAME) 263 blockLength += symbolLength + 2; 264 265 if (blockLength > 0) 266 result.append(buffer, blockStart, blockLength); 267 268 return result.toString(); 269 } 270 271 private String expandSymbol(String name, Location location) 272 { 273 String value = valueForSymbol(name); 274 275 if (value != null) 276 return value; 277 278 _errorHandler.error(LOG, XmlImplMessages.noSuchSymbol(name), location, null); 279 280 return "${" + name + "}"; 281 } 282 283 } | Popular Tags |