1
2
3
4
5
6
7
8
9
10
11
12
13
14 package gr.abiss.mvn.plugins.jstools;
15
16 import gr.abiss.mvn.plugins.jstools.utils.FileSystemDirectoryUtils;
17 import java.io.BufferedOutputStream;
18 import java.io.ByteArrayOutputStream;
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.FileNotFoundException;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.io.PrintStream;
27 import java.nio.channels.FileChannel;
28 import java.util.ArrayList;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Locale;
32 import java.util.Set;
33 import org.apache.commons.io.IOUtils;
34 import org.apache.maven.reporting.MavenReportException;
35 import org.codehaus.plexus.archiver.ArchiverException;
36 import org.codehaus.plexus.archiver.UnArchiver;
37 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
38 import org.mozilla.javascript.tools.shell.Main;
39
40 /***
41 * Goal to generate JavaScript documentation using the JSDoc Toolkit
42 *
43 * @goal jsdoc
44 * @version $Id$
45 * @author manos
46 *
47 */
48 public class JsDocMojo extends AbstractBaseJstoolsReport {
49 /***
50 * The JSDoc template to use. Valid values are template directory names in
51 * the JSDoc Toolkit Distribution used or paths to an appropriate template
52 * directory. The default is JSDocs' "jsdoc" template.
53 *
54 * @parameter expression="jsdoc"
55 */
56 private String template;
57
58 /***
59 * A path pointing to a the desired JSDoc Toolkit directory (e.g.
60 * /home/username/stuff/jsdoc_toolkit-1.3.0). If no value is provided the
61 * plugin wil use its own internal version.
62 *
63 * @parameter
64 */
65 private String jsdocHome;
66
67 /***
68 * Whether to include symbols tagged as private. Default is <code>false</code>.
69 * @parameter expression="false"
70 */
71 private boolean includePrivate;
72
73 /***
74 * Include all functions, even undocumented ones. Default is <code>false</code>.
75 * @parameter expression="false"
76 */
77 private boolean includeUndocumented;
78
79 /***
80 * Include all functions, even undocumented, underscored ones. Default is <code>false</code>.
81 * @parameter expression="false"
82 */
83 private boolean includeUndocumentedUnderscored;
84
85 /***
86 * Use the -j option, must be set to <code>false</code> for JSDoc Toolkit 1.x. or
87 * <code>true</code> for JSDoc Toolkit version 2.0 and above. Default is <code>true</code>.
88 * @parameter expression="true"
89 */
90 private boolean jArgument;
91
92
93 /***
94 * Use JSDoc to generate Javascript API documentation
95 *
96 * @see gr.abiss.mvn.plugins.jstools.AbstractBaseJstoolsReport#doGenerateReport(java.util.Locale)
97 */
98 public void doGenerateReport(Locale defaultLocale)
99 throws MavenReportException {
100
101
102
103 String systemJsdocDir = System.getProperty("jsdoc.dir");
104 System.setProperty("jsdoc.dir", this.jsdocHome);
105 if (systemJsdocDir != null) {
106 getLog().debug("Temporarily switched the system's 'sdoc.dir' property to: "+System.getProperty("jsdoc.dir"));
107 }
108
109 List<String> args = new ArrayList<String>();
110
111 ByteArrayOutputStream baos = null;
112 PrintStream ps = null;
113 if(!this.getLog().isDebugEnabled()){
114 baos = new ByteArrayOutputStream();
115 ps = new PrintStream(baos);
116 Main.setOut(ps);
117 }
118 String runJsPath = this.jsdocHome + "/app/run.js";
119 args.add(runJsPath);
120 if(this.includeUndocumented){
121 args.add( "-a" );
122 }
123 if(this.includeUndocumentedUnderscored){
124 args.add( "-A" );
125 }
126 if(this.includePrivate){
127 args.add( "-p" );
128 }
129 args.add("-d=" + this.getOutputDirectory());
130 String targetTemplate = this.template.indexOf(File.separator) != -1 ? this.template
131 : this.jsdocHome + "/templates/" + this.template;
132 args.add("-t=" + targetTemplate);
133
134 Set jsfiles = this.getJavaScriptFiles();
135 for(Iterator iter = jsfiles.iterator(); iter.hasNext();){
136 args.add(((File) iter.next()).getAbsolutePath());
137 }
138 if(this.jArgument){
139
140 args.add("-j=" + runJsPath);
141 }
142 getLog().debug("Executing: '" + args.toString().replaceAll(",","") + "'");
143
144
145
146 Main.exec(args.toArray(new String[0]));
147
148
149 if (systemJsdocDir != null) {
150 System.setProperty("jsdoc.dir", systemJsdocDir);
151 getLog().debug("Switched the system's 'sdoc.dir' property back to original value: "+System.getProperty("jsdoc.dir"));
152 }
153
154 try {
155 File in = new File(this.getOutputDirectory() + "/" + "index.htm");
156 if (in.exists()) {
157 File out = new File(this.getOutputDirectory() + "/"
158 + "index.html");
159 FileChannel sourceChannel = new FileInputStream(in)
160 .getChannel();
161 FileChannel destinationChannel = new FileOutputStream(out)
162 .getChannel();
163 sourceChannel.transferTo(0, sourceChannel.size(),
164 destinationChannel);
165 sourceChannel.close();
166 destinationChannel.close();
167 }
168 } catch (IOException e) {
169 throw new MavenReportException("Could not copy file");
170 }
171
172 }
173
174 /***
175 * Setup the plugin's internal JSDoc Toolkit version if no other is provided
176 *
177 * @param defaultLocale
178 * @throws MavenReportException
179 */
180 protected void setUp(Locale defaultLocale) throws MavenReportException {
181 if (this.jsdocHome == null || this.jsdocHome.trim().length() == 0) {
182 String jsdocDistFilename = this.getBundle(defaultLocale).getString(
183 "jsdoc.dist.filename");
184 this.jsdocHome = this.buildDir + "/jsdoc_run/" + jsdocDistFilename;
185 String jsDocJar = this.baseDir + "/target/" + jsdocDistFilename
186 + ".zip";
187
188 try {
189 InputStream input = this.getClass().getResourceAsStream(
190 "/" + jsdocDistFilename + ".zip");
191 OutputStream output = new FileOutputStream(jsDocJar);
192 IOUtils.copy(input, output);
193 input.close();
194 output.close();
195 } catch (FileNotFoundException fe) {
196 throw new MavenReportException("Cannot find "
197 + jsdocDistFilename + ".zip" + " in classpath", fe);
198 } catch (IOException ioe) {
199 throw new MavenReportException("Error copying "
200 + jsdocDistFilename + ".zip" + " to target dir", ioe);
201 }
202
203 File jarFile = new File(jsDocJar);
204 try {
205 UnArchiver unArchiver = this.archiverManager
206 .getUnArchiver(jarFile);
207 unArchiver.setSourceFile(jarFile);
208 File destDir = new File(this.jsdocHome).getParentFile();
209 destDir.mkdirs();
210 unArchiver.setDestDirectory(destDir);
211 unArchiver.extract();
212 } catch (NoSuchArchiverException ae) {
213 throw new MavenReportException("Unknown archiver type", ae);
214 } catch (ArchiverException ae) {
215 throw new MavenReportException("Error unpacking " + jarFile
216 + ": " + ae.toString(), ae);
217 }
218 }
219 }
220
221 /***
222 * @see org.apache.maven.reporting.AbstractMavenReport#isExternalReport()
223 */
224 public boolean isExternalReport() {
225 return true;
226 }
227
228 /***
229 * @see gr.abiss.mvn.plugins.jstools.AbstractBaseJstoolsReport#getBundleKey()
230 */
231 public String getBundleKey() {
232 return "jsdoc";
233 }
234
235 /***
236 * Does nothing
237 *
238 * @see gr.abiss.mvn.plugins.jstools.AbstractBaseJstoolsReport#tearDown(java.util.Locale)
239 */
240 protected void tearDown(Locale defaultLocale) throws MavenReportException {
241 try {
242 File runDir = new File(this.buildDir + "/jsdoc_run/");
243 if (runDir.exists()) {
244 FileSystemDirectoryUtils.deleteDirectory(runDir);
245 }
246 File jsdocJar = new File(this.baseDir
247 + "/target/"
248 + this.getBundle(defaultLocale).getString(
249 "jsdoc.dist.filename") + ".zip");
250 if(jsdocJar.exists()){
251 jsdocJar.delete();
252 }
253 } catch (Exception ioe) {
254 throw new MavenReportException("Error clearing up", ioe);
255 }
256 }
257 }