/* * $Id$ * * Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.jct.utils.mapmerge; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; import java.io.Reader; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.FileScanner; import org.apache.tools.ant.taskdefs.MatchingTask; import org.apache.tools.ant.types.FileSet; /** * A utility to merge JavaHelp map files. */ public class Main { /** * An exception to report bad command line arguments. */ public static class BadArgs extends Exception { BadArgs(String msg) { super(msg); } } /** * Command line entry point.
* @param args Command line arguments, per the usage as described. */ public static void main(String[] args) { try { if (args.length == 0) usage(System.err); else { Main m = new Main(args); m.run(); } } catch (BadArgs e) { System.err.println(e); usage(System.err); System.exit(1); } catch (Throwable t) { t.printStackTrace(); System.exit(2); } } /** * Write out short command line help. * @param out A stream to which to write the help. */ private static void usage(PrintStream out) { String program = System.getProperty("program", "java " + Main.class.getName()); out.println("Usage:"); out.println(" " + program + " options files..."); out.println(""); out.println("Arguments:"); out.println("-o file"); out.println(" Output file."); out.println("files..."); out.println(" Input files to be merged."); } public Main() { } /** * Create an object based on command line args. * It is an error if no input files or no output file is given. * @param args Command line args. * @see #main * @throws Main.BadArgs if problems are found in the given arguments. */ public Main(String[] args) throws BadArgs { for (int i = 0; i < args.length; i++) { if (args[i].equals("-o") && i + 1 < args.length) { outFile = new File(args[++i]); } else { inFiles = new File[args.length - i]; for (int j = 0; j < inFiles.length; j++) inFiles[j] = new File(args[i++]); } } } public static class Ant extends MatchingTask { private Main m = new Main(); private List fileSets = new ArrayList(); public void setOutFile(File file) { m.outFile = file; } public void addFileSet(FileSet fs) { fileSets.add(fs); } public void execute() { for (Iterator iter = fileSets.iterator(); iter.hasNext(); ) { FileSet fs = iter.next(); FileScanner s = fs.getDirectoryScanner(getProject()); m.addFiles(s.getBasedir(), s.getIncludedFiles()); } try { m.run(); } catch (BadArgs e) { throw new BuildException(e.getMessage()); } catch (IOException e) { throw new BuildException(e); } } } public void addFiles(File baseDir, String[] paths) { if (paths == null) return; List files = new ArrayList(); if (inFiles != null) files.addAll(Arrays.asList(inFiles)); for (int i = 0; i < paths.length; i++) files.add(new File(baseDir, paths[i])); inFiles = files.toArray(new File[files.size()]); } private void run() throws BadArgs, IOException { if (inFiles == null || inFiles.length == 0) throw new BadArgs("no input files specified"); if (outFile == null) throw new BadArgs("no output file specified"); map = new TreeMap<>(); for (int i = 0; i < inFiles.length; i++) read(inFiles[i]); PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(outFile))); out.println(""); out.println(""); out.println(""); int maxLen = 0; for (Iterator> iter = map.entrySet().iterator(); iter.hasNext(); ) { Map.Entry e = iter.next(); String target = e.getKey(); String url = e.getValue(); maxLen = Math.max(maxLen, target.length()); } for (Iterator> iter = map.entrySet().iterator(); iter.hasNext(); ) { Map.Entry e = iter.next(); String target = e.getKey(); String url = e.getValue(); out.print(" "); } out.println(""); out.close(); } private void read(File f) throws IOException { Reader in = new BufferedReader(new FileReader(f)); currFile = f; read(in); in.close(); } private void read(Reader in) throws IOException { this.in = in; line = 1; nextCh(); while (c >= 0) { if (c == '<') { nextCh(); skipSpace(); switch (c) { case '!': nextCh(); if (c == '-') { nextCh(); if (c == '-') { nextCh(); skipComment(); } } break; case '?': nextCh(); skipTag(); break; case '/': nextCh(); skipTag(); break; default: String startTag = scanIdentifier(); if (isMapID(startTag)) scanMapID(true); else skipTag(); } } else { nextCh(); } } } private boolean isMapID(String tag) { return tag.equals("mapID"); } private void scanMapID(boolean start) throws IOException { String target = null; String url = null; skipSpace(); while (c != '>') { if (c == '/') { nextCh(); if (c == '>') break; else throw new IOException("error parsing HTML input (" + currFile + ":" + line + ")"); } String att = scanIdentifier(); if (att.equals("target")) { target = scanValue(); } else if (att.equals("url")) { url = scanValue(); } else scanValue(); skipSpace(); } map.put(target, url); nextCh(); } /** * Read an identifier */ private String scanIdentifier() throws IOException { StringBuffer buf = new StringBuffer(); while (true) { if ((c >= 'a') && (c <= 'z')) { buf.append((char)c); nextCh(); } else if ((c >= 'A') && (c <= 'Z')) { buf.append((char)c); nextCh(); } else if ((c >= '0') && (c <= '9')) { buf.append((char)c); nextCh(); } else if (c == '-') { // needed for buf.append((char)c); nextCh(); } else if (buf.length() == 0) throw new IOException("Identifier expected (" + currFile + ":" + line + ")"); else return buf.toString(); } } /** * Read the value of an HTML attribute, which may be quoted. */ private String scanValue() throws IOException { skipSpace(); if (c != '=') return ""; int quote = -1; nextCh(); skipSpace(); if ((c == '\'') || (c == '\"')) { quote = c; nextCh(); skipSpace(); } StringBuffer buf = new StringBuffer(); while (((quote < 0) && (c != ' ') && (c != '\t') && (c != '\n') && (c != '\r') && (c != '>')) || ((quote >= 0) && (c != quote))) { if (c == -1 || c == '\n' || c == '\r') { throw new IOException("mismatched quotes (" + currFile + ":" + line + ")"); } buf.append((char)c); nextCh(); } if (c == quote) nextCh(); skipSpace(); return buf.toString(); } /** * Skip an HTML comment */ private void skipComment() throws IOException { // a comment sequence is "" // at the time this is called, "