/*
 * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 * @test
 * @bug 4092905
 * @summary Tests that hasListeners() is not failed across serialization
 * @author Graham Hamilton
 */

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

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Test4092905 {
    private static final String PUBLIC = "public";
    private static final String PRIVATE = "private";

    public static void main(String[] args) {
        PropertyChangeSupport pcs = new PropertyChangeSupport(args);
        pcs.addPropertyChangeListener(PUBLIC, new PublicListener());
        pcs.addPropertyChangeListener(PRIVATE, new PrivateListener());

        if (!pcs.hasListeners(PUBLIC)) {
            throw new Error("no public listener");
        }
        if (!pcs.hasListeners(PRIVATE)) {
            throw new Error("no private listener");
        }

        try {
            // serialize into byte array
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream output = new ObjectOutputStream(baos);
            output.writeObject(pcs);
            output.flush();
            // deserialize from byte array
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream input = new ObjectInputStream(bais);
            pcs = (PropertyChangeSupport) input.readObject();
        } catch (Exception exception) {
            throw new Error("unexpected exception", exception);
        }

        if (!pcs.hasListeners(PUBLIC)) {
            throw new Error("no public listener");
        }
        if (pcs.hasListeners(PRIVATE)) {
            throw new Error("unexpected private listener");
        }
    }

    public static class PublicListener implements PropertyChangeListener, Serializable {
        public void propertyChange(PropertyChangeEvent event) {
        }
    }

    private static class PrivateListener implements PropertyChangeListener {
        public void propertyChange(PropertyChangeEvent event) {
        }
    }
}
