Is there a way to create an XML binding file from a class using MOXy?

I would like to use MOXy to marshal / non-marshal an object from existing classes.

I would like to know if there is a middle way to generate XML binding files (because I don't want to use annotations) from my classes.

Or do we need to do it all with our little hands :)?

+3


source to share


2 answers


By default, JAXB / MOXy does not require any metadata to be specified (see http://blog.bdoughan.com/2012/07/jaxb-no-annotations-required.html ). You only need to specify the metadata where you want to override the default behavior.

I guess your real question is the easiest way to create an external MOXy document. I am doing the following with Eclipse, possibly similar steps for your favorite IDE:



  • Get XML schema for MOXy mapping document

    <EclipseLink_Home>/xsds/eclipselink_oxm_2_5.xsd
    
          

  • Register XML schema with your IDE

    • Eclipse | Settings | XML | XML directory | Add to
  • Create an XML document in the IDE and specify the following as the root element.

    <xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"/>
    
          

  • Use the autocomplete feature provided by your IDE to generate an XML document.

+1


source


Another option is to create the jaxb classes and those who read the bindings (annotations) creating the external mapping (after which you can remove the annotations). PoC code:



    public class MoxyBindingGenerator {
    private static final String PACKAGE = "com.company.binding.jaxbclasses";
    private static ObjectFactory xmlBindingsFactory = new ObjectFactory();

    public static void main(String[] args) throws Exception {
        Collection<TypeInfo> typeInfos = readAnnotations();

        XmlBindings xmlBindings = xmlBindingsFactory.createXmlBindings();
        xmlBindings.setPackageName(PACKAGE);

        JavaTypes javaTypes = xmlBindingsFactory.createXmlBindingsJavaTypes();
        xmlBindings.setJavaTypes(javaTypes);
        List<JavaType> javaTypesList = javaTypes.getJavaType();

        XmlEnums xmlEnums = xmlBindingsFactory.createXmlBindingsXmlEnums();
        xmlBindings.setXmlEnums(xmlEnums);
        List<XmlEnum> xmlEnumsList = xmlEnums.getXmlEnum();

        typeInfos.stream().forEach(typeInfo -> {
            if (!typeInfo.isEnumerationType()) {
                fillJavaTypes(javaTypesList, typeInfo);
            }
            else {
                fillEnumTypes(xmlEnumsList, typeInfo);
            }
        });

        saveToFile(xmlBindings);
    }

    private static Collection<TypeInfo> readAnnotations() throws JAXBException, Exception {
        JAXBContext jaxbContext = (JAXBContext) javax.xml.bind.JAXBContext.newInstance(PACKAGE);
        Object contextState = getPrivateField(jaxbContext, "contextState");
        Generator generator = (Generator) getPrivateField(contextState, "generator");
        AnnotationsProcessor annotationsProcessor = generator.getAnnotationsProcessor();
        Collection<TypeInfo> typeInfos = annotationsProcessor.getTypeInfo().values();
        return typeInfos;
    }

    private static void fillEnumTypes(List<XmlEnum> xmlEnumsList, TypeInfo typeInfo) {
        EnumTypeInfo et = (EnumTypeInfo) typeInfo;

        XmlEnum xmlEnum = xmlBindingsFactory.createXmlEnum();
        xmlEnum.setJavaEnum(et.getJavaClassName());
        List<String> xmlEnumNames = et.getFieldNames();
        List<Object> xmlEnumValues = et.getXmlEnumValues();
        for (int i = 0; i < xmlEnumNames.size(); i++) {
            String xmlEnumName = xmlEnumNames.get(i);
            Object xmlEnumObject = xmlEnumValues.get(i);

            XmlEnumValue xmlEnumValue = xmlBindingsFactory.createXmlEnumValue();
            xmlEnumValue.setJavaEnumValue(xmlEnumName);
            xmlEnumValue.setValue(xmlEnumObject.toString());
            xmlEnum.getXmlEnumValue().add(xmlEnumValue);
        }
        xmlEnumsList.add(xmlEnum);
    }

    private static void fillJavaTypes(List<JavaType> javaTypesList, TypeInfo typeInfo) {
        JavaType javaType = xmlBindingsFactory.createJavaType();
        javaType.setName(typeInfo.getJavaClassName());
        fillXmlType(javaType, typeInfo);
        if (typeInfo.getXmlRootElement() != null) {
            XmlRootElement xmlRootElement = typeInfo.getXmlRootElement();
            xmlRootElement.setNamespace(null);
            javaType.setXmlRootElement(xmlRootElement);
        }
        JavaAttributes javaAttributes = xmlBindingsFactory.createJavaTypeJavaAttributes();
        javaType.setJavaAttributes(javaAttributes);
        List<JAXBElement<? extends JavaAttribute>> javaAttributeList = javaAttributes.getJavaAttribute();
        typeInfo.getNonTransientPropertiesInPropOrder().stream().forEach(field -> {
            fillFields(javaAttributeList, field);
        });
        javaTypesList.add(javaType);
    }

    private static void fillFields(List<JAXBElement<? extends JavaAttribute>> javaAttributeList, Property field) {
        if (field.getXmlElements() != null && field.getXmlElements().getXmlElement().size() > 0) {
            XmlElements xmlElements = xmlBindingsFactory.createXmlElements();
            xmlElements.setJavaAttribute(field.getPropertyName());
            List<XmlElement> elements = field.getXmlElements().getXmlElement();
            elements.stream().forEach(e -> {
                e.setDefaultValue(null);
                e.setNamespace(null);
                xmlElements.getXmlElement().add(e);
            });
            JAXBElement<XmlElements> value = xmlBindingsFactory.createXmlElements(xmlElements);
            javaAttributeList.add(value);
        }
        else if (!field.isAttribute()) {
            XmlElement value = xmlBindingsFactory.createXmlElement();
            value.setJavaAttribute(field.getPropertyName());
            value.setName(field.getSchemaName().getLocalPart());
            if (field.isNillable())
                value.setNillable(field.isNillable());
            if (field.isRequired())
                value.setRequired(field.isRequired());
            javaAttributeList.add(xmlBindingsFactory.createXmlElement(value));
        }
        else {
            XmlAttribute value = xmlBindingsFactory.createXmlAttribute();
            value.setJavaAttribute(field.getPropertyName());
            value.setName(field.getSchemaName().getLocalPart());
            javaAttributeList.add(xmlBindingsFactory.createXmlAttribute(value));
        }
    }

    private static void saveToFile(XmlBindings xmlBindings)
            throws JAXBException, PropertyException, FileNotFoundException, IOException {
        JAXBContext xmlModelJaxbContext =
            (JAXBContext) javax.xml.bind.JAXBContext.newInstance("org.eclipse.persistence.jaxb.xmlmodel");
        JAXBMarshaller marshaller = xmlModelJaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        FileOutputStream fos = new FileOutputStream(new File(System.getProperty("user.home"), "binding-imspoor-oxm.xml"));
        marshaller.marshal(xmlBindings, fos);
        fos.close();
    }

    private static void fillXmlType(JavaType javaType, TypeInfo typeInfo) {
        XmlType orgXmlType = typeInfo.getXmlType();
        if (orgXmlType != null) {
            boolean add = false;
            XmlType xmlType = xmlBindingsFactory.createXmlType();
            if (!StringUtils.isEmpty(orgXmlType.getName())) {
                xmlType.setName(orgXmlType.getName());
                add = true;
            }
            if (orgXmlType.getPropOrder() != null && orgXmlType.getPropOrder().size() > 1) {
                xmlType.getPropOrder().addAll(orgXmlType.getPropOrder());
                add = true;
            }
            if (add)
                javaType.setXmlType(xmlType);
        }
    }

    private static Object getPrivateField(Object obj, String fieldName) throws Exception {
        Field declaredField = obj.getClass().getDeclaredField(fieldName);
        declaredField.setAccessible(true);
        return declaredField.get(obj);
    }
}

      

0


source







All Articles