JaxB Referenzauflösung

Für das folgende Beispiel einer XML-Eingabe:

<Participants course="someCourse">
  <workers>
    <Worker ref="p3">
    <Worker ref="p2">
  </workers>
  <Trainer ref="p1"/>
</Participants>

<Group id="group1" name="some mixed Person group">
   <trainers>
     <Trainer id="p1" name="John Doe">
   </trainers>
   <workers>
     <Worker id="p2" name="Jim Scott">
     <Worker id="p3" name="Walter Peace">
   </workers>
</Group>

Ich versuche sicherzustellen, dass die Personenliste in den Teilnehmern auf die Personen verweist, die aus Gruppe 1 gelesen wurden. (Die verwendeten JaxB-Anmerkungen finden Sie in den folgenden Codefragmenten.) Dies ist nur ein Beispiel für den allgemeineren Ansatz, den ich suche. Ich muss generell in der Lage sein, den Attributen id = "" und ref = "" so zu folgen, dass die Listenelemente korrekt als Referenzen deklassiert werden.

Mit einem UnmarshalListener und zweimal Unmarshalling umgehe ich das Problem der Verweise vom ref-Attribut auf das id-Attribut. In der ersten Phase wird die Lookup-Map aus den ID-Attributen gefüllt. In der zweiten Phase werden die Refs nachgeschlagen. Leider schafft diese LösungKopien anstelle von Referenzen. Ich könnte das übergeordnete Objekt verwenden, um dieses Problem zu beheben, suche jedoch nach einer allgemeineren Lösung. Was wäre ein guter Weg, um die richtige Dereferenzierung mit ref / id-Attributen in der gezeigten Weise zu erreichen?

/**
 * intercept the unmarshalling
 */
public static class ModelElementMarshallerListener extends javax.xml.bind.Unmarshaller.Listener {

 public Map<String,Person> lookup=new HashMap<String,Person>();

 @Override
 public void afterUnmarshal(java.lang.Object target, java.lang.Object parent) {
  if (target instanceof Person) {
    person=(Person) target;
    if (person.getId()!=null) {
       lookup.put(person.getId(), person);
    }
    if (person.getRef()!=null) {
      if (lookup.containsKey(person.getRef())) {
        Person personRef=lookup.get(person.getRef());
        person.copyFrom(personRef);
        person.setRef(null);
      }
    }
   }
 }

}

@XmlRootElement(name="Participants")
public class Participants  {
  private List<Worker> workers;

 /**
   * getter for List<Worker> workers
   * @return workers
   */
  @XmlElementWrapper(name="workers")
  @XmlElement(name="Worker", type=Worker.class)
  public List<Worker> getWorkers() { 
    return workers; 
  }

...

}

@XmlRootElement(name="Group")
public class Group {

  private List<Worker> workers;

 /**
   * getter for List<Worker> workers
   * @return workers
   */
  @XmlElementWrapper(name="workers")
  @XmlElement(name="Worker", type=Worker.class)
  public List<Worker> getWorkers() { 
    return workers; 
  }
 ...

}
@XmlRootElement(name="Trainer")
public class Trainer extends Person {}


@XmlRootElement(name="Worker")
public class Worker extends Person {}

@XmlRootElement(name="Person")
public class Person {
 private String name;

 /**
   * getter for xsd:string/String name
   * @return name
   */
  @XmlAttribute(name="name")  
  public String getName() {
    return name;
  }

  public void setName(String name) {
     this.name=name;
  }
  private String ref;

 /**
   * getter for xsd:string/String id
   * @return id
   */
  @XmlAttribute(name="ref")  
  public String getRef() {
    return ref;
  }

  public void setRef(String ref) {
    this.ref=ref;
  }

  private String id;
 /**
   * getter for xsd:string/String id
   * @return id
   */
  @XmlAttribute(name="id")  
  @XmlID
  public String getId() { 
    this.id;
  }

  /**
   * setter for xsd:string/String id
   * @param pid - new value for id
   */
  public void setId(String pid) { 
    this.id=pid; 
  }
}

Antworten auf die Frage(1)

Ihre Antwort auf die Frage