2016-07-19 24 views
2

實體「消息」的XML描述。如何在xStream中指定接口的實現?

<Message id="11600005" name="some_name"> 
     <sourcePartitionId>11600</sourcePartitionId> 
     <destPartitionId>11700</destPartitionId> 
     <payloadId>1300005</payloadId> 
     <sourceUdp>1045</sourceUdp> 
     <destUdp>1046</destUdp> 
     <sourceIp>10.4.48.0</sourceIp> 
     <destIp>10.4.49.0</destIp> 
     <sourcePort id="1045" name="sp_q_1045_11600_11700_005"> 
      <type>Queuing</type> 
      <maxMessageSize>8192</maxMessageSize> 
      <characteristic>1</characteristic> 
     </sourcePort> 
     <destPort id="1046" name="dp_q_1045_1046_11600_11700_005"> 
      <type>Queuing</type> 
      <maxMessageSize>8192</maxMessageSize> 
      <characteristic>1</characteristic> 
     </destPort> 
    </Message> 

在字段sourcePortdestPort描述對象實現了接口ComPort

public interface ComPort { 

    enum PortType {Sampling, Queuing} 
    enum PortDirection {Rx,Tx} 

    public PortType getPortType(); 
    public PortDirection getPortDirection(); 

    public int getMaxMessageSize(); 
    public int getPortCharacteristic(); 

在界面有兩個實現:SamplingPortQueuingPort。主要差異 - 特徵領域。告訴我如何使基於<type>標記的xstream創建相應實現的實例?

重要的一點:這也是需要考慮的是,當sourcePort標籤 - 方向字段爲Tx,當destPort標籤 - 方向場Rx

回答

0

我想通了,這個問題我自己。 首先,你需要創建一個類轉換器:

public class ComPortConverter implements Converter { 

    @Override 
    public void marshal(Object o, HierarchicalStreamWriter out, MarshallingContext context) { 

     ComPort comPort = (ComPort)o;  

     if (comPort.getPortDirection()== ComPort.PortDirection.Tx){ 
      out.startNode("sourcePort"); 
     }else { 
      out.startNode("destPort"); 
     } 

     out.addAttribute("id",Integer.toString(comPort.getId())); 
     out.addAttribute("name", comPort.getName()); 

     out.startNode("type"); 
     out.setValue(comPort.getPortType().name()); 
     out.endNode(); 

     out.startNode("maxMessageSize"); 
     out.setValue(Integer.toString(comPort.getMaxMessageSize())); 
     out.endNode(); 

     out.startNode("characteristic"); 
     out.setValue(Integer.toString(comPort.getPortCharacteristic()));  
     out.endNode(); 
     out.close(); 
    } 

    @Override 
    public Object unmarshal(HierarchicalStreamReader in, UnmarshallingContext context) { 

     ComPort result; 
     ComPort.PortDirection direction=null; 

     if (in.getNodeName().equals("sourcePort")){ 
      direction = ComPort.PortDirection.Tx; 
     }else if (in.getNodeName().equals("destPort")){ 
      direction = ComPort.PortDirection.Rx; 
     } 
     int id = Integer.parseInt(in.getAttribute("id")); 
     String name = in.getAttribute("name"); 

     in.moveDown(); 
     if (in.getValue().equals("Sampling")) result = new SamplingPort(id,name); 
     else if(in.getValue().equals("Queuing")) result = new QueuingPort(id,name); 
     else throw new IllegalArgumentException("Illegal port type value"); 
     result.setPortDirection(direction); 
     in.moveUp(); 
     in.moveDown(); 
     result.setMaxMessageSize(Integer.parseInt(in.getValue())); 
     in.moveUp(); 
     in.moveDown(); 
     result.setPortCharacteristic(Integer.parseInt(in.getValue())); 
     in.moveUp(); 

     return result; 
    } 

    @Override 
    public boolean canConvert(Class type) { 
     return ComPort.class.isAssignableFrom(type); 
    } 
} 

然後,你需要註冊一個轉換器

public static MessagesStorage unmarshallingMessages(File file){ 
     XStream xStream = new XStream(); 
     xStream.processAnnotations(new Class[]{MessagesStorage.class,Message.class}); 
     xStream.registerConverter(new ComPortConverter()); 
     return (MessagesStorage) xStream.fromXML(file); 
    }