001    /*
002     * $Id: AbstractSerializableBean.java 3100 2008-10-14 22:33:10Z rah003 $
003     *
004     * Copyright 2008 Sun Microsystems, Inc., 4150 Network Circle,
005     * Santa Clara, California 95054, U.S.A. All rights reserved.
006     *
007     * This library is free software; you can redistribute it and/or
008     * modify it under the terms of the GNU Lesser General Public
009     * License as published by the Free Software Foundation; either
010     * version 2.1 of the License, or (at your option) any later version.
011     * 
012     * This library is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015     * Lesser General Public License for more details.
016     * 
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this library; if not, write to the Free Software
019     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020     */
021    package org.jdesktop.beans;
022    
023    import java.beans.PropertyChangeListener;
024    import java.beans.PropertyChangeSupport;
025    import java.beans.VetoableChangeListener;
026    import java.beans.VetoableChangeSupport;
027    import java.io.IOException;
028    import java.io.ObjectInputStream;
029    import java.io.ObjectOutputStream;
030    import java.io.Serializable;
031    
032    /**
033     * This subclass enhances {@code AbstractBean} by implementing the
034     * {@code Serializable} interface. {@code AbstractSerializableBean} correctly
035     * serializes all {@code Serializable} listeners that it contains. Implementors
036     * that need to extends {@code AbstractBean} or one of its subclasses and
037     * require serialization should use this class if possible. If it is not
038     * possible to extend this class, the implementation can guide implementors on
039     * how to properly serialize the listeners.
040     * 
041     * @author Karl George Schaefer
042     * 
043     * @see Serializable
044     * @see ObjectInputStream
045     * @see ObjectOutputStream
046     */
047    public abstract class AbstractSerializableBean extends AbstractBean implements
048            Serializable {
049        /**
050         * Creates a new instance of {@code AbstractSerializableBean}.
051         */
052        protected AbstractSerializableBean() {
053            super();
054        }
055    
056        /**
057         * Creates a new instance of {@code AbstractSerializableBean}, using the
058         * supplied support delegates. Neither of these may be {@code null}.
059         * 
060         * @param pcs
061         *            the property change support class to use
062         * @param vcs
063         *            the vetoable change support class to use
064         * @throws NullPointerException
065         *             if any parameter is {@code null}
066         */
067        protected AbstractSerializableBean(PropertyChangeSupport pcs,
068                VetoableChangeSupport vcs) {
069            super(pcs, vcs);
070        }
071    
072        private void writeObject(ObjectOutputStream s) throws IOException {
073            s.defaultWriteObject();
074    
075            for (PropertyChangeListener l : getPropertyChangeListeners()) {
076                if (l instanceof Serializable) {
077                    s.writeObject(l);
078                }
079            }
080    
081            for (VetoableChangeListener l : getVetoableChangeListeners()) {
082                if (l instanceof Serializable) {
083                    s.writeObject(l);
084                }
085            }
086    
087            s.writeObject(null);
088        }
089    
090        private void readObject(ObjectInputStream s) throws ClassNotFoundException,
091                IOException {
092            s.defaultReadObject();
093    
094            Object listenerOrNull;
095            while (null != (listenerOrNull = s.readObject())) {
096                if (listenerOrNull instanceof PropertyChangeListener) {
097                    addPropertyChangeListener((PropertyChangeListener) listenerOrNull);
098                } else if (listenerOrNull instanceof VetoableChangeListener) {
099                    addVetoableChangeListener((VetoableChangeListener) listenerOrNull);
100                }
101            }
102        }
103    }