8157975: Remove duplicate files in sample API

Reviewed-by: jjg, ksrini
This commit is contained in:
Alexandre Iline 2016-06-02 17:31:38 -07:00 committed by Kumar Srinivasan
parent a06ab4d4e1
commit 57b82df0b9
23 changed files with 460 additions and 1988 deletions

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,21 +30,30 @@
* jdk.compiler/com.sun.tools.javac.parser
* jdk.compiler/com.sun.tools.javac.tree
* jdk.compiler/com.sun.tools.javac.util
* @run main sampleapi.SampleApiDefaultRunner -o:out/src
* jdk.javadoc/jdk.javadoc.internal.tool
* @run main SampleApiTest
*/
import java.io.File;
import com.sun.tools.javadoc.*;
import java.nio.file.Paths;
import jdk.javadoc.internal.tool.Main;
import sampleapi.SampleApiDefaultRunner;
public class SampleApiTest {
public static void main(String... args) {
public static void main(String... args) throws Exception {
// html4
Main.execute(
// generate
SampleApiDefaultRunner.execute(
new String[] {
"-d", "out/doc.html4",
"-o=out/src",
"-r=" + System.getProperty("test.src") + "/res"
});
// html4 / unnamed modules
System.err.println(">> HTML4, unnamed modules");
int res1 = Main.execute(
new String[] {
"-d", "out/doc.html4.unnamed",
"-verbose",
"-private",
"-use",
@ -53,16 +62,20 @@ public class SampleApiTest {
"-html4",
"-javafx",
"-windowtitle", "SampleAPI",
"-sourcepath", "out/src",
"-overview", "overview.html",
"-sourcepath", "out/src" + File.pathSeparator + "out/src/sat.sampleapi",
"sampleapi.simple",
"sampleapi.simple.sub",
"sampleapi.tiny",
"sampleapi.tiny.sub",
"sampleapi.fx"
});
// html5
Main.execute(
// html5 / unnamed modules
System.err.println(">> HTML5, unnamed modules");
int res2 = Main.execute(
new String[] {
"-d", "out/doc.html5",
"-d", "out/doc.html5.unnamed",
"-verbose",
"-private",
"-use",
@ -71,10 +84,17 @@ public class SampleApiTest {
"-html5",
"-javafx",
"-windowtitle", "SampleAPI",
"-sourcepath", "out/src",
"-overview", "overview.html",
"-sourcepath", "out/src" + File.pathSeparator + "out/src/sat.sampleapi",
"sampleapi.simple",
"sampleapi.simple.sub",
"sampleapi.tiny",
"sampleapi.tiny.sub",
"sampleapi.fx"
});
if (res1 > 0 || res2 > 0)
throw new Exception("One of exit statuses is non-zero: "
+ res1 + " for HTML4, " + res2 + " for HTML5.");
}
}

@ -24,6 +24,7 @@
package sampleapi;
import java.io.File;
import java.io.FilenameFilter;
import java.nio.file.Path;
import sampleapi.generator.PackageGenerator;
@ -32,21 +33,21 @@ public class SampleApi {
PackageGenerator pkgGen = new PackageGenerator();
public void generate(File dir) throws Fault {
pkgGen.processDataSet("simple");
pkgGen.generate(dir);
pkgGen.processDataSet("tiny");
pkgGen.generate(dir);
pkgGen.processDataSet("fx");
pkgGen.generate(dir);
public void generate(File resDir, File outDir) throws Fault {
FilenameFilter filter = (dir, name) -> { return name.endsWith(".xml"); };
File[] resFiles = resDir.listFiles(filter);
for (File resFile : resFiles) {
pkgGen.processDataSet(resFile);
pkgGen.generate(outDir);
}
}
public void generate(Path dir) throws Fault {
generate(dir.toFile());
public void generate(Path res, Path dir) throws Fault {
generate(res.toFile(), dir.toFile());
}
public void generate(String dir) throws Fault {
generate(new File(dir));
public void generate(String res, String dir) throws Fault {
generate(new File(res), new File(dir));
}
public static class Fault extends Exception {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,28 +29,48 @@ import sampleapi.SampleApi.Fault;
public class SampleApiDefaultRunner {
public static final String MSG_NO_OUTDIR =
"SampleApi: no outdir set";
public static final String MSG_NO_RESDIR =
"SampleApi: no resourcedir set";
public static final String MSG_DUP_OUTDIR =
"SampleApi: duplicated outdir detected: ";
public static final String MSG_DUP_RESDIR =
"SampleApi: duplicated resourcedir detected: ";
public static final String MSG_USE_FIRST =
" will use first occurance: ";
public static final String MSG_INVAL_OUTDIR =
"SampleApi: outdir is not valid: ";
public static final String MSG_INVAL_RESDIR =
"SampleApi: outdir is not valid: ";
public static final String MSG_CANNOT_GEN =
"SampleApi: cannot generate output: ";
public static final String MSG_WRONG_OPTION =
"SampleApi: incorrect option: ";
public static final String MSG_USE_HELP =
" use -? for help";
public static final String[] MSG_HELP = {
"SampleApi options:",
" -?|-h|--help - print help",
" -r=<dir>|--resdir=<dir>|--resourcedir=<dir> - set <dir> to find xml resources",
" -o=<dir>|--outdir=<dir> - set <dir> to generate output"
};
public static void main(String... args) throws Exception {
System.exit(execute(args));
}
public static int execute(String... args) throws Exception {
if (args.length == 0) {
printHelp();
System.exit(1);
return 1;
}
String outDirName = "";
String resDirName = "";
boolean isOutDirSet = false;
boolean isResDirSet = false;
boolean isHelpPrinted = false;
for (String arg : args) {
Option option = new Option(arg);
@ -73,6 +93,17 @@ public class SampleApiDefaultRunner {
System.err.println(MSG_USE_FIRST + outDirName);
}
break;
case "-r":
case "--resdir":
case "--resourcedir":
if (!isResDirSet) {
resDirName = option.getOptionValue();
isResDirSet = true;
} else {
System.err.println(MSG_DUP_RESDIR + option.getOptionValue());
System.err.println(MSG_USE_FIRST + resDirName);
}
break;
default:
System.err.println(MSG_WRONG_OPTION + arg);
System.err.println(MSG_USE_HELP);
@ -82,40 +113,47 @@ public class SampleApiDefaultRunner {
}
if (!isOutDirSet) {
System.exit(1);
System.err.println(MSG_NO_OUTDIR);
return 1;
}
if (outDirName.length() == 0) {
System.err.println(MSG_INVAL_OUTDIR + outDirName);
System.exit(1);
return 1;
}
if (!isResDirSet) {
System.err.println(MSG_NO_RESDIR);
return 1;
}
if (resDirName.length() == 0) {
System.err.println(MSG_INVAL_RESDIR + resDirName);
return 1;
}
File resDir = new File(resDirName);
File outDir = new File(outDirName);
outDir.mkdirs();
SampleApi apiGen = new SampleApi();
try {
apiGen.generate(outDir);
} catch (Fault e) {
System.err.println(MSG_CANNOT_GEN + e.getMessage());
e.printStackTrace();
}
apiGen.generate(resDir, outDir);
return 0;
}
private static void printHelp() {
System.out.println("SampleApi:");
System.out.println(" options: [-?|-h|--help] [-o:<dir>|--outdir:<dir>]");
System.out.println(" -?|-h|--help - print help");
System.out.println(" -o:<dir>|--outdir:<dir> - set <dir> to generate output");
for (String line : MSG_HELP)
System.out.println(line);
}
private static class Option {
private String optionName;
private String optionValue;
private final String optionName;
private final String optionValue;
public Option(String arg) {
int delimPos = arg.indexOf(':');
int delimPos = arg.indexOf('=');
if (delimPos == -1) {
optionName = arg;

@ -199,11 +199,11 @@ class DocCommentGenerator {
public String getPackageComment() {
return InlineTag.INDEX.value("PackageCommentLabel") + " "
+ Text.LOREMIPSUM
+ "\n <p>" + Text.LIEUROPANLINGUES
+ "\n<p>" + Text.LIEUROPANLINGUES
+ "\n" + Text.CODE
+ "\n" + LinkTag.nextLink()
+ "\n" + LinkTag.nextSee()
+ "\n" + Tag.SINCE;
+ "\n" + Tag.SINCE + "\n";
}
String[] serialVals = new String[] { "include", "exclude" };

@ -29,14 +29,14 @@ import java.io.InputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@ -54,7 +54,6 @@ import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.code.TypeMetadata;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symtab;
@ -67,16 +66,16 @@ public class PackageGenerator {
String packageDirName;
ArrayList<JCCompilationUnit> topLevels;
Hashtable<String, Integer> nameIndex;
Hashtable<String, JCClassDecl> idBases;
Hashtable<String, JCAnnotation> idAnnos;
Map<String, Integer> nameIndex;
Map<String, JCClassDecl> idBases;
Map<String, JCAnnotation> idAnnos;
TreeMaker make;
Names names;
Symtab syms;
DocumentBuilderFactory factory;
Documentifier documentifier;
boolean fx = false;
boolean fx;
public PackageGenerator() {
JavacTool jt = JavacTool.create();
@ -91,27 +90,27 @@ public class PackageGenerator {
documentifier = Documentifier.instance(ctx);
}
String dataSetName;
boolean isDataSetProcessed = false;
public void processDataSet(String dsName) throws Fault {
dataSetName = dsName;
public void processDataSet(File dsFile) throws Fault {
isDataSetProcessed = true;
topLevels = new ArrayList<>();
nameIndex = new Hashtable<>();
idBases = new Hashtable<>();
idAnnos = new Hashtable<>();
String dsPath = "res/xml/" + dsName + ".xml";
nameIndex = new HashMap<>();
idBases = new HashMap<>();
idAnnos = new HashMap<>();
fx = false;
try {
InputStream is = getClass().getResourceAsStream("/" + dsPath);
if (is == null)
is = new FileInputStream(dsPath);
InputStream is = new FileInputStream(dsFile);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(is);
Element rootElement = document.getDocumentElement();
packageName = rootElement.getAttribute("package");
if (!rootElement.getTagName().equals("package"))
throw new IllegalStateException("Unexpected tag name: "
+ rootElement.getTagName());
packageName = rootElement.getAttribute("name");
fx = "fx".equals(rootElement.getAttribute("style"));
packageDirName = packageName.replace('.', '/');
@ -122,17 +121,15 @@ public class PackageGenerator {
if (!(node instanceof Element))
continue;
processTopLevel((Element)node);
processTopLevel((Element) node);
}
} catch (ParserConfigurationException | SAXException | IOException e) {
throw new Fault("Error parsing dataset " + dsName, e);
throw new Fault("Error parsing dataset " + dsFile, e);
}
fx = false;
}
public void generate(File outDir) throws Fault {
if (dataSetName == null)
if (!isDataSetProcessed)
throw new Fault("No Data Set processed");
try {
@ -140,9 +137,9 @@ public class PackageGenerator {
pkgDir.mkdirs();
for (JCCompilationUnit decl : topLevels) {
JCClassDecl classDecl = (JCClassDecl)decl.getTypeDecls().get(0);
File outFile = new File(pkgDir,
classDecl.getSimpleName().toString() + ".java");
JCClassDecl classDecl = (JCClassDecl) decl.getTypeDecls().get(0);
File outFile
= new File(pkgDir, classDecl.getSimpleName().toString() + ".java");
FileWriter writer = new FileWriter(outFile);
writer.write(decl.toString());
writer.flush();
@ -155,7 +152,19 @@ public class PackageGenerator {
writer.write("/**\n");
writer.write(documentifier.getDocGenerator().getPackageComment());
writer.write("*/\n");
writer.write("package " + packageName + ";");
writer.write("package " + packageName + ";\n");
writer.flush();
writer.close();
// overview
outFile = new File(pkgDir, "overview.html");
writer = new FileWriter(outFile);
writer.write("<html>\n");
writer.write("<head>\n<title>" + packageName + "</title>\n</head>\n");
writer.write("<body>\n");
writer.write("<p>Package " + packageName + " overview.\n");
writer.write("</body>\n");
writer.write("</html>\n");
writer.flush();
writer.close();
} catch (IOException e) {
@ -197,7 +206,7 @@ public class PackageGenerator {
}
}
ListBuffer<JCTree>[] processBases(Element baseTag, Hashtable<String, Integer> scope) {
ListBuffer<JCTree>[] processBases(Element baseTag, HashMap<String, Integer> scope) {
String kind = baseTag.getTagName();
String baseName = baseTag.getAttribute("basename");
String typeParam = baseTag.getAttribute("tparam");
@ -232,21 +241,21 @@ public class PackageGenerator {
if (!(node instanceof Element))
continue;
switch (((Element)node).getTagName()) {
Element element = (Element)node;
switch (element.getTagName()) {
case "modifier":
multiply.addAxis(((Element)node).getTextContent());
multiply.addAxis(element.getTextContent());
break;
case "anno":
multiply.addAxis(((Element)node).getTextContent());
multiply.addAxis(element.getTextContent());
break;
case "member":
// process members here
members.appendList(processMembers((Element)node, baseName, kind));
members.appendList(processMembers(element, baseName, kind));
break;
case "extend":
String classId = ((Element)node).getAttribute("id"); // this pkg
String classRef = ((Element)node).getAttribute("ref"); // external
String classId = element.getAttribute("id"); // this pkg
String classRef = element.getAttribute("ref"); // external
if (classId.length() !=0 &&
idBases.containsKey(classId)) {
// if have base, take methods from base members
@ -260,8 +269,8 @@ public class PackageGenerator {
}
break;
case "implement":
String interfaceId = ((Element)node).getAttribute("id");
String interfaceRef = ((Element)node).getAttribute("ref");
String interfaceId = element.getAttribute("id");
String interfaceRef = element.getAttribute("ref");
if (interfaceId.length() != 0 &&
idBases.containsKey(interfaceId)) {
JCClassDecl baseDecl = idBases.get(interfaceId);
@ -277,7 +286,7 @@ public class PackageGenerator {
case "import":
imports.append(
make.Import(
make.Ident(names.fromString(((Element)node).getTextContent())),
make.Ident(names.fromString(element.getTextContent())),
false));
}
}
@ -342,7 +351,7 @@ public class PackageGenerator {
ListBuffer<JCTree> processMembers(Element memberTag, String name, String kind) {
ListBuffer<JCTree> members = new ListBuffer<>();
NodeList nodes = memberTag.getChildNodes();
Hashtable<String, Integer> scope = new Hashtable<>();
HashMap<String, Integer> scope = new HashMap<>();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
@ -378,7 +387,7 @@ public class PackageGenerator {
return members;
}
ListBuffer<JCTree> processFields(Element fieldsNode, Hashtable<String, Integer> scope) {
ListBuffer<JCTree> processFields(Element fieldsNode, HashMap<String, Integer> scope) {
String kind = fieldsNode.getTagName();
String baseName = fieldsNode.getAttribute("basename");
@ -431,7 +440,7 @@ public class PackageGenerator {
TypeTag.BOT,
"String".equals(type)
? new String("blah-blah-blah")
: new Integer(0));
: Integer.valueOf(0));
JCVariableDecl fieldDecl = make.VarDef(
make.Modifiers(declFlags, annos.toList()),
@ -451,7 +460,7 @@ public class PackageGenerator {
String[] fieldTypes = sfNode.getTextContent().split(",");
ListBuffer<JCExpression> serialFields = new ListBuffer<>();
Hashtable<String, Integer> scope = new Hashtable<>();
HashMap<String, Integer> scope = new HashMap<>();
for (String fType : fieldTypes) {
String fieldName = baseName + getUniqIndex(scope, baseName);
@ -482,7 +491,7 @@ public class PackageGenerator {
return sfDecl;
}
ListBuffer<JCTree> processConstants(Element constNode, Hashtable<String, Integer> scope) {
ListBuffer<JCTree> processConstants(Element constNode, HashMap<String, Integer> scope) {
String baseName = constNode.getAttribute("basename");
int count = 1;
try {
@ -507,7 +516,7 @@ public class PackageGenerator {
return fields;
}
ListBuffer<JCTree> processMethods(Element methodsNode, Hashtable<String, Integer> scope, boolean needBody, boolean isConstructor) {
ListBuffer<JCTree> processMethods(Element methodsNode, HashMap<String, Integer> scope, boolean needBody, boolean isConstructor) {
String kind = methodsNode.getTagName();
String baseName = methodsNode.getAttribute("basename");
String name = methodsNode.getAttribute("name");
@ -590,7 +599,7 @@ public class PackageGenerator {
retType.isPrimitive() ?
retType.getTag() :
TypeTag.BOT,
new Integer(0))));
Integer.valueOf(0))));
}
body = make.Block(0, bodyStatements);
}
@ -681,7 +690,7 @@ public class PackageGenerator {
retType.isPrimitive() ?
retType.getTag() :
TypeTag.BOT,
new Integer(0))));
Integer.valueOf(0))));
JCBlock body = make.Block(0, bodyStatements);
@ -763,16 +772,16 @@ public class PackageGenerator {
String getUniqName(String name) {
if (!nameIndex.containsKey(name))
nameIndex.put(name, new Integer(0));
nameIndex.put(name, 0);
Integer index = nameIndex.get(name);
String uniqName = name + index;
nameIndex.put(name, index + 1);
return uniqName;
}
int getUniqIndex(Hashtable<String, Integer> scope, String name) {
int getUniqIndex(HashMap<String, Integer> scope, String name) {
if (!scope.containsKey(name))
scope.put(name, new Integer(0));
scope.put(name, 0);
Integer index = scope.get(name);
scope.put(name, index + 1);
return index;

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@ -21,7 +21,7 @@
or visit www.oracle.com if you need additional information or have any
questions.
-->
<dataset package="sampleapi.fx" style="fx">
<package name="sampleapi.fx" style="fx">
<class basename="FXClass">
<modifier>public</modifier>
@ -42,4 +42,4 @@
</member>
</class>
</dataset>
</package>

@ -21,7 +21,7 @@
or visit www.oracle.com if you need additional information or have any
questions.
-->
<dataset package="sampleapi.simple">
<package name="sampleapi.simple">
<class basename="SampleClass" id="baseclass">
<modifier>public</modifier>
@ -526,4 +526,4 @@
</method>
</member>
</class>
</dataset>
</package>

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<package name="sampleapi.simple.sub">
<class basename="SClass">
<modifier>public</modifier>
<modifier>none|abstract</modifier>
<implement>SInterface0</implement>
<member>
<field basename="id">
<modifier>public</modifier>
<type>int</type>
</field>
<method basename="get">
<modifier>public</modifier>
<type>int</type>
<throw>SException0</throw>
</method>
<method basename="put">
<modifier>public</modifier>
<param>int</param>
<type>void</type>
<throw>SException0</throw>
</method>
</member>
</class>
<class basename="SException">
<modifier>public</modifier>
<extend ref="java.lang.Exception"/>
<member>
<constructor>
<modifier>public</modifier>
<param>String</param>
</constructor>
</member>
</class>
<interface basename="SInterface">
<modifier>public</modifier>
<member>
<method basename="put">
<modifier>public</modifier>
<type>void</type>
<param>int</param>
</method>
</member>
</interface>
<enum basename="SEnum">
<modifier>public</modifier>
<member>
<constant basename="ON" count="1"/>
<constant basename="OFF" count="1"/>
</member>
</enum>
<annotation basename="SAnno">
<modifier>public</modifier>
<member>
<method basename="value">
<modifier>public</modifier>
<type>boolean</type>
</method>
</member>
</annotation>
</package>

@ -21,7 +21,7 @@
or visit www.oracle.com if you need additional information or have any
questions.
-->
<dataset package="sampleapi.tiny">
<package name="sampleapi.tiny" module="sat.sampleapi">
<class basename="TinyClass">
<modifier>public</modifier>
@ -68,4 +68,4 @@
</member>
</annotation>
</dataset>
</package>

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<package name="sampleapi.tiny.sub" module="sat.sampleapi">
<class basename="TSClass">
<modifier>public</modifier>
<modifier>none|abstract</modifier>
<implement>TSInterface0</implement>
<member>
<field basename="id">
<modifier>public</modifier>
<type>int</type>
</field>
<method basename="get">
<modifier>public</modifier>
<type>int</type>
<throw>TSException0</throw>
</method>
<method basename="put">
<modifier>public</modifier>
<param>int</param>
<type>void</type>
<throw>TSException0</throw>
</method>
</member>
</class>
<class basename="TSException">
<modifier>public</modifier>
<extend ref="java.lang.Exception"/>
<member>
<constructor>
<modifier>public</modifier>
<param>String</param>
</constructor>
</member>
</class>
<interface basename="TSInterface">
<modifier>public</modifier>
<member>
<method basename="put">
<modifier>public</modifier>
<type>void</type>
<param>int</param>
</method>
</member>
</interface>
<enum basename="TSEnum">
<modifier>public</modifier>
<member>
<constant basename="ON" count="1"/>
<constant basename="OFF" count="1"/>
</member>
</enum>
<annotation basename="TSAnno">
<modifier>public</modifier>
<member>
<method basename="value">
<modifier>public</modifier>
<type>boolean</type>
</method>
</member>
</annotation>
</package>

@ -1,59 +0,0 @@
SampleAPI Generator for javadoc
1. General description
The primary goal is to provide one or more data sets to be used as input
to the javadoc tool, such that it can be used to generate representative samples
of all the different content on all the different types of pages that can be
generated by javadoc.
The tool is implemented as generator based on xml descriptions of data sets.
The xml description of data set provides top level entities (class, interface,
enum, annotation) with all possible content. Desired output parameters (fields,
methods, inner/nested classes) are also described in xml as lists of modifiers,
types and annotations. The generator "multiply" the entities from the lists
providing the set of all possible combinations.
After the api generation the tool connects the javadoc style comments to
the generated entities with full possible sets of supported tags.
2. Tool structure
Sources:
test/tools/javadoc/sampleapi/lib - generator sources
test/tools/javadoc/sampleapi/res/xml - sample data sets in xml
test/tools/javadoc/sampleapi/res/txt - sample texts for doc comments
3. Public API
3.1 Command line runner
* test/tools/javadoc/sampleapi/lib/sampleapi/SampleApiDefaultRunner.java
class sampleapi.SampleApiDefaultRunner
Options: [-?|-h|--help] [-o:<dir>|--outdir:<dir>]
-?|-h|--help - print help
-o:<dir>|--outdir:<dir> - set <dir> to generate output
3.2 Programmatic access
* test/tools/javadoc/sampleapi/lib/sampleapi/SampleApi.java
class sampleapi.SampleApi
public void generate(File dir)
public void generate(Path dir)
public void generate(String dir)
3.3 How to run other xml data set description
Put data set xml description into res/xml directory
* test/tools/javadoc/sampleapi/lib/sampleapi/generator/PackageGenerator.java
class sampleapi.generator.PackageGenerator
public void processDataSet(String dsName)
public void generate(File outDir)

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,24 +24,31 @@
/*
* @test
* @bug 8130880
* @library lib
* @library /jdk/javadoc/tool/sampleapi/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.parser
* jdk.compiler/com.sun.tools.javac.tree
* jdk.compiler/com.sun.tools.javac.util
* @run main sampleapi.SampleApiDefaultRunner -o:out/src
* @run main SampleApiTest
*/
import com.sun.tools.javadoc.*;
import sampleapi.*;
public class SampleApiTest {
public static void main(String... args) {
public static void main(String... args) throws Exception {
// generate
SampleApiDefaultRunner.execute(
new String[] {
"-o=out/src",
"-r=" + System.getProperty("test.src") + "/res"
});
// html4
Main.execute(
int res1 = Main.execute(
new String[] {
"-d", "out/doc.html4",
"-verbose",
@ -54,12 +61,13 @@ public class SampleApiTest {
"-windowtitle", "SampleAPI",
"-sourcepath", "out/src",
"sampleapi.simple",
"sampleapi.simple.sub",
"sampleapi.tiny",
"sampleapi.fx"
});
// html5
Main.execute(
int res2 = Main.execute(
new String[] {
"-d", "out/doc.html5",
"-verbose",
@ -72,8 +80,13 @@ public class SampleApiTest {
"-windowtitle", "SampleAPI",
"-sourcepath", "out/src",
"sampleapi.simple",
"sampleapi.simple.sub",
"sampleapi.tiny",
"sampleapi.fx"
});
if (res1 + res2 > 0)
throw new Exception("One of exit statuses of test execution is non-zero: "
+ res1 + " for HTML4, " + res2 + " for HTML5.");
}
}

@ -1,60 +0,0 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sampleapi;
import java.io.File;
import java.nio.file.Path;
import sampleapi.generator.PackageGenerator;
public class SampleApi {
PackageGenerator pkgGen = new PackageGenerator();
public void generate(File dir) throws Fault {
pkgGen.processDataSet("simple");
pkgGen.generate(dir);
pkgGen.processDataSet("tiny");
pkgGen.generate(dir);
pkgGen.processDataSet("fx");
pkgGen.generate(dir);
}
public void generate(Path dir) throws Fault {
generate(dir.toFile());
}
public void generate(String dir) throws Fault {
generate(new File(dir));
}
public static class Fault extends Exception {
public Fault(String msg) {
super(msg);
}
public Fault(String msg, Throwable th) {
super(msg, th);
}
}
}

@ -1,137 +0,0 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sampleapi;
import java.io.File;
import sampleapi.SampleApi.Fault;
public class SampleApiDefaultRunner {
public static final String MSG_DUP_OUTDIR =
"SampleApi: duplicated outdir detected: ";
public static final String MSG_USE_FIRST =
" will use first occurance: ";
public static final String MSG_INVAL_OUTDIR =
"SampleApi: outdir is not valid: ";
public static final String MSG_CANNOT_GEN =
"SampleApi: cannot generate output: ";
public static final String MSG_WRONG_OPTION =
"SampleApi: incorrect option: ";
public static final String MSG_USE_HELP =
" use -? for help";
public static void main(String... args) throws Exception {
if (args.length == 0) {
printHelp();
System.exit(1);
}
String outDirName = "";
boolean isOutDirSet = false;
boolean isHelpPrinted = false;
for (String arg : args) {
Option option = new Option(arg);
switch (option.getOptionName()) {
case "-?":
case "-h":
case "--help":
if (!isHelpPrinted) {
printHelp();
isHelpPrinted = true;
}
break;
case "-o":
case "--outdir":
if (!isOutDirSet) {
outDirName = option.getOptionValue();
isOutDirSet = true;
} else {
System.err.println(MSG_DUP_OUTDIR + option.getOptionValue());
System.err.println(MSG_USE_FIRST + outDirName);
}
break;
default:
System.err.println(MSG_WRONG_OPTION + arg);
System.err.println(MSG_USE_HELP);
break;
}
}
if (!isOutDirSet) {
System.exit(1);
}
if (outDirName.length() == 0) {
System.err.println(MSG_INVAL_OUTDIR + outDirName);
System.exit(1);
}
File outDir = new File(outDirName);
outDir.mkdirs();
SampleApi apiGen = new SampleApi();
try {
apiGen.generate(outDir);
} catch (Fault e) {
System.err.println(MSG_CANNOT_GEN + e.getMessage());
e.printStackTrace();
}
}
private static void printHelp() {
System.out.println("SampleApi:");
System.out.println(" options: [-?|-h|--help] [-o:<dir>|--outdir:<dir>]");
System.out.println(" -?|-h|--help - print help");
System.out.println(" -o:<dir>|--outdir:<dir> - set <dir> to generate output");
}
private static class Option {
private String optionName;
private String optionValue;
public Option(String arg) {
int delimPos = arg.indexOf(':');
if (delimPos == -1) {
optionName = arg;
optionValue = "";
} else {
optionName = arg.substring(0, delimPos);
optionValue = arg.substring(delimPos + 1, arg.length());
}
}
public String getOptionName() {
return optionName;
}
public String getOptionValue() {
return optionValue;
}
}
}

@ -1,495 +0,0 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sampleapi.generator;
import java.io.File;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.Set;
import javax.lang.model.element.Modifier;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.List;
import java.util.HashMap;
import java.util.Map;
class DocCommentGenerator {
public enum Text {
BROWNFOX(BROWNFOX_TEXT),
NOWISTHETIME(NOWISTHETIME_TEXT),
THISPANGRAM(THISPANGRAM_TEXT),
LOREMIPSUM(LOREMIPSUM_TEXT),
LIEUROPANLINGUES(LIEUROPANLINGUES_TEXT),
CODE(CODE_TEXT);
String commentText;
Text(String text) {
commentText = text;
}
@Override
public String toString() {
return commentText;
}
}
public enum Tag {
AUTHOR("@author", "Cody J. Writer"),
PARAM("@param", ""),
RETURN("@return", Text.NOWISTHETIME.toString()),
SINCE("@since", "1.0"),
THROWS("@throws", "If problem detected"),
EXCEPTION("@exception", "If problem detected"),
SERIAL("@serial", ""),
SERIALDATA("@serialData", "The types and order of data could be here."),
SERIALFIELD("@serialField", "\n Serial field in special array"),
FX_PROPSETTER("@propertySetter", "Set the property"),
FX_PROPGETTER("@propertyGetter", "Get the property"),
FX_PROPDESC("@propertyDescription", ""),
FX_DEFVALUE("@defaultValue", ""),
FX_TREATASPRIVATE("@treatAsPrivate", "");
String tagName;
String tagValue;
Tag(String tagName, String tagValue) {
this.tagName = tagName;
this.tagValue = tagValue;
}
public String toString() {
return value("", "");
}
public String value(String value) {
return value(value, "");
}
public String value(String value, String extra) {
return tagName
+ ((value.length() != 0) ? " " + value : "")
+ ((tagValue.length() != 0) ? " " + tagValue : "")
+ ((extra.length() != 0) ? " " + extra : "");
}
}
public enum InlineTag {
LITERAL("@literal", "Use < and > brackets instead of &lt; and &gt; escapes."),
CODE("@code", "(i) -> new Abc<Object>((i > 0) ? (i << 1) : 0)"),
LINK("@link", ""),
VALUE("@value", ""),
INDEX("@index", "", true);
String tagName;
String tagValue;
boolean counted;
Map<String, Integer> counters;
InlineTag(String tagName, String tagValue) {
this(tagName, tagValue, false);
}
InlineTag(String tagName, String tagValue, boolean counted) {
this.tagName = tagName;
this.tagValue = tagValue;
this.counted = counted;
if (counted) {
counters = new HashMap<>();
}
}
public String toString() {
return value("");
}
public String value(String value) {
String name = ((tagValue.length() != 0) ? " " + tagValue : "")
+ ((value.length() != 0) ? " " + value : "");
if (counted && !counters.containsKey(name)) {
counters.put(name, 0);
}
return "{" + tagName
+ name
+ (counted ? "_" + counters.put(name, counters.get(name) + 1) : "")
+ "}";
}
}
public static class LinkTag {
static String[] links = new String[] {
"Boolean",
"Boolean#TRUE",
"Boolean#Boolean(boolean)",
"Boolean#Boolean(String s)",
"Boolean#compare(boolean, boolean)",
"Boolean#compareTo(Boolean b)",
"java.util.Vector",
"java.util.Vector#elementCount",
"java.util.Vector#Vector(int)",
"java.util.Vector#Vector(int initialCapacity, int capacityIncrement)",
"java.util.Vector#indexOf(Object)",
"java.util.Vector#indexOf(Object o, int index)",
"java.lang.annotation" };
static int index = 0;
public static String nextSee() {
String next = "@see " + links[index];
index = (index + 1) % links.length;
return next;
}
public static String nextLink() {
String next = "Also check "
+ (((index % 2) == 0) ? "{@link " : "{@linkplain ")
+ links[index]
+ "} for details.\n";
index = (index + 1) % links.length;
return next;
}
}
public static class VersionTag {
static String[] versions = new String[] {
"1.5, 09/01/04",
"1.6, 12/11/06",
"1.7, 07/28/11",
"1.8, 04/19/14",
"9, 06/03/16" };
static int index = 0;
public static String nextVersion() {
String next = "@version " + versions[index];
index = (index + 1) % versions.length;
return next;
}
}
//
// getters (build comments for entities)
//
public String getPackageComment() {
return InlineTag.INDEX.value("PackageCommentLabel") + " "
+ Text.LOREMIPSUM
+ "\n <p>" + Text.LIEUROPANLINGUES
+ "\n" + Text.CODE
+ "\n" + LinkTag.nextLink()
+ "\n" + LinkTag.nextSee()
+ "\n" + Tag.SINCE;
}
String[] serialVals = new String[] { "include", "exclude" };
// static index to roll over "include/exclude"
static int serialValIdx = 0;
public String getBaseComment(JCClassDecl baseDecl, boolean toplevel) {
String buildComment = InlineTag.INDEX.value("BaseCommentLabel") + " ";
buildComment += Text.LIEUROPANLINGUES + "\n";
buildComment += "<p>It is possible to see inlined code:\n"
+ InlineTag.CODE
+ " is the example.\n\n";
buildComment += "<p>Literal use example.\n"
+ InlineTag.LITERAL + "\n\n";
buildComment += "<p>" + Text.THISPANGRAM + "\n"; // make comment longer
buildComment += "<p>" + LinkTag.nextLink() + "\n";
if (toplevel)
buildComment += "\n" + VersionTag.nextVersion() + "\n";
// @param for type params
List<JCTypeParameter> params = baseDecl.getTypeParameters();
int paramIndex = 0;
for (JCTypeParameter paramDecl : params) {
buildComment += Tag.PARAM.value(
"<" + paramDecl.getName().toString() + ">",
"the type of value set #" + paramIndex++)
+ "\n";
}
buildComment += "\n" + LinkTag.nextSee();
buildComment += "\n";
if (toplevel)
buildComment += Tag.AUTHOR + "\n";
buildComment += Tag.SINCE + "\n";
// for serial; currently no need to dig too deep
if (isSerializable(baseDecl) || isErrorOrException(baseDecl)) {
buildComment += "\n" + Tag.SERIAL.value(serialVals[serialValIdx]);
serialValIdx = (serialValIdx + 1) % 2;
}
return buildComment;
}
public String getConstComment() {
String buildComment = InlineTag.INDEX.value("ConstCommentLabel") + " ";
buildComment += Text.NOWISTHETIME + " " + Text.BROWNFOX + "\n";
buildComment += LinkTag.nextLink() + "\n";
buildComment += LinkTag.nextSee() + "\n";
buildComment += Tag.SINCE + "\n";
return buildComment;
}
public String getFieldComment(JCClassDecl baseDecl,
JCVariableDecl varDecl,
boolean isFxStyle) {
String buildComment = InlineTag.INDEX.value("FieldCommentLabel") + " ";
buildComment += Text.BROWNFOX + "<p>" + Text.NOWISTHETIME + "\n";
Set<Modifier> mods = varDecl.getModifiers().getFlags();
String varName = varDecl.getName().toString();
if (mods.contains(Modifier.STATIC) && mods.contains(Modifier.FINAL)) {
JCExpression init = varDecl.getInitializer();
if (init != null
&& !"null".equals(init.toString())
&& !"serialPersistentFields".equals(varName))
buildComment += "<p>The value of this constant is "
+ InlineTag.VALUE
+ ".\n";
}
buildComment += "<p>" + LinkTag.nextLink() + "\n";
if (isSerializable(baseDecl)) {
if (isErrorOrException(baseDecl)) {
buildComment += Tag.SERIAL + "\n";
} else if ("serialPersistentFields".equals(varName)) {
JCNewArray sfList = (JCNewArray)varDecl.getInitializer();
for (JCExpression sf : sfList.getInitializers()) {
List<JCExpression> args = ((JCNewClass)sf).getArguments();
String sfName = ((JCLiteral)args.get(0)).getValue().toString();
String sfClass = ((JCIdent)args.get(1)).getName().toString();
String sfType = sfClass.substring(0, sfClass.indexOf(".class"));
buildComment += Tag.SERIALFIELD.value(sfName + " " + sfType)
+ "\n";
}
} else {
buildComment += Tag.SERIAL.value("Very important value.") + "\n";
}
}
if (isFxStyle) {
// set default value
String varType = varDecl.getType().toString();
buildComment += Tag.FX_DEFVALUE.value(defValue(varType)) + "\n";
}
buildComment += LinkTag.nextSee() + "\n";
return buildComment;
}
public String getMethodComment(JCClassDecl baseDecl,
JCMethodDecl methodDecl,
boolean isFxStyle) {
String buildComment = InlineTag.INDEX.value("MethodCommentLabel") + " ";
buildComment += Text.BROWNFOX + "\n<p>" + Text.THISPANGRAM + "\n";
buildComment += "<p>" + LinkTag.nextLink() + "\n";
buildComment += "<p>Literal use example.\n"
+ InlineTag.LITERAL + "\n\n";
// @param for type params
List<JCTypeParameter> tparams = methodDecl.getTypeParameters();
int tparamIndex = 0;
for (JCTypeParameter paramDecl : tparams) {
String paramDeclString = paramDecl.getName().toString();
// simplify it (could contain 'extend'/'super' clauses
int spacePos = paramDeclString.indexOf(' ');
if (spacePos != -1)
paramDeclString = paramDeclString.substring(0, spacePos);
buildComment += Tag.PARAM.value(
"<" + paramDeclString + ">",
"the type of value set #" + tparamIndex++)
+ "\n";
}
// @param
List<JCVariableDecl> params = methodDecl.getParameters();
int paramIndex = 0;
for (JCVariableDecl paramDecl : params) {
buildComment += Tag.PARAM.value(
paramDecl.getName().toString(),
"an income parameter #" + paramIndex++)
+ "\n";
}
// @return
JCTree retType = methodDecl.getReturnType(); // null for constructors
if (retType != null && !"void".equals(retType.toString()))
buildComment += Tag.RETURN + "\n";
// @throws/@exception
Tag t = isDerived(baseDecl) ? Tag.EXCEPTION : Tag.THROWS;
List<JCExpression> throwTypes = methodDecl.getThrows();
for (JCExpression throwsExp : throwTypes) {
buildComment += t.value(throwsExp.toString()) + "\n";
}
if (isSerializable(baseDecl)) {
switch (methodDecl.getName().toString()) {
case "writeObject":
case "readObject":
case "writeExternal":
case "readExternal":
case "writeReplace":
case "readResolve":
buildComment += Tag.SERIALDATA + "\n";
break;
default:
}
}
if (isFxStyle) {
// @propertySetter/Getter + Description
if ("void".equals(retType.toString())) {
buildComment += Tag.FX_PROPSETTER + "\n";
} else {
buildComment += Tag.FX_PROPGETTER + "\n";
buildComment += Tag.FX_DEFVALUE.value(defValue(retType.toString()))
+ "\n";
}
buildComment += Tag.FX_PROPDESC.value(Text.BROWNFOX.toString()) + "\n";
// @treatAsPrivate
if (methodDecl.getModifiers().getFlags().contains(Modifier.PUBLIC))
buildComment += Tag.FX_TREATASPRIVATE + "\n";
}
// @see
buildComment += LinkTag.nextSee() + "\n";
// @since
buildComment += Tag.SINCE + "\n";
return buildComment;
}
//
// util methods
//
private boolean isErrorOrException(JCClassDecl baseDecl) {
JCExpression ext = baseDecl.getExtendsClause();
if (ext != null) {
String extClassName = ext.toString();
if (extClassName.contains("Error") || extClassName.contains("Exception"))
return true;
}
return false;
}
private boolean isSerializable(JCClassDecl baseDecl) {
List<JCExpression> impls = baseDecl.getImplementsClause();
for (JCExpression impl : impls) {
if (impl.toString().contains("Serializable"))
return true;
}
return false;
}
private boolean isDerived(JCClassDecl baseDecl) {
return (baseDecl.getExtendsClause() == null) ? false : true;
}
private String defValue(String type) {
switch (type) {
case "boolean":
return "true";
case "byte": case "char": case "int": case "long":
case "Integer": case "Long":
return "1";
case "float": case "double": case "Float": case "Double":
return "1.0";
case "String":
return "string";
default:
return "null";
}
}
private static final String BROWNFOX_TEXT =
"The quick brown fox jumps over the lazy dog.\n";
private static final String NOWISTHETIME_TEXT =
"Now is the time for all good men to come to the aid of the party.\n";
private static final String THISPANGRAM_TEXT =
"This pangram contains four a's, one b, two c's, one d, thirty e's,\n" +
"six f's, five g's, seven h's, eleven i's, one j, one k, two l's,\n" +
"two m's, eighteen n's, fifteen o's, two p's, one q, five r's,\n" +
"twenty-seven s's, eighteen t's, two u's, seven v's, eight w's,\n" +
"two x's, three y's, &amp; one z.";
private static final String LOREMIPSUM_TEXT =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\n" +
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut\n" +
"enim ad minim veniam, quis nostrud exercitation ullamco laboris\n" +
"nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor\n" +
"in reprehenderit in voluptate velit esse cillum dolore eu fugiat\n" +
"nulla pariatur. Excepteur sint occaecat cupidatat non proident,\n" +
"sunt in culpa qui officia deserunt mollit anim id est laborum.\n";
private static final String LIEUROPANLINGUES_TEXT =
"Li Europan lingues es membres del sam familie. Lor separat existentie\n" +
"es un myth. Por scientie, musica, sport etc, litot Europa usa li sam\n" +
"vocabular. Li lingues differe solmen in li grammatica, li pronunciation\n" +
"e li plu commun vocabules. Omnicos directe al desirabilite de un nov\n" +
"lingua franca: On refusa continuar payar custosi traductores.\n" +
"\n" +
"<p>At solmen va esser necessi far uniform grammatica, pronunciation\n" +
"e plu commun paroles. Ma quande lingues coalesce, li grammatica del\n" +
"resultant lingue es plu simplic e regulari quam ti del coalescent\n" +
"lingues. Li nov lingua franca va esser plu simplic e regulari quam\n" +
"li existent Europan lingues. It va esser tam simplic quam Occidental\n" +
"in fact, it va esser Occidental. A un Angleso it va semblar un simplificat\n" +
"Angles, quam un skeptic Cambridge amico dit me que Occidental es.\n";
private static final String CODE_TEXT =
"<pre>\n" +
"public void checkLanguage(Language lang) throws Exception {\n" +
" if (lang.getName().equals(\"Java\")) {\n" +
" System.out.println(\"Warning! Hot!\");\n" +
" else {\n" +
" throw new LooserException();\n" +
" }\n" +
"}\n" +
"</pre>\n";
}

@ -1,124 +0,0 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sampleapi.generator;
import java.util.ArrayList;
import java.util.Set;
import javax.lang.model.element.Modifier;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.DocCommentTable;
import com.sun.tools.javac.parser.ScannerFactory;
import com.sun.tools.javac.parser.Scanner;
import com.sun.tools.javac.parser.Tokens.Token;
import com.sun.tools.javac.parser.Tokens.Comment;
import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
import com.sun.source.tree.Tree.Kind;
import sampleapi.util.*;
class Documentifier {
static Documentifier instance;
final DocCommentGenerator docGen;
final ScannerFactory scanners;
private Documentifier(Context context) {
docGen = new DocCommentGenerator();
scanners = ScannerFactory.instance(context);
}
public static Documentifier instance(Context context) {
if (instance == null)
instance = new Documentifier(context);
return instance;
}
private DocCommentTable curDocComments;
public void documentify(JCCompilationUnit topLevel, boolean isFxStyle) {
JCClassDecl base = (JCClassDecl)topLevel.getTypeDecls().get(0);
curDocComments = new PoorDocCommentTable();
documentifyBase(base, true, isFxStyle);
topLevel.docComments = curDocComments;
}
private void documentifyBase(JCClassDecl base, boolean isTopLevel, boolean isFxStyle) {
// add doc comment to class itself
Comment comm = comment(docGen.getBaseComment(base, isTopLevel));
curDocComments.putComment(base, comm);
// add doc comments to members
for (JCTree member : base.getMembers()) {
switch (member.getTag()) {
case VARDEF:
documentifyField(base, (JCVariableDecl)member, isFxStyle);
break;
case METHODDEF:
documentifyMethod(base, (JCMethodDecl)member, isFxStyle);
break;
case CLASSDEF:
documentifyBase((JCClassDecl)member, false, isFxStyle);
break;
}
}
}
private void documentifyField(JCClassDecl base, JCVariableDecl field, boolean isFxStyle) {
Kind baseKind = base.getKind();
Set<Modifier> fieldMods = field.getModifiers().getFlags();
String doc = (baseKind == Kind.ENUM
&& fieldMods.contains(Modifier.PUBLIC)
&& fieldMods.contains(Modifier.STATIC)
&& fieldMods.contains(Modifier.FINAL)) ?
docGen.getConstComment() :
docGen.getFieldComment(base, field, isFxStyle);
Comment comm = comment(doc);
curDocComments.putComment(field, comm);
}
private void documentifyMethod(JCClassDecl base, JCMethodDecl method, boolean isFxStyle) {
Comment comm = comment(docGen.getMethodComment(base, method, isFxStyle));
curDocComments.putComment(method, comm);
}
private Comment comment(String docString) {
StringBuilder docComment = new StringBuilder()
.append("/**")
.append(docString)
.append("*/");
Scanner scanner = scanners.newScanner(docComment, true);
scanner.nextToken();
Token token = scanner.token();
return token.comment(CommentStyle.JAVADOC);
}
// provide package comment data ONLY
public DocCommentGenerator getDocGenerator() {
return docGen;
}
}

@ -1,832 +0,0 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sampleapi.generator;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.sun.source.util.JavacTask;
import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.code.TypeMetadata;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symtab;
import sampleapi.util.*;
import sampleapi.SampleApi.Fault;
public class PackageGenerator {
String packageName;
String packageDirName;
ArrayList<JCCompilationUnit> topLevels;
Hashtable<String, Integer> nameIndex;
Hashtable<String, JCClassDecl> idBases;
Hashtable<String, JCAnnotation> idAnnos;
TreeMaker make;
Names names;
Symtab syms;
DocumentBuilderFactory factory;
Documentifier documentifier;
boolean fx = false;
public PackageGenerator() {
JavacTool jt = JavacTool.create();
JavacTask task = jt.getTask(null, null, null, null, null, null);
Context ctx = ((JavacTaskImpl)task).getContext();
make = TreeMaker.instance(ctx);
names = Names.instance(ctx);
syms = Symtab.instance(ctx);
factory = DocumentBuilderFactory.newInstance();
documentifier = Documentifier.instance(ctx);
}
String dataSetName;
public void processDataSet(String dsName) throws Fault {
dataSetName = dsName;
topLevels = new ArrayList<>();
nameIndex = new Hashtable<>();
idBases = new Hashtable<>();
idAnnos = new Hashtable<>();
String dsPath = "res/xml/" + dsName + ".xml";
try {
InputStream is = getClass().getResourceAsStream("/" + dsPath);
if (is == null)
is = new FileInputStream(dsPath);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(is);
Element rootElement = document.getDocumentElement();
packageName = rootElement.getAttribute("package");
fx = "fx".equals(rootElement.getAttribute("style"));
packageDirName = packageName.replace('.', '/');
// process nodes (toplevels)
NodeList nodeList = rootElement.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (!(node instanceof Element))
continue;
processTopLevel((Element)node);
}
} catch (ParserConfigurationException | SAXException | IOException e) {
throw new Fault("Error parsing dataset " + dsName, e);
}
fx = false;
}
public void generate(File outDir) throws Fault {
if (dataSetName == null)
throw new Fault("No Data Set processed");
try {
File pkgDir = new File(outDir, packageDirName);
pkgDir.mkdirs();
for (JCCompilationUnit decl : topLevels) {
JCClassDecl classDecl = (JCClassDecl)decl.getTypeDecls().get(0);
File outFile = new File(pkgDir,
classDecl.getSimpleName().toString() + ".java");
FileWriter writer = new FileWriter(outFile);
writer.write(decl.toString());
writer.flush();
writer.close();
}
// package-info
File outFile = new File(pkgDir, "package-info.java");
FileWriter writer = new FileWriter(outFile);
writer.write("/**\n");
writer.write(documentifier.getDocGenerator().getPackageComment());
writer.write("*/\n");
writer.write("package " + packageName + ";");
writer.flush();
writer.close();
} catch (IOException e) {
throw new Fault("Error writing output");
}
}
// levels' processing methods
void processTopLevel(Element tlTag) {
String kind = tlTag.getTagName();
if (kind.equals("annodecl")) {
// decls stored separately, does not affect bases
String declId = tlTag.getAttribute("id");
if (!declId.startsWith("@"))
declId = "@" + declId;
idAnnos.put(declId, processAnnoDecl(tlTag));
return;
}
ListBuffer<JCTree>[] bases = processBases(tlTag, null);
for (JCTree base : bases[0]) { // [0] - bases namely
JCPackageDecl pkg = make.PackageDecl(
List.<JCAnnotation>nil(),
make.QualIdent(
new Symbol.PackageSymbol(
names.fromString(packageName),
null)));
ListBuffer<JCTree> topLevelParts = new ListBuffer<>();
topLevelParts.append(pkg);
topLevelParts.appendList(bases[1]); // [1] imports
topLevelParts.append(base);
JCCompilationUnit topLevel = make.TopLevel(topLevelParts.toList());
documentifier.documentify(topLevel, fx);
topLevels.add(topLevel);
}
}
ListBuffer<JCTree>[] processBases(Element baseTag, Hashtable<String, Integer> scope) {
String kind = baseTag.getTagName();
String baseName = baseTag.getAttribute("basename");
String typeParam = baseTag.getAttribute("tparam");
String baseId = baseTag.getAttribute("id");
long kindFlag = 0;
switch (kind) {
case "class":
// no flags for class
break;
case "interface":
kindFlag |= Flags.INTERFACE;
break;
case "enum":
kindFlag |= Flags.ENUM;
break;
case "annotation":
kindFlag |= Flags.ANNOTATION | Flags.INTERFACE;
break;
}
// go through other nodes; add modifiers to multiplier
NodeList nodes = baseTag.getChildNodes();
ListBuffer<JCTree> bases = new ListBuffer<>();
ListBuffer<JCTree> members = new ListBuffer<>();
ListBuffer<JCTree> imports = new ListBuffer<>();
JCExpression extType = null;
ListBuffer<JCExpression> implTypes = new ListBuffer<>();
SimpleMultiplier multiply = new SimpleMultiplier();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (!(node instanceof Element))
continue;
switch (((Element)node).getTagName()) {
case "modifier":
multiply.addAxis(((Element)node).getTextContent());
break;
case "anno":
multiply.addAxis(((Element)node).getTextContent());
break;
case "member":
// process members here
members.appendList(processMembers((Element)node, baseName, kind));
break;
case "extend":
String classId = ((Element)node).getAttribute("id"); // this pkg
String classRef = ((Element)node).getAttribute("ref"); // external
if (classId.length() !=0 &&
idBases.containsKey(classId)) {
// if have base, take methods from base members
JCClassDecl baseDecl = idBases.get(classId);
extType = make.Type(
getTypeByName(
baseDecl.getSimpleName().toString()));
members.appendList(processMethods(baseDecl.getMembers(), false));
} else if (classRef.length() !=0) {
extType = make.Type(getTypeByName(classRef));
}
break;
case "implement":
String interfaceId = ((Element)node).getAttribute("id");
String interfaceRef = ((Element)node).getAttribute("ref");
if (interfaceId.length() != 0 &&
idBases.containsKey(interfaceId)) {
JCClassDecl baseDecl = idBases.get(interfaceId);
implTypes.add(
make.Type(
getTypeByName(
baseDecl.getSimpleName().toString())));
members.appendList(processMethods(baseDecl.getMembers(), true));
} else if (interfaceRef.length() != 0) {
implTypes.add(make.Type(getTypeByName(interfaceRef)));
}
break;
case "import":
imports.append(
make.Import(
make.Ident(names.fromString(((Element)node).getTextContent())),
false));
}
}
// process modifiers through multiplier
multiply.initIterator();
while (multiply.hasNext()) {
ArrayList<String> tuple = multiply.getNext();
long declFlags = kindFlag;
ListBuffer<JCAnnotation> annos = new ListBuffer<>();
for (String modifier : tuple) {
if (modifier.startsWith("@") && idAnnos.containsKey(modifier))
annos.add(idAnnos.get(modifier)); // it's anno
else
declFlags |= getFlagByName(modifier); // it's modifier
}
String declName = (scope == null)
? getUniqName(baseName)
: baseName + getUniqIndex(scope, baseName);
JCClassDecl baseDecl = make.ClassDef(
make.Modifiers(declFlags, annos.toList()),
names.fromString(declName),
processTypeParams(typeParam), // type params
extType, // ext
implTypes.toList(), // impl
members.toList()); // members
// fix constructors names
fixConstructorNames(baseDecl);
bases.append(baseDecl);
// for non-empty ids store first base occurence from multiplied sequence
if (baseId.length() != 0) {
idBases.put(baseId, baseDecl);
baseId = "";
}
}
return new ListBuffer[] { bases, imports };
}
List<JCTypeParameter> processTypeParams(String typeParams) {
if (typeParams == null || typeParams.length() == 0)
return List.<JCTypeParameter>nil(); // empty
String[] typeVarsArr = typeParams.split(",");
ListBuffer<JCTypeParameter> typeParamsDecls = new ListBuffer<>();
for (String typeVar : typeVarsArr) {
typeParamsDecls.add(
make.TypeParameter(names.fromString(typeVar),
List.<JCExpression>nil()));
}
return typeParamsDecls.toList();
}
ListBuffer<JCTree> processMembers(Element memberTag, String name, String kind) {
ListBuffer<JCTree> members = new ListBuffer<>();
NodeList nodes = memberTag.getChildNodes();
Hashtable<String, Integer> scope = new Hashtable<>();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (!(node instanceof Element))
continue;
switch (((Element)node).getTagName()) {
case "field":
members.appendList(processFields((Element)node, scope));
break;
case "serialfield":
members.append(processSerialFields((Element)node));
break;
case "constant":
members.appendList(processConstants((Element)node, scope));
break;
case "constructor":
members.appendList(processMethods((Element)node, scope, true, true));
break;
case "method":
boolean needBody = kind.equals("class") || kind.equals("enum");
members.appendList(processMethods((Element)node, scope, needBody, false));
break;
case "class":
case "interface":
case "enum":
case "annotation":
members.appendList(processBases((Element)node, scope)[0]);
break;
}
}
return members;
}
ListBuffer<JCTree> processFields(Element fieldsNode, Hashtable<String, Integer> scope) {
String kind = fieldsNode.getTagName();
String baseName = fieldsNode.getAttribute("basename");
ListBuffer<JCTree> fields = new ListBuffer<>();
NodeList nodes = fieldsNode.getChildNodes();
SimpleMultiplier multiply = new SimpleMultiplier(); // for modifiers
String[] types = new String[] {};
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (!(node instanceof Element))
continue;
// parse type and modifiers
switch (((Element)node).getTagName()) {
case "modifier":
multiply.addAxis(((Element)node).getTextContent());
break;
case "anno":
multiply.addAxis(((Element)node).getTextContent());
case "type":
types = ((Element)node).getTextContent().split("\\|");
break;
}
}
// process through modifiers and types
multiply.initIterator();
while (multiply.hasNext()) {
ArrayList<String> tuple = multiply.getNext();
long declFlags = 0;
ListBuffer<JCAnnotation> annos = new ListBuffer<>();
for (String modifier : tuple) {
if (modifier.startsWith("@") && idAnnos.containsKey(modifier))
annos.add(idAnnos.get(modifier)); // it's anno
else
declFlags |= getFlagByName(modifier); // it's modifier
}
for (String type : types) {
String declName = baseName + getUniqIndex(scope, baseName);
Type initType = getTypeByName(type);
JCExpression initExpr = null;
if ((declFlags & Flags.STATIC) != 0) // static to be initialized
initExpr = make.Literal(initType.isPrimitive() ?
initType.getTag() :
TypeTag.BOT,
"String".equals(type)
? new String("blah-blah-blah")
: new Integer(0));
JCVariableDecl fieldDecl = make.VarDef(
make.Modifiers(declFlags, annos.toList()),
names.fromString(declName),
make.Type(getTypeByName(type)),
initExpr);
fields.append(fieldDecl);
}
}
return fields;
}
JCTree processSerialFields(Element sfNode) {
String baseName = sfNode.getAttribute("basename");
String[] fieldTypes = sfNode.getTextContent().split(",");
ListBuffer<JCExpression> serialFields = new ListBuffer<>();
Hashtable<String, Integer> scope = new Hashtable<>();
for (String fType : fieldTypes) {
String fieldName = baseName + getUniqIndex(scope, baseName);
serialFields.add(
make.NewClass(
null,
null,
make.Type(getTypeByName("ObjectStreamField")),
List.from(
new JCTree.JCExpression[] {
make.Literal(fieldName),
make.Ident(names.fromString(fType + ".class"))
}),
null));
}
JCTree sfDecl = make.VarDef(
make.Modifiers(
Flags.PRIVATE | Flags.STATIC | Flags.FINAL),
names.fromString("serialPersistentFields"),
make.TypeArray(
make.Type(getTypeByName("ObjectStreamField"))),
make.NewArray(
null,
List.<JCExpression>nil(),
serialFields.toList()));
return sfDecl;
}
ListBuffer<JCTree> processConstants(Element constNode, Hashtable<String, Integer> scope) {
String baseName = constNode.getAttribute("basename");
int count = 1;
try {
count = Integer.parseInt(constNode.getAttribute("count"));
} catch (Exception e) {} // nothing to do, will use count = 1
long declFlags = Flags.PUBLIC | Flags.STATIC | Flags.FINAL | Flags.ENUM;
ListBuffer<JCTree> fields = new ListBuffer<>();
for (int i = 0; i < count; i++) {
String declName = baseName +
((count == 1) ? "" : getUniqIndex(scope, baseName));
JCVariableDecl constDecl = make.VarDef(
make.Modifiers(declFlags),
names.fromString(declName),
null, // no need for type in enum decl
null); // no init
fields.append(constDecl);
}
return fields;
}
ListBuffer<JCTree> processMethods(Element methodsNode, Hashtable<String, Integer> scope, boolean needBody, boolean isConstructor) {
String kind = methodsNode.getTagName();
String baseName = methodsNode.getAttribute("basename");
String name = methodsNode.getAttribute("name");
String methodTypeParam = methodsNode.getAttribute("tparam");
ListBuffer<JCTree> methods = new ListBuffer<>();
NodeList nodes = methodsNode.getChildNodes();
SimpleMultiplier multiply = new SimpleMultiplier(); // for modifiers
String[] types = new String[0];
String[] params = new String[] { "none" }; // default - no params
ListBuffer<Type> throwTypes = new ListBuffer<>();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (!(node instanceof Element))
continue;
// parse type and modifiers
switch (((Element)node).getTagName()) {
case "modifier":
multiply.addAxis(((Element)node).getTextContent());
break;
case "anno":
multiply.addAxis(((Element)node).getTextContent());
break;
case "type":
types = ((Element)node).getTextContent().split("\\|");
break;
case "param":
params = ((Element)node).getTextContent().split("\\|");
break;
case "throw":
throwTypes.add(
getTypeByName(((Element)node).getTextContent()));
break;
}
}
// constructor?
if (isConstructor) {
baseName = "constructor";
types = new String[] { "" };
}
// direct name not indexed
boolean isDirectName = false;
if (name.length() > 0) {
baseName = name;
isDirectName = true;
}
// process through modifiers and types
multiply.initIterator();
while (multiply.hasNext()) {
ArrayList<String> tuple = multiply.getNext();
long declFlags = 0;
ListBuffer<JCAnnotation> annos = new ListBuffer<>();
for (String modifier : tuple) {
if (modifier.startsWith("@") && idAnnos.containsKey(modifier))
annos.add(idAnnos.get(modifier)); // it's anno
else
declFlags |= getFlagByName(modifier); // it's modifier
}
for (String type : types) {
String declName = baseName
+ ((isConstructor || isDirectName)
? "" : getUniqIndex(scope, baseName));
JCBlock body = null;
if (needBody && (declFlags & Flags.ABSTRACT) == 0) { // create body
List<JCStatement> bodyStatements = List.<JCStatement>nil();
if (!type.equals("") && !type.equals("void")) { // create return statement
Type retType = getTypeByName(type);
bodyStatements = List.<JCStatement>of(
make.Return(
make.Literal(
retType.isPrimitive() ?
retType.getTag() :
TypeTag.BOT,
new Integer(0))));
}
body = make.Block(0, bodyStatements);
}
// same method by different params (if they exist)
for (String param : params) {
JCMethodDecl methodDecl =
make.MethodDef(
make.Modifiers(declFlags, annos.toList()),
names.fromString(declName),
isConstructor ? null : make.Type(getTypeByName(type)),
processTypeParams(methodTypeParam), // type params
null, // no receiver
processParams(param), // formal params
make.Types(throwTypes.toList()), // throws
body,
null); // no default value YET
methods.append(methodDecl);
}
}
}
return methods;
}
JCAnnotation processAnnoDecl(Element annoDeclNode) {
String annoId = annoDeclNode.getAttribute("id");
ListBuffer<JCExpression> args = new ListBuffer<>();
String className = "";
NodeList nodes = annoDeclNode.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (!(node instanceof Element))
continue;
switch (((Element)node).getTagName()) {
case "class":
className = ((Element)node).getTextContent();
break;
case "arg":
String argName = ((Element)node).getAttribute("name");
String argValue = ((Element)node).getAttribute("value");
JCExpression arg;
if (argName.length() == 0)
arg = make.Ident(names.fromString(argValue));
else
arg = make.Assign(
make.Ident(names.fromString(argName)),
make.Ident(names.fromString(argValue)));
args.add(arg);
break;
}
}
return make.Annotation(
make.Ident(names.fromString(className)),
args.toList());
}
ListBuffer<JCTree> processMethods(List<JCTree> tree, boolean needBody) {
// for "extends" clause; returns methods only
ListBuffer<JCTree> methods = new ListBuffer<>();
for (JCTree memberDecl : tree) {
if (memberDecl instanceof JCMethodDecl) {
JCMethodDecl methodDecl = (JCMethodDecl)memberDecl;
JCTree retTypeTree = methodDecl.getReturnType();
// skip constructors
if (retTypeTree == null)
continue;
if (needBody) {
// here we need to 'implement' interface declared methods
Type retType = retTypeTree.type;
List<JCStatement> bodyStatements = List.<JCStatement>nil();
if (retType.getTag() != TypeTag.VOID)
bodyStatements = List.<JCStatement>of(
make.Return(
make.Literal(
retType.isPrimitive() ?
retType.getTag() :
TypeTag.BOT,
new Integer(0))));
JCBlock body = make.Block(0, bodyStatements);
methodDecl = make.MethodDef(
methodDecl.getModifiers(),
methodDecl.getName(),
(JCExpression)methodDecl.getReturnType(),
methodDecl.getTypeParameters(),
methodDecl.getReceiverParameter(),
methodDecl.getParameters(),
methodDecl.getThrows(),
body,
(JCExpression)methodDecl.getDefaultValue());
}
methods.add(methodDecl);
}
}
return methods;
}
void fixConstructorNames(JCClassDecl baseDecl) {
ListBuffer<JCTree> newMembers = new ListBuffer<>();
List<JCTree> members = baseDecl.getMembers();
Name name = baseDecl.getSimpleName();
for (JCTree memberDecl : members) {
JCTree newDecl = memberDecl;
if (memberDecl instanceof JCMethodDecl) {
JCMethodDecl methodDecl = (JCMethodDecl)memberDecl;
JCTree retTypeTree = methodDecl.getReturnType();
if (retTypeTree == null)
newDecl = make.MethodDef(
methodDecl.getModifiers(),
name,
(JCExpression)methodDecl.getReturnType(),
methodDecl.getTypeParameters(),
methodDecl.getReceiverParameter(),
methodDecl.getParameters(),
methodDecl.getThrows(),
methodDecl.getBody(),
(JCExpression)methodDecl.getDefaultValue());
}
newMembers.add(newDecl);
}
baseDecl.defs = newMembers.toList();
}
List<JCVariableDecl> processParams(String paramTypes) {
if ("none".equals(paramTypes))
return List.<JCVariableDecl>nil(); // empty
String[] typesArr = paramTypes.split(",(?!(\\w+,)*\\w+>)");
ListBuffer<JCVariableDecl> paramsDecls = new ListBuffer<>();
int i = 0;
for (String typeName : typesArr) {
String paramName = "param"
+ (typesArr.length == 1 ? "" : String.valueOf(i));
paramsDecls.add(
make.VarDef(make.Modifiers(0),
names.fromString(paramName),
make.Type(getTypeByName(typeName)),
null));
i++;
}
return paramsDecls.toList();
}
//
// util methods
//
String getUniqName(String name) {
if (!nameIndex.containsKey(name))
nameIndex.put(name, new Integer(0));
Integer index = nameIndex.get(name);
String uniqName = name + index;
nameIndex.put(name, index + 1);
return uniqName;
}
int getUniqIndex(Hashtable<String, Integer> scope, String name) {
if (!scope.containsKey(name))
scope.put(name, new Integer(0));
Integer index = scope.get(name);
scope.put(name, index + 1);
return index;
}
long getFlagByName(String modifierName) {
switch (modifierName) {
case "public":
return Flags.PUBLIC;
case "private":
return Flags.PRIVATE;
case "protected":
return Flags.PROTECTED;
case "static":
return Flags.STATIC;
case "final":
return Flags.FINAL;
case "abstract":
return Flags.ABSTRACT;
case "strictfp":
return Flags.STRICTFP;
default:
return 0;
}
}
Type getTypeByName(String typeName) {
//check for primitive types
switch (typeName) {
case "void":
return syms.voidType;
case "boolean":
return syms.booleanType;
case "byte":
return syms.byteType;
case "char":
return syms.charType;
case "double":
return syms.doubleType;
case "float":
return syms.floatType;
case "int":
return syms.intType;
case "long":
return syms.longType;
default:
return getTypeByName(typeName, List.<Type>nil());
}
}
Type getTypeByName(String typeName, List<Type> tparams) {
return new Type.ClassType(
Type.noType,
tparams,
new Symbol.ClassSymbol(0, names.fromString(typeName), null));
}
}

@ -1,67 +0,0 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sampleapi.util;
import java.util.HashMap;
import com.sun.tools.javac.parser.Tokens.Comment;
import com.sun.tools.javac.tree.DCTree.DCDocComment;
import com.sun.tools.javac.tree.DocCommentTable;
import com.sun.tools.javac.tree.JCTree;
/*
* This class is replica of LazyDocCommentTable from com.sun.tools.javac.parser
* package. It's created due to restrictions of LazyDocCommentTable (cannot be
* used outside the package) and implements minimal functionality necessary
* for doc comment generation purposes.
*/
public class PoorDocCommentTable implements DocCommentTable {
HashMap<JCTree, Comment> table;
public PoorDocCommentTable() {
table = new HashMap<>();
}
public boolean hasComment(JCTree tree) {
return table.containsKey(tree);
}
public Comment getComment(JCTree tree) {
return table.get(tree);
}
public String getCommentText(JCTree tree) {
Comment c = getComment(tree);
return (c == null) ? null : c.getText();
}
public DCDocComment getCommentTree(JCTree tree) {
return null; // no need for generator purposes, Pretty does not call it
}
public void putComment(JCTree tree, Comment c) {
table.put(tree, c);
}
}

@ -1,102 +0,0 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sampleapi.util;
import java.util.StringTokenizer;
import java.util.ArrayList;
/*
* The class implements unknown number of nested loops. The number of modifiers
* in class/interface definitions could be any size. Annotations are also multiplied
* by this class.
* That is, dataset xml can provide any number of modifier sets, and generator should
* iterate through all possible modifiers, annotations and types combinations.
*
* For example, class definition xml provides 3 modifiers sets:
*
* "public,private"
* "static"
* "final,abstract"
*
* and one types set "void,int"
*
* the class will generate the sequence like:
* "public static final void"
* "public static final int"
* "public static abstract void"
* "public static abstract int"
* "private static final void"
* "private static final int"
* "private static abstract void"
* "private static abstract int".
*
* This sequence could be processed by just one loop instead of four.
*
* In other places where the number of possible positions are known,
* the generator uses nested loops instead.
*/
public class SimpleMultiplier {
ArrayList<ArrayList<String>> valueSpace = new ArrayList<>();
int size = 0;
int index = 0;
public void addAxis(String values) {
ArrayList<String> valueAxis = new ArrayList<>();
StringTokenizer valuesTokens = new StringTokenizer(values, "|");
while (valuesTokens.hasMoreTokens())
valueAxis.add(valuesTokens.nextToken());
valueSpace.add(valueAxis);
}
public void initIterator() {
if (!valueSpace.isEmpty()) {
size = 1;
for (int i = 0; i < valueSpace.size(); i++)
size *= valueSpace.get(i).size();
}
index = 0;
}
public boolean hasNext() {
return index < size;
}
public ArrayList<String> getNext() {
ArrayList<String> next = new ArrayList<>();
int positionIndex = index;
// last added changing faster
for (int i = valueSpace.size() - 1; i >= 0; i--) {
ArrayList<String> valueAxis = valueSpace.get(i);
int axisSize = valueAxis.size();
next.add(valueAxis.get(positionIndex % axisSize));
positionIndex /= axisSize;
}
index += 1;
return next;
}
}

@ -21,7 +21,7 @@
or visit www.oracle.com if you need additional information or have any
questions.
-->
<dataset package="sampleapi.fx" style="fx">
<package name="sampleapi.fx" style="fx">
<class basename="FXClass">
<modifier>public</modifier>
@ -42,4 +42,4 @@
</member>
</class>
</dataset>
</package>

@ -21,7 +21,7 @@
or visit www.oracle.com if you need additional information or have any
questions.
-->
<dataset package="sampleapi.simple">
<package name="sampleapi.simple">
<class basename="SampleClass" id="baseclass">
<modifier>public</modifier>
@ -526,4 +526,4 @@
</method>
</member>
</class>
</dataset>
</package>

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<package name="sampleapi.simple.sub">
<class basename="SClass">
<modifier>public</modifier>
<modifier>none|abstract</modifier>
<implement>SInterface0</implement>
<member>
<field basename="id">
<modifier>public</modifier>
<type>int</type>
</field>
<method basename="get">
<modifier>public</modifier>
<type>int</type>
<throw>SException0</throw>
</method>
<method basename="put">
<modifier>public</modifier>
<param>int</param>
<type>void</type>
<throw>SException0</throw>
</method>
</member>
</class>
<class basename="SException">
<modifier>public</modifier>
<extend ref="java.lang.Exception"/>
<member>
<constructor>
<modifier>public</modifier>
<param>String</param>
</constructor>
</member>
</class>
<interface basename="SInterface">
<modifier>public</modifier>
<member>
<method basename="put">
<modifier>public</modifier>
<type>void</type>
<param>int</param>
</method>
</member>
</interface>
<enum basename="SEnum">
<modifier>public</modifier>
<member>
<constant basename="ON" count="1"/>
<constant basename="OFF" count="1"/>
</member>
</enum>
<annotation basename="SAnno">
<modifier>public</modifier>
<member>
<method basename="value">
<modifier>public</modifier>
<type>boolean</type>
</method>
</member>
</annotation>
</package>

@ -21,7 +21,7 @@
or visit www.oracle.com if you need additional information or have any
questions.
-->
<dataset package="sampleapi.tiny">
<package name="sampleapi.tiny">
<class basename="TinyClass">
<modifier>public</modifier>
@ -68,4 +68,4 @@
</member>
</annotation>
</dataset>
</package>