2014-04-03 4 views
0

Я пытаюсь создать @XmlAdapter для разделения слов в смешанном списке на объекты класса Wrapper под названием Word. Это поле также может содержать экземпляры расширения Word под названием Group.JAXB @XmlMixed и @XmlAdapter

Идея заключается в том, что это:

<span>Some text and a <g>group of words</g> and more<span> 

будет эквивалентно:

span.getContent().add(new Word("Some"); 
span.getContent().add(new Word("text"); 
span.getContent().add(new Word("and"); 
span.getContent().add(new Word("a"); 
span.getContent().add(new Group("group of words"); 
span.getContent().add(new Word("and"); 
span.getContent().add(new Word("more"); 

Я борюсь со всеми возможными комбинациями OX XmlMixed и XMLAdapter я могу думать, но не повезло!

Это мой адаптер, Новости из мира не работает на всех:

public class SpanAdapter extends XmlAdapter<List<Word>, List> { 

@Override 
public List<Word> marshal(List v) throws Exception { 
    List<Word> list = new ArrayList<>(); 
    for (Object o : v) { 
     if (o instanceof String) { 
      String s = (String) o; 
      StringTokenizer st = new StringTokenizer(s, " "); 
      while (st.hasMoreElements()) { 
       Word word = new Word(); 
       word.setValue(st.nextToken()); 
       list.add(word); 
      } 
     } else if (o instanceof Group) { 
      list.add((Group) o); 
     } 
    } 
    return list; 
} 

@Override 
public List unmarshal(List<Word> v) throws Exception { 
    List list = new ArrayList<>(); 
    for (Word w : v) { 
     if(w instanceof Group){ 
      list.add(w); 
     } else{ 
      list.add(w.getValue()+ " "); 
     } 
    } 
    return v; 
} 

} 

И мой пролет класс:

@XmlRootElement(name = "span") 
public class Span extends AudioComponent implements Item.Component { 

private List<Word> value = new ArrayList(); 

@XmlMixed 
@XmlElementRefs({ 
     @XmlElementRef(type = Group.class), 
     @XmlElementRef(type = Word.class) 
}) 
@XmlJavaTypeAdapter(SpanAdapter.class) 
public List<Word> getValue() { 
    return value; 
} 

public void setValue(List<Word> value) { 
    this.value = value; 
} 

} 

Слово и группа просто обертки String. Группа расширяет Word.

Я использую MOXY в случае, если это помогает.

Спасибо заранее!

ответ

1

В случае это помогает кто-нибудь:

мне удалось сделать это, установив адаптер в поле списка, содержащего элемент Span.

Настройка адаптера на уровне пакета или уровне класса Span не будет работать.

Также адаптер не конвертируется из списка в список, а из диапазона от Span и изменяет список внутри.

Конечная конфигурация:

Место, где я определяю адаптер:

@XmlElementRefs({ 
     @XmlElementRef(type = Span.class), 
     @XmlElementRef(type = Other.class), 
     @XmlElementRef(type = Another.class) 

}) 
@XmlJavaTypeAdapter(value = SpanAdapter.class) 
public List<Component> getComponents() { 
    if (components == null) components = new ArrayList(); 
    return components; 
} 

адаптер (не может сделать это из диапазона, чтобы охватить, потому что я использую его в поле списка, который может содержат другие классы):

public class SpanAdapter extends XmlAdapter<Object, Object> { 

@Override 
public Object unmarshal(Object o) throws Exception { 
    if (o instanceof Span) { 
     Span span = (Span) o; 
     List<Span.Component> list = new ArrayList<>(); 
     for (Object child : span.getValue()) { 
      if (child instanceof String) { 
       String s = (String) child; 
       for (String w : s.split(" ")) { 
        Word word = new Word(); 
        word.setValue(w.trim()); 
        list.add(word); 
       } 
      } else if (child instanceof Group) { 
       list.add((Group) child); 
      } 
     } 
     span.setValue(list); 
     return span; 
    } 
    return o; 
} 

@Override 
public Object marshal(Object o) throws Exception { 
    if(o instanceof Span) { 
     Span span = (Span) o; 
     List list = new ArrayList<>(); 
     Iterator<Span.Component> iterator = span.getValue().iterator(); 
     while (iterator.hasNext()) { 
      Span.Component w = iterator.next(); 
      if (w instanceof Group) { 
       list.add(w); 
      } else if (w instanceof Word) { 
       String value = ((Word) w).getValue(); 
       list.add(iterator.hasNext() ? value + " " : value); 
      } 
     } 
     span.setValue(list); 
     return span; 
    }else return o; 
} 
}