Input.java revision 560:dca8c03d693d
1/*
2 * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package build.tools.logutil;
27
28import java.io.BufferedReader;
29import java.io.File;
30import java.io.FileInputStream;
31import java.io.FileNotFoundException;
32import java.io.InputStreamReader;
33import java.io.IOException;
34
35import java.util.LinkedList;
36import java.util.Queue;
37
38import java.util.regex.Matcher;
39import java.util.regex.Pattern;
40
41public class Input {
42
43  /**
44   * The name of the package this class will inhabit.
45   */
46  private String packageName;
47
48  /**
49   * The name of the generated class.
50   */
51  private String className;
52
53  /**
54   * The name of the group of exceptions handled by the class.
55   */
56  private String groupName;
57
58  /**
59   * The group of exceptions.
60   */
61  private Queue<InputException> exceptions;
62
63  /**
64   * Represents the current state of parsing the input.
65   */
66  private enum State
67  {
68    OUTER,
69    IN_CLASS,
70    IN_EXCEPTION_LIST
71  };
72
73  /**
74   * Regular expression to match each code line.
75   */
76  private static final Pattern EXCEPTION_INFO_REGEX =
77    Pattern.compile("(\\w+)\\s*(\\d+)\\s*(\\w+)");
78
79  /**
80   * Parses the specified file to create a new {@link Input}
81   * object.
82   *
83   * @param filename the file to parse.
84   * @throws FileNotFoundException if the file can't be found.
85   * @throws IOException if an I/O error occurs.
86   */
87  public Input(final String filename)
88  throws FileNotFoundException, IOException {
89    BufferedReader r =
90      new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
91    State state = State.OUTER;
92    InputException current = null;
93    exceptions = new LinkedList<InputException>();
94    String line;
95    while ((line = r.readLine()) != null) {
96      // Skip ; comments
97      if (line.startsWith(";"))
98        continue;
99
100      int index = line.indexOf("(");
101      if (index == -1)
102        continue;
103
104      switch (state) {
105      case OUTER:
106        state = State.IN_CLASS;
107        String[] classInfo = line.substring(index).split(" ");
108        packageName = classInfo[0].substring(2, classInfo[0].length() - 1);
109        className = classInfo[1].substring(1, classInfo[1].length() - 1);
110        groupName = classInfo[2];
111        break;
112      case IN_CLASS:
113        state = State.IN_EXCEPTION_LIST;
114        break;
115      case IN_EXCEPTION_LIST:
116        boolean inQuote = false;
117        boolean inCode = false;
118        boolean end = false;
119        int start = index + 1;
120        Queue<String> lines = new LinkedList<String>();
121        for (int a = start; a < line.length(); ++a) {
122          if (line.charAt(a) == '(' && !inCode && !inQuote) {
123            if (current == null)
124              current =
125                new InputException(line.substring(start, a).trim());
126            start = a + 1;
127            inCode = true;
128          }
129          if (line.charAt(a) == '"')
130            inQuote = !inQuote;
131          if (line.charAt(a) == ')' && !inQuote) {
132            if (inCode) {
133              lines.offer(line.substring(start, a));
134              inCode = false;
135            } else
136              end = true;
137          }
138          if (!end && a == line.length() - 1)
139            line += r.readLine();
140        }
141        for (String l : lines) {
142          int stringStart = l.indexOf("\"") + 1;
143          int stringEnd = l.indexOf("\"", stringStart);
144          Matcher matcher = EXCEPTION_INFO_REGEX.matcher(l.substring(0, stringStart));
145          if (matcher.find())
146            current.add(new InputCode(matcher.group(1),
147                                      Integer.parseInt(matcher.group(2)),
148                                      matcher.group(3),
149                                      l.substring(stringStart, stringEnd)));
150        }
151        exceptions.offer(current);
152        current = null;
153        break;
154      }
155    }
156  }
157
158  /**
159   * Returns the name of this group of exceptions.
160   *
161   * @return the name of this group of exceptions.
162   */
163  public String getGroupName()
164  {
165    return groupName;
166  }
167
168  /**
169   * Returns the name of the package this class will go in.
170   *
171   * @return the name of the package.
172   */
173  public String getPackageName()
174  {
175    return packageName;
176  }
177
178  /**
179   * Returns the name of the generated class.
180   *
181   * @return the name of the class.
182   */
183  public String getClassName()
184  {
185    return className;
186  }
187
188  /**
189   * Returns the exceptions contained in this class.
190   *
191   * @return the exceptions.
192   */
193  public Queue<InputException> getExceptions() {
194    return exceptions;
195  }
196
197  /**
198   * Returns a textual representation of this input.
199   *
200   * @return a textual representation.
201   */
202  public String toString() {
203    return getClass().getName() +
204      "[packageName=" + packageName +
205      ",className=" + className +
206      ",groupName=" + groupName +
207      ",exceptions=" + exceptions +
208      "]";
209  }
210
211}
212