/*
* $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("");
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, "