Commit 27eb2f0e authored by Claus Nagel's avatar Claus Nagel
Browse files

even more flexible support for JAXB plugins

parent 2069595d
......@@ -2,22 +2,11 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/args4j/args4j-2.33.jar"/>
<classpathentry kind="lib" path="lib/jaxb/jaxb-core.jar"/>
<classpathentry kind="lib" path="lib/jaxb/jaxb-impl.jar"/>
<classpathentry kind="lib" path="lib/jaxb/jaxb-xjc.jar"/>
<classpathentry kind="lib" path="lib/xerces/xercesImpl.jar"/>
<classpathentry kind="lib" path="lib/xerces/xml-apis.jar"/>
<classpathentry kind="lib" path="lib/jaxb2-basics/commons-beanutils-1.9.2.jar"/>
<classpathentry kind="lib" path="lib/jaxb2-basics/commons-collections-3.2.1.jar"/>
<classpathentry kind="lib" path="lib/jaxb2-basics/commons-lang3-3.2.1.jar"/>
<classpathentry kind="lib" path="lib/jaxb2-basics/javaparser-1.0.11.jar"/>
<classpathentry kind="lib" path="lib/jaxb2-basics/jaxb2-basics-0.11.1.jar"/>
<classpathentry kind="lib" path="lib/jaxb2-basics/jaxb2-basics-runtime-0.11.1.jar"/>
<classpathentry kind="lib" path="lib/jaxb2-basics/jaxb2-basics-tools-0.11.1.jar"/>
<classpathentry kind="lib" path="lib/jaxb2-basics/jcl-over-slf4j-1.7.7.jar"/>
<classpathentry kind="lib" path="lib/jaxb2-basics/slf4j-api-1.7.7.jar"/>
<classpathentry kind="lib" path="lib/jaxb2-basics/slf4j-simple-1.7.7.jar"/>
<classpathentry kind="lib" path="lib/jaxb2-namespace-prefix/jaxb2-namespace-prefix-1.1.jar"/>
<classpathentry kind="lib" path="lib/args4j-2.33.jar"/>
<classpathentry kind="lib" path="lib/jaxb-core.jar"/>
<classpathentry kind="lib" path="lib/jaxb-impl.jar"/>
<classpathentry kind="lib" path="lib/jaxb-xjc.jar"/>
<classpathentry kind="lib" path="lib/xercesImpl.jar"/>
<classpathentry kind="lib" path="lib/xml-apis.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
......@@ -39,6 +39,7 @@
<property name="src" location="src" />
<property name="lib" location="lib" />
<property name="schemas" location="schemas" />
<property name="jaxb-plugins" location="jaxb-plugins" />
<property name="sample" location="sample" />
......@@ -53,11 +54,12 @@
<property name="dist.lib" location="${dist}/lib" />
<property name="dist.license" location="${dist}/license" />
<property name="dist.schemas" location="${dist}/schemas" />
<property name="dist.jaxb-plugins" location="${dist}/jaxb-plugins" />
<property name="dist.sample" location="${dist}/sample" />
<!-- classpath -->
<path id="classpath">
<fileset dir="lib" includes="**/*.jar" />
<fileset dir="lib" includes="*.jar" />
</path>
<tstamp>
......@@ -125,14 +127,16 @@
<fileset dir="${schemas}" includes="**/*" />
</copy>
<!-- copy jaxb-plugins files -->
<copy todir="${dist.jaxb-plugins}">
<fileset dir="${jaxb-plugins}" includes="**/*" />
</copy>
<buildnumber file="build.num" />
<!-- set package variables -->
<fileset dir="${dist.lib}" id="lib.files">
<include name="*.jar" />
</fileset>
<pathconvert property="manifest.classpath" dirsep="/" pathsep=" " refid="lib.files">
<map from="${dist}${file.separator}lib${file.separator}" to="lib${file.separator}" />
<pathconvert property="manifest.classpath" dirsep="/" pathsep=" " refid="classpath">
<map from="${basedir}${file.separator}lib${file.separator}" to="lib${file.separator}" />
</pathconvert>
<!-- put everything in ${build} into .jar file -->
......
......@@ -26,6 +26,7 @@ import java.io.IOException;
import java.io.PrintStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
......@@ -36,7 +37,9 @@ import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.citygml4j.ade_xjc.Util.URLClassLoader;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
......@@ -56,13 +59,14 @@ public class ADE_XJC {
private SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
// some dirs we will need
private File schema_dir = new File("schemas");
private Path schema_dir = Paths.get("schemas");
private Path plugins_dir = Paths.get("jaxb-plugins");
// some files we will need
private File baseProfileFile = new File(schema_dir.getAbsoluteFile() + "/CityGML/citygml4j_profile.xsd");
private File bindingFile = new File(schema_dir.getAbsoluteFile() + "/CityGML/binding.xjb");
private File adeSchemaFile = null;
private Path baseProfileFile = schema_dir.resolve("CityGML/citygml4j_profile.xsd");
private Path bindingFile = schema_dir.resolve("CityGML/binding.xjb");
private Path adeSchemaFile = null;
// args
@Argument
private List<String> adeSchemaFileList = new ArrayList<String>();
......@@ -72,25 +76,25 @@ public class ADE_XJC {
@Option(name="-binding", usage="optional JAXB binding file for ADE XML Schema", metaVar="<fileName>")
private File adeBindingFile = null;
@Option(name="-output", usage="output folder", metaVar="<folderName>")
private File outputFolder = new File("src-gen");
@Option(name="-non-strict", usage="allow changes to contents of subfolder 'schemas'")
private boolean nonStrict = false;
@Option(name="-clean", usage="clean output folder")
private boolean clean;
@Option(name="-h", aliases={"-help"}, usage="print this help message and exit")
private boolean help;
@Option(name="-version", usage="print product version and exit")
private boolean version;
@Option(name="-X{arg}", usage="one or more arguments for JAXB plugins")
private Boolean dummy = null;
public static void main(String[] args) {
new ADE_XJC().doMain(args);
}
......@@ -99,10 +103,10 @@ public class ADE_XJC {
List<String> tmp = new ArrayList<String>();
for (String arg : _args)
tmp.addAll(Arrays.asList(arg.split(" +")));
Map<Boolean, List<String>> args = tmp.stream().collect(Collectors.partitioningBy(arg -> !arg.startsWith("-X")));
CmdLineParser parser = new CmdLineParser(this, ParserProperties.defaults().withUsageWidth(80));
try {
parser.parseArgument(args.get(Boolean.TRUE));
} catch (CmdLineException e) {
......@@ -127,26 +131,26 @@ public class ADE_XJC {
printUsage(parser, System.out);
System.exit(1);
}
if (adeSchemaFileList.size() > 1) {
System.out.println("Just provide one ADE XML Schema definition file at a time");
printUsage(parser, System.out);
System.exit(1);
}
log(LogLevel.INFO, "Starting ade-xjc compiler");
adeSchemaFile = new File(adeSchemaFileList.get(0));
adeSchemaFile = Paths.get(adeSchemaFileList.get(0));
int status = 0;
try {
log(LogLevel.INFO, "Setting up build environment");
checkBuildEnvironment();
if (clean && Files.exists(outputFolder.toPath())) {
log(LogLevel.INFO, "Cleaning output folder");
Files.walkFileTree(outputFolder.toPath(), new FileDeleter(true));
}
createBuildEnvironment();
if (packageName.startsWith("org.citygml4j")) {
......@@ -154,45 +158,51 @@ public class ADE_XJC {
log(LogLevel.ERROR, "Choose a package which is not a subpackage of org.citygml4j. Aborting.");
System.exit(1);
}
log(LogLevel.INFO, "Using ADE schema " + adeSchemaFile.getCanonicalFile());
log(LogLevel.INFO, "Using ADE schema " + adeSchemaFile.toAbsolutePath().toString());
if (adeBindingFile != null)
log(LogLevel.INFO, "Using JAXB binding " + adeBindingFile.getCanonicalFile());
log(LogLevel.INFO, "Using Java package " + packageName + " for JAXB classes");
SchemaCompiler sc = XJC.createSchemaCompiler();
sc.setDefaultPackageName(packageName);
if (!args.get(Boolean.FALSE).isEmpty()) {
if (!args.get(Boolean.FALSE).isEmpty() && Files.exists(plugins_dir)) {
log(LogLevel.INFO, "Loading and configuring JAXB plugins");
String[] pluginArgs = args.get(Boolean.FALSE).stream().toArray(String[]::new);
Options options = ((SchemaCompilerImpl)sc).getOptions();
ServiceLoader<Plugin> plugins = ServiceLoader.load(Plugin.class);
URLClassLoader loader = new URLClassLoader();
try (Stream<Path> stream = Files.walk(plugins_dir).filter(path -> path.getFileName().toString().toLowerCase().endsWith(".jar"))) {
stream.forEach(path -> loader.addPath(path));
}
ServiceLoader<Plugin> plugins = ServiceLoader.load(Plugin.class, loader);
for (Plugin plugin : plugins) {
for (int i = 0; i < pluginArgs.length; i++) {
if (('-' + plugin.getOptionName()).equals(pluginArgs[i])) {
log(LogLevel.INFO, "Found JAXB plugin for option '-" + plugin.getOptionName() + "'");
options.activePlugins.add(plugin);
plugin.onActivated(options);
}
plugin.parseArgument(options, pluginArgs, i);
}
}
}
XJCErrorListener listener = new XJCErrorListener();
sc.setErrorListener(listener);
log(LogLevel.INFO, "Generating JAXB classes. This may take some time...");
sc.parseSchema(new InputSource(baseProfileFile.toURI().toString()));
sc.parseSchema(new InputSource(bindingFile.toURI().toString()));
sc.parseSchema(new InputSource(adeSchemaFile.toURI().toString()));
sc.parseSchema(new InputSource(baseProfileFile.toUri().toString()));
sc.parseSchema(new InputSource(bindingFile.toUri().toString()));
sc.parseSchema(new InputSource(adeSchemaFile.toUri().toString()));
if (adeBindingFile != null)
sc.parseSchema(new InputSource(adeBindingFile.toURI().toString()));
S2JJAXBModel model = sc.bind();
JCodeModel code = model.generateCode(null, listener);
code.build(outputFolder, (PrintStream)null);
......@@ -202,7 +212,7 @@ public class ADE_XJC {
} catch (Exception e) {
if (e.getMessage() != null)
log(LogLevel.ERROR, e.getMessage());
log(LogLevel.ERROR, "Unable to recover from previous error(s). Aborting.");
status = 1;
} finally {
......@@ -234,22 +244,22 @@ public class ADE_XJC {
}
private void checkBuildEnvironment() throws Exception, FileNotFoundException, NoSuchAlgorithmException {
if (!schema_dir.exists())
throw new FileNotFoundException("Failed to open folder " + schema_dir.getAbsolutePath());
if (!Files.exists(schema_dir))
throw new FileNotFoundException("Failed to open folder " + schema_dir.toAbsolutePath().toString());
if (!nonStrict) {
log(LogLevel.INFO, "Running in strict mode. Checking sanity of subfolder 'schemas'");
BigInteger md5 = new BigInteger("0");
md5 = Util.dir2md5(schema_dir, md5);
md5 = Util.dir2md5(schema_dir.toFile(), md5);
if (!md5.toString(16).equals("79facf9d68ad19afacf8d51a58c5f8b6"))
throw new Exception("Contents of subfolder 'schemas' have been altered. Please restore its original state.");
}
if (!adeSchemaFile.exists() || !adeSchemaFile.isFile() || !adeSchemaFile.canRead())
throw new Exception("Could not open ADE schema file " + adeSchemaFile.getAbsolutePath());
if (!Files.exists(adeSchemaFile) || !Files.isRegularFile(adeSchemaFile) || !Files.isReadable(adeSchemaFile))
throw new Exception("Could not open ADE schema file " + adeSchemaFile.toAbsolutePath().toString());
if (adeBindingFile != null && (!adeBindingFile.exists() || !adeBindingFile.isFile() || !adeBindingFile.canRead()))
throw new Exception("Could not open ADE binding file " + adeBindingFile.getAbsolutePath());
}
......@@ -276,7 +286,7 @@ public class ADE_XJC {
parser.printUsage(System.out);
out.println();
}
private void log(LogLevel level, String msg) {
StringBuilder builder = new StringBuilder();
builder.append("[")
......@@ -285,24 +295,24 @@ public class ADE_XJC {
.append(level.toString())
.append("] ")
.append(msg);
System.out.println(builder.toString());
}
private enum LogLevel {
INFO("info"),
WARN("warn"),
ERROR("error");
private String value;
LogLevel(String value) {
this.value = value;
}
public String toString() {
return value;
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment