Logo Search packages:      
Sourcecode: aspectj version File versions  Download package

ConfigParser.java

/* *******************************************************************
 * Copyright (c) 1999-2001 Xerox Corporation, 
 *               2002 Palo Alto Research Center, Incorporated (PARC).
 * All rights reserved. 
 * This program and the accompanying materials are made available 
 * under the terms of the Eclipse Public License v1.0 
 * which accompanies this distribution and is available at 
 * http://www.eclipse.org/legal/epl-v10.html 
 *  
 * Contributors: 
 *     Xerox/PARC     initial implementation 
 * ******************************************************************/

package org.aspectj.ajdt.ajc;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ConfigParser {
      Location location;
      protected File relativeDirectory = null;
      protected List files = new LinkedList();
      protected List xmlfiles = new ArrayList();
      private boolean fileParsed = false;
      protected static String CONFIG_MSG = "build config error: ";

      public List getFiles() {
            return files;
      }

      public List getXmlFiles() {
            return xmlfiles;
      }

      public void parseCommandLine(String[] argsArray) throws ParseException {
            location = new CommandLineLocation();
            LinkedList args = new LinkedList();
            for (int i = 0; i < argsArray.length; i++) {
                  args.add(new Arg(argsArray[i], location));
            }
            parseArgs(args);
      }

      public void parseConfigFile(File configFile) throws ParseException {
            if (fileParsed == true) {
                  throw new ParseException(CONFIG_MSG + "The file has already been parsed.", null);
            } else {
                  parseConfigFileHelper(configFile);
            }
      }

      /**
       * @throws ParseException if the config file has already been prased.
       */
      private void parseConfigFileHelper(File configFile) {
            if (!configFile.exists()) {
                  showError("file does not exist: " + configFile.getPath());
                  return;
            }

            LinkedList args = new LinkedList();
            int lineNum = 0;

            try {
                  BufferedReader stream = new BufferedReader(new FileReader(configFile));
                  String line = null;
                  while ((line = stream.readLine()) != null) {
                        lineNum += 1;
                        line = stripWhitespaceAndComments(line);
                        if (line.length() == 0)
                              continue;
                        args.add(new Arg(line, new CPSourceLocation(configFile, lineNum)));
                  }
                  stream.close();
            } catch (IOException e) {
                  location = new CPSourceLocation(configFile, lineNum);
                  showError("error reading config file: " + e.toString());
            }
            File oldRelativeDirectory = relativeDirectory; // for nested arg files;
            relativeDirectory = configFile.getParentFile();
            parseArgs(args);
            relativeDirectory = oldRelativeDirectory;
            fileParsed = true;
      }

      File getCurrentDir() {
            return location.getDirectory();
      }

      String stripSingleLineComment(String s, String commentString) {
            int commentStart = s.indexOf(commentString);
            if (commentStart == -1)
                  return s;
            else
                  return s.substring(0, commentStart);
      }

      String stripWhitespaceAndComments(String s) {
            s = stripSingleLineComment(s, "//");
            s = stripSingleLineComment(s, "#");
            s = s.trim();
            if (s.startsWith("\"") && s.endsWith("\"")) {
                  if (s.length() == 1) {
                        return "";
                  } else {
                        s = s.substring(1, s.length() - 1);
                  }
            }
            return s;
      }

      /**
       * ??? We would like to call a showNonFatalError method here to show all errors in config files before aborting the compilation
       */
      protected void addFile(File sourceFile) {
            if (!sourceFile.isFile()) {
                  showError("source file does not exist: " + sourceFile.getPath());
            }
            files.add(sourceFile);
      }

      protected void addXmlFile(File xmlFile) {
            if (!xmlFile.isFile()) {
                  showError("XML file does not exist: " + xmlFile.getPath());
            }
            xmlfiles.add(xmlFile);
      }

      void addFileOrPattern(File sourceFile) {
            if (sourceFile.getName().charAt(0) == '*') {
                  if (sourceFile.getName().equals("*.java")) {
                        addFiles(sourceFile.getParentFile(), new FileFilter() {
                              public boolean accept(File f) {
                                    return f != null && f.getName().endsWith(".java");
                              }
                        });
                  } else if (sourceFile.getName().equals("*.aj")) {
                        addFiles(sourceFile.getParentFile(), new FileFilter() {
                              public boolean accept(File f) {
                                    return f != null && f.getName().endsWith(".aj");
                              }
                        });
                  } else {
                        addFile(sourceFile);
                  }
            } else {
                  addFile(sourceFile);
            }
      }

      void addFiles(File dir, FileFilter filter) {
            if (dir == null)
                  dir = new File(System.getProperty("user.dir"));

            if (!dir.isDirectory()) {
                  showError("can't find " + dir.getPath());
            } else {

                  File[] files = dir.listFiles(filter);
                  if (files.length == 0) {
                        showWarning("no matching files found in: " + dir);
                  }

                  for (int i = 0; i < files.length; i++) {
                        addFile(files[i]);
                  }
            }
      }

      protected void parseOption(String arg, LinkedList args) {
            showWarning("unrecognized option: " + arg);
      }

      protected void showWarning(String message) {
            if (location != null) {
                  message += " at " + location.toString();
            }
            System.err.println(CONFIG_MSG + message);
      }

      protected void showError(String message) {
            throw new ParseException(CONFIG_MSG + message, location);
      }

      void parseArgs(LinkedList args) {
            while (args.size() > 0)
                  parseOneArg(args);
      }

      protected Arg removeArg(LinkedList args) {
            if (args.size() == 0) {
                  showError("value missing");
                  return null;
            } else {
                  return (Arg) args.removeFirst();
            }
      }

      protected String removeStringArg(LinkedList args) {
            Arg arg = removeArg(args);
            if (arg == null)
                  return null;
            return arg.getValue();
      }

      /**
       * aop.xml configuration files can be passed on the command line.
       */
      boolean isXml(String s) {
            return s.endsWith(".xml");
      }

      boolean isSourceFileName(String s) {
            if (s.endsWith(".java"))
                  return true;
            if (s.endsWith(".aj"))
                  return true;
            // if (s.endsWith(".ajava")) {
            // showWarning(".ajava is deprecated, replace with .aj or .java: " + s);
            // return true;
            // }
            return false;
      }

      void parseOneArg(LinkedList args) {
            Arg arg = removeArg(args);
            String v = arg.getValue();
            location = arg.getLocation();
            if (v.startsWith("@")) {
                  parseImportedConfigFile(v.substring(1));
            } else if (v.equals("-argfile")) {
                  parseConfigFileHelper(makeFile(removeArg(args).getValue()));
            } else if (isSourceFileName(v)) {
                  addFileOrPattern(makeFile(v));
            } else if (isXml(v)) {
                  addXmlFile(makeFile(v));
            } else {
                  parseOption(arg.getValue(), args);
            }
      }

      protected void parseImportedConfigFile(String relativeFilePath) {
            parseConfigFileHelper(makeFile(relativeFilePath));
      }

      public File makeFile(String name) {
            if (relativeDirectory != null) {
                  return makeFile(relativeDirectory, name);
            } else {
                  return makeFile(getCurrentDir(), name);
            }
      }

      private File makeFile(File dir, String name) {
            name = name.replace('/', File.separatorChar);
            File ret = new File(name);
            boolean isAbsolute = ret.isAbsolute() || (ret.exists() && ret.getPath().startsWith(File.separator));
            if (!isAbsolute && (dir != null)) {
                  ret = new File(dir, name);
            }
            try {
                  ret = ret.getCanonicalFile();
            } catch (IOException ioEx) {
                  // proceed without canonicalization
                  // so nothing to do here
            }
            return ret;
      }

      protected static class Arg {
            private Location location;
            private String value;

            public Arg(String value, Location location) {
                  this.value = value;
                  this.location = location;
            }

            public void setValue(String value) {
                  this.value = value;
            }

            public void setLocation(Location location) {
                  this.location = location;
            }

            public String getValue() {
                  return value;
            }

            public Location getLocation() {
                  return location;
            }
      }

      static abstract class Location {
            public abstract File getFile();

            public abstract File getDirectory();

            public abstract int getLine();

            public abstract String toString();
      }

      static class CPSourceLocation extends Location {
            private int line;
            private File file;

            public CPSourceLocation(File file, int line) {
                  this.line = line;
                  this.file = file;
            }

            public File getFile() {
                  return file;
            }

            public File getDirectory() {
                  return file.getParentFile();
            }

            public int getLine() {
                  return line;
            }

            public String toString() {
                  return file.getPath() + ":" + line;
            }
      }

      static class CommandLineLocation extends Location {
            public File getFile() {
                  return new File(System.getProperty("user.dir"));
            }

            public File getDirectory() {
                  return new File(System.getProperty("user.dir"));
            }

            public int getLine() {
                  return -1;
            }

            public String toString() {
                  return "command-line";
            }
      }

      public static class ParseException extends RuntimeException {
            private Location location;

            public ParseException(String message, Location location) {
                  super(message);
                  this.location = location;
            }

            public int getLine() {
                  if (location == null)
                        return -1;
                  return location.getLine();
            }

            public File getFile() {
                  if (location == null)
                        return null;
                  return location.getFile();
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index