1 19 20 package org.netbeans.modules.languages; 21 22 import java.lang.reflect.InvocationTargetException ; 23 import java.util.ArrayList ; 24 import java.util.Collections ; 25 import java.util.HashMap ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.Map ; 29 import org.netbeans.api.languages.ASTNode; 30 import org.netbeans.api.languages.ASTToken; 31 import org.netbeans.api.languages.Context; 32 import org.netbeans.api.languages.SyntaxContext; 33 import org.netbeans.api.lexer.Token; 34 import org.netbeans.modules.languages.parser.Pattern; 35 import org.netbeans.modules.languages.parser.Pattern; 36 import org.openide.ErrorManager; 37 import org.openide.util.Lookup; 38 39 43 public class Feature { 44 45 public enum Type { 46 STRING, 47 METHOD_CALL, 48 PATTERN, 49 NOT_SET 50 } 51 52 public static Feature create ( 53 String featureName, 54 Selector selector 55 ) { 56 return new Feature ( 57 featureName, 58 selector, 59 null, 60 Collections.<String ,Evaluator>emptyMap (), 61 Collections.<String ,Pattern>emptyMap () 62 ); 63 } 64 65 public static Feature createMethodCallFeature ( 66 String featureName, 67 Selector selector, 68 String methodCall 69 ) { 70 return new Feature ( 71 featureName, 72 selector, 73 new Method (methodCall), 74 Collections.<String ,Evaluator>emptyMap (), 75 Collections.<String ,Pattern>emptyMap () 76 ); 77 } 78 79 public static Feature createExpressionFeature ( 80 String featureName, 81 Selector selector, 82 String expression 83 ) { 84 return new Feature ( 85 featureName, 86 selector, 87 new Expression (expression), 88 Collections.<String ,Evaluator>emptyMap (), 89 Collections.<String ,Pattern>emptyMap () 90 ); 91 } 92 93 public static Feature createExpressionFeature ( 94 String featureName, 95 Selector selector, 96 Pattern pattern 97 ) { 98 return new Feature ( 99 featureName, 100 selector, 101 pattern, 102 Collections.<String ,Evaluator>emptyMap (), 103 Collections.<String ,Pattern>emptyMap () 104 ); 105 } 106 107 public static Feature create ( 108 String featureName, 109 Selector selector, 110 Map <String ,String > expressions, 111 Map <String ,String > methods, 112 Map <String ,Pattern> patterns 113 ) { 114 Map <String ,Evaluator> evaluators = new HashMap <String ,Evaluator> (); 115 Iterator <String > it = expressions.keySet ().iterator (); 116 while (it.hasNext ()) { 117 String key = it.next (); 118 evaluators.put (key, new Expression (expressions.get (key))); 119 } 120 it = methods.keySet ().iterator (); 121 while (it.hasNext ()) { 122 String key = it.next (); 123 evaluators.put (key, new Method (methods.get (key))); 124 } 125 return new Feature ( 126 featureName, 127 selector, 128 null, 129 evaluators, 130 patterns 131 ); 132 } 133 134 135 private String featureName; 136 private Selector selector; 137 private Object value; 138 private Map <String ,Evaluator> evaluators; 139 private Map <String ,Pattern> patterns; 140 141 private Feature ( 142 String featureName, 143 Selector selector, 144 Object value, 145 Map <String ,Evaluator> evaluators, 146 Map <String ,Pattern> patterns 147 ) { 148 this.featureName = featureName; 149 this.selector = selector; 150 this.value = value; 151 this.evaluators = evaluators; 152 this.patterns = patterns; 153 } 154 155 public String getFeatureName () { 156 return featureName; 157 } 158 159 public Selector getSelector () { 160 return selector; 161 } 162 163 public boolean hasSingleValue () { 164 return value != null; 165 } 166 167 public Type getType () { 168 if (value == null) return Type.NOT_SET; 169 if (value instanceof Pattern) return Type.PATTERN; 170 if (value instanceof Method) return Type.METHOD_CALL; 171 return Type.STRING; 172 } 173 174 public Object getValue () { 175 if (value instanceof Evaluator) 176 return ((Evaluator) value).evaluate (); 177 return value; 178 } 179 180 public Pattern getPattern () { 181 return (Pattern) value; 182 } 183 184 public Object getValue (Context context) { 185 if (value == null) return null; 186 return ((Evaluator) value).evaluate (context); 187 } 188 189 public Object getValue (Object [] parameters) { 190 if (value == null) return null; 191 return ((Method) value).evaluate (parameters); 192 } 193 194 public boolean getBoolean (String propertyName, boolean defaultValue) { 195 Object o = getValue (propertyName); 196 if (o == null) return defaultValue; 197 if (o instanceof Boolean ) return ((Boolean ) o).booleanValue (); 198 return Boolean.parseBoolean ((String ) o); 199 } 200 201 public boolean getBoolean (String propertyName, Context context, boolean defaultValue) { 202 Object o = getValue (propertyName, context); 203 if (o == null) return defaultValue; 204 if (o instanceof Boolean ) return ((Boolean ) o).booleanValue (); 205 return Boolean.parseBoolean ((String ) o); 206 } 207 208 public Object getValue (String propertyName) { 209 Evaluator e = evaluators.get (propertyName); 210 if (e != null) 211 return e.evaluate (); 212 return patterns.get (propertyName); 213 } 214 215 public Object getValue (String propertyName, Context context) { 216 Evaluator e = evaluators.get (propertyName); 217 if (e == null) return null; 218 return e.evaluate (context); 219 } 220 221 public Object getValue (String propertyName, Object [] parameters) { 222 Method e = (Method) evaluators.get (propertyName); 223 if (e == null) return null; 224 return e.evaluate (parameters); 225 } 226 227 public Pattern getPattern (String propertyName) { 228 return patterns.get (propertyName); 229 } 230 231 public Type getType (String propertyName) { 232 if (patterns.containsKey (propertyName)) return Type.PATTERN; 233 Evaluator e = evaluators.get (propertyName); 234 if (e == null) return Type.NOT_SET; 235 if (e instanceof Method) return Type.METHOD_CALL; 236 return Type.STRING; 237 } 238 239 public String getMethodName () { 240 return ((Method) value).getMethodName (); 241 } 242 243 public String getMethodName (String propertyName) { 244 Method m = (Method) evaluators.get (propertyName); 245 if (m == null) return null; 246 return m.getMethodName (); 247 } 248 249 250 252 private abstract static class Evaluator { 253 public abstract Object evaluate (); 254 public abstract Object evaluate (Context context); 255 } 256 257 private static class Expression extends Evaluator { 258 259 private String [] names; 260 private String expression; 261 262 private Expression (String expression) { 263 this.expression = expression; 264 if (expression == null) return; 265 List <String > l = new ArrayList <String > (); 266 int start = 0; 267 do { 268 int ss = expression.indexOf ('$', start); 269 if (ss < 0) { 270 l.add (expression.substring (start, expression.length ())); 271 break; 272 } 273 l.add (expression.substring (start, ss)); 274 ss++; 275 int se = expression.indexOf ('$', ss); 276 if (se < 0) se = expression.length (); 277 l.add (expression.substring (ss, se)); 278 start = se + 1; 279 } while (start < expression.length ()); 280 names = l.toArray (new String [l.size ()]); 281 } 282 283 public Object evaluate (Context context) { 284 if (context instanceof SyntaxContext) { 285 Object l = ((SyntaxContext) context).getASTPath ().getLeaf (); 286 if (l instanceof ASTNode) 287 return evaluate ((ASTNode) l); 288 if (l instanceof ASTToken) 289 return evaluate ((ASTToken) l); 290 } else { 291 Token t = context.getTokenSequence ().token (); 292 ASTToken stoken = ASTToken.create ( 293 context.getTokenSequence ().language ().mimeType (), 294 t.id ().name (), 295 t.text ().toString (), 296 context.getTokenSequence ().offset () 297 ); 298 return evaluate (stoken); 299 } 300 throw new IllegalArgumentException (); 301 } 302 303 public Object evaluate () { 304 return expression; 305 } 306 307 private Object evaluate (ASTNode node) { 308 if (names == null) return null; 309 StringBuilder sb = new StringBuilder (); 310 int i, k = names.length; 311 for (i = 0; i < k; i += 2) { 312 sb.append (names [i]); 313 if (i + 1 >= names.length) break; 314 if (names [i + 1].equals ("")) { 315 sb.append (node.getAsText ()); 316 continue; 317 } 318 Object o = get (node, names [i + 1]); 319 if (o == null) 320 return null; else 322 if (o instanceof ASTToken) 323 sb.append (((ASTToken) o).getIdentifier ()); 324 else 325 sb.append (((ASTNode) o).getAsText ()); 326 } 327 return sb.toString (); 328 } 329 330 private static Object get (ASTNode node, String s) { 331 int i = s.indexOf ('.'); 332 if (i > 0) { 333 String ss = s.substring (0, i); 334 ASTNode n = node.getNode (ss); 335 if (n != null) 336 return get (n, s.substring (i + 1)); 337 return null; 338 } 339 ASTNode n = node.getNode (s); 340 if (n != null) return n; 341 return node.getTokenType (s); 342 } 343 344 private Object evaluate (ASTToken token) { 345 if (names == null) return null; 346 StringBuilder sb = new StringBuilder (); 347 int i, k = names.length; 348 for (i = 0; i < k; i += 2) { 349 sb.append (names [i]); 350 if (i + 1 >= names.length) break; 351 if (names [i + 1].equals ("identifier")) 352 sb.append (token.getIdentifier ()); 353 else 354 if (names [i + 1].equals ("")) 355 sb.append (token.getIdentifier ()); 356 else 357 if (names [i + 1].equals ("type")) 358 sb.append (token.getType ()); 359 else 360 return null; } 362 return sb.toString (); 363 } 364 } 365 366 private static class Method extends Evaluator { 367 368 private String methodName; 369 private java.lang.reflect.Method method; 370 private boolean resolved = false; 371 372 private Method (String methodName) { 373 this.methodName = methodName; 374 } 375 376 public Object evaluate () { 377 return evaluate (new Object [] {}); 378 } 379 380 public Object evaluate (Context context) { 381 return evaluate (new Object [] {context}); 382 } 383 384 388 public Object evaluate ( 389 Object [] params 390 ) { 391 if (!resolved) { 392 resolved = true; 393 int i = methodName.lastIndexOf ('.'); 394 if (i < 1) 395 throw new IllegalArgumentException (methodName); 396 String className = methodName.substring (0, i); 397 String methodN = methodName.substring (i + 1); 398 ClassLoader cl = (ClassLoader ) Lookup.getDefault (). 399 lookup (ClassLoader .class); 400 try { 401 Class cls = cl.loadClass (className); 402 java.lang.reflect.Method [] ms = cls.getMethods (); 403 int j, jj = ms.length; 404 for (j = 0; j < jj; j++) 405 if (ms [j].getName ().equals (methodN) && 406 ms [j].getParameterTypes ().length == params.length 407 ) { 408 Class [] pts = ms [j].getParameterTypes (); 409 int l, ll = params.length; 410 for (l = 0; l < ll; l++) { 411 if (params [l] != null && 412 !pts [l].isAssignableFrom (params [l].getClass ()) 413 ) 414 break; 415 } 416 if (l < ll) continue; 417 method = ms [j]; 418 break; 419 } 420 if (method == null) 421 throw new NoSuchMethodException (methodName); 422 } catch (ClassNotFoundException ex) { 423 ErrorManager.getDefault ().notify (ex); 424 } catch (NoSuchMethodException ex) { 425 ErrorManager.getDefault ().notify (ex); 426 } 427 } 428 if (method != null) 429 try { 430 return method.invoke (null, params); 431 } catch (IllegalAccessException ex) { 432 System.out.println(method); 433 ErrorManager.getDefault ().notify (ex); 434 } catch (InvocationTargetException ex) { 435 System.out.println(method); 436 ErrorManager.getDefault ().notify (ex); 437 } catch (IllegalArgumentException ex) { 438 System.out.println(method); 439 ErrorManager.getDefault ().notify (ex); 440 } 441 return null; 442 } 443 444 public String getMethodName() { 445 return methodName; 446 } 447 } 448 } 449 450 451 | Popular Tags |