2 Replies Latest reply: Feb 24, 2010 12:07 PM by 843807 RSS

    XMLEncoder on a singleton class

    cowwoc
      Hi,

      I'm trying to use XMLEncoder to encode my singleton class. It has a static getInstance() and JavaBeans properties. I created a PersistenceDelegate for it, but it doesn't seem to encode any of the bean properties. My PersistenceDelegate reads:

      new DefaultPersistenceDelegate()
      {
      protected Expression instantiate(Object oldInstance, Encoder out)
      {
      return new Expression(oldInstance, oldInstance.getClass(),
      "getInstance",
      null);
      }
      }

      and the resulting XML file contains:

      <?xml version="1.0" encoding="UTF-8"?>
      <java version="1.5.0" class="java.beans.XMLDecoder">
      <object class="com.tog.desktopbeautifier1.client.Settings" property="instance"/>
      </java>

      As you can see, it seems to encode "instance" which I don't want and it doesn't encode any of the other properties. Any ideas?

      Gili
        • 1. Re: XMLEncoder on a singleton class
          843807
          Since the singleton is still in the same version in memory when
          trying to persist, the comparison using the equals-method always returns true
          once the singleton has been constructed.

          Use this persistence-delegate instead:
          /*
           * Created on Oct 14, 2004
           *
           */
          package singletonPersistenceTest;
          
          import java.beans.BeanInfo;
          import java.beans.DefaultPersistenceDelegate;
          import java.beans.Encoder;
          import java.beans.Expression;
          import java.beans.IntrospectionException;
          import java.beans.Introspector;
          import java.beans.PropertyDescriptor;
          import java.beans.Statement;
          import java.lang.reflect.InvocationTargetException;
          import java.lang.reflect.Method;
          
          
          /**
           * 
           * @author Koen Casier
           */
          public class SingletonPersistenceDelegate extends DefaultPersistenceDelegate {
          
              /**
               * constructing a singleton instance using the getInstance-method 
               */
              protected Expression instantiate(Object oldInstance, Encoder out)
              {
                  return new Expression(oldInstance, oldInstance.getClass(), "getInstance", null);
              }
              
              /**
               * @see java.beans.DefaultPersistenceDelegate#initialize(java.lang.Class, java.lang.Object, java.lang.Object, java.beans.Encoder)
               */
              protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) {
                  try {
                      BeanInfo info = Introspector.getBeanInfo(type);
                      PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
                      for(int i=0;i<descriptors.length; i++){
                          Method readMethod = descriptors.getReadMethod();
          Method writeMethod = descriptors[i].getWriteMethod();
          if(writeMethod != null && readMethod != null){
          out.writeStatement(new Statement(newInstance, writeMethod.getName(), new Object[]{readMethod.invoke(oldInstance, new Object[]{})}));
          }
          }
          }
          catch(IntrospectionException e) {
          e.printStackTrace();
          }
          catch(IllegalArgumentException e) {
          e.printStackTrace();
          }
          catch(IllegalAccessException e) {
          e.printStackTrace();
          }
          catch(InvocationTargetException e) {
          e.printStackTrace();
          }
          }

          }



          This persistencedelegate does yet take notice of transient fields and might suffer from some other
          problems, but gives a fair overview of how to implement the extra behaviour.


          kind regards,
          • 2. Re: XMLEncoder on a singleton class
            843807
            Thanks Koen! This example is perfect and very generic. Is the only drawback that it will always write information and assume changes are made?