2009-09-03 3 views
4

Я хочу, чтобы иметь короткие имена классов, теперь я могу это сделать с псевдонимамиXSTREAM короткие динамические псевдонимы

XStream x = new XStream(); 
x.alias("dic", Dic.class); 

, но я должен определить псевдоним вручную для каждого класса, есть ли способ настроить XStream сделать это автоматически?

ответ

3

Внутри XStream использует свой интерфейс Mapper для обработки сопоставления классов и полей с их соответствующими именами в XML. Существует большое количество реализаций этого интерфейса. Сам класс XStream может принимать в своем конструкторе Mapper. Возможно, вы захотите проверить исходный код этого класса, чтобы увидеть, какая реализация Mapper используется по умолчанию, а затем написать собственную реализацию, которая автоматически сделает ваше псевдонимы для вас. ClassAliasingMapper выглядит, например, полезным.

+0

Это будет отлично работать, если у вас есть уникальный двунаправленный способ сопоставления классов с псевдонимами (например, если все сопоставленные классы находятся в одном и том же известном пакете). В противном случае это добавит еще один уровень косвенности, так как вам все равно нужно сообщить вашему картографу, как сопоставить псевдонимы классам. Я применяю это к моему сценарию, однако - это может отлично справиться с обстоятельствами OP. – ChssPly76

+2

Мне просто нужно превратить объекты (не мои) в xml, так что это может сработать. – IAdapter

5

Единственной альтернативой является использование XStream annotations:

package com.my.incredibly.long.package.name; 

@XStreamAlias("dic") 
public class Dic { 
    ... 

Затем в коде, где можно настроить XStream:

xstream.processAnnotations(Dic.class); 
// OR 
xstream.autodetectAnnotations(true); 

Проблема, однако, заключается в том, что для того, чтобы десериализации классы XStream должен знать свои псевдонимы уже, поэтому autodetectAnnotations(true) НЕ поможет, если вы не можете гарантировать, что вы сериализуете класс перед десериализацией. Плюс (и это может или не может быть для вас проблемой) вы вводите явную зависимость XStream с вашими объектами.

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

+1

классная идея, я мог бы даже получить это на объектах domian с заменой регулярных выражений @Entity, однако это не будет работать для меня на этот раз, THX в любом случае. – IAdapter

6

Они, как я решил это:

1.- Когда я создаю XStream я переопределить его метод wrapmapper

XStream xstream = new XStream() { 
    @Override 
    protected MapperWrapper wrapMapper(MapperWrapper next) { 
     return new MyClassAliasingMapper(next); 
    } 
}; 

2.- с

public class MyClassAliasingMapper extends ClassAliasingMapper { 

    public MyClassAliasingMapper(Mapper wrapped) { 
     super(wrapped); 
    } 

    @Override 
    public Class realClass(String elementName) { 
     try { 
      return <… your own class …> 
     } catch (Exception e) { 
      // do nothing we fall back on super's implementation 
     } 
     return super.realClass(elementName); 
    } 

    @Override 
    public String serializedClass(Class type) { 
     try { 
      return <… your own element name …> 
     } catch (Exception e) { 
      // do nothing we fall back on super's implementation 
     } 
     return super.serializedClass(type); 
    } 
}