source: src/main/java/weka/core/Javadoc.java @ 6

Last change on this file since 6 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 14.7 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 * Javadoc.java
19 * Copyright (C) 2006 University of Waikato, Hamilton, New Zealand
20 */
21
22package weka.core;
23
24import java.io.BufferedReader;
25import java.io.File;
26import java.io.FileReader;
27import java.util.Enumeration;
28import java.util.StringTokenizer;
29import java.util.Vector;
30
31/**
32 * Abstract superclass for classes that generate Javadoc comments and replace
33 * the content between certain comment tags.
34 *
35 * @author  fracpete (fracpete at waikato dot ac dot nz)
36 * @version $Revision: 5953 $
37 */
38public abstract class Javadoc 
39  implements OptionHandler, RevisionHandler {
40
41  /** the start tag */
42  protected String[] m_StartTag = null;
43
44  /** the end tag */
45  protected String[] m_EndTag = null;
46 
47  /** the classname */
48  protected String m_Classname = Javadoc.class.getName();
49 
50  /** whether to include the stars in the Javadoc */
51  protected boolean m_UseStars = true;
52
53  /** the directory above the class to update */
54  protected String m_Dir = "";
55 
56  /** whether to suppress error messages (no printout in the console) */
57  protected boolean m_Silent = false;
58 
59  /**
60   * Returns an enumeration describing the available options.
61   *
62   * @return an enumeration of all the available options.
63   */
64  public Enumeration listOptions() {
65    Vector<Option> result = new Vector<Option>();
66
67    result.addElement(new Option(
68        "\tThe class to load.",
69        "W", 1, "-W <classname>"));
70   
71    result.addElement(new Option(
72        "\tSuppresses the '*' in the Javadoc.",
73        "nostars", 0, "-nostars"));
74   
75    result.addElement(new Option(
76        "\tThe directory above the package hierarchy of the class.",
77        "dir", 1, "-dir <dir>"));
78   
79    result.addElement(new Option(
80        "\tSuppresses printing in the console.",
81        "silent", 0, "-silent"));
82   
83    return result.elements();
84  }
85 
86  /**
87   * Parses a given list of options.
88   *
89   * @param options the list of options as an array of strings
90   * @throws Exception if an option is not supported
91   */
92  public void setOptions(String[] options) throws Exception {
93    String                      tmpStr;
94   
95    tmpStr = Utils.getOption('W', options);
96    if (tmpStr.length() > 0)
97      setClassname(tmpStr);
98    else
99      setClassname(this.getClass().getName());
100
101    setUseStars(!Utils.getFlag("nostars", options));
102
103    setDir(Utils.getOption("dir", options));
104
105    setSilent(Utils.getFlag("silent", options));
106  }
107 
108  /**
109   * Gets the current settings of this object.
110   *
111   * @return an array of strings suitable for passing to setOptions
112   */
113  public String[] getOptions() {
114    Vector<String>      result;
115
116    result = new Vector<String>();
117   
118    result.add("-W");
119    result.add(getClassname());
120   
121    if (!getUseStars())
122      result.add("-nostars");
123   
124    if (getDir().length() != 0) {
125      result.add("-dir");
126      result.add(getDir());
127    }
128   
129    if (getSilent())
130      result.add("-silent");
131   
132    return (String[]) result.toArray(new String[result.size()]);
133  }
134 
135  /**
136   * sets the classname of the class to generate the Javadoc for
137   *
138   * @param value       the new classname
139   */
140  public void setClassname(String value) {
141    m_Classname = value;
142  }
143 
144  /**
145   * returns the current classname
146   *
147   * @return    the current classname
148   */
149  public String getClassname() {
150    return m_Classname;
151  }
152 
153  /**
154   * sets whether to prefix the Javadoc with "*"
155   *
156   * @param value       true if stars are used
157   */
158  public void setUseStars(boolean value) {
159    m_UseStars = value;
160  }
161 
162  /**
163   * whether the Javadoc is prefixed with "*"
164   *
165   * @return            whether stars are used
166   */
167  public boolean getUseStars() {
168    return m_UseStars;
169  }
170 
171  /**
172   * sets the dir containing the file that is to be updated. It is the dir
173   * above the package hierarchy of the class.
174   *
175   * @param value       the directory containing the classes
176   */
177  public void setDir(String value) {
178    m_Dir = value;
179  }
180 
181  /**
182   * returns the current dir containing the class to update. It is the dir
183   * above the package name of the class.
184   *
185   * @return            the  current directory
186   */
187  public String getDir() {
188    return m_Dir;
189  }
190 
191  /**
192   * sets whether to suppress output in the console
193   *
194   * @param value       true if output is to be suppressed
195   */
196  public void setSilent(boolean value) {
197    m_Silent = value;
198  }
199 
200  /**
201   * whether output in the console is suppressed
202   *
203   * @return            true if output is suppressed
204   */
205  public boolean getSilent() {
206    return m_Silent;
207  }
208 
209  /**
210   * prints the given object to System.err
211   *
212   * @param o           the object to print
213   */
214  protected void println(Object o) {
215    if (!getSilent())
216      System.err.println(o.toString());
217  }
218
219  /**
220   * returns true if the class can be instantiated, i.e., has a default
221   * constructor.
222   *
223   * @return true if the class can be instantiated
224   */
225  protected boolean canInstantiateClass() {
226    boolean     result;
227    Class       cls;
228
229    result = true;
230    cls    = null;
231
232    try {
233      cls = Class.forName(getClassname());
234    }
235    catch (Exception e) {
236      result = false;
237      println("Cannot instantiate '" + getClassname() + "'! Class in CLASSPATH?");
238    }
239
240    if (result) {
241      try {
242        cls.newInstance();
243      }
244      catch (Exception e) {
245        result = false;
246        println("Cannot instantiate '" + getClassname() + "'! Missing default constructor?");
247      }
248    }
249   
250    return result;
251  }
252 
253  /**
254   * Returns a new instance of the class
255   *
256   * @return a new instance of the class
257   */
258  protected Object getInstance() {
259    Object      result;
260    Class       cls;
261
262    result = null;
263   
264    try {
265      cls    = Class.forName(getClassname());
266      result = cls.newInstance();
267    }
268    catch (Exception e) {
269      result = null;
270    }
271   
272    return result;
273  }
274 
275  /**
276   * converts the given String into HTML, i.e., replacing some char entities
277   * with HTML entities.
278   *
279   * @param s           the string to convert
280   * @return            the HTML conform string
281   */
282  protected String toHTML(String s) {
283    String      result;
284   
285    result = s;
286   
287    result = result.replaceAll("&", "&amp;");
288    result = result.replaceAll("<", "&lt;");
289    result = result.replaceAll(">", "&gt;");
290    result = result.replaceAll("@", "&#64;");
291    result = result.replaceAll("\n", "<br/>\n");
292   
293    return result;
294  }
295
296  /**
297   * indents the given string by a given number of indention strings
298   *
299   * @param content     the string to indent
300   * @param count       the number of times to indent one line
301   * @param indentStr   the indention string
302   * @return            the indented content
303   */
304  protected String indent(String content, int count, String indentStr) {
305    String              result;
306    StringTokenizer     tok;
307    int                 i;
308   
309    tok = new StringTokenizer(content, "\n", true);
310    result = "";
311    while (tok.hasMoreTokens()) {
312      if (result.endsWith("\n") || (result.length() == 0)) {
313        for (i = 0; i < count; i++)
314          result += indentStr;
315      }
316      result += tok.nextToken();
317    }
318   
319    return result;
320  }
321 
322  /**
323   * generates and returns the Javadoc for the specified start/end tag pair.
324   *
325   * @param index       the index in the start/end tag array
326   * @return            the generated Javadoc
327   * @throws Exception  in case the generation fails
328   */
329  protected abstract String generateJavadoc(int index) throws Exception;
330 
331  /**
332   * generates and returns the Javadoc
333   *
334   * @return            the generated Javadoc
335   * @throws Exception  in case the generation fails
336   */
337  protected String generateJavadoc() throws Exception {
338    String      result;
339    int         i;
340   
341    result = "";
342   
343    for (i = 0; i < m_StartTag.length; i++) {
344      if (i > 0)
345        result += "\n\n";
346      result += generateJavadoc(i).trim();
347    }
348   
349    return result;
350  }
351
352  /**
353   * determines the base string of the given indention string, whether it's
354   * either only spaces (one space will be retured) or mixed mode (tabs and
355   * spaces, in that case the same string will be returned)
356   *
357   * @param str         the string to analyze
358   * @return            the indention string
359   */
360  protected String getIndentionString(String str) {
361    String      result;
362   
363    // only spaces?
364    if (str.replaceAll(" ", "").length() == 0)
365      result = " ";
366    // only tabs?
367    else if (str.replaceAll("\t", "").length() == 0)
368      result = "\t";
369    else
370      result = str;
371     
372    return result;
373  }
374 
375  /**
376   * determines the number of indention strings that have to be inserted to
377   * generated the given indention string.
378   *
379   * @param str         the string to analyze
380   * @return            the number of base indention strings to insert
381   */
382  protected int getIndentionLength(String str) {
383    int         result;
384   
385    // only spaces?
386    if (str.replaceAll(" ", "").length() == 0)
387      result = str.length();
388    // only tabs?
389    else if (str.replaceAll("\t", "").length() == 0)
390      result = str.length();
391    else
392      result = 1;
393   
394    return result;
395  }
396 
397  /**
398   * generates and returns the Javadoc for the specified start/end tag pair
399   *
400   * @param content     the current source code
401   * @param index       the index in the start/end tag array
402   * @return            the generated Javadoc
403   * @throws Exception  in case the generation fails
404   */
405  protected String updateJavadoc(String content, int index) throws Exception {
406    StringBuffer        resultBuf;
407    int                 indentionLen;
408    String              indentionStr;
409    String              part;
410    String              tmpStr;
411
412    // start and end tag?
413    if (    (content.indexOf(m_StartTag[index]) == -1)
414           || (content.indexOf(m_EndTag[index]) == -1) ) {
415        println(
416            "No start and/or end tags found: " 
417            + m_StartTag[index] + "/" + m_EndTag[index]);
418        return content;
419    }
420
421    // replace option-tags
422    resultBuf = new StringBuffer();
423    while (content.length() > 0) {
424      if (content.indexOf(m_StartTag[index]) > -1) {
425        part = content.substring(0, content.indexOf(m_StartTag[index]));
426        // is it a Java constant? -> skip
427        if (part.endsWith("\"")) {
428          resultBuf.append(part);
429          resultBuf.append(m_StartTag[index]);
430          content = content.substring(part.length() + m_StartTag[index].length());
431        }
432        else {
433          tmpStr       = part.substring(part.lastIndexOf("\n") + 1);
434          indentionLen = getIndentionLength(tmpStr);
435          indentionStr = getIndentionString(tmpStr);
436          part         = part.substring(0, part.lastIndexOf("\n") + 1);
437          resultBuf.append(part);
438          resultBuf.append(indent(m_StartTag[index], indentionLen, indentionStr) + "\n");
439          resultBuf.append(indent(generateJavadoc(index), indentionLen, indentionStr));
440          resultBuf.append(indent(m_EndTag[index], indentionLen, indentionStr));
441          content = content.substring(content.indexOf(m_EndTag[index]));
442          content = content.substring(m_EndTag[index].length());
443        }
444      }
445      else {
446        resultBuf.append(content);
447        content = "";
448      }
449    }
450   
451    return resultBuf.toString().trim();
452  }
453 
454  /**
455   * updates the Javadoc in the given source code.
456   *
457   * @param content     the source code
458   * @return            the updated source code
459   * @throws Exception  in case the generation fails
460   */
461  protected String updateJavadoc(String content) throws Exception {
462    String      result;
463    int         i;
464   
465    result = content;
466   
467    for (i = 0; i < m_StartTag.length; i++) {
468      result = updateJavadoc(result, i);
469    }
470   
471    return result;
472  }
473 
474  /**
475   * generates the Javadoc and returns it applied to the source file if one
476   * was provided, otherwise an empty string.
477   *
478   * @return            the generated Javadoc
479   * @throws Exception  in case the generation fails
480   */
481  public String updateJavadoc() throws Exception {
482    StringBuffer        contentBuf;
483    BufferedReader      reader;
484    String              line;
485    String              result;
486    File                file;
487   
488    result = "";
489   
490    // non-existing?
491    file = new File(getDir() + "/" + getClassname().replaceAll("\\.", "/") + ".java");
492    if (!file.exists()) {
493      println("File '" + file.getAbsolutePath() + "' doesn't exist!");
494      return result;
495    }
496   
497    try {
498      // load file
499      reader     = new BufferedReader(new FileReader(file));
500      contentBuf = new StringBuffer();
501      while ((line = reader.readLine()) != null) {
502        contentBuf.append(line + "\n");
503      }
504      reader.close();
505      result = updateJavadoc(contentBuf.toString());
506    }
507    catch (Exception e) {
508      e.printStackTrace();
509    }
510   
511    return result.trim();
512  }
513 
514  /**
515   * generates either the plain Javadoc (if no filename specified) or the
516   * updated file (if a filename is specified). The start and end tag for
517   * the global info have to be specified in the file in the latter case.
518   *
519   * @return            either the plain Javadoc or the modified file
520   * @throws Exception  in case the generation fails
521   */
522  public String generate() throws Exception {
523    if (getDir().length() == 0)
524      return generateJavadoc();
525    else
526      return updateJavadoc();
527  }
528 
529  /**
530   * generates a string to print as help on the console
531   *
532   * @return    the generated help
533   */
534  public String generateHelp() {
535    String              result;
536    Enumeration         enm;
537    Option              option;
538   
539    result = getClass().getName().replaceAll(".*\\.", "") + " Options:\n\n";
540    enm = listOptions();
541    while (enm.hasMoreElements()) {
542      option = (Option) enm.nextElement();
543      result += option.synopsis() + "\n" + option.description() + "\n";
544    }
545   
546    return result;
547  }
548 
549  /**
550   * runs the javadoc producer with the given commandline options
551   *
552   * @param javadoc     the javadoc producer to execute
553   * @param options     the commandline options
554   */
555  protected static void runJavadoc(Javadoc javadoc, String[] options) {
556    try {
557      try {
558        if (Utils.getFlag('h', options))
559          throw new Exception("Help requested");
560
561        javadoc.setOptions(options);
562        Utils.checkForRemainingOptions(options);
563
564        // directory is necessary!
565        if (javadoc.getDir().length() == 0)
566          throw new Exception("No directory provided!");
567      } 
568      catch (Exception ex) {
569        String result = "\n" + ex.getMessage() + "\n\n" + javadoc.generateHelp();
570        throw new Exception(result);
571      }
572
573      System.out.println(javadoc.generate() + "\n");
574    } 
575    catch (Exception ex) {
576      System.err.println(ex.getMessage());
577    }
578  }
579}
Note: See TracBrowser for help on using the repository browser.