/** * Reads the file that specifies method calls that should be replaced by other method calls. The * file is of the form: * * <p>[regex] [orig-method-def] [new-method-name] * * <p>where the orig_method-def is of the form: * * <p>fully-qualified-method-name (args) * * <p>Blank lines and // comments are ignored. The orig-method-def is replaced by a call to * new-method-name with the same arguments in any classfile that matches the regular expressions. * All method names and argument types should be fully qualified. */ public void read_map_file(File map_file) throws IOException { LineNumberReader lr = new LineNumberReader(new FileReader(map_file)); MapFileError mfe = new MapFileError(lr, map_file); Pattern current_regex = null; Map<MethodDef, MethodInfo> map = new LinkedHashMap<MethodDef, MethodInfo>(); for (String line = lr.readLine(); line != null; line = lr.readLine()) { line = line.replaceFirst("//.*$", ""); if (line.trim().length() == 0) continue; if (line.startsWith(" ")) { if (current_regex == null) throw new IOException("No current class regex on line " + lr.getLineNumber()); StrTok st = new StrTok(line, mfe); st.stok.wordChars('.', '.'); MethodDef md = parse_method(st); String new_method = st.need_word(); map.put(md, new MethodInfo(new_method)); } else { if (current_regex != null) { MethodMapInfo mmi = new MethodMapInfo(current_regex, map); map_list.add(mmi); map = new LinkedHashMap<MethodDef, MethodInfo>(); } current_regex = Pattern.compile(line); } } if (current_regex != null) { MethodMapInfo mmi = new MethodMapInfo(current_regex, map); map_list.add(mmi); } dump_map_list(); }
/** * Parse a method declaration. The declaration should be in the following format: * * <p>fully-qualified-method-name (args) * * <p>where the arguments are comma separated and all arguments other than primitives should have * fully qualified names. Arrays are indicating by trailing brackets. For example: * * <p>int int[] int[][] java.lang.String java.util.Date[] * * <p>The arguments are translated into BCEL types and a MethodDef is returned. */ private MethodDef parse_method(StrTok st) { // Get the method name String method_name = st.need_word(); // Get the opening paren st.need("("); // Read the arguments ArrayList<String> args = new ArrayList<String>(); String tok = st.nextToken(); if (tok != ")") { st.pushBack(); do { tok = st.need_word(); args.add(tok); } while (st.nextToken() == ","); st.pushBack(); st.need(")"); } // Convert the arguments to Type Type[] targs = new Type[args.size()]; for (int ii = 0; ii < args.size(); ii++) { targs[ii] = BCELUtil.classname_to_type(args.get(ii)); } return new MethodDef(method_name, targs); }