/** evaluate the link function */ public static Data link(VMethod m, Object[] o) throws VisADException { Data ans = null; if (o != null) { for (int i = 0; i < o.length; i++) { // convert VRealTypes to RealTypes if (o[i] instanceof VRealType) { o[i] = ((VRealType) o[i]).getRealType(); } } } try { ans = (Data) FormulaUtil.invokeMethod(m.getMethod(), o); } catch (ClassCastException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); throw new VisADException("Link error: invalid linked method"); } catch (IllegalAccessException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); throw new VisADException("Link error: cannot access linked method"); } catch (IllegalArgumentException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); throw new VisADException("Link error: bad method argument"); } catch (InvocationTargetException exc) { if (FormulaVar.DEBUG) exc.getTargetException().printStackTrace(); throw new VisADException("Link error: linked method threw an exception"); } if (ans == null) { throw new VisADException("Link error: linked method returned null data"); } return ans; }
/** used by preParse */ private static String preParseOnce(String s, FormulaManager fm) { // convert to lower case String l = s.toLowerCase(); // scan entire string int len = l.length(); boolean letter = false; String ns = ""; for (int i = 0; i < len; i++) { if (!letter && i < len - 1 && l.substring(i, i + 2).equals("d(")) { // convert d(x)/d(y) notation to standard derive(x, y) notation i += 2; int s1 = i; for (int paren = 1; paren > 0; i++) { // check for correct syntax if (i >= len) return s; char c = l.charAt(i); if (c == '(') paren++; if (c == ')') paren--; } int e1 = i - 1; // check for correct syntax if (i > len - 3 || !l.substring(i, i + 3).equals("/d(")) return s; i += 3; int s2 = i; for (int paren = 1; paren > 0; i++) { // check for correct syntax if (i >= len) return s; char c = l.charAt(i); if (c == '(') paren++; if (c == ')') paren--; } int e2 = i - 1; ns = ns + "derive(" + s.substring(s1, e1) + "," + s.substring(s2, e2) + ")"; i--; } else if (!letter && i < len - 4 && l.substring(i, i + 5).equals("link(")) { // evaluate link(code) notation and replace with link variable i += 5; int s1 = i; try { while (l.charAt(i) != '(') i++; } catch (ArrayIndexOutOfBoundsException exc) { // incorrect syntax return s; } i++; int e1 = i - 1; int s2 = i; for (int paren = 2; paren > 1; i++) { // check for correct syntax if (i >= len) return s; char c = l.charAt(i); if (c == '(') paren++; if (c == ')') paren--; } int e2 = i - 1; // check for correct syntax if (i >= len || l.charAt(i) != ')') return s; String prestr = s.substring(s1, e1) + "("; String str = prestr; // parse method's arguments; determine if they are Data or RealType String sub = s.substring(s2, e2); StringTokenizer st = new StringTokenizer(sub, ",", false); boolean first = true; Vector v = new Vector(); while (st.hasMoreTokens()) { String token = st.nextToken(); if (first) first = false; else str = str + ","; RealType rt = RealType.getRealTypeByName(token); String sv = (rt == null ? "visad.Data" : "visad.RealType"); v.add(sv); str = str + sv; } str = str + ")"; // obtain Method object Method[] meths = FormulaUtil.stringsToMethods(new String[] {str}); if (meths[0] == null) { // attempt to identify any matching methods by compressing // some or all of the arguments into array form int vlen = v.size(); Vector vstrs = new Vector(); for (int iv = 0; iv < vlen; iv++) { String si = (String) v.elementAt(iv); int lv = iv; String sl; while (lv < vlen) { sl = (String) v.elementAt(lv++); if (!sl.equals(si)) { break; } str = prestr; first = true; for (int j = 0; j < vlen; j++) { if (first) first = false; else str = str + ","; String sj = (String) v.elementAt(j); str = str + sj; if (iv == j) { str = str + "[]"; j = lv - 1; } } str = str + ")"; vstrs.add(str); } } String[] strlist = new String[vstrs.size()]; vstrs.toArray(strlist); meths = FormulaUtil.stringsToMethods(strlist); int found = -1; for (int j = 0; j < meths.length && found < 0; j++) { if (meths[j] != null) found = j; } if (found >= 0) meths[0] = meths[found]; else { // could not find a matching method return s; } } // store method object in a link variable String link = "link" + (++linkNum); try { fm.setThing(link, new VMethod(meths[0])); } // catch any errors setting the link variable catch (FormulaException exc) { return s; } catch (VisADException exc) { return s; } catch (RemoteException exc) { return s; } ns = ns + "linkx(" + link + "," + s.substring(s2, e2) + ")"; } else if (!letter) { int j = i; char c = l.charAt(j++); while (j < len && ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))) { c = l.charAt(j++); } // check for end-of-string if (j == len) return ns + s.substring(i, len); if (c == '[') { // convert x[y] notation to standard getSample(x, y) notation int k = j; for (int paren = 1; paren > 0; k++) { // check for correct syntax if (k >= len) return s; c = l.charAt(k); if (c == '[') paren++; if (c == ']') paren--; } ns = ns + "getSample(" + s.substring(i, j - 1) + "," + s.substring(j, k - 1) + ")"; i = k - 1; } else ns = ns + s.charAt(i); } else { // append character to new string ns = ns + s.charAt(i); } char c = (i < len) ? l.charAt(i) : '\0'; letter = (c >= 'a' && c <= 'z'); } return ns; }