Property change listener helps us succeed when running next few functions beans
authorJaroslav Tulach <jtulach@netbeans.org>
Sun, 03 Aug 2014 18:27:17 +0200
branchbeans
changeset 7974c97b8860766
parent 796 77922b8f0e36
child 798 adea790315fc
Property change listener helps us succeed when running next few functions
json-beans/src/main/java/net/java/html/beans/JSONBeans.java
     1.1 --- a/json-beans/src/main/java/net/java/html/beans/JSONBeans.java	Sun Aug 03 18:04:06 2014 +0200
     1.2 +++ b/json-beans/src/main/java/net/java/html/beans/JSONBeans.java	Sun Aug 03 18:27:17 2014 +0200
     1.3 @@ -47,6 +47,8 @@
     1.4  import java.beans.IntrospectionException;
     1.5  import java.beans.Introspector;
     1.6  import java.beans.MethodDescriptor;
     1.7 +import java.beans.PropertyChangeEvent;
     1.8 +import java.beans.PropertyChangeListener;
     1.9  import java.beans.PropertyDescriptor;
    1.10  import java.lang.ref.Reference;
    1.11  import java.lang.ref.WeakReference;
    1.12 @@ -54,6 +56,8 @@
    1.13  import java.lang.reflect.Method;
    1.14  import java.util.HashMap;
    1.15  import java.util.Map;
    1.16 +import java.util.logging.Level;
    1.17 +import java.util.logging.Logger;
    1.18  import net.java.html.BrwsrCtx;
    1.19  import org.apidesign.html.json.spi.Proto;
    1.20  
    1.21 @@ -67,9 +71,23 @@
    1.22      
    1.23      public static void register(Class<?> javaBeanClass) throws IntrospectionException {
    1.24          BeanInfo bi = Introspector.getBeanInfo(javaBeanClass);
    1.25 -        Html4JavaType html4JavaType = new Html4JavaType(javaBeanClass, 
    1.26 +        Method addPCL;
    1.27 +        try {
    1.28 +            addPCL = javaBeanClass.getMethod("addPropertyChangeListener", PropertyChangeListener.class);
    1.29 +        } catch (NoSuchMethodException ex) {
    1.30 +            addPCL = null;
    1.31 +        }
    1.32 +        Method removePCL;
    1.33 +        try {
    1.34 +            removePCL = javaBeanClass.getMethod("removePropertyChangeListener", PropertyChangeListener.class);
    1.35 +        } catch (NoSuchMethodException ex) {
    1.36 +            removePCL = null;
    1.37 +        }
    1.38 +        Html4JavaType html4JavaType = new Html4JavaType(javaBeanClass,
    1.39              bi.getPropertyDescriptors(),
    1.40 -            bi.getMethodDescriptors()
    1.41 +            bi.getMethodDescriptors(),
    1.42 +            removePCL != null ? addPCL : null, 
    1.43 +            addPCL != null ? removePCL : null
    1.44          );
    1.45      }
    1.46      
    1.47 @@ -78,11 +96,14 @@
    1.48              new HashMap<Object, Reference<Proto>>();
    1.49          private final PropertyDescriptor[] properties;
    1.50          private final MethodDescriptor[] methods;
    1.51 +        private final Method addPCL;
    1.52 +        private final Method removePCL;
    1.53          
    1.54          Html4JavaType(
    1.55              Class<?> javaBeanClass, 
    1.56              PropertyDescriptor[] pd,
    1.57 -            MethodDescriptor[] md
    1.58 +            MethodDescriptor[] md,
    1.59 +            Method addPCL, Method removePCL
    1.60          ) {
    1.61              super(javaBeanClass, javaBeanClass, pd.length, md.length);
    1.62              this.properties = pd;
    1.63 @@ -93,6 +114,8 @@
    1.64              for (int i = 0; i < md.length; i++) {
    1.65                  registerFunction(md[i].getName(), i);
    1.66              }
    1.67 +            this.addPCL = addPCL;
    1.68 +            this.removePCL = removePCL;
    1.69          }
    1.70  
    1.71          @Override
    1.72 @@ -177,8 +200,46 @@
    1.73                  return p;
    1.74              }
    1.75              p = type.createProto(object, ctx);
    1.76 -            protos.put(object, new WeakReference<Proto>(p));
    1.77 +            final BeanRef br = new BeanRef(type, p);
    1.78 +            protos.put(object, br);
    1.79 +            if (type.addPCL != null) {
    1.80 +                br.initialize(object, type.addPCL);
    1.81 +            }
    1.82              return p;
    1.83          }
    1.84      }
    1.85 +    
    1.86 +    private static final class BeanRef 
    1.87 +    extends WeakReference<Proto> implements PropertyChangeListener {
    1.88 +        private final Html4JavaType type;
    1.89 +        
    1.90 +        public BeanRef(Html4JavaType type, Proto referent) {
    1.91 +            super(referent);
    1.92 +            this.type = type;
    1.93 +        }
    1.94 +        
    1.95 +        @Override
    1.96 +        public void propertyChange(PropertyChangeEvent evt) {
    1.97 +            String n = evt.getPropertyName();
    1.98 +            Proto proto = get();
    1.99 +            if (proto == null) {
   1.100 +                return;
   1.101 +            }
   1.102 +            for (int i = 0; i < type.properties.length; i++) {
   1.103 +                PropertyDescriptor p = type.properties[i];
   1.104 +                if (n == null || n.equals(p.getName())) {
   1.105 +                    proto.valueHasMutated(n, evt.getOldValue(), evt.getNewValue());
   1.106 +                }
   1.107 +            }
   1.108 +        }
   1.109 +
   1.110 +        final void initialize(Object object, Method addPCL) {
   1.111 +            try {
   1.112 +                addPCL.invoke(object, this);
   1.113 +            } catch (Exception ex) {
   1.114 +                throw new IllegalStateException(ex);
   1.115 +            }
   1.116 +        }
   1.117 +        
   1.118 +    }
   1.119  }