Demo
MOXy provides a class called JAXBHelper to easily obtain MOXy's implementation of JAXBContext. This exposes the refreshMetadata() method. The refreshMetadata() call does not affect any marshal or unmarshal operations that may currently be in progress, and once the refresh is complete the new metadata will be used.
package blog.metadatasource.refresh; import java.util.HashMap; import java.util.Map; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import org.eclipse.persistence.jaxb.JAXBContextFactory; import org.eclipse.persistence.jaxb.JAXBHelper; public class Demo { public static void main(String[] args) throws Exception { Map<String, Object> properties = new HashMap<String, Object>(1); ExtensionsMetadataSource extensions = new ExtensionsMetadataSource(); properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, extensions); JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class}, properties); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); Customer customer = new Customer(); customer.setFirstName("Jane"); customer.set("middleName", "Anne"); customer.setLastName("Doe"); Address billingAddress = new Address(); billingAddress.setStreet("123 Billing Address"); customer.setBillingAddress(billingAddress); Address shippingAddress = new Address(); shippingAddress.setStreet("456 Shipping Address"); customer.set("shippingAddress", shippingAddress); marshaller.marshal(customer, System.out); extensions.addXmlElement(Customer.class, "middleName", String.class); extensions.addXmlElement(Customer.class, "shippingAddress", Address.class); JAXBHelper.getJAXBContext(jc).refeshMetadata(); marshaller.marshal(customer, System.out); } }
Output
In the first document that is marshalled the extensions are not included, this is because the JAXBContext is not yet aware of the metadata. Once the metadata has been added and the JAXBContext refreshed the new properties are included. One thing to note is that we did not need to obtain a new instance of Marshaller.
<?xml version="1.0" encoding="UTF-8"?> <customer> <firstName>Jane</firstName> <lastName>Doe</lastName> <billingAddress> <street>123 Billing Address</street> </billingAddress> </customer> <?xml version="1.0" encoding="UTF-8"?> <customer> <firstName>Jane</firstName> <lastName>Doe</lastName> <billingAddress> <street>123 Billing Address</street> </billingAddress> <middleName>Anne</middleName> <shippingAddress> <street>456 Shipping Address</street> </shippingAddress> </customer>
ExtensionMetadataSource
package blog.metadatasource.refresh; import java.util.HashMap; import java.util.Map; import org.eclipse.persistence.jaxb.metadata.MetadataSourceAdapter; import org.eclipse.persistence.jaxb.xmlmodel.JavaType; import org.eclipse.persistence.jaxb.xmlmodel.JavaType.JavaAttributes; import org.eclipse.persistence.jaxb.xmlmodel.ObjectFactory; import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings; import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.JavaTypes; import org.eclipse.persistence.jaxb.xmlmodel.XmlElement; public class ExtensionsMetadataSource extends MetadataSourceAdapter { private ObjectFactory objectFactory; private Map<Class<?>, JavaType> javaTypes; private XmlBindings xmlBindings; public ExtensionsMetadataSource() { objectFactory = new ObjectFactory(); javaTypes = new HashMap<Class<?>, JavaType>(); xmlBindings = new XmlBindings(); xmlBindings.setPackageName("blog.metadatasource.refresh"); xmlBindings.setJavaTypes(new JavaTypes()); } @Override public XmlBindings getXmlBindings(Map<String, ?> properties, ClassLoader classLoader) { return xmlBindings; } public JavaType getJavaType(Class<?> clazz) { JavaType javaType = javaTypes.get(clazz); if(null == javaType) { javaType = new JavaType(); javaType.setName(clazz.getSimpleName()); javaType.setJavaAttributes(new JavaAttributes()); xmlBindings.getJavaTypes().getJavaType().add(javaType); javaTypes.put(clazz, javaType); } return javaType; } public void addXmlElement(Class<?> domainClass, String propertyName, Class<?> type) { XmlElement xmlElement = new XmlElement(); xmlElement.setJavaAttribute(propertyName); xmlElement.setType(type.getName()); JavaType javaType = getJavaType(domainClass); javaType.getJavaAttributes().getJavaAttribute().add(objectFactory.createXmlElement(xmlElement)); } }
Customer
package blog.metadatasource.refresh; import java.util.HashMap; import java.util.Map; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import org.eclipse.persistence.oxm.annotations.XmlVirtualAccessMethods; @XmlRootElement @XmlType(propOrder={"firstName", "lastName", "address"}) @XmlVirtualAccessMethods public class Customer { private String firstName; private String lastName; private Address billingAddress; private Map<String, Object> extensions = new HashMap<String, Object>(); public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public Address getBillingAddress() { return billingAddress; } public void setBillingAddress(Address billingAddress) { this.billingAddress = billingAddress; } public Object get(String key) { return extensions.get(key); } public void set(String key, Object value) { extensions.put(key, value); } }
Address
package blog.metadatasource.refresh; public class Address { private String street; public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } }
Further Reading
If you enjoyed this post you may also be interested in:
Other articles related to new MOXy features in EclipseLink 2.3:
Other articles related to new MOXy features in EclipseLink 2.3:
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.