1 11 package org.eclipse.core.internal.variables; 12 13 import java.util.ArrayList ; 14 import java.util.HashSet ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 import java.util.Stack ; 18 import org.eclipse.core.runtime.CoreException; 19 import org.eclipse.core.runtime.IStatus; 20 import org.eclipse.core.runtime.Status; 21 import org.eclipse.core.variables.IDynamicVariable; 22 import org.eclipse.core.variables.IStringVariableManager; 23 import org.eclipse.core.variables.IValueVariable; 24 import org.eclipse.core.variables.VariablesPlugin; 25 import org.eclipse.osgi.util.NLS; 26 27 30 public class StringSubstitutionEngine { 31 32 private static final String VARIABLE_START = "${"; private static final char VARIABLE_END = '}'; 35 private static final char VARIABLE_ARG = ':'; 36 private static final int SCAN_FOR_START = 0; 38 private static final int SCAN_FOR_END = 1; 39 40 43 private StringBuffer fResult; 44 45 48 private boolean fSubs; 49 50 53 private Stack fStack; 54 55 class VariableReference { 56 57 private StringBuffer fText; 59 60 public VariableReference() { 61 fText = new StringBuffer (); 62 } 63 64 public void append(String text) { 65 fText.append(text); 66 } 67 68 public String getText() { 69 return fText.toString(); 70 } 71 72 } 73 74 85 public String performStringSubstitution(String expression, boolean reportUndefinedVariables, boolean resolveVariables, IStringVariableManager manager) throws CoreException { 86 substitute(expression, reportUndefinedVariables, resolveVariables, manager); 87 List resolvedVariableSets = new ArrayList (); 88 while (fSubs) { 89 HashSet resolved = substitute(fResult.toString(), reportUndefinedVariables, true, manager); 90 91 for(int i=resolvedVariableSets.size()-1; i>=0; i--) { 92 93 HashSet prevSet = (HashSet )resolvedVariableSets.get(i); 94 95 if (prevSet.equals(resolved)) { 96 HashSet conflictingSet = new HashSet (); 97 for (; i<resolvedVariableSets.size(); i++) 98 conflictingSet.addAll((HashSet )resolvedVariableSets.get(i)); 99 100 StringBuffer problemVariableList = new StringBuffer (); 101 for (Iterator it=conflictingSet.iterator(); it.hasNext(); ) { 102 problemVariableList.append(it.next().toString()); 103 problemVariableList.append(", "); } 105 problemVariableList.setLength(problemVariableList.length()-2); throw new CoreException(new Status(IStatus.ERROR, VariablesPlugin.getUniqueIdentifier(), VariablesPlugin.REFERENCE_CYCLE_ERROR, NLS.bind(VariablesMessages.StringSubstitutionEngine_4, new String []{problemVariableList.toString()}), null)); 107 } 108 } 109 110 resolvedVariableSets.add(resolved); 111 } 112 return fResult.toString(); 113 } 114 115 123 public void validateStringVariables(String expression, IStringVariableManager manager) throws CoreException { 124 performStringSubstitution(expression, true, false, manager); 125 } 126 127 136 private HashSet substitute(String expression, boolean reportUndefinedVariables, boolean resolveVariables, IStringVariableManager manager) throws CoreException { 137 fResult = new StringBuffer (expression.length()); 138 fStack = new Stack (); 139 fSubs = false; 140 141 HashSet resolvedVariables = new HashSet (); 142 143 int pos = 0; 144 int state = SCAN_FOR_START; 145 while (pos < expression.length()) { 146 switch (state) { 147 case SCAN_FOR_START: 148 int start = expression.indexOf(VARIABLE_START, pos); 149 if (start >= 0) { 150 int length = start - pos; 151 if (length > 0) { 153 fResult.append(expression.substring(pos, start)); 154 } 155 pos = start + 2; 156 state = SCAN_FOR_END; 157 158 fStack.push(new VariableReference()); 159 } else { 160 fResult.append(expression.substring(pos)); 162 pos = expression.length(); 163 } 164 break; 165 case SCAN_FOR_END: 166 start = expression.indexOf(VARIABLE_START, pos); 168 int end = expression.indexOf(VARIABLE_END, pos); 169 if (end < 0) { 170 VariableReference tos = (VariableReference)fStack.peek(); 172 tos.append(expression.substring(pos)); 173 pos = expression.length(); 174 } else { 175 if (start >= 0 && start < end) { 176 int length = start - pos; 178 if (length > 0) { 179 VariableReference tos = (VariableReference)fStack.peek(); 180 tos.append(expression.substring(pos, start)); 181 } 182 pos = start + 2; 183 fStack.push(new VariableReference()); 184 } else { 185 VariableReference tos = (VariableReference)fStack.pop(); 187 String substring = expression.substring(pos, end); 188 tos.append(substring); 189 resolvedVariables.add(substring); 190 191 pos = end + 1; 192 String value= resolve(tos, reportUndefinedVariables, resolveVariables, manager); 193 if (value == null) { 194 value = ""; } 196 if (fStack.isEmpty()) { 197 fResult.append(value); 199 state = SCAN_FOR_START; 200 } else { 201 tos = (VariableReference)fStack.peek(); 203 tos.append(value); 204 } 205 } 206 } 207 break; 208 } 209 } 210 while (!fStack.isEmpty()) { 212 VariableReference tos = (VariableReference)fStack.pop(); 213 if (fStack.isEmpty()) { 214 fResult.append(VARIABLE_START); 215 fResult.append(tos.getText()); 216 } else { 217 VariableReference var = (VariableReference)fStack.peek(); 218 var.append(VARIABLE_START); 219 var.append(tos.getText()); 220 } 221 } 222 223 224 return resolvedVariables; 225 } 226 227 239 private String resolve(VariableReference var, boolean reportUndefinedVariables, boolean resolveVariables, IStringVariableManager manager) throws CoreException { 240 String text = var.getText(); 241 int pos = text.indexOf(VARIABLE_ARG); 242 String name = null; 243 String arg = null; 244 if (pos > 0) { 245 name = text.substring(0, pos); 246 pos++; 247 if (pos < text.length()) { 248 arg = text.substring(pos); 249 } 250 } else { 251 name = text; 252 } 253 IValueVariable valueVariable = manager.getValueVariable(name); 254 if (valueVariable == null) { 255 IDynamicVariable dynamicVariable = manager.getDynamicVariable(name); 256 if (dynamicVariable == null) { 257 if (reportUndefinedVariables) { 259 throw new CoreException(new Status(IStatus.ERROR, VariablesPlugin.getUniqueIdentifier(), VariablesPlugin.INTERNAL_ERROR, NLS.bind(VariablesMessages.StringSubstitutionEngine_3, new String []{name}), null)); 260 } 261 return getOriginalVarText(var); 263 } 264 265 if (resolveVariables) { 266 fSubs = true; 267 return dynamicVariable.getValue(arg); 268 } 269 return getOriginalVarText(var); 271 } 272 273 if (arg == null) { 274 if (resolveVariables) { 275 fSubs = true; 276 return valueVariable.getValue(); 277 } 278 return getOriginalVarText(var); 280 } 281 throw new CoreException(new Status(IStatus.ERROR, VariablesPlugin.getUniqueIdentifier(), VariablesPlugin.INTERNAL_ERROR, NLS.bind(VariablesMessages.StringSubstitutionEngine_4, new String []{valueVariable.getName()}), null)); 283 } 284 285 private String getOriginalVarText(VariableReference var) { 286 StringBuffer res = new StringBuffer (var.getText()); 287 res.insert(0, VARIABLE_START); 288 res.append(VARIABLE_END); 289 return res.toString(); 290 } 291 } 292 | Popular Tags |