Details

    • Type: Wish Wish
    • Status: Open Open
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None
    • JDK version and platform:
      Sun 1.5.06 Windows xp

      Description

      I create an ADD-On, i try to post on user ML but it was too large... so i create an account ad i post it as a Issue - Wish

      My Add-on that implements Element order and a lot of other features

      i see in the last SnapShot that someting was added... but my add on has something more
      here there's some explanation.. sorry but i'm italian ad the comments in code are in italian language.. i hope u understand the code with my little presentation

      private ConfigurableXStream getXStreamConfiguratoBasic()

      { ConfigurableXStream confXStream = new ConfigurableXStream(); logger.debug("Inizio configurazione MarshallingStrategy"); //this TreeNullSafeMarshallingStrategy simple test the null fields and puts them to a empty string ="" confXStream .setMarshallingStrategy(new TreeNullSafeMarshallingStrategy()); logger.debug("Inizio configurazione Mapper"); mapperProvider = confXStream.getMapperProvider(); //the mapperProvider contains some etended mapper that i'll use for my extensions attributeClassAliasingMapper = mapperProvider .getAttributeClassAliasingMapper(); fieldOrderMapper = mapperProvider.getFieldOrderMapper(); fieldOfClassDefaultValueMapper = mapperProvider .getFieldOfClassDefaultValueMapper(); fieldOfClassCustomConverterMapper = mapperProvider .getFieldOfClassCustomConverterMapper(); logger.debug("Inizio configurazione BasicConverter"); confXStream.registerConverter(new ConfigurableStringConverter()); ConfigurableReflectionConverter configurableReflectionConverter = new ConfigurableReflectionConverter( new ConfigurableReflectionProvider(confXStream .getMapperProvider())); confXStream.registerConverter(configurableReflectionConverter, XStream.PRIORITY_VERY_LOW); return confXStream; }

      //This permit to serialize field in desidered order, simply put the fieldname in order separeted by comma ","

      fieldOrderMapper
      .setFieldOrderList(
      RiepilogoMensile.class,
      "Sostituzione,Mese,DataGenerazione,OraGenerazione,ProgressivoGenerazione,Titolare");

      //for this i need ConfigurableReflectionProvider, this use OrderFieldDictionary instead of his parent FieldDictionary, but it's a lot inefficent since FieldDictionary give me only an //Iterator, please... in the next release give me //more access to the biuldmap method so i can implement a more efficent OrderFieldDictionary!!!!
      //ps this filters also the non serializable fields

      //ps in other case i need more access to some field/method

      //in ConfigurableReflectionConverter i added the suppport for a custom converter based on fieldname of class

      fieldOfClassCustomConverterMapper.addCustomConverterForFieldOfClass(
      sqlTimeFormatConverter, "oraEvento", Evento.class);

      //in ConfigurableReflectionConverter i added the suppport for a default value based on fieldname of class

      fieldOfClassDefaultValueMapper.addDefaultValueForFieldOfClass("G",
      "codiceTipoOrganizzatore", Organizzatore.class);

      //in ConfigurableReflectionConverter i added the suppport for a ParentTagAttribute on fieldname of class

      attributeClassAliasingMapper
      .addAliasForFieldOfClassToParentTagAttribute("Sostituzione",
      "Sostituzione", RiepilogoMensile.class);

      in this case i have

      <RiepilogoMensile Sostituzione="N" ...>

      //in ConfigurableReflectionConverter i added the suppport for a OwnTagAttribute on fieldname of class

      attributeClassAliasingMapper.addAliasForFieldOfClassToOwnTagAttribute(
      "codiceTipoOrganizzatore", "valore", Organizzatore.class);
      confXStream.aliasField("TipoOrganizzatore", Organizzatore.class,
      "codiceTipoOrganizzatore");

      in this case i have

      <Organizzatore>
      ....
      <TipoOrganizzatore valore="E"/>

      the field is serialized in a Empty tag with the alias name defined as usual, but this mapper define that his own tag has an attribute with the name

      //i extend omitField so i can simply put the fieldname to omit separeted by comma ","
      confXStream.omitFieldList(TitolareServizio.class,
      "idTitolareServizio,codiceTitolareServizio");

      I have to specify that i'm using XStream one way only: i serialize object to xml and never the opposite, since i need to comply to a dtd i added a lot of features to control XML output.

      I'm like to propose some Structural modifications: for example the mapper interface: i need to extend it and i don't find a way to "cast" my method inside this interface... so i propose the ExtendableMapper in the package npg.icecuber.xstream.mapper:

      public Converter getConverterForFieldOfTypeDefinedInClass(
      int converterType, String fieldName, Object value, Class fieldType,
      Class definedInClass);

      public void addConverterForFieldOfTypeDefinedInClass(int converterType,
      String fieldName, Object value, Class fieldType,
      Class definedInClass, Converter converter);

      public String getAliasForFieldOfTypeDefinedInClass(
      int AliasType, String fieldName, Object value, Class fieldType,
      Class definedInClass);

      public void addAliasForFieldOfTypeDefinedInClass(int converterType,
      String fieldName, Object value, Class fieldType,
      Class definedInClass, String alias);

      or even more generic:

      public Object getObjectFor(
      int objectType, Object[] param);

      public void addObjectFor(
      int objectType, Object[] param);

      but this is maybe too generic... but with this it's possible to extend mapper without add any other method!!!

      Another thing: the Converter and SingleValueConverter aren't compatible, so i write ConverterToSingleValueConverterWrapper and SingleValueConverterToConverterWrapper as u can imagine.. with this i can use a Converter as SingleValueConverter and the opposite. My opinion is that a Converter can be used in both cases: i defined an interface called MultiConverter:

      package npg.icecuber.xstream.converters;

      import com.thoughtworks.xstream.converters.MarshallingContext;
      import com.thoughtworks.xstream.converters.UnmarshallingContext;
      import com.thoughtworks.xstream.io.HierarchicalStreamReader;

      public interface MultiConverter {

      /**

      • Marshalls an Object into a value representation
      • @param obj
      • the Object to be converted
      • @param writer
      • @param context
      • A context that allows nested objects to be processed by
      • XStream.
      • @return A String with the value of the Object
        */
        public String toString(String fieldName, Object obj, Class fieldType,
        Class definedInClass, MarshallingContext context);

      /**

      • Unmarshalls an Object from its single value representation
      • @param str
      • the String with the single value of the Object
      • @return The Object
        */
        /**
      • Unmarshalls an Object from its value representation
      • @param str
      • @param reader
      • The stream to read the text from.
      • @param context
      • A context that allows nested objects to be processed by
      • XStream.
      • @return The resulting object.
        */
        public Object fromString(String str, HierarchicalStreamReader reader,
        UnmarshallingContext context);
        }

      for example : now i must write

      writer.startNode("CodiceOrdine");
      context.convertAnother(odp.getCodiceOrdinePosto());
      writer.endNode();

      i have no control over the type!!!! i see come java.util.date passed as timestamp!!!! and i can't hanbdle the fieldName or Class definedInClass... i think it's useful for get a custom converter....
      i prefer something like:

      writer.startNode("CodiceOrdine");
      writer.setValue(toString(fieldName, obj, fieldType, definedInClass, context));
      writer.endNode();

      because with this i can handle the Attribute case:

      writer.addAttribute(attributeName, toString(fieldName, obj, fieldType, definedInClass, context));

      with one type of converters without wrapper!!!

      The last thing... i added a separeted Visitor....

      package npg.icecuber.xstream.converters.reflection;
      public class ReflectionVisitor implements ReflectionProvider.Visitor

      {...}

      and a Configuration class that handle statically the configuration parameters.... for example if i need to filter cglib classes or implicit collections...

      I hope my work will be useful!!

      Bye!!!!

        Issue Links

          People

          • Assignee:
            Unassigned
            Reporter:
            Stefano Girotti
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated: