我们可以将 jaxb 上下文绑定保存到 oxm 元数据文件吗?

Can we save jaxb context bindings to oxm metadata file?

我们有机会从外部 oxm 文件初始化 jaxb 上下文

Map<String, Object> props = new HashMap<String, Object>(1);
props.put(JAXBContextProperties.OXM_METADATA_SOURCE, "oxm.xml");
JAXBContext jc = JAXBContextFactory.createContext(new Class[0], props, <ClassLoader>);

我们可以将当前的 jaxb 上下文 xml 绑定到 xml 吗?来自 jaxb 注释的上下文 类 (我有 jaxb.properties)

JAXBContext jc = JAXBContext.newInstance(new Class[]{...});

就像我将生成的模式保存到文件

jc.generateSchema(new SchemaOutputResolver(){...});

我需要编写我的模式的 oxm 文件,只有 date/time 表示不同。

我创建了从包中创建 oxm 的函数。它不完整,但做了我需要的一切,作为起点很好......

  public static void createOXM(Package pack, String filename)
    throws Exception
  {
    /*
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="eclipselink_oxm_2_4.xsd"
                  xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" package-name="<name>"
                  xml-mapping-metadata-complete="true" xml-accessor-type="NONE" xml-accessor-order="UNDEFINED">
    */

    org.eclipse.persistence.jaxb.xmlmodel.XmlBindings bindings =
      new org.eclipse.persistence.jaxb.xmlmodel.XmlBindings();

    bindings.setPackageName(pack.getName());
    bindings.setXmlMappingMetadataComplete(true);
    bindings.setXmlAccessorType(org.eclipse.persistence.jaxb.xmlmodel.XmlAccessType.NONE);
    bindings.setXmlAccessorOrder(org.eclipse.persistence.jaxb.xmlmodel.XmlAccessOrder.UNDEFINED);

    List<Class<?>> classes = getClassesForPackage(pack);

    for (Class<?> cls: classes)
    {
      int clsMod = cls.getModifiers();
      String clsName = cls.getName().replaceAll("[^\.]+\.", "");

      if (cls.isAnonymousClass() || !Modifier.isPublic(clsMod)) // Class etc...
        continue;

      if (cls.getAnnotation(XmlTransient.class) != null)
        continue;

      org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.JavaTypes javaTypes = bindings.getJavaTypes();

      if (javaTypes == null)
      {
        javaTypes = new org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.JavaTypes();
        bindings.setJavaTypes(javaTypes);
      }

      org.eclipse.persistence.jaxb.xmlmodel.JavaType javaType = new org.eclipse.persistence.jaxb.xmlmodel.JavaType();
      javaTypes.getJavaType().add(javaType);
      javaType.setName(clsName);

      XmlRootElement xmlRoot = cls.getAnnotation(XmlRootElement.class);
      if (xmlRoot != null)
      {
        org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement root =
          new org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement();
        javaType.setXmlRootElement(root);

        if (!"##default".equals(xmlRoot.name()))
          root.setName(xmlRoot.name());

        if (!"##default".equals(xmlRoot.namespace()))
          root.setNamespace(xmlRoot.namespace());
      }

      XmlType xmlType = cls.getAnnotation(XmlType.class);
      if (xmlType != null)
      {
        org.eclipse.persistence.jaxb.xmlmodel.XmlType type = new org.eclipse.persistence.jaxb.xmlmodel.XmlType();
        javaType.setXmlType(type);

        if (!"##default".equals(xmlType.name()))
          type.setName(xmlType.name());

        if (!"##default".equals(xmlType.namespace()))
          type.setNamespace(xmlType.namespace());

        String[] props = xmlType.propOrder();

        if (props != null && props.length > 0)
        {
          for (String prop: props)
            if (!prop.trim().isEmpty())
              type.getPropOrder().add(prop.trim());
        }
      }

      XmlAccessorType xmlAccType = cls.getAnnotation(XmlAccessorType.class);
      if (xmlAccType != null)
      {
        String accType = xmlAccType.value().name();
        javaType.setXmlAccessorType(org.eclipse.persistence.jaxb.xmlmodel.XmlAccessType.valueOf(accType));
      }

      if (cls.isEnum())
      {
        org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.XmlEnums enums = bindings.getXmlEnums();

        if (enums == null)
        {
          enums = new org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.XmlEnums();
          bindings.setXmlEnums(enums);
        }

        org.eclipse.persistence.jaxb.xmlmodel.XmlEnum en = new org.eclipse.persistence.jaxb.xmlmodel.XmlEnum();
        en.setJavaEnum(clsName);
        enums.getXmlEnum().add(en);

        XmlEnum xmlEnum = cls.getAnnotation(XmlEnum.class);
        if (xmlEnum != null)
        {
          Class<?> xmlClass = xmlEnum.value();

          if (xmlClass != String.class)
            en.setValue(xmlClass.getName());
        }

        for (Field field: cls.getDeclaredFields())
          if (field.isEnumConstant())
          {
            org.eclipse.persistence.jaxb.xmlmodel.XmlEnumValue value =
              new org.eclipse.persistence.jaxb.xmlmodel.XmlEnumValue();

            en.getXmlEnumValue().add(value);
            value.setJavaEnumValue(field.getName());
            value.setValue(field.getName());

            XmlEnumValue enumValue = field.getAnnotation(XmlEnumValue.class);

            if (enumValue != null)
              value.setValue(enumValue.value());
          }

        continue;
      }

      Class clsSuper = cls.getSuperclass();

      if (clsSuper.getPackage() == pack)
        javaType.setSuperType(clsSuper.getName());

      for (Field field: cls.getDeclaredFields())
      {
        org.eclipse.persistence.jaxb.xmlmodel.JavaType.JavaAttributes javaAttrs = javaType.getJavaAttributes();

        if (javaAttrs == null)
        {
          javaAttrs = new org.eclipse.persistence.jaxb.xmlmodel.JavaType.JavaAttributes();
          javaType.setJavaAttributes(javaAttrs);
        }

        XmlTransient xmlTrans = field.getAnnotation(XmlTransient.class);
        if (xmlTrans != null)
        {
          org.eclipse.persistence.jaxb.xmlmodel.XmlTransient attr =
            new org.eclipse.persistence.jaxb.xmlmodel.XmlTransient();
          attr.setJavaAttribute(field.getName());

          javaAttrs.getJavaAttribute().add(new JAXBElement(new QName("", "xml-transient"), attr.getClass(), attr));
          continue;
        }

        XmlValue xmlValue = field.getAnnotation(XmlValue.class);
        if (xmlValue != null)
        {
          org.eclipse.persistence.jaxb.xmlmodel.XmlValue attr = new org.eclipse.persistence.jaxb.xmlmodel.XmlValue();
          attr.setJavaAttribute(field.getName());

          javaAttrs.getJavaAttribute().add(new JAXBElement(new QName("", "xml-value"), attr.getClass(), attr));
          continue;
        }

        XmlAttribute xmlAttr = field.getAnnotation(XmlAttribute.class);
        if (xmlAttr != null)
        {
          org.eclipse.persistence.jaxb.xmlmodel.XmlAttribute attr =
            new org.eclipse.persistence.jaxb.xmlmodel.XmlAttribute();
          attr.setJavaAttribute(field.getName());

          if (!"##default".equals(xmlAttr.name()) && !field.getName().equals(xmlAttr.name()))
            attr.setName(xmlAttr.name());

          if (!"##default".equals(xmlAttr.namespace()))
            attr.setNamespace(xmlAttr.namespace());

          if (xmlAttr.required())
            attr.setRequired(true);

          XmlSchemaType xmlSchemaType = field.getAnnotation(XmlSchemaType.class);
          if (xmlSchemaType != null)
          {
            org.eclipse.persistence.jaxb.xmlmodel.XmlSchemaType schemaType =
              new org.eclipse.persistence.jaxb.xmlmodel.XmlSchemaType();

            attr.setXmlSchemaType(schemaType);
            schemaType.setName(xmlSchemaType.name());

            if (!"http://www.w3.org/2001/XMLSchema".equals(xmlSchemaType.namespace()))
              schemaType.setName(xmlSchemaType.namespace());

            if (xmlSchemaType.type() != XmlSchemaType.DEFAULT.class)
              schemaType.setType(xmlSchemaType.type().getName());
          }

          XmlJavaTypeAdapter xmlJavaTypeAdapter = field.getAnnotation(XmlJavaTypeAdapter.class);
          if (xmlJavaTypeAdapter != null)
          {
            org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter javaTypeAdapter =
              new org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter();

            attr.setXmlJavaTypeAdapter(javaTypeAdapter);

            if (xmlJavaTypeAdapter.value() != null)
              javaTypeAdapter.setValue(xmlJavaTypeAdapter.value().getName());

            if (xmlJavaTypeAdapter.type() != XmlJavaTypeAdapter.DEFAULT.class)
              javaTypeAdapter.setValue(xmlJavaTypeAdapter.type().getName());
          }

          javaAttrs.getJavaAttribute().add(new JAXBElement(new QName("", "xml-attribute"), attr.getClass(), attr));
          continue;
        }

        XmlElement xmlElem = field.getAnnotation(XmlElement.class);

        if (xmlElem != null && xmlAttr != null)
          throw new RuntimeException("XmlAttribute and XmlElement can be both");

        org.eclipse.persistence.jaxb.xmlmodel.XmlElement attr = new org.eclipse.persistence.jaxb.xmlmodel.XmlElement();
        attr.setJavaAttribute(field.getName());

        if (xmlElem != null)
        {
          if (!"##default".equals(xmlElem.name()) && !field.getName().equals(xmlElem.name()))
            attr.setName(xmlElem.name());

          if (!"##default".equals(xmlElem.namespace()))
            attr.setNamespace(xmlElem.namespace());

          if (!"\u0000".equals(xmlElem.defaultValue()))
            attr.setDefaultValue(xmlElem.defaultValue());

          if (xmlElem.required())
            attr.setRequired(true);

          if (xmlElem.nillable())
            attr.setNillable(true);
        }

        XmlElementWrapper xmlWrapper = field.getAnnotation(XmlElementWrapper.class);
        if (xmlWrapper != null)
        {
          org.eclipse.persistence.jaxb.xmlmodel.XmlElementWrapper elemWrapper =
            new org.eclipse.persistence.jaxb.xmlmodel.XmlElementWrapper();
          attr.setXmlElementWrapper(elemWrapper);

          if (!"##default".equals(xmlWrapper.name()))
            elemWrapper.setName(xmlWrapper.name());

          if (!"##default".equals(xmlWrapper.namespace()))
            elemWrapper.setNamespace(xmlWrapper.namespace());

          if (xmlWrapper.required())
            elemWrapper.setRequired(true);

          if (xmlWrapper.nillable())
            elemWrapper.setNillable(true);
        }

        XmlSchemaType xmlSchemaType = field.getAnnotation(XmlSchemaType.class);
        if (xmlSchemaType != null)
        {
          org.eclipse.persistence.jaxb.xmlmodel.XmlSchemaType schemaType =
            new org.eclipse.persistence.jaxb.xmlmodel.XmlSchemaType();

          attr.setXmlSchemaType(schemaType);
          schemaType.setName(xmlSchemaType.name());

          if (!"http://www.w3.org/2001/XMLSchema".equals(xmlSchemaType.namespace()))
            schemaType.setName(xmlSchemaType.namespace());

          if (xmlSchemaType.type() != XmlSchemaType.DEFAULT.class)
            schemaType.setType(xmlSchemaType.type().getName());
        }

        XmlJavaTypeAdapter xmlJavaTypeAdapter = field.getAnnotation(XmlJavaTypeAdapter.class);
        if (xmlJavaTypeAdapter != null)
        {
          org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter javaTypeAdapter =
            new org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter();

          attr.setXmlJavaTypeAdapter(javaTypeAdapter);

          if (xmlJavaTypeAdapter.value() != null)
            javaTypeAdapter.setValue(xmlJavaTypeAdapter.value().getName());

          if (xmlJavaTypeAdapter.type() != XmlJavaTypeAdapter.DEFAULT.class)
            javaTypeAdapter.setValue(xmlJavaTypeAdapter.type().getName());
        }

        javaAttrs.getJavaAttribute().add(new JAXBElement(new QName("", "xml-element"), attr.getClass(), attr));
      }
    }

    JAXBContext jc = JAXBContext.newInstance(bindings.getClass());
    Marshaller m = jc.createMarshaller();

    m.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
    m.setProperty(Marshaller.JAXB_FRAGMENT, false);
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    m.marshal(bindings, new File(filename));
  }

玩得开心!