• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.doclava.apicheck;
18 
19 import java.io.FileInputStream;
20 import java.io.FileNotFoundException;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.PrintStream;
24 import java.net.URL;
25 import java.util.ArrayList;
26 import java.util.Set;
27 import java.util.Stack;
28 
29 import com.google.doclava.Errors;
30 import com.google.doclava.Errors.ErrorMessage;
31 import com.google.doclava.Stubs;
32 
33 public class ApiCheck {
34   // parse out and consume the -whatever command line flags
parseFlags(ArrayList<String> allArgs)35   private static ArrayList<String[]> parseFlags(ArrayList<String> allArgs) {
36     ArrayList<String[]> ret = new ArrayList<String[]>();
37 
38     int i;
39     for (i = 0; i < allArgs.size(); i++) {
40       // flags with one value attached
41       String flag = allArgs.get(i);
42       if (flag.equals("-error") || flag.equals("-warning") || flag.equals("-hide")) {
43         String[] arg = new String[2];
44         arg[0] = flag;
45         arg[1] = allArgs.get(++i);
46         ret.add(arg);
47       } else {
48         // we've consumed all of the -whatever args, so we're done
49         break;
50       }
51     }
52 
53     // i now points to the first non-flag arg; strip what came before
54     for (; i > 0; i--) {
55       allArgs.remove(0);
56     }
57     return ret;
58   }
59 
main(String[] originalArgs)60   public static void main(String[] originalArgs) {
61     if (originalArgs.length == 3 && "-convert".equals(originalArgs[0])) {
62       System.exit(convertToApi(originalArgs[1], originalArgs[2]));
63     } else if (originalArgs.length == 3 && "-convert2xml".equals(originalArgs[0])) {
64       System.exit(convertToXml(originalArgs[1], originalArgs[2]));
65     } else {
66       ApiCheck acheck = new ApiCheck();
67       Report report = acheck.checkApi(originalArgs);
68 
69       Errors.printErrors(report.errors());
70       System.exit(report.code);
71     }
72   }
73 
74   /**
75    * Compares two api xml files for consistency.
76    */
checkApi(String[] originalArgs)77   public Report checkApi(String[] originalArgs) {
78     // translate to an ArrayList<String> for munging
79     ArrayList<String> args = new ArrayList<String>(originalArgs.length);
80     for (String a : originalArgs) {
81       args.add(a);
82     }
83 
84     ArrayList<String[]> flags = ApiCheck.parseFlags(args);
85     for (String[] a : flags) {
86       if (a[0].equals("-error") || a[0].equals("-warning") || a[0].equals("-hide")) {
87         try {
88           int level = -1;
89           if (a[0].equals("-error")) {
90             level = Errors.ERROR;
91           } else if (a[0].equals("-warning")) {
92             level = Errors.WARNING;
93           } else if (a[0].equals("-hide")) {
94             level = Errors.HIDDEN;
95           }
96           Errors.setErrorLevel(Integer.parseInt(a[1]), level);
97         } catch (NumberFormatException e) {
98           System.err.println("Bad argument: " + a[0] + " " + a[1]);
99           return new Report(2, Errors.getErrors());
100         }
101       }
102     }
103 
104     ApiInfo oldApi;
105     ApiInfo newApi;
106 
107     try {
108       oldApi = parseApi(args.get(0));
109       newApi = parseApi(args.get(1));
110     } catch (ApiParseException e) {
111       e.printStackTrace();
112       System.err.println("Error parsing API");
113       return new Report(1, Errors.getErrors());
114     }
115 
116     // only run the consistency check if we haven't had XML parse errors
117     if (!Errors.hadError) {
118       oldApi.isConsistent(newApi);
119     }
120 
121     return new Report(Errors.hadError ? 1 : 0, Errors.getErrors());
122   }
123 
parseApi(String filename)124   public static ApiInfo parseApi(String filename) throws ApiParseException {
125     InputStream stream = null;
126     // try it as our format
127     try {
128       stream = new FileInputStream(filename);
129     } catch (IOException e) {
130       throw new ApiParseException("Could not open file for parsing: " + filename, e);
131     }
132     try {
133       return ApiFile.parseApi(filename, stream);
134     } catch (ApiParseException ignored) {
135       if (false) {
136         System.out.println("stopping for file: " + filename);
137         ignored.printStackTrace();
138         return null;
139       }
140     } finally {
141       try {
142         stream.close();
143       } catch (IOException ignored) {}
144     }
145     // try it as xml
146     try {
147       stream = new FileInputStream(filename);
148     } catch (IOException e) {
149       throw new ApiParseException("Could not open file for parsing: " + filename, e);
150     }
151     try {
152       return XmlApiFile.parseApi(stream);
153     } finally {
154       try {
155         stream.close();
156       } catch (IOException ignored) {}
157     }
158   }
159 
parseApi(URL url)160   public ApiInfo parseApi(URL url) throws ApiParseException {
161     InputStream stream = null;
162     // try it as our format
163     try {
164       stream = url.openStream();
165     } catch (IOException e) {
166       throw new ApiParseException("Could not open stream for parsing: " + url, e);
167     }
168     try {
169       return ApiFile.parseApi(url.toString(), stream);
170     } catch (ApiParseException ignored) {
171     } finally {
172       try {
173         stream.close();
174       } catch (IOException ignored) {}
175     }
176     // try it as xml
177     try {
178       stream = url.openStream();
179     } catch (IOException e) {
180       throw new ApiParseException("Could not open stream for parsing: " + url, e);
181     }
182     try {
183       return XmlApiFile.parseApi(stream);
184     } finally {
185       try {
186         stream.close();
187       } catch (IOException ignored) {}
188     }
189   }
190 
191   public class Report {
192     private int code;
193     private Set<ErrorMessage> errors;
194 
Report(int code, Set<ErrorMessage> errors)195     private Report(int code, Set<ErrorMessage> errors) {
196       this.code = code;
197       this.errors = errors;
198     }
199 
code()200     public int code() {
201       return code;
202     }
203 
errors()204     public Set<ErrorMessage> errors() {
205       return errors;
206     }
207   }
208 
convertToApi(String src, String dst)209   static int convertToApi(String src, String dst) {
210     ApiInfo api;
211     try {
212       api = parseApi(src);
213     } catch (ApiParseException e) {
214       e.printStackTrace();
215       System.err.println("Error parsing API: " + src);
216       return 1;
217     }
218 
219     PrintStream apiWriter = null;
220     try {
221       apiWriter = new PrintStream(dst);
222     } catch (FileNotFoundException ex) {
223       System.err.println("can't open file: " + dst);
224     }
225 
226     Stubs.writeApi(apiWriter, api.getPackages().values());
227 
228     return 0;
229   }
230 
convertToXml(String src, String dst)231   static int convertToXml(String src, String dst) {
232     ApiInfo api;
233     try {
234       api = parseApi(src);
235     } catch (ApiParseException e) {
236       e.printStackTrace();
237       System.err.println("Error parsing API: " + src);
238       return 1;
239     }
240 
241     PrintStream apiWriter = null;
242     try {
243       apiWriter = new PrintStream(dst);
244     } catch (FileNotFoundException ex) {
245       System.err.println("can't open file: " + dst);
246     }
247 
248     Stubs.writeXml(apiWriter, api.getPackages().values());
249 
250     return 0;
251   }
252 
253 }
254