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 }