// Copyright (C) 2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.caja.tools;
import com.google.caja.parser.quasiliteral.DojoRuleDoclet;
import com.google.caja.parser.quasiliteral.HtmlRuleDoclet;
import com.google.caja.parser.quasiliteral.JsonRuleDoclet;
import com.google.caja.parser.quasiliteral.Rewriter;
import com.google.caja.parser.quasiliteral.RuleDoclet;
import com.google.caja.parser.quasiliteral.TextRuleDoclet;
import com.google.caja.parser.quasiliteral.WikiRuleDoclet;
import com.google.caja.reporting.BuildInfo;
import com.google.caja.reporting.MessageQueue;
import com.google.caja.reporting.SimpleMessageQueue;
import com.google.caja.util.Charsets;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
/**
* ANT task that extracts and generates documentation on rewrite rules
*
* @author jasvir@gmail.com (Jasvir Nagra)
*/
public class DocletAntTask extends Task {
private String outputDir;
private RuleDoclet output;
private Rewriter rewriter;
public void setOutputDir(String outputDir) {
this.outputDir = outputDir;
}
/**
* Sets the type of output generated by the doclet.
* @param output Valid options are text|html|wiki|json|dojo
*/
public void setOutput(String output) {
if(output.equals("text")) {
this.output = new TextRuleDoclet();
} else if(output.equals("html")) {
this.output = new HtmlRuleDoclet();
} else if(output.equals("json")) {
this.output = new JsonRuleDoclet();
} else if(output.equals("text")) {
this.output = new WikiRuleDoclet();
} else if(output.equals("dojo")) {
this.output = new DojoRuleDoclet();
} else {
throw new BuildException("Unsupported doclet type");
}
}
public void setRewriter(String className) {
try {
Class<? extends Rewriter> rewriterClass = Class.forName(className)
.asSubclass(Rewriter.class);
Constructor<? extends Rewriter> ctor = publicCtor(rewriterClass);
Object[] actuals = new Object[ctor.getParameterTypes().length];
int i = 0;
for (Class<?> ptype : ctor.getParameterTypes()) {
if (Boolean.TYPE.equals(ptype)) {
actuals[i] = Boolean.FALSE; // No logging
} else if (BuildInfo.class.isAssignableFrom(ptype)) {
actuals[i] = BuildInfo.getInstance();
} else if (MessageQueue.class.isAssignableFrom(ptype)) {
actuals[i] = new SimpleMessageQueue();
}
++i;
}
this.rewriter = ctor.newInstance(actuals);
} catch (InstantiationException e) {
throw new BuildException(e);
} catch (InvocationTargetException e) {
throw new BuildException(e);
} catch (IllegalAccessException e) {
throw new BuildException(e);
} catch (ClassNotFoundException e) {
throw new BuildException(e);
}
}
@SuppressWarnings("unchecked")
private static <T> Constructor<T> publicCtor(Class<T> cl)
throws IllegalAccessException {
for (Constructor<?> c : cl.getDeclaredConstructors()) {
if (Modifier.isPublic(c.getModifiers())) {
return (Constructor<T>) c;
}
}
throw new IllegalAccessException(); // No public ctor
}
private void checkValidParameters() {
if (null == output) {
throw new BuildException("Doclet \"output\" type not set");
}
if (null == rewriter) {
throw new BuildException("Doclet \"rewriter\" not set");
}
if (null == outputDir) {
throw new BuildException("Doclet \"outputDir\" not set");
}
}
/**
* Constructs output file name for a given rewriter and output directory
*/
private String getOutputFileName() {
String simpleFileName = rewriter.getClass().getSimpleName();
String dirFileName = outputDir.endsWith("/")
? outputDir + simpleFileName
: outputDir + '/' + simpleFileName;
String completeFileName = dirFileName + '.' + output.getDefaultExtension();
return completeFileName;
}
@Override
public void execute() throws BuildException {
try {
checkValidParameters();
output.setRewriter(rewriter);
String outputFile = getOutputFileName();
BufferedWriter outputStream = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputFile), Charsets.UTF_8.name()));
output.generateDocumentation(outputStream);
outputStream.close();
} catch (IOException e) {
throw new BuildException(e);
}
}
}