From 945011dc88a3e55bd8afd3dec61196f5c7ce0945 Mon Sep 17 00:00:00 2001 From: Laurent SCHOELENS <61973605+laurentschoelens@users.noreply.github.com> Date: Wed, 6 Dec 2023 13:25:28 +0100 Subject: [PATCH] [#460] take back plugins from org.andromda.thirdparty.jaxb2_commons groupId --- README.md | 7 +- .../main/java/org/jvnet/jaxb/lang/Child.java | 7 + .../plugin/booleangetter/BooleanGetter.java | 49 ++ .../camelcase/CamelCaseNameConverter.java | 27 + .../plugin/camelcase/CamelCasePlugin.java | 98 ++++ .../jaxb/plugin/elementwrapper/Candidate.java | 55 ++ .../plugin/elementwrapper/Instantiation.java | 5 + ...ugin.java => OldElementWrapperPlugin.java} | 2 +- .../XmlElementWrapperPlugin.java | 533 ++++++++++++++++++ .../parentpointer/ParentPointerPlugin.java | 121 ++++ .../Customizations.java | 11 + .../PropertyListenerInjectorPlugin.java | 133 +++++ .../services/com.sun.tools.xjc.Plugin | 6 +- .../tests/booleangetter/pom.xml | 41 ++ .../src/main/resources/Person.xsd | 28 + .../jaxb/tests/booleangetter/PersonTest.java | 15 + .../src/test/resources/log4j.properties | 5 + jaxb-plugins-parent/tests/camelcase/pom.xml | 41 ++ .../camelcase/src/main/resources/Person.xsd | 28 + .../jaxb/tests/camelcase/AddressTest.java | 18 + .../jaxb/tests/camelcase/PersonTest.java | 15 + .../src/test/resources/log4j.properties | 5 + .../tests/elementwrapper/pom.xml | 46 ++ .../src/main/resources/example.xsd | 21 + .../tests/parentpointer/pom.xml | 41 ++ .../src/main/resources/Person.xsd | 28 + .../jaxb/tests/parentpointer/AddressTest.java | 17 + .../src/test/resources/log4j.properties | 5 + jaxb-plugins-parent/tests/pom.xml | 5 + .../tests/propertylistenerinjector/pom.xml | 41 ++ .../src/main/resources/Person.xsd | 28 + .../src/main/resources/binding.xjb | 15 + .../propertylistenerinjector/AddressTest.java | 16 + .../src/test/resources/log4j.properties | 5 + 34 files changed, 1515 insertions(+), 3 deletions(-) create mode 100644 jaxb-plugins-parent/jaxb-plugins-runtime/src/main/java/org/jvnet/jaxb/lang/Child.java create mode 100644 jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/booleangetter/BooleanGetter.java create mode 100644 jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/camelcase/CamelCaseNameConverter.java create mode 100644 jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/camelcase/CamelCasePlugin.java create mode 100644 jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/Candidate.java create mode 100644 jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/Instantiation.java rename jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/{ElementWrapperPlugin.java => OldElementWrapperPlugin.java} (99%) create mode 100644 jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/XmlElementWrapperPlugin.java create mode 100644 jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/parentpointer/ParentPointerPlugin.java create mode 100644 jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/propertylistenerinjector/Customizations.java create mode 100644 jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/propertylistenerinjector/PropertyListenerInjectorPlugin.java create mode 100644 jaxb-plugins-parent/tests/booleangetter/pom.xml create mode 100644 jaxb-plugins-parent/tests/booleangetter/src/main/resources/Person.xsd create mode 100644 jaxb-plugins-parent/tests/booleangetter/src/test/java/org/jvnet/jaxb/tests/booleangetter/PersonTest.java create mode 100644 jaxb-plugins-parent/tests/booleangetter/src/test/resources/log4j.properties create mode 100644 jaxb-plugins-parent/tests/camelcase/pom.xml create mode 100644 jaxb-plugins-parent/tests/camelcase/src/main/resources/Person.xsd create mode 100644 jaxb-plugins-parent/tests/camelcase/src/test/java/org/jvnet/jaxb/tests/camelcase/AddressTest.java create mode 100644 jaxb-plugins-parent/tests/camelcase/src/test/java/org/jvnet/jaxb/tests/camelcase/PersonTest.java create mode 100644 jaxb-plugins-parent/tests/camelcase/src/test/resources/log4j.properties create mode 100644 jaxb-plugins-parent/tests/elementwrapper/pom.xml create mode 100644 jaxb-plugins-parent/tests/elementwrapper/src/main/resources/example.xsd create mode 100644 jaxb-plugins-parent/tests/parentpointer/pom.xml create mode 100644 jaxb-plugins-parent/tests/parentpointer/src/main/resources/Person.xsd create mode 100644 jaxb-plugins-parent/tests/parentpointer/src/test/java/org/jvnet/jaxb/tests/parentpointer/AddressTest.java create mode 100644 jaxb-plugins-parent/tests/parentpointer/src/test/resources/log4j.properties create mode 100644 jaxb-plugins-parent/tests/propertylistenerinjector/pom.xml create mode 100644 jaxb-plugins-parent/tests/propertylistenerinjector/src/main/resources/Person.xsd create mode 100644 jaxb-plugins-parent/tests/propertylistenerinjector/src/main/resources/binding.xjb create mode 100644 jaxb-plugins-parent/tests/propertylistenerinjector/src/test/java/org/jvnet/jaxb/tests/propertylistenerinjector/AddressTest.java create mode 100644 jaxb-plugins-parent/tests/propertylistenerinjector/src/test/resources/log4j.properties diff --git a/README.md b/README.md index 239fa8b22..92b570207 100644 --- a/README.md +++ b/README.md @@ -134,8 +134,13 @@ JAXB Basics can only be used with JAXB/XJC 4.x. * [Commons Lang Plugin](https://github.com/highsource/jaxb-tools/wiki/JAXB2-Commons-Lang-Plugin) - generates the `toString()`, `hashCode()` and `equals()` methods using Apache commons-lang3. * [Default Value Plugin](https://github.com/highsource/jaxb-tools/wiki/JAXB2-Default-Value-Plugin) - modifies the JAXB code model to set default values to the schema `default` attribute. * [Fluent API Plugin](https://github.com/highsource/jaxb-tools/wiki/JAXB2-Fluent-API-Plugin) - support a fluent api in addition to the default (JavaBean) setter methods. -* [Namespace Prefix Plugin](https://github.com/highsource/jaxb-tools/wiki/JAXB2-Namespace-Prefix-Plugin) - adds `javax.xml.bind.annotation.XmlNs` annotations to `package-info.java` files +* [Namespace Prefix Plugin](https://github.com/highsource/jaxb-tools/wiki/JAXB2-Namespace-Prefix-Plugin) - adds `jakarta.xml.bind.annotation.XmlNs` annotations to `package-info.java` files * [Value Constructor Plugin](https://github.com/highsource/jaxb-tools/wiki/JAXB2-Value-Constructor-Plugin) - generates another constructor, taking an argument for each field in the class and initialises the field with the argument value. +* [Boolean Getter Plugin](https://github.com/highsource/jaxb-tools/wiki/JAXB-Boolean-Getter-Plugin) - generates getters for boolean property in `getXXX` instead of `isXXX`. +* [CamelCase Plugin](https://github.com/highsource/jaxb-tools/wiki/JAXB-CamelCase-Plugin) - modifies the classes name generated by XJC to always be in CamelCase. +* [Xml ElementWrapper Plugin](https://github.com/highsource/jaxb-tools/wiki/JAXB-XML-ElementWrapper-Plugin) - generates `jakarta.xml.bind.annotation.XmlElementWrapper` annotation to simplify generated structure. +* [Parent Pointer Plugin](https://github.com/highsource/jaxb-tools/wiki/JAXB-Parent-Pointer-Plugin) - generates getter in child elements to get the parent object (depends on `jaxb-plugins-runtime`) +* [Property Listener Injector Plugin](https://github.com/highsource/jaxb-tools/wiki/JAXB-Property-Listener-Injector-Plugin) - adds methods in order to configure the generation of events on each `setXXX` method ## Credits diff --git a/jaxb-plugins-parent/jaxb-plugins-runtime/src/main/java/org/jvnet/jaxb/lang/Child.java b/jaxb-plugins-parent/jaxb-plugins-runtime/src/main/java/org/jvnet/jaxb/lang/Child.java new file mode 100644 index 000000000..813f0e163 --- /dev/null +++ b/jaxb-plugins-parent/jaxb-plugins-runtime/src/main/java/org/jvnet/jaxb/lang/Child.java @@ -0,0 +1,7 @@ +package org.jvnet.jaxb.lang; + +public interface Child { + Object getParent(); + + void setParent(Object parent); +} diff --git a/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/booleangetter/BooleanGetter.java b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/booleangetter/BooleanGetter.java new file mode 100644 index 000000000..7d6f46bd4 --- /dev/null +++ b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/booleangetter/BooleanGetter.java @@ -0,0 +1,49 @@ +package org.jvnet.jaxb.plugin.booleangetter; + +import com.sun.codemodel.JMethod; +import com.sun.tools.xjc.Options; +import com.sun.tools.xjc.Plugin; +import com.sun.tools.xjc.outline.ClassOutline; +import com.sun.tools.xjc.outline.Outline; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; + +import java.util.Collection; + +/** + * XJC plugin to generate getXX functions instead of isXX functions for boolean values. + * The motivation is to make using XJC generated classes easier to use with Spring, since + * Spring expects accessors to be called getXX. + * + * @author Adam Burnett + * + * This plugin came from here : org.andromda.thirdparty.jaxb2_commons:booleangetter:1.0 + */ +public class BooleanGetter extends Plugin { + + protected final String OPTION_NAME = "Xboolean-getter"; + + @Override + public String getOptionName() { + return OPTION_NAME; + } + + @Override + public String getUsage() { + return "-" + OPTION_NAME + " : Generate getXX instead of isXX functions for boolean values\n"; + } + + @Override + public boolean run(Outline model, Options opts, ErrorHandler errors) throws SAXException { + for (ClassOutline co : model.getClasses()) { + Collection methods = co.implClass.methods(); + // pretty simple, just look at all our generated methods and rename isXX to getXX + for (JMethod m : methods) { + if (m.name().startsWith("is")) { + m.name("get" + m.name().substring("is".length())); + } + } + } + return true; + } +} diff --git a/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/camelcase/CamelCaseNameConverter.java b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/camelcase/CamelCaseNameConverter.java new file mode 100644 index 000000000..306f9185c --- /dev/null +++ b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/camelcase/CamelCaseNameConverter.java @@ -0,0 +1,27 @@ +package org.jvnet.jaxb.plugin.camelcase; + +import org.glassfish.jaxb.core.api.impl.NameConverter; + +/** + * Name converter that unconditionally converts to camel case. + */ +class CamelCaseNameConverter extends NameConverter.Standard { + + /** + * Changes the first character of the specified string to uppercase, + * and the rest of characters to lowercase. + * + * @param + * s string to capitalize + * + * @return + * capitalized string + */ + @Override + public String capitalize(String s) { + StringBuilder sb = new StringBuilder(s.length()); + sb.append(Character.toUpperCase(s.charAt(0))); + sb.append(s.substring(1).toLowerCase()); + return sb.toString(); + } +} diff --git a/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/camelcase/CamelCasePlugin.java b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/camelcase/CamelCasePlugin.java new file mode 100644 index 000000000..855909cd3 --- /dev/null +++ b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/camelcase/CamelCasePlugin.java @@ -0,0 +1,98 @@ +package org.jvnet.jaxb.plugin.camelcase; + +import com.sun.tools.xjc.BadCommandLineException; +import com.sun.tools.xjc.Options; +import com.sun.tools.xjc.Plugin; +import com.sun.tools.xjc.outline.Outline; +import org.xml.sax.ErrorHandler; + +/** + * {@link Plugin} that always converts an XML name into a camel case java name. + * This plugin changes the first character of every word composing an XML name + * to uppercase and the others to lowercase, while the default XJC behavior is + * to do so only if the first character of the word is lowercase. + *
+ *
+ * XJC default:
+ *   FIRST_NAME -> FIRSTNAME
+ *   FOOBar     -> FOOBar
+ *   SSNCode    -> SSNCode
+ *
+ * Camel case always:
+ *   FIRST_NAME -> FirstName
+ *   FOOBar     -> FooBar
+ *   SSNCode    -> SsnCode
+ *
+ * 
+ * + * @author Nicola Fagnani + * + * This plugin came from here : org.andromda.thirdparty.jaxb2_commons:camelcase-always:1.0 + */ +public class CamelCasePlugin extends Plugin { + + /** Constant for the option string. */ + protected final String OPTION_NAME = "Xcamelcase"; + + /** + * Returns the option string used to turn on this plugin. + * + * @return + * option string to invoke this plugin + */ + @Override + public String getOptionName() { + return OPTION_NAME; + } + + /** + * Returns a string specifying how to use this plugin and what it does. + * + * @return + * string containing the plugin usage message + */ + @Override + public String getUsage() { + return " -" + OPTION_NAME + + " : converts every XML name to camel case"; + } + + /** + * On plugin activation, sets a customized NameConverter to adjust code + * generation. + * + * @param opts + * options used to invoke XJC + * + * @throws com.sun.tools.xjc.BadCommandLineException + * if the plugin is invoked with wrong parameters + */ + @Override + public void onActivated(Options opts) throws BadCommandLineException { + opts.setNameConverter( new CamelCaseNameConverter(), this ); + } + + /** + * Returns true without touching the generated code. All the relevant + * work is done during name conversion. + * + * @param model + * This object allows access to various generated code. + * + * @param opts + * options used to invoke XJC + + * @param errorHandler + * Errors should be reported to this handler. + * + * @return + * If the add-on executes successfully, return true. + * If it detects some errors but those are reported and + * recovered gracefully, return false. + */ + @Override + public boolean run(Outline model, Options opts, ErrorHandler errorHandler ) { + return true; + } + +} diff --git a/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/Candidate.java b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/Candidate.java new file mode 100644 index 000000000..200e2f9cf --- /dev/null +++ b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/Candidate.java @@ -0,0 +1,55 @@ +package org.jvnet.jaxb.plugin.elementwrapper; + +import com.sun.codemodel.JDefinedClass; +import com.sun.codemodel.JFieldVar; +import com.sun.tools.xjc.model.CClassInfo; +import com.sun.tools.xjc.model.CPropertyInfo; +import com.sun.tools.xjc.model.CTypeInfo; + +/** + * @author bjh + */ +class Candidate { + protected CClassInfo classInfo; + protected CPropertyInfo propertyInfo; + protected CTypeInfo propertyTypeInfo; + + protected JDefinedClass implClass; + protected JFieldVar field; + protected String wrappedSchemaTypeName = null; + + public Candidate(CClassInfo classInfo) { + this.classInfo = classInfo; + this.propertyInfo = classInfo.getProperties().get(0); + this.propertyTypeInfo = propertyInfo.ref().iterator().next(); + this.wrappedSchemaTypeName = XmlElementWrapperPlugin.elementName(propertyInfo); + } + + public CClassInfo getClassInfo() { + return classInfo; + } + + public CPropertyInfo getPropertyInfo() { + return propertyInfo; + } + + public CTypeInfo getPropertyTypeInfo() { + return propertyTypeInfo; + } + + public String getClassName() { + return classInfo.fullName(); + } + + public String getFieldName() { + return getPropertyInfo().getName(false); + } + + public String getFieldTypeName() { + return propertyTypeInfo.getType().fullName(); + } + + public String getWrappedSchemaTypeName() { + return wrappedSchemaTypeName; + } +} diff --git a/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/Instantiation.java b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/Instantiation.java new file mode 100644 index 000000000..b4ac2e70b --- /dev/null +++ b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/Instantiation.java @@ -0,0 +1,5 @@ +package org.jvnet.jaxb.plugin.elementwrapper; + +enum Instantiation { + EARLY, LAZY +} diff --git a/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/ElementWrapperPlugin.java b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/OldElementWrapperPlugin.java similarity index 99% rename from jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/ElementWrapperPlugin.java rename to jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/OldElementWrapperPlugin.java index 5a5e192c0..114c9755f 100644 --- a/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/ElementWrapperPlugin.java +++ b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/OldElementWrapperPlugin.java @@ -31,7 +31,7 @@ import com.sun.tools.xjc.model.nav.NClass; import com.sun.tools.xjc.model.nav.NType; -public class ElementWrapperPlugin extends AbstractModelPlugin { +public class OldElementWrapperPlugin extends AbstractModelPlugin { @Override public String getOptionName() { diff --git a/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/XmlElementWrapperPlugin.java b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/XmlElementWrapperPlugin.java new file mode 100644 index 000000000..502de913e --- /dev/null +++ b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/elementwrapper/XmlElementWrapperPlugin.java @@ -0,0 +1,533 @@ +package org.jvnet.jaxb.plugin.elementwrapper; + +import com.sun.codemodel.JAnnotationUse; +import com.sun.codemodel.JClass; +import com.sun.codemodel.JDefinedClass; +import com.sun.codemodel.JExpr; +import com.sun.codemodel.JFieldVar; +import com.sun.codemodel.JMethod; +import com.sun.codemodel.JMod; +import com.sun.codemodel.JPackage; +import com.sun.tools.xjc.BadCommandLineException; +import com.sun.tools.xjc.Options; +import com.sun.tools.xjc.Plugin; +import com.sun.tools.xjc.model.CClassInfo; +import com.sun.tools.xjc.model.CElementPropertyInfo; +import com.sun.tools.xjc.model.CPropertyInfo; +import com.sun.tools.xjc.model.CTypeInfo; +import com.sun.tools.xjc.model.Model; +import com.sun.tools.xjc.outline.ClassOutline; +import com.sun.tools.xjc.outline.FieldOutline; +import com.sun.tools.xjc.outline.Outline; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import org.xml.sax.ErrorHandler; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * When generating XML schema from Java source code using the schemagen tool a common approach is to use + * the @XmlElementWrapper and @XmlElement annotations to handle schema generation for collections. However, when + * generating Java source from a schema using the xjc tool the resulting code is not created with these + * annotations. Instead, the generated Java source contains "injected" inner classes to accommodate the collection + * of elements contained within an element. + * + * This plugin came from here : org.andromda.thirdparty.jaxb2_commons:xml-element-wrapper:1.0 + */ +public class XmlElementWrapperPlugin extends Plugin { + + /** Constant for the option string. */ + protected final String OPTION_NAME = "XelementWrapper"; + + protected Map candidates = null; + protected File includeFile = null; + protected Set include = null; + protected File excludeFile = null; + protected Set exclude = null; + protected File summaryFile = null; + protected PrintWriter summary = null; + protected boolean debugMode = false; + protected boolean verbose = false; + @SuppressWarnings("unchecked") + protected Class interfaceClass = List.class; + @SuppressWarnings("unchecked") + protected Class collectionClass = ArrayList.class; + protected Instantiation instantiation = Instantiation.EARLY; + protected boolean deleteCandidates = false; + protected String factoryClassName = "ObjectFactory"; + protected String debugClassName = "JAXBDebug"; + + public XmlElementWrapperPlugin() { + } + + @Override + public String getOptionName() { + return OPTION_NAME; + } + + @Override + public String getUsage() { + return " -" + OPTION_NAME + " : Replace collection types with fields having the @XmlElementWrapper and @XmlElement annotations."; + } + + @Override + public void onActivated(Options opts) throws BadCommandLineException { + debugMode = opts.debugMode; + verbose = opts.verbose; + + // If we are in debug mode, report... + writeDebug("JAXB Compilation started (onActivated):"); + writeDebug("\tbuildId :\t" + Options.getBuildID()); + writeDebug("\tdefaultPackage :\t" + opts.defaultPackage); + writeDebug("\tdefaultPackage2:\t" + opts.defaultPackage2); + writeDebug("\tquiet :\t" + opts.quiet); + writeDebug("\tdebug :\t" + opts.debugMode); + writeDebug("\ttargetDir :\t" + opts.targetDir); + writeDebug("\tverbose :\t" + opts.verbose); + writeDebug("\tGrammars :\t" + opts.getGrammars().length); + for (int i = 0; i < opts.getGrammars().length; i++) + writeDebug("\t [" + i + "]: " + opts.getGrammars()[i].getSystemId()); + } + + @Override + public int parseArgument(Options opt, String[] args, int i) throws BadCommandLineException, + IOException { + + int recognized = 0; + String filename; + + String arg = args[i]; + writeDebug("Argument[" + i + "] = " + arg); + + if (arg.startsWith("-" + OPTION_NAME + ":delete")) { + recognized++; + deleteCandidates = true; + } else if (arg.startsWith("-" + OPTION_NAME + ":include")) { + recognized++; + include = new HashSet<>(); + + if (arg.length() > 8) { + filename = arg.substring(8).trim(); + } else { + filename = args[i + 1]; + recognized++; + } + includeFile = new File(filename); + readCandidates(includeFile, include); + } else if (arg.startsWith("-" + OPTION_NAME + ":exclude")) { + recognized++; + exclude = new HashSet(); + + if (arg.length() > 8) { + filename = arg.substring(8).trim(); + } else { + filename = args[i + 1]; + recognized++; + } + excludeFile = new File(filename); + readCandidates(excludeFile, exclude); + } else if (arg.startsWith("-" + OPTION_NAME + ":summary")) { + recognized++; + if (arg.length() > 8) { + filename = arg.substring(8).trim(); + } else { + filename = args[i + 1]; + recognized++; + } + + summaryFile = new File(filename); + summary = new PrintWriter(new FileOutputStream(summaryFile)); + } else if (arg.startsWith("-" + OPTION_NAME + ":collection")) { + String ccn; + + recognized++; + if (arg.length() > 11) { + ccn = arg.substring(11).trim(); + } else { + ccn = args[i + 1]; + recognized++; + } + try { + collectionClass = Class.forName(ccn); + } catch (ClassNotFoundException e) { + throw new BadCommandLineException("-collection " + ccn + ": Class not found."); + } + } else if (arg.startsWith("-" + OPTION_NAME + ":instantiate")) { + String instantiate; + recognized++; + + if (arg.length() > 12) { + instantiate = arg.substring(12).trim().toUpperCase(); + } else { + instantiate = args[i + 1].trim().toUpperCase(); + recognized++; + } + instantiation = Instantiation.valueOf(instantiate); + } else { + //throw new BadCommandLineException("Invalid argument " + arg); + } + + return recognized; + } + + + @Override + public void postProcessModel(Model model, ErrorHandler errorHandler) { + super.postProcessModel(model, errorHandler); + } + + @Override + public boolean run(Outline model, Options opt, ErrorHandler errorHandler) { + int candidateCount = 0; + int modificationCount = 0; + int deletionCount = 0; + + JDefinedClass implementationClass; + Candidate candidate; + String fieldName; + String typeName; + Collection methodsToRemove; + + writeDebug("JAXB Process Model (run)..."); + + // Write summary information on the option for this compilation. + writeSummary(" "); + writeSummary("Compilation:"); + writeSummary("\tDate :\t-"); + writeSummary("\tVersion :\t-"); + writeSummary("\tJAXB version :\t" + Options.getBuildID()); + writeSummary("\tInclude file :\t" + (includeFile == null ? "" : includeFile)); + writeSummary("\tExclude file :\t" + (excludeFile == null ? "" : excludeFile)); + writeSummary("\tSummary file :\t" + (summaryFile == null ? "" : summaryFile)); + writeSummary("\tInstantiate :\t" + instantiation); + writeSummary("\tCollection :\t" + collectionClass); + writeSummary("\tInterface :\t" + interfaceClass); + writeSummary("\tDelete :\t" + deleteCandidates); + writeSummary(" "); + + // Find candidate classes for transformation. + // Candidates are classes having exactly one field which is a collection. + candidates = findCandidateClasses(model.getModel(), errorHandler); + + // Write information on candidate classes to summary file. + writeSummary("Candidates:"); + for (Candidate c : candidates.values()) { + if (isIncluded(c)) { + writeSummary("\t[+] " + getIncludeOrExcludeReason(c) + ":\t" + c.getClassName()); + candidateCount++; + } else { + writeSummary("\t[-]: " + getIncludeOrExcludeReason(c) + ":\t" + c.getClassName()); + } + } + writeSummary("\t" + candidateCount + " candidate(s) being considered."); + writeSummary(" "); + + // Visit all classes generated by JAXB. + writeSummary("Modifications:"); + for (ClassOutline classOutline : model.getClasses()) { + // Get the implementation class for the current class. + implementationClass = classOutline.implClass; + + // Visit all fields in this class. + for (FieldOutline field : classOutline.getDeclaredFields()) { + + // Extract the field name and type of the current field. + fieldName = field.getPropertyInfo().getName(false); + typeName = field.getRawType().fullName(); + + // Check to see if the current field references one of the candidate classes. + candidate = candidates.get(typeName); + + if (candidate != null && isIncluded(candidate)) { + // We have a candidate field to be replaced with a wrapped version. Report finding to + // summary file. + writeSummary("\t" + classOutline.target.getName() + "#" + fieldName + "\t" + typeName); + modificationCount++; + + // Create the new interface and collection classes using the specified interface and + // collection classes (configuration) with an element type corresponding to + // the element type from the collection present in the candidate class (narrowing). + JDefinedClass candidateClass = model.getClazz(candidate.getClassInfo()).implClass; + List itemNarrowing = ((JClass) candidateClass.fields().get( + candidate.getFieldName()).type()).getTypeParameters(); + JClass newInterfaceClass = implementationClass.owner().ref(interfaceClass).narrow( + itemNarrowing); + JClass newCollectionClass = implementationClass.owner().ref(collectionClass).narrow( + itemNarrowing); + + // Remove original field which refers to the inner class. + JFieldVar implField = implementationClass.fields().get(fieldName); + implementationClass.removeField(implField); + + // Add new wrapped version of the field using the original field name. + // CODE: protected I fieldName; + implField = implementationClass.field(JMod.PROTECTED, newInterfaceClass, fieldName); + + // If instantiation is specified to be "early", add code for creating new instance of the + // collection class. + if (instantiation == Instantiation.EARLY) { + writeDebug("Applying EARLY instantiation..."); + // CODE: ... fieldName = new C(); + implField.init(JExpr._new(newCollectionClass)); + } + + // Annotate the new field with the @XmlElementWrapper annotation using the original field + // name as name. + JAnnotationUse annotation = implField.annotate(XmlElementWrapper.class); + annotation.param("name", XmlElementWrapperPlugin.elementName(field.getPropertyInfo()) == null ? fieldName : XmlElementWrapperPlugin.elementName(field.getPropertyInfo())); + writeDebug("XmlElementWrapper(name=" + (XmlElementWrapperPlugin.elementName(field.getPropertyInfo()) == null ? fieldName : XmlElementWrapperPlugin.elementName(field.getPropertyInfo())) + ")"); + + // Annotate the new field with the @XmlElement annotation using the field name from the + // wrapped type as name. + annotation = implField.annotate(XmlElement.class); + annotation.param("name", candidate.getWrappedSchemaTypeName() == null ? candidate.getFieldName() : candidate.getWrappedSchemaTypeName()); + writeDebug("XmlElement(name=" + (candidate.getWrappedSchemaTypeName() == null ? candidate.getFieldName() : candidate.getWrappedSchemaTypeName()) + ")"); + + // Find original getter and setter methods to remove. + methodsToRemove = new ArrayList(); + for (JMethod m : implementationClass.methods()) { + if (m.name().equals("set" + firstUpper(fieldName)) + || m.name().equals("get" + firstUpper(fieldName))) { + methodsToRemove.add(m); + } + } + + // Remove original getter and setter methods. + for (JMethod m : methodsToRemove) { + implementationClass.methods().remove(m); + } + + // Add a new getter method returning the (wrapped) field added. + // CODE: public I getFieldname() { ... }; + JMethod method = implementationClass.method(JMod.PUBLIC, newInterfaceClass, "get" + + firstUpper(fieldName)); + + if (instantiation == Instantiation.LAZY) { + writeDebug("Applying LAZY instantiation..."); + // CODE: if (fieldName == null) fieldName = new C(); + method.body()._if(JExpr.ref(fieldName).eq(JExpr._null()))._then().assign( + JExpr.ref(fieldName), JExpr._new(newCollectionClass)); + } + + // CODE: return "fieldName"; + method.body()._return(JExpr.ref(fieldName)); + } + } + } + writeSummary("\t" + modificationCount + " modification(s) to original code."); + writeSummary(" "); + + writeSummary("Deletions:"); + if (deleteCandidates) { + + // REMOVED: + // Get the default package from options. + // This code was used earlier to only get the factory class from the default package. + // pkg = model.getModel().codeModel._package(opt.defaultPackage); + // JDefinedClass factoryClass = pkg._getClass(factoryClassName); + + JPackage pkg; + + // Get the factory class from the default package. + JDefinedClass factoryClass; + JDefinedClass candidateClass; + + // Visit all candidate classes. + for (Candidate c : candidates.values()) { + // Only consider candidates that are actually included... + if (isIncluded(c)) { + // Get the defined class for candidate class. + candidateClass = model.getClazz(c.getClassInfo()).implClass; + + // ADDED: + // This code was added to locate the ObjectFactory inside the package of the candidate class. + pkg = candidateClass._package(); + factoryClass = pkg._getClass(factoryClassName); + + // Remove methods referencing the candidate class from the ObjectFactory. + methodsToRemove = new ArrayList<>(); + for (JMethod m : factoryClass.methods()) { + if (m.type().compareTo(candidateClass) == 0) methodsToRemove.add(m); + } + + for (JMethod m : methodsToRemove) { + writeSummary("\tRemoving method " + m.type().fullName() + " " + m.name() + " from " + + factoryClass.fullName()); + factoryClass.methods().remove(m); + deletionCount++; + } + + // Remove the candidate from the class or package it is defined in. + if (candidateClass.parentContainer().isClass()) { + // The candidate class is an inner class. Remove the class from its parent class. + JDefinedClass parent = (JDefinedClass) candidateClass.parentContainer(); + writeSummary("\tRemoving class " + candidateClass.fullName() + " from class " + parent.fullName()); + Iterator itor = parent.classes(); + while (itor.hasNext()) { + if (itor.next().equals(candidateClass)) { + itor.remove(); + break; + } + } + deletionCount++; + } else { + // The candidate class in in a package. Remove the class from the package. + JPackage parent = (JPackage) candidateClass.parentContainer(); + writeSummary("\tRemoving class " + candidateClass.fullName() + " from package " + parent.name()); + parent.remove(candidateClass); + deletionCount++; + } + } + } + } + writeSummary("\t" + deletionCount + " deletion(s) from original code."); + writeSummary(" "); + + try { + writeDebug("Closing summary..."); + closeSummary(); + } catch (IOException e) { + // TODO BJH: How would this type of exception be reported? Should it just be ignored? + } + writeDebug("Done"); + return true; + } + + protected boolean isIncluded(Candidate candidate) { + // + // A candidate is included if, ... + // 1. No includes and no excludes have been specified + // 2. Includes have been specified and canditate is included, and no excludes have been + // specified. + // 3. No includes have been specified and excludes have been specified and candidate is not in + // excludes. + // 4. Both includes and excludes have been specified and candidate is in includes and not in + // excludes. + // + if (!hasIncludes() && !hasExcludes()) { + return true; // [+] (default) + } else if (hasIncludes() && !hasExcludes()) { + return include.contains(candidate.getClassName()); // [+/-] (included) + } else if (!hasIncludes() && hasExcludes()) { + return !exclude.contains(candidate.getClassName()); // [+/-] (excluded) + } else { + return include.contains(candidate.getClassName()) + && !exclude.contains(candidate.getClassName()); // [+/-] (override) + } + } + + protected String getIncludeOrExcludeReason(Candidate candidate) { + if (!hasIncludes() && !hasExcludes()) { + return "(default)"; // [+] (default) + } else if (hasIncludes() && !hasExcludes()) { + return "(included)"; + } else if (!hasIncludes() && hasExcludes()) { + return "(excluded)"; + } else { + return "(override)"; + } + } + + protected boolean hasIncludes() { + return include != null; + } + + protected boolean hasExcludes() { + return exclude != null; + } + + protected void readCandidates(File file, Set candidates) throws IOException { + LineNumberReader input; + String line; + + input = new LineNumberReader(new FileReader(file)); + while ((line = input.readLine()) != null) { + line = line.trim(); + + // Lines starting with # are considered comments. + if (!line.startsWith("#")) { + candidates.add(line); + } + } + input.close(); + } + + protected String firstUpper(String s) { + if (s == null) return null; + if (s.length() == 0) return ""; + return s.substring(0, 1).toUpperCase() + s.substring(1); + } + + protected Map findCandidateClasses(Model model, ErrorHandler errorHandler) { + Map candidates = new HashMap<>(); + + // Visit all beans created by JAXB processing. + for (CClassInfo classInfo : model.beans().values()) { + String className = classInfo.fullName(); + + // The candidate class must have exactly one property. + if (classInfo.getProperties().size() == 1) { + CPropertyInfo property = classInfo.getProperties().get(0); + + // The property must be a collection + if (property.isCollection()) { + if (property.ref().size() == 1) { + // We have a candidate class. + Candidate candidate = new Candidate(classInfo); + candidates.put(className, candidate); + writeDebug("Candidate found: " + candidate.getClassName() + ", " + candidate.getFieldName() + ", [" + candidate.getFieldTypeName() + "]"); + } + } + } + } + return candidates; + } + + protected void writeSummary(String s) { + if (summary != null) { + summary.println(s); + if (verbose) { + System.out.println(s); + } + } else if (verbose) { + System.out.println(s); + } + } + + protected void closeSummary() throws IOException { + if (summary != null) { + summary.close(); + } + } + + protected void writeDebug(String s) { + if (debugMode) { + System.out.println("DEBUG:" + s); + } + } + + protected static String elementName(CPropertyInfo property) { + try { + if (property instanceof CElementPropertyInfo) { + return ((CElementPropertyInfo) property).getTypes().get(0).getTagName().getLocalPart(); + } else { + return null; + } + } catch (Exception ex) { + return null; + } + } +} diff --git a/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/parentpointer/ParentPointerPlugin.java b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/parentpointer/ParentPointerPlugin.java new file mode 100644 index 000000000..e0fef5fb9 --- /dev/null +++ b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/parentpointer/ParentPointerPlugin.java @@ -0,0 +1,121 @@ +package org.jvnet.jaxb.plugin.parentpointer; + +import com.sun.codemodel.JDefinedClass; +import com.sun.codemodel.JExpr; +import com.sun.codemodel.JFieldVar; +import com.sun.codemodel.JMethod; +import com.sun.codemodel.JMod; +import com.sun.codemodel.JVar; +import com.sun.tools.xjc.Options; +import com.sun.tools.xjc.Plugin; +import com.sun.tools.xjc.outline.ClassOutline; +import com.sun.tools.xjc.outline.Outline; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.annotation.XmlTransient; +import org.jvnet.jaxb.lang.Child; +import org.xml.sax.ErrorHandler; + +import java.util.logging.Logger; + +/** + * @author gk5885 + * This plugin came from here : org.andromda.thirdparty.jaxb2_commons:parent-pointer-plugin:1.0 + */ +public class ParentPointerPlugin extends Plugin { + + protected final String OPTION_NAME = "Xparent-pointer"; + + private static final String className = Plugin.class.getName(); + + private static final Logger logger = Logger.getLogger(className); + + private static final String parentFieldName = "parent"; + + private static final String parentGetterName = "getParent"; + + private static final String parentSetterName = "setParent"; + + private static final String unmarshalCallbackName = "afterUnmarshal"; + + @Override + public String getOptionName() { + return OPTION_NAME; + } + + @Override + public String getUsage() { + return "-" + OPTION_NAME + " : Add a field that points to the parent object."; + } + + @Override + public boolean run(Outline outline, Options options, ErrorHandler errorHandler) { + logger.entering(className, "run"); + for (ClassOutline classOutline : outline.getClasses()) { + implementChild(outline, classOutline.implClass); + addUnmarshalCallback(outline, classOutline.implClass); + } + logger.exiting(className, "run", true); + return true; + } + + private void addParentField(JDefinedClass definedClass) { + logger.entering(className, "addParentField"); + JFieldVar parentField = definedClass.field(JMod.PRIVATE, Object.class, parentFieldName); + parentField.annotate(XmlTransient.class); + logger.exiting(className, "addParentField"); + } + + private void addParentGetter(Outline outline, JDefinedClass definedClass) { + logger.entering(className, "addParentGetter"); + JMethod getParentMethod = + definedClass.method(JMod.PUBLIC, Object.class, parentGetterName); + getParentMethod.body()._return(JExpr.ref(JExpr._this(), parentFieldName)); + getParentMethod + .javadoc() + .append( + "Gets the parent object in the object tree representing the unmarshalled xml document."); + getParentMethod.javadoc().addReturn().append("The parent object."); + logger.exiting(className, "addParentGetter"); + } + + private void addParentSetter(Outline outline, JDefinedClass definedClass) { + logger.entering(className, "addParentSetter"); + JMethod setParentMethod = + definedClass.method(JMod.PUBLIC, outline.getCodeModel().VOID, + parentSetterName); + JVar parentSetterVar = + setParentMethod.param(Object.class, parentFieldName); + setParentMethod.body().assign(JExpr.ref(JExpr._this(), parentFieldName), parentSetterVar); + logger.exiting(className, "addParentSetter"); + } + + private void addUnmarshalCallback(Outline outline, JDefinedClass definedClass) { + logger.entering(className, "addUnmarshalCallback"); + JMethod afterUnmarshalMethod = + definedClass.method(JMod.PUBLIC, outline.getCodeModel().VOID, + unmarshalCallbackName); + JVar unmarshallerVar = + afterUnmarshalMethod.param(Unmarshaller.class, "unmarshaller"); + JVar parentVar = + afterUnmarshalMethod.param(Object.class, parentFieldName); + afterUnmarshalMethod.body().invoke(parentSetterName).arg(parentVar); + afterUnmarshalMethod + .javadoc() + .append( + "This method is invoked by the JAXB implementation on each instance when unmarshalling completes."); + afterUnmarshalMethod.javadoc().addParam(unmarshallerVar).append( + "The unmarshaller that generated the instance."); + afterUnmarshalMethod.javadoc().addParam(parentVar).append( + "The parent object in the object tree."); + logger.exiting(className, "addUnmarshalCallback"); + } + + private void implementChild(Outline outline, JDefinedClass definedClass) { + logger.entering(className, "implementChild"); + definedClass._implements(Child.class); + addParentField(definedClass); + addParentGetter(outline, definedClass); + addParentSetter(outline, definedClass); + logger.exiting(className, "implementChild"); + } +} diff --git a/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/propertylistenerinjector/Customizations.java b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/propertylistenerinjector/Customizations.java new file mode 100644 index 000000000..4b6d551da --- /dev/null +++ b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/propertylistenerinjector/Customizations.java @@ -0,0 +1,11 @@ +package org.jvnet.jaxb.plugin.propertylistenerinjector; + +import javax.xml.namespace.QName; + +public class Customizations { + + public static String NAMESPACE_URI = "urn:jaxb.jvnet.org:plugin:propertyListenerInjector"; + + public static QName LISTENER_ELEMENT_NAME = new QName(NAMESPACE_URI, "listener"); + +} diff --git a/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/propertylistenerinjector/PropertyListenerInjectorPlugin.java b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/propertylistenerinjector/PropertyListenerInjectorPlugin.java new file mode 100644 index 000000000..7ba52cc13 --- /dev/null +++ b/jaxb-plugins-parent/jaxb-plugins/src/main/java/org/jvnet/jaxb/plugin/propertylistenerinjector/PropertyListenerInjectorPlugin.java @@ -0,0 +1,133 @@ +package org.jvnet.jaxb.plugin.propertylistenerinjector; + +import com.sun.codemodel.JDefinedClass; +import com.sun.codemodel.JExpr; +import com.sun.codemodel.JFieldVar; +import com.sun.codemodel.JInvocation; +import com.sun.codemodel.JMethod; +import com.sun.codemodel.JMod; +import com.sun.tools.xjc.Options; +import com.sun.tools.xjc.Plugin; +import com.sun.tools.xjc.model.CPluginCustomization; +import com.sun.tools.xjc.outline.ClassOutline; +import com.sun.tools.xjc.outline.Outline; +import com.sun.tools.xjc.util.DOMUtils; +import jakarta.xml.bind.annotation.XmlTransient; +import org.xml.sax.ErrorHandler; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.beans.VetoableChangeListener; +import java.beans.VetoableChangeSupport; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Collections; +import java.util.List; + +/** + * This Plugin will generate property change events on each setXXX. + * + * See the javadoc of {@link com.sun.tools.xjc.Plugin} for what those methods mean. + * + * @author Jerome Dochez + * This plugin came from here : org.andromda.thirdparty.jaxb2_commons:property-listener-injector:1.1 + */ +public class PropertyListenerInjectorPlugin extends Plugin { + + protected final String OPTION_NAME = "Xinject-listener-code"; + + public String getOptionName() { + return OPTION_NAME; + } + + public List getCustomizationURIs() { + return Collections.singletonList(Customizations.NAMESPACE_URI); + } + + public boolean isCustomizationTagName(String nsUri, String localName) { + return nsUri.equals(Customizations.LISTENER_ELEMENT_NAME.getNamespaceURI()) + && localName.equals(Customizations.LISTENER_ELEMENT_NAME.getLocalPart()); + } + + public String getUsage() { + return " -X" + OPTION_NAME + "\t: inject property change event support to setter methods"; + } + + // meat of the processing + public boolean run(Outline model, Options opt, ErrorHandler errorHandler) { + CPluginCustomization listener = model.getModel().getCustomizations().find(Customizations.NAMESPACE_URI, Customizations.LISTENER_ELEMENT_NAME.getLocalPart()); + String globalInterfaceSetting = VetoableChangeListener.class.getName(); + if (listener != null) { + listener.markAsAcknowledged(); + globalInterfaceSetting = DOMUtils.getElementText(listener.element); + } + + for (ClassOutline co : model.getClasses()) { + CPluginCustomization c = co.target.getCustomizations().find(Customizations.NAMESPACE_URI, Customizations.LISTENER_ELEMENT_NAME.getLocalPart()); + + String interfaceName; + if (c != null) { + c.markAsAcknowledged(); + interfaceName = DOMUtils.getElementText(c.element); + } else { + interfaceName = globalInterfaceSetting; + } + if (VetoableChangeListener.class.getName().equals(interfaceName)) { + addSupport(VetoableChangeListener.class, VetoableChangeSupport.class, co.implClass); + } + if (PropertyChangeListener.class.getName().equals(interfaceName)) { + addSupport(PropertyChangeListener.class, PropertyChangeSupport.class, co.implClass); + } + + } + + return true; + } + + private void addSupport(Class listener, Class support, JDefinedClass target) { + + // add the support field. + // JFieldVar field = target.field(JMod.PRIVATE|JMod.TRANSIENT, support, "support"); + JFieldVar field = target.field(JMod.PRIVATE, support, "support"); + + field.annotate(XmlTransient.class); + + // and initialize it.... + field.init(JExpr.direct("new " + support.getSimpleName() + "(this)")); + + // we need to hadd + for (Method method : support.getMethods()) { + if (Modifier.isPublic(method.getModifiers())) { + if (method.getName().startsWith("add")) { + // look if one of the parameters in the listnener class... + for (Class param : method.getParameterTypes()) { + if (param.getName().equals(listener.getName())) { + addMethod(method, target); + break; + } + } + } + if (method.getName().startsWith("remove")) { + // look if one of the parameters in the listnener class... + for (Class param : method.getParameterTypes()) { + if (param.getName().equals(listener.getName())) { + addMethod(method, target); + break; + } + } + } + } + } + } + + private void addMethod(Method method, JDefinedClass target) { + JMethod addListener = target.method(JMod.PUBLIC, method.getReturnType(), method.getName()); + Class params[] = method.getParameterTypes(); + + JInvocation inv = addListener.body().invoke(JExpr.ref("support"), method.getName()); + + for (int i=0; i + 4.0.0 + + org.jvnet.jaxb + jaxb-plugins-tests + 4.0.1-SNAPSHOT + + jaxb-plugins-test-booleangetter + jar + JAXB Tools :: JAXB Plugins :: Test [booleangetter] + + + org.jvnet.jaxb + jaxb-maven-plugin-testing + test + + + + test + + + org.jvnet.jaxb + jaxb-maven-plugin + + true + + -Xboolean-getter + + + + org.jvnet.jaxb + jaxb-plugins + + + + + + + diff --git a/jaxb-plugins-parent/tests/booleangetter/src/main/resources/Person.xsd b/jaxb-plugins-parent/tests/booleangetter/src/main/resources/Person.xsd new file mode 100644 index 000000000..1ee143788 --- /dev/null +++ b/jaxb-plugins-parent/tests/booleangetter/src/main/resources/Person.xsd @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxb-plugins-parent/tests/booleangetter/src/test/java/org/jvnet/jaxb/tests/booleangetter/PersonTest.java b/jaxb-plugins-parent/tests/booleangetter/src/test/java/org/jvnet/jaxb/tests/booleangetter/PersonTest.java new file mode 100644 index 000000000..bf65f1a5d --- /dev/null +++ b/jaxb-plugins-parent/tests/booleangetter/src/test/java/org/jvnet/jaxb/tests/booleangetter/PersonTest.java @@ -0,0 +1,15 @@ +package org.jvnet.jaxb.tests.booleangetter; + +import org.junit.Assert; +import org.junit.Test; + +import generated.Person; + +public class PersonTest { + + @Test + public void testPerson() { + Person p = new Person(); + Assert.assertEquals(false, p.getMailingAddressIdentical()); + } +} diff --git a/jaxb-plugins-parent/tests/booleangetter/src/test/resources/log4j.properties b/jaxb-plugins-parent/tests/booleangetter/src/test/resources/log4j.properties new file mode 100644 index 000000000..ca4ee5e2c --- /dev/null +++ b/jaxb-plugins-parent/tests/booleangetter/src/test/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootCategory=DEBUG, stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.target=system.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n diff --git a/jaxb-plugins-parent/tests/camelcase/pom.xml b/jaxb-plugins-parent/tests/camelcase/pom.xml new file mode 100644 index 000000000..44154ea48 --- /dev/null +++ b/jaxb-plugins-parent/tests/camelcase/pom.xml @@ -0,0 +1,41 @@ + + 4.0.0 + + org.jvnet.jaxb + jaxb-plugins-tests + 4.0.1-SNAPSHOT + + jaxb-plugins-test-camelcase + jar + JAXB Tools :: JAXB Plugins :: Test [camelcase] + + + org.jvnet.jaxb + jaxb-maven-plugin-testing + test + + + + test + + + org.jvnet.jaxb + jaxb-maven-plugin + + true + + -Xcamelcase + + + + org.jvnet.jaxb + jaxb-plugins + + + + + + + diff --git a/jaxb-plugins-parent/tests/camelcase/src/main/resources/Person.xsd b/jaxb-plugins-parent/tests/camelcase/src/main/resources/Person.xsd new file mode 100644 index 000000000..cae2d4953 --- /dev/null +++ b/jaxb-plugins-parent/tests/camelcase/src/main/resources/Person.xsd @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxb-plugins-parent/tests/camelcase/src/test/java/org/jvnet/jaxb/tests/camelcase/AddressTest.java b/jaxb-plugins-parent/tests/camelcase/src/test/java/org/jvnet/jaxb/tests/camelcase/AddressTest.java new file mode 100644 index 000000000..e9edf2c83 --- /dev/null +++ b/jaxb-plugins-parent/tests/camelcase/src/test/java/org/jvnet/jaxb/tests/camelcase/AddressTest.java @@ -0,0 +1,18 @@ +package org.jvnet.jaxb.tests.camelcase; + +import org.junit.Assert; +import org.junit.Test; + +import generated.Address; + +public class AddressTest { + + @Test + public void testAddress() { + Address a = new Address(); + // No plugin default-value present, checking everything is null or default java value + Assert.assertEquals(0, a.getNumber()); + Assert.assertNull(a.getCareOf()); + Assert.assertNull(a.getStreet()); + } +} diff --git a/jaxb-plugins-parent/tests/camelcase/src/test/java/org/jvnet/jaxb/tests/camelcase/PersonTest.java b/jaxb-plugins-parent/tests/camelcase/src/test/java/org/jvnet/jaxb/tests/camelcase/PersonTest.java new file mode 100644 index 000000000..0b1ac84a9 --- /dev/null +++ b/jaxb-plugins-parent/tests/camelcase/src/test/java/org/jvnet/jaxb/tests/camelcase/PersonTest.java @@ -0,0 +1,15 @@ +package org.jvnet.jaxb.tests.camelcase; + +import org.junit.Assert; +import org.junit.Test; + +import generated.Person; + +public class PersonTest { + + @Test + public void testPerson() { + Person p = new Person(); + Assert.assertEquals(false, p.isMailingAddressIdentical()); + } +} diff --git a/jaxb-plugins-parent/tests/camelcase/src/test/resources/log4j.properties b/jaxb-plugins-parent/tests/camelcase/src/test/resources/log4j.properties new file mode 100644 index 000000000..ca4ee5e2c --- /dev/null +++ b/jaxb-plugins-parent/tests/camelcase/src/test/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootCategory=DEBUG, stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.target=system.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n diff --git a/jaxb-plugins-parent/tests/elementwrapper/pom.xml b/jaxb-plugins-parent/tests/elementwrapper/pom.xml new file mode 100644 index 000000000..342e8188f --- /dev/null +++ b/jaxb-plugins-parent/tests/elementwrapper/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + + org.jvnet.jaxb + jaxb-plugins-tests + 4.0.1-SNAPSHOT + + jaxb-plugins-test-elementwrapper + jar + JAXB Tools :: JAXB Plugins :: Test [element-wrapper] + + + org.jvnet.jaxb + jaxb-maven-plugin-testing + test + + + org.jvnet.jaxb + jaxb-plugins-runtime + + + + test + + + org.jvnet.jaxb + jaxb-maven-plugin + + true + + -XelementWrapper + -XelementWrapper:delete + + + + org.jvnet.jaxb + jaxb-plugins + + + + + + + diff --git a/jaxb-plugins-parent/tests/elementwrapper/src/main/resources/example.xsd b/jaxb-plugins-parent/tests/elementwrapper/src/main/resources/example.xsd new file mode 100644 index 000000000..77162fdb5 --- /dev/null +++ b/jaxb-plugins-parent/tests/elementwrapper/src/main/resources/example.xsd @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/jaxb-plugins-parent/tests/parentpointer/pom.xml b/jaxb-plugins-parent/tests/parentpointer/pom.xml new file mode 100644 index 000000000..2772d5c87 --- /dev/null +++ b/jaxb-plugins-parent/tests/parentpointer/pom.xml @@ -0,0 +1,41 @@ + + 4.0.0 + + org.jvnet.jaxb + jaxb-plugins-tests + 4.0.1-SNAPSHOT + + jaxb-plugins-test-parentpointer + jar + JAXB Tools :: JAXB Plugins :: Test [parentpointer] + + + org.jvnet.jaxb + jaxb-maven-plugin-testing + test + + + + test + + + org.jvnet.jaxb + jaxb-maven-plugin + + true + + -Xparent-pointer + + + + org.jvnet.jaxb + jaxb-plugins + + + + + + + diff --git a/jaxb-plugins-parent/tests/parentpointer/src/main/resources/Person.xsd b/jaxb-plugins-parent/tests/parentpointer/src/main/resources/Person.xsd new file mode 100644 index 000000000..8d35ae415 --- /dev/null +++ b/jaxb-plugins-parent/tests/parentpointer/src/main/resources/Person.xsd @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxb-plugins-parent/tests/parentpointer/src/test/java/org/jvnet/jaxb/tests/parentpointer/AddressTest.java b/jaxb-plugins-parent/tests/parentpointer/src/test/java/org/jvnet/jaxb/tests/parentpointer/AddressTest.java new file mode 100644 index 000000000..096a655f9 --- /dev/null +++ b/jaxb-plugins-parent/tests/parentpointer/src/test/java/org/jvnet/jaxb/tests/parentpointer/AddressTest.java @@ -0,0 +1,17 @@ +package org.jvnet.jaxb.tests.parentpointer; + +import generated.Person; +import org.junit.Assert; +import org.junit.Test; + +import generated.Address; + +public class AddressTest { + + @Test + public void testAddress() { + Address a = new Address(); + a.setParent(new Person()); + Assert.assertNotNull(a.getParent()); + } +} diff --git a/jaxb-plugins-parent/tests/parentpointer/src/test/resources/log4j.properties b/jaxb-plugins-parent/tests/parentpointer/src/test/resources/log4j.properties new file mode 100644 index 000000000..ca4ee5e2c --- /dev/null +++ b/jaxb-plugins-parent/tests/parentpointer/src/test/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootCategory=DEBUG, stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.target=system.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n diff --git a/jaxb-plugins-parent/tests/pom.xml b/jaxb-plugins-parent/tests/pom.xml index 25ba55f01..60ce30945 100644 --- a/jaxb-plugins-parent/tests/pom.xml +++ b/jaxb-plugins-parent/tests/pom.xml @@ -14,8 +14,11 @@ true + booleangetter + camelcase commons_lang defaultvalue + elementwrapper episodes ignoring issues @@ -23,8 +26,10 @@ JAXB-1058 namespace one + parentpointer po po-2.3 + propertylistenerinjector qa-simple qa-strategic simple-hashCode-equals-01 diff --git a/jaxb-plugins-parent/tests/propertylistenerinjector/pom.xml b/jaxb-plugins-parent/tests/propertylistenerinjector/pom.xml new file mode 100644 index 000000000..8df55c614 --- /dev/null +++ b/jaxb-plugins-parent/tests/propertylistenerinjector/pom.xml @@ -0,0 +1,41 @@ + + 4.0.0 + + org.jvnet.jaxb + jaxb-plugins-tests + 4.0.1-SNAPSHOT + + jaxb-plugins-test-propertylistenerinjector + jar + JAXB Tools :: JAXB Plugins :: Test [propertylistenerinjector] + + + org.jvnet.jaxb + jaxb-maven-plugin-testing + test + + + + test + + + org.jvnet.jaxb + jaxb-maven-plugin + + true + + -Xinject-listener-code + + + + org.jvnet.jaxb + jaxb-plugins + + + + + + + diff --git a/jaxb-plugins-parent/tests/propertylistenerinjector/src/main/resources/Person.xsd b/jaxb-plugins-parent/tests/propertylistenerinjector/src/main/resources/Person.xsd new file mode 100644 index 000000000..8d35ae415 --- /dev/null +++ b/jaxb-plugins-parent/tests/propertylistenerinjector/src/main/resources/Person.xsd @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxb-plugins-parent/tests/propertylistenerinjector/src/main/resources/binding.xjb b/jaxb-plugins-parent/tests/propertylistenerinjector/src/main/resources/binding.xjb new file mode 100644 index 000000000..e0338dd35 --- /dev/null +++ b/jaxb-plugins-parent/tests/propertylistenerinjector/src/main/resources/binding.xjb @@ -0,0 +1,15 @@ + + + + + java.beans.PropertyChangeListener + + + diff --git a/jaxb-plugins-parent/tests/propertylistenerinjector/src/test/java/org/jvnet/jaxb/tests/propertylistenerinjector/AddressTest.java b/jaxb-plugins-parent/tests/propertylistenerinjector/src/test/java/org/jvnet/jaxb/tests/propertylistenerinjector/AddressTest.java new file mode 100644 index 000000000..624ac701e --- /dev/null +++ b/jaxb-plugins-parent/tests/propertylistenerinjector/src/test/java/org/jvnet/jaxb/tests/propertylistenerinjector/AddressTest.java @@ -0,0 +1,16 @@ +package org.jvnet.jaxb.tests.propertylistenerinjector; + +import org.junit.Test; + +import generated.Address; + +public class AddressTest { + + @Test + public void testAddress() { + Address a = new Address(); + // just checking new methods have been added + a.addPropertyChangeListener(null); + a.removePropertyChangeListener(null); + } +} diff --git a/jaxb-plugins-parent/tests/propertylistenerinjector/src/test/resources/log4j.properties b/jaxb-plugins-parent/tests/propertylistenerinjector/src/test/resources/log4j.properties new file mode 100644 index 000000000..ca4ee5e2c --- /dev/null +++ b/jaxb-plugins-parent/tests/propertylistenerinjector/src/test/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootCategory=DEBUG, stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.target=system.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n