forked from highsource/jaxb-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue highsource#14. A plugin to fix JAXB-1058.
- Loading branch information
1 parent
4fd7b8d
commit dfa4a18
Showing
7 changed files
with
239 additions
and
2 deletions.
There are no files selected for viewing
100 changes: 100 additions & 0 deletions
100
basic/src/main/java/org/jvnet/jaxb2_commons/plugin/fixjaxb1058/FixJAXB1058Plugin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package org.jvnet.jaxb2_commons.plugin.fixjaxb1058; | ||
|
||
import org.jvnet.jaxb2_commons.reflection.util.Accessor; | ||
import org.jvnet.jaxb2_commons.reflection.util.FieldAccessor; | ||
import org.xml.sax.ErrorHandler; | ||
import org.xml.sax.SAXException; | ||
|
||
import com.sun.codemodel.JBlock; | ||
import com.sun.codemodel.JClass; | ||
import com.sun.codemodel.JExpr; | ||
import com.sun.codemodel.JFieldVar; | ||
import com.sun.codemodel.JMethod; | ||
import com.sun.codemodel.JMod; | ||
import com.sun.codemodel.JType; | ||
import com.sun.tools.xjc.Options; | ||
import com.sun.tools.xjc.Plugin; | ||
import com.sun.tools.xjc.generator.bean.field.DummyListField; | ||
import com.sun.tools.xjc.generator.bean.field.IsSetField; | ||
import com.sun.tools.xjc.outline.ClassOutline; | ||
import com.sun.tools.xjc.outline.FieldOutline; | ||
import com.sun.tools.xjc.outline.Outline; | ||
|
||
public class FixJAXB1058Plugin extends Plugin { | ||
|
||
@Override | ||
public String getOptionName() { | ||
return "XfixJAXB1058"; | ||
} | ||
|
||
@Override | ||
public String getUsage() { | ||
return " -XfixJAXB1058 : Fixes JAXB-1058 (see https://java.net/jira/browse/JAXB-1058)"; | ||
} | ||
|
||
private Accessor<JMethod> DummyListField_$get; | ||
private Accessor<FieldOutline> IsSetField_core; | ||
private Accessor<JFieldVar> AbstractListField_field; | ||
private Accessor<JClass> AbstractListField_listT; | ||
private Accessor<JClass> DummyListField_coreList; | ||
|
||
@Override | ||
public boolean run(Outline outline, Options opt, ErrorHandler errorHandler) | ||
throws SAXException { | ||
try { | ||
DummyListField_$get = new FieldAccessor<JMethod>( | ||
DummyListField.class, "$get", JMethod.class); | ||
|
||
IsSetField_core = new FieldAccessor<FieldOutline>(IsSetField.class, | ||
"core", FieldOutline.class); | ||
AbstractListField_field = new FieldAccessor<JFieldVar>( | ||
DummyListField.class.getSuperclass(), "field", | ||
JFieldVar.class); | ||
AbstractListField_listT = new FieldAccessor<JClass>( | ||
DummyListField.class.getSuperclass(), "listT", JClass.class); | ||
DummyListField_coreList = new FieldAccessor<JClass>( | ||
DummyListField.class, "coreList", | ||
JClass.class); | ||
} catch (Exception ex) { | ||
throw new SAXException("Could not create field accessors. " | ||
+ "This plugin can not be used in this environment.", ex); | ||
} | ||
|
||
for (ClassOutline classOutline : outline.getClasses()) { | ||
for (FieldOutline fieldOutline : classOutline.getDeclaredFields()) { | ||
fixFieldOutline(fieldOutline); | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
private void fixFieldOutline(FieldOutline fieldOutline) { | ||
if (fieldOutline instanceof DummyListField) { | ||
fixDummyListField((DummyListField) fieldOutline); | ||
} else if (fieldOutline instanceof IsSetField) { | ||
fixIsSetField((IsSetField) fieldOutline); | ||
} | ||
} | ||
|
||
private void fixDummyListField(DummyListField fieldOutline) { | ||
if (DummyListField_$get.get(fieldOutline) == null) { | ||
final JFieldVar field = AbstractListField_field.get(fieldOutline); | ||
final JType listT = AbstractListField_listT.get(fieldOutline); | ||
final JClass coreList = DummyListField_coreList | ||
.get(fieldOutline); | ||
final JMethod $get = fieldOutline.parent().implClass.method( | ||
JMod.PUBLIC, listT, "get" + | ||
fieldOutline.getPropertyInfo().getName(true)); | ||
JBlock block = $get.body(); | ||
block._if(field.eq(JExpr._null()))._then() | ||
.assign(field, JExpr._new(coreList)); | ||
block._return(JExpr._this().ref(field)); | ||
DummyListField_$get.set(fieldOutline, $get); | ||
} | ||
} | ||
|
||
private void fixIsSetField(IsSetField isSetField) { | ||
final FieldOutline core = IsSetField_core.get(isSetField); | ||
fixFieldOutline(core); | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
tests/JAXB-1058/src/test/java/org/jvnet/jaxb2_commons/tests/JAXB_1058/ExecuteJAXB1058.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package org.jvnet.jaxb2_commons.tests.JAXB_1058; | ||
|
||
import java.io.File; | ||
|
||
import org.junit.Test; | ||
|
||
import com.sun.codemodel.JCodeModel; | ||
import com.sun.tools.xjc.ConsoleErrorReporter; | ||
import com.sun.tools.xjc.ModelLoader; | ||
import com.sun.tools.xjc.Options; | ||
import com.sun.tools.xjc.model.Model; | ||
|
||
public class ExecuteJAXB1058 { | ||
|
||
@Test | ||
public void compilesContext_V_1_1_0() throws Exception { | ||
|
||
new File("target/generated-sources/xjc").mkdirs(); | ||
|
||
final String[] arguments = new String[] { "-xmlschema", | ||
new File("src/main/resources/schema.xsd").toURI().toString(), | ||
"-d", | ||
"target/generated-sources/xjc", | ||
"-XfixJAXB1058", | ||
"-extension", "-XtoString", | ||
"-Xequals", "-XhashCode", "-Xcopyable", "-Xmergeable"}; | ||
|
||
Options options = new Options(); | ||
options.parseArguments(arguments); | ||
ConsoleErrorReporter receiver = new ConsoleErrorReporter(); | ||
Model model = ModelLoader.load(options, new JCodeModel(), receiver); | ||
model.generateCode(options, receiver); | ||
com.sun.codemodel.CodeWriter cw = options.createCodeWriter(); | ||
model.codeModel.build(cw); | ||
} | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
tools/src/main/java/org/jvnet/jaxb2_commons/reflection/util/Accessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package org.jvnet.jaxb2_commons.reflection.util; | ||
|
||
public interface Accessor<T> { | ||
|
||
public T get(Object target); | ||
|
||
public void set(Object target, T value); | ||
|
||
} |
64 changes: 64 additions & 0 deletions
64
tools/src/main/java/org/jvnet/jaxb2_commons/reflection/util/FieldAccessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package org.jvnet.jaxb2_commons.reflection.util; | ||
|
||
import java.lang.reflect.Field; | ||
import java.text.MessageFormat; | ||
|
||
import org.apache.commons.lang3.Validate; | ||
|
||
public class FieldAccessor<T> implements Accessor<T> { | ||
|
||
private final Field field; | ||
|
||
public FieldAccessor(Class<?> theClass, String fieldName, Class<T> type) { | ||
try { | ||
this.field = theClass.getDeclaredField(fieldName); | ||
} catch (NoSuchFieldException nsfex) { | ||
throw new IllegalArgumentException(MessageFormat.format( | ||
"Could not retrieve the field [{0}] from the class [{1}].", | ||
fieldName, theClass), nsfex); | ||
|
||
} catch (SecurityException sex) { | ||
throw new IllegalArgumentException(MessageFormat.format( | ||
"Could not retrieve the field [{0}] from the class [{1}].", | ||
fieldName, theClass), sex); | ||
} | ||
|
||
if (!type.equals(this.field.getType())) { | ||
throw new IllegalArgumentException( | ||
MessageFormat | ||
.format("The fieldfield [{0}] does not have the expected type [{1}].", | ||
this.field, type)); | ||
} | ||
|
||
try { | ||
field.setAccessible(true); | ||
} catch (SecurityException sex) { | ||
throw new IllegalArgumentException( | ||
MessageFormat.format( | ||
"Could not make the field [{0}] of the class [{1}] accessible.", | ||
this.field, theClass), sex); | ||
} | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
@Override | ||
public T get(Object target) { | ||
Validate.notNull(target); | ||
try { | ||
return (T) field.get(target); | ||
} catch (IllegalAccessException iaex) { | ||
throw new IllegalArgumentException(iaex); | ||
} | ||
} | ||
|
||
@Override | ||
public void set(Object target, T value) { | ||
Validate.notNull(target); | ||
try { | ||
this.field.set(target, value); | ||
} catch (IllegalAccessException iaex) { | ||
throw new IllegalArgumentException(iaex); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
tools/src/test/java/org/jvnet/jaxb2_commons/reflection/util/test/FieldAccessorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package org.jvnet.jaxb2_commons.reflection.util.test; | ||
|
||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
import org.jvnet.jaxb2_commons.reflection.util.Accessor; | ||
import org.jvnet.jaxb2_commons.reflection.util.FieldAccessor; | ||
|
||
public class FieldAccessorTest { | ||
|
||
@Test | ||
public void testGetAndSet() throws URISyntaxException { | ||
final URI uri = new URI("urn:test"); | ||
|
||
final Accessor<String> schemeAccessor = new FieldAccessor<String>( | ||
URI.class, "scheme", String.class); | ||
|
||
Assert.assertEquals("urn", schemeAccessor.get(uri)); | ||
schemeAccessor.set(uri, "nru"); | ||
Assert.assertEquals("nru", schemeAccessor.get(uri)); | ||
Assert.assertEquals("nru", uri.getScheme()); | ||
|
||
} | ||
|
||
} |