Skip to content

Commit

Permalink
[#517] customize with mapinit:class local class for map type
Browse files Browse the repository at this point in the history
  • Loading branch information
laurentschoelens authored and mattrpav committed Apr 9, 2024
1 parent d1d8075 commit 14aeb02
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package org.jvnet.jaxb.plugin.map_init;

import com.sun.tools.xjc.model.CClassInfo;
import com.sun.tools.xjc.model.CPluginCustomization;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import org.glassfish.jaxb.runtime.v2.ContextFactory;
import org.jvnet.jaxb.util.CustomizationUtils;

import javax.xml.namespace.QName;

public class Customizations {
Expand All @@ -8,4 +15,33 @@ public class Customizations {

public static QName IGNORED_ELEMENT_NAME = new QName(NAMESPACE_URI, "ignored");

public static QName OBJECT_FACTORY_ELEMENT_NAME = new QName(NAMESPACE_URI, "objectFactory");

public static QName INIT_CLASS_ELEMENT_NAME = new QName(NAMESPACE_URI, "class");


private static final JAXBContext context;
static {
try {
context = ContextFactory.createContext(
org.jvnet.jaxb.plugin.map_init.ObjectFactory.class.getPackage().getName(),
ObjectFactory.class.getClassLoader(),
null);
} catch (JAXBException e) {
throw new ExceptionInInitializerError(e);
}
}

public static JAXBContext getContext() {
return context;
}

public static void _initClass(CClassInfo classInfo, String className) {
final InitClass initClass = new InitClass();
initClass.setClassName(className);
final CPluginCustomization customization = CustomizationUtils.marshal(getContext(), Customizations.INIT_CLASS_ELEMENT_NAME, initClass);
classInfo.getCustomizations().add(customization);
customization.markAsAcknowledged();

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.jvnet.jaxb.plugin.map_init;

import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlValue;
import jakarta.xml.bind.annotation.adapters.CollapsedStringAdapter;
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement(namespace = "urn:jaxb.jvnet.org:plugin:mapinit", name = "class")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class InitClass {

private String className;

@XmlValue
@XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
String getClassName() {
return className;
}

public void setClassName(String className) {
this.className = className;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JType;
import com.sun.tools.xjc.Options;
import com.sun.tools.xjc.model.CPluginCustomization;
import com.sun.tools.xjc.outline.ClassOutline;
import com.sun.tools.xjc.outline.FieldOutline;
import com.sun.tools.xjc.outline.Outline;
Expand All @@ -17,7 +18,9 @@
import org.jvnet.jaxb.plugin.ComposedIgnoring;
import org.jvnet.jaxb.plugin.CustomizedIgnoring;
import org.jvnet.jaxb.plugin.Ignoring;
import org.jvnet.jaxb.plugin.inheritance.ExtendsClass;
import org.jvnet.jaxb.plugin.util.FieldOutlineUtils;
import org.jvnet.jaxb.util.CustomizationUtils;
import org.xml.sax.ErrorHandler;

import javax.xml.namespace.QName;
Expand Down Expand Up @@ -80,23 +83,34 @@ private void generateMapInit(ClassOutline classOutline,

if (getter != null && getter.type().erasure().boxify().isAssignableFrom(codeModel.ref(Map.class))) {
final JFieldVar field = theClass.fields().get(fieldOutline.getPropertyInfo().getName(false));

final CPluginCustomization initClassCustomization = CustomizationUtils
.findCustomization(fieldOutline, Customizations.INIT_CLASS_ELEMENT_NAME);
String mapClassName = getMapClass();
if (initClassCustomization != null) {
final InitClass initClass = (InitClass) CustomizationUtils
.unmarshall(Customizations.getContext(), initClassCustomization);
if (initClass != null && initClass.getClassName() != null && !"".equals(initClass.getClassName())) {
mapClassName = initClass.getClassName();
}
}
if (field != null) {
getter.body().pos(0);
getter.body()._if(field.eq(JExpr._null()))._then()
.assign(field, newCoreMap(codeModel, getter.type().boxify().getTypeParameters()));
.assign(field, newCoreMap(codeModel, mapClassName, getter.type().boxify().getTypeParameters()));
}
}
}
}

private JExpression newCoreMap(JCodeModel codeModel, List<JClass> typeParameters) {
return JExpr._new(codeModel.ref(getMapClass()).narrow(typeParameters));
private JExpression newCoreMap(JCodeModel codeModel, String mapClassName, List<JClass> typeParameters) {
return JExpr._new(codeModel.ref(mapClassName).narrow(typeParameters));
}

private Ignoring ignoring = new ComposedIgnoring(
logger,
new CustomizedIgnoring(
org.jvnet.jaxb.plugin.map_init.Customizations.IGNORED_ELEMENT_NAME));
Customizations.IGNORED_ELEMENT_NAME));

public Ignoring getIgnoring() {
return ignoring;
Expand All @@ -109,6 +123,7 @@ public void setIgnoring(Ignoring ignoring) {
@Override
public Collection<QName> getCustomizationElementNames() {
return Arrays.asList(
org.jvnet.jaxb.plugin.map_init.Customizations.IGNORED_ELEMENT_NAME);
Customizations.IGNORED_ELEMENT_NAME,
Customizations.INIT_CLASS_ELEMENT_NAME);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.jvnet.jaxb.plugin.map_init;

import jakarta.xml.bind.annotation.XmlRegistry;

@XmlRegistry
public class ObjectFactory {

public InitClass createInitClass() {
return new InitClass();
}

public ObjectFactoryCustomization createObjectFactoryCustomization() {
return new ObjectFactoryCustomization();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.jvnet.jaxb.plugin.map_init;

import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlType;

@XmlRootElement(namespace = "urn:jaxb.jvnet.org:plugin:mapinit", name = "objectFactory")
@XmlType(propOrder = { "initClass" })
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
public class ObjectFactoryCustomization {

private InitClass initClass;

@XmlElement(namespace = "urn:jaxb.jvnet.org:plugin:mapinit", name = "class")
public InitClass getInitClass() {
return initClass;
}

public void setInitClass(InitClass initClass) {
this.initClass = initClass;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,28 @@
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="weakDataMap">
<xsd:annotation>
<xsd:appinfo>
<mapinit:class>java.util.WeakHashMap</mapinit:class>
<jaxb:property>
<jaxb:baseType name="java.util.Map&lt;String,Object&gt;" />
</jaxb:property>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="entry" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="key" minOccurs="0" type="xsd:string"/>
<xsd:element name="value" minOccurs="0" type="xsd:anyType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="ignoredDataMap">
<xsd:annotation>
<xsd:appinfo>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,28 @@
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="weakDataMap">
<xsd:annotation>
<xsd:appinfo>
<mapinit:class>java.util.WeakHashMap</mapinit:class>
<jaxb:property>
<jaxb:baseType name="java.util.Map&lt;String,Object&gt;" />
</jaxb:property>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="entry" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="key" minOccurs="0" type="xsd:string"/>
<xsd:element name="value" minOccurs="0" type="xsd:anyType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="ignoredDataMap">
<xsd:annotation>
<xsd:appinfo>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import org.jvnet.jaxb.example.defined.Employee;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.TreeMap;
import java.util.WeakHashMap;

public class EmployeeDefinedTest {

Expand All @@ -15,6 +15,8 @@ public void testEmployee() {
Employee a = new Employee();
Assert.assertNotNull(a.getDataMap());
Assert.assertTrue(a.getDataMap() instanceof TreeMap);
Assert.assertNotNull(a.getWeakDataMap());
Assert.assertTrue(a.getWeakDataMap() instanceof WeakHashMap);
Assert.assertNull(a.getIgnoredDataMap());
Assert.assertNull(a.getValue());
Assert.assertNotNull(a.getListValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.util.ArrayList;
import java.util.HashMap;
import java.util.WeakHashMap;

public class EmployeeUndefinedTest {

Expand All @@ -14,6 +15,8 @@ public void testEmployee() {
Employee a = new Employee();
Assert.assertNotNull(a.getDataMap());
Assert.assertTrue(a.getDataMap() instanceof HashMap);
Assert.assertNotNull(a.getWeakDataMap());
Assert.assertTrue(a.getWeakDataMap() instanceof WeakHashMap);
Assert.assertNull(a.getIgnoredDataMap());
Assert.assertNull(a.getValue());
Assert.assertNotNull(a.getListValue());
Expand Down

0 comments on commit 14aeb02

Please sign in to comment.