Package com.totsp.gwittir.client.beans.adapters

Source Code of com.totsp.gwittir.client.beans.adapters.BindableAdapter$MethodWrapper

/*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/
package com.totsp.gwittir.client.beans.adapters;

import com.totsp.gwittir.client.beans.BeanDescriptor;
import com.totsp.gwittir.client.beans.Introspector;
import com.totsp.gwittir.client.beans.Method;
import com.totsp.gwittir.client.beans.Property;
import com.totsp.gwittir.client.beans.SelfDescribed;
import com.totsp.gwittir.client.beans.SourcesPropertyChangeEvents;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import java.util.HashMap;
import java.util.Map;


/**
* This is an abstract class for creating Adapters for @Introspectable types that
* do not source PropertyChangeEvents.
*
* @author <a href="mailto:kebernet@gmail.com">Robert "kebernet" Cooper</a>
*/
public abstract class BindableAdapter implements SourcesPropertyChangeEvents, SelfDescribed {
    private BeanDescriptor descriptor;
    private Map<String, Object> values = new HashMap<String, Object>();
    private Object watched;
    private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
    private Property[] properties;

    public BindableAdapter(Object watched) {
        this.watched = watched;
        this.properties = Introspector.INSTANCE.getDescriptor(watched)
                                               .getProperties();
        initValues();
        initListener();
    }

    public BindableAdapter(Object watched, String... properties) {
        this.watched = watched;
        this.properties = new Property[properties.length];

        BeanDescriptor bd = Introspector.INSTANCE.getDescriptor(watched);

        for (int i = 0; i < properties.length; i++) {
            this.properties[i] = bd.getProperty(properties[i]);
        }

        initValues();
        initListener();
    }

    public PropertyChangeListener[] getPropertyChangeListeners() {
        return propertyChangeSupport.getPropertyChangeListeners();
    }

    /**
     * @return the watched
     */
    public Object getWatched() {
        return watched;
    }

    public BeanDescriptor __descriptor() {
        if (this.descriptor == null) { //No lazy thread issues in the browser;

            final Property[] wrappedProps = new Property[this.properties.length];

            for (int i = 0; i < this.properties.length; i++) {
                wrappedProps[i] = new Property(
                        this.properties[i].getName(),
                        this.properties[i].getType(),
                        (this.properties[i].getAccessorMethod() != null) ? new MethodWrapper(this.properties[i].getAccessorMethod()) : null,
                        (this.properties[i].getMutatorMethod() != null) ? new MethodWrapper(this.properties[i].getAccessorMethod()) : null);
            }

            this.descriptor = new BeanDescriptor() {
                        public Property[] getProperties() {
                            return wrappedProps;
                        }

                        public Property getProperty(String name) {
                            for (Property p : wrappedProps) {
                                if (p.getName()
                                         .equals(name)) {
                                    return p;
                                }
                            }

                            return null;
                        }
                    };
        }

        return this.descriptor;
    }

    public void addPropertyChangeListener(PropertyChangeListener l) {
        propertyChangeSupport.addPropertyChangeListener(l);
    }

    public void addPropertyChangeListener(String propertyName, PropertyChangeListener l) {
        propertyChangeSupport.addPropertyChangeListener(propertyName, l);
    }

    public void removePropertyChangeListener(PropertyChangeListener l) {
        propertyChangeSupport.removePropertyChangeListener(l);
    }

    public void removePropertyChangeListener(String propertyName, PropertyChangeListener l) {
        propertyChangeSupport.removePropertyChangeListener(propertyName, l);
    }

    public void update() {
        for (Property p : properties) {
            if (p.getAccessorMethod() == null) {
                continue;
            }

            try {
                Object old = this.values.get(p.getName());
                Object cur = p.getAccessorMethod()
                              .invoke(
                        this.getWatched(),
                        null);
                this.propertyChangeSupport.firePropertyChange(
                    p.getName(),
                    old,
                    cur);
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }

    protected abstract void initListener();

    protected void initValues() {
        try {
            for (Property p : this.properties) {
                if (p.getAccessorMethod() != null) {
                    values.put(
                        p.getName(),
                        p.getAccessorMethod().invoke(
                            this.getWatched(),
                            null));
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    protected abstract void stopListener();

    protected static class MethodWrapper implements Method {
        private Method internal;

        MethodWrapper(Method internal) {
            this.internal = internal;
        }

        public String getName() {
            return internal.getName();
        }

        public Object invoke(Object target, Object[] args)
            throws Exception {
            return internal.invoke(
                ((BindableAdapter) target).getWatched(),
                args);
        }
    }
}
TOP

Related Classes of com.totsp.gwittir.client.beans.adapters.BindableAdapter$MethodWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.