eclipselink / Moxy: наследование и перераспределение имени атрибута в зависимости от типа

Я столкнулся с проблемой маршаллинга / демаршаллинга, связанной с наследованием и полиморфизмом с использованием реализации MOXy JAXB и файла привязок внешних метаданных.

Я не могу контролировать файлы XML или классы моделей.

Внутри модели есть несколько классов, которые наследуют другие классы DTO. Вот пример среды, в которой я работаю. Этот пример здесь только для некоторой синтаксической цели, реальная среда включает вложенное наследование, коллекции и т. Д.:

Вот класс, который будет унаследован

  class A {

        private String name;

        public String getName(){
              return name;
        }

        public void setName(String value){
              name = value;
        }

  } 

Вот один унаследованный класс

  class B extends A {

        private String attrFromB;

        public String getAttrFromB(){
              return attrFromB;
        }

        public void setAttrFromB(String value){
              attrFromB = value;
        }
  } 

И другой

  class C extends A {

        private String attrFromC;

        public String getAttrFromC(){
              return attrFromC;
        }

        public void setAttrFromC(String value){
              attrFromC= value;
        }
  } 

Вот контейнерный класс

  class MyContainerClass{

        private A myObject;

        public A getMyObject(){
           return myObject;
        }

        public void setMyObject(A value){
           myObject = value;
        }
  }

Вот XML, который он должен создать в случае MyContainer, содержащего A

  <MyContainer>
        <MyObject nameA="foo" />
  </MyContainer>

MyContainer, содержащий B

  <MyContainer>
        <MyObject nameB="foo" attrFromB="bar" />
  </MyContainer>

, и MyContainer, содержащий C

  <MyContainer>
        <MyObject nameC="foo" attrFromC="bar" />
  </MyContainer>

Итак, вы уже можете видеть проблемы на горизонте ...

Вот файл сопоставления, который я бы написал:

  <?xml version="1.0"?>
     <xml-bindings 
        xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
        package-name="com.test.example"
        version="2.1">  

        <java-type name="A" xml-accessor-type="NONE">
           <xml-root-element name="MyObject" />
           <java-attributes>
              <xml-element java-attribute="name" xml-path="@nameA" />
           </java-attributes>
        </java-type>  

        <java-type name="B" xml-accessor-type="NONE">
           <xml-root-element name="MyObject" />
           <xml-see-also>
              com.test.example.A
           </xml.see.also>
           <java-attributes>
              <xml-element java-attribute="name" xml-path="@nameB" />
              <xml-element java-attribute="attrFromB" xml-path="@attrFromB" />
           </java-attributes>
        </java-type>

        <java-type name="C" xml-accessor-type="NONE">
           <xml-root-element name="MyObject" />
           <xml-see-also>
              com.test.example.A
           </xml.see.also>
           <java-attributes>
              <xml-element java-attribute="name" xml-path="@nameC" />
              <xml-element java-attribute="attrFromC" xml-path="@attrFromC" />
           </java-attributes>
        </java-type>

        <java-type name="MyContainer" xml-accessor-type="NONE">
           <xml-root-element name="MyContainer" />
           <java-attributes>
              <xml-element java-attribute="myObject" type="com.test.example.A" xml-path="MyObject" />
           </java-attributes>
        </java-type>

     </xml-bindings>

Первая проблема заключается в том, что если я привязываю классы таким образом, я получаю следующее исключение:

  [Exception [EclipseLink-44] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DescriptorException
  Exception Description: Missing class indicator field from database row [UnmarshalRecord()].

1-й вопрос : Я понимаю, что это нормально, Jaxb нужно каким-то образом определить тип атрибута MyContaioner.myObject. Проблема в том, что у меня нет доступа к входящим XML-файлам, поэтому я не могу добавлять к ним поля xsi: type. Есть ли способ определить класс по наличию в нем определенного атрибута? независимо от его стоимости. Если исходный xml содержит атрибут @attrFromC, я знаю, что объект должен быть типа C. Если он содержит attrFromB, это B.


Вторая проблема заключается в том, что атрибут «name» не существует внутри B и C, поэтому jaxb игнорирует их.

  --Ignoring attribute [name] on class [com.test.example.B] as no Property was generated for it.
  --Ignoring attribute [name] on class [com.test.example.C] as no Property was generated for it.

2-й вопрос : Другая проблема заключается в том, что я не знаю, способен ли Jaxb переопределять имена атрибутов xml, как это ожидается внутри файла XML (@nameA, @nameB и nameC все относятся к A.name), есть способ сделать это?

Заранее благодарим за уделенное время.

6
задан bdoughan 22 January 2012 в 11:53
поделиться