1 11 package org.eclipse.jface.text.templates; 12 13 import java.util.ArrayList ; 14 import java.util.Iterator ; 15 import java.util.LinkedHashMap ; 16 import java.util.List ; 17 import java.util.Map ; 18 import java.util.regex.Matcher ; 19 import java.util.regex.Pattern ; 20 21 43 public class TemplateTranslator { 44 48 private static final Pattern PARAM_PATTERN= Pattern.compile("(?:\\w++\\.)*\\w++"); 54 private static final Pattern ESCAPE_PATTERN= Pattern.compile("\\$\\$|\\$\\{\\s*+(\\w*+)\\s*+(?::\\s*+((?:\\w++\\.)*\\w++)\\s*+(?:\\(\\s*+((?:(?:\\w++\\.)*\\w++\\s*+,\\s*+)*(?:\\w++\\.)*\\w++)\\s*+\\))?\\s*+)?\\}|\\$"); 58 private final class VariableDescription { 59 final List fOffsets= new ArrayList (5); 60 final String fName; 61 TemplateVariableType fType; 62 63 VariableDescription(String name, TemplateVariableType type) { 64 fName= name; 65 fType= type; 66 } 67 68 void mergeType(TemplateVariableType type) throws TemplateException { 69 if (type == null) 70 return; 71 if (fType == null) 72 fType= type; 73 if (!type.equals(fType)) 74 fail(TextTemplateMessages.getFormattedString("TemplateTranslator.error.incompatible.type", fName)); } 76 } 77 78 79 private String fErrorMessage; 80 85 private TemplateVariableType fCurrentType; 86 87 94 public String getErrorMessage() { 95 return fErrorMessage; 96 } 97 98 107 public TemplateBuffer translate(Template template) throws TemplateException { 108 return parse(template.getPattern()); 109 } 110 111 121 public TemplateBuffer translate(String string) throws TemplateException { 122 return parse(string); 123 } 124 125 132 private TemplateBuffer parse(String string) throws TemplateException { 133 134 fErrorMessage= null; 135 final StringBuffer buffer= new StringBuffer (string.length()); 136 final Matcher matcher= ESCAPE_PATTERN.matcher(string); 137 final Map variables= new LinkedHashMap (); 138 139 int complete= 0; 140 while (matcher.find()) { 141 buffer.append(string.substring(complete, matcher.start())); 143 144 if ("$".equals(matcher.group())) { fail(TextTemplateMessages.getString("TemplateTranslator.error.incomplete.variable")); } else if ("$$".equals(matcher.group())) { buffer.append('$'); 150 } else { 151 String name= matcher.group(1); 153 String typeName= matcher.group(2); 154 String params= matcher.group(3); 155 TemplateVariableType type= createType(typeName, params); 156 157 updateOrCreateVariable(variables, name, type, buffer.length()); 158 159 buffer.append(name); 160 } 161 complete= matcher.end(); 162 } 163 buffer.append(string.substring(complete)); 165 166 TemplateVariable[] vars= createVariables(variables); 167 return new TemplateBuffer(buffer.toString(), vars); 168 } 169 170 private TemplateVariableType createType(String typeName, String paramString) { 171 if (typeName == null) 172 return null; 173 174 if (paramString == null) 175 return new TemplateVariableType(typeName); 176 177 final Matcher matcher= PARAM_PATTERN.matcher(paramString); 178 List params= new ArrayList (5); 179 while (matcher.find()) 180 params.add(matcher.group()); 181 182 return new TemplateVariableType(typeName, (String []) params.toArray(new String [params.size()])); 183 } 184 185 private void fail(String message) throws TemplateException { 186 fErrorMessage= message; 187 throw new TemplateException(message); 188 } 189 190 202 private void updateOrCreateVariable(Map variables, String name, TemplateVariableType type, int offset) throws TemplateException { 203 VariableDescription varDesc= (VariableDescription) variables.get(name); 204 if (varDesc == null) { 205 varDesc= new VariableDescription(name, type); 206 variables.put(name, varDesc); 207 } else { 208 varDesc.mergeType(type); 209 } 210 varDesc.fOffsets.add(new Integer (offset)); 211 } 212 213 220 private TemplateVariable[] createVariables(Map variables) { 221 TemplateVariable[] result= new TemplateVariable[variables.size()]; 222 int idx= 0; 223 for (Iterator it= variables.values().iterator(); it.hasNext(); idx++) { 224 VariableDescription desc= (VariableDescription) it.next(); 225 TemplateVariableType type= desc.fType == null ? new TemplateVariableType(desc.fName) : desc.fType; 226 int[] offsets= new int[desc.fOffsets.size()]; 227 int i= 0; 228 for (Iterator intIt= desc.fOffsets.iterator(); intIt.hasNext(); i++) { 229 Integer offset= (Integer ) intIt.next(); 230 offsets[i]= offset.intValue(); 231 } 232 fCurrentType= type; 233 237 TemplateVariable var= createVariable(type.getName(), desc.fName, offsets); 238 result[idx]= var; 239 } 240 fCurrentType= null; return result; 242 } 243 244 257 protected TemplateVariable createVariable(String type, String name, int[] offsets) { 258 return createVariable(fCurrentType, name, offsets); 259 } 260 261 274 protected TemplateVariable createVariable(TemplateVariableType type, String name, int[] offsets) { 275 return new TemplateVariable(type, name, name, offsets); 276 } 277 } 278 | Popular Tags |