Path: blob/master/test/jdk/java/beans/PropertyChangeSupport/Test4682386.java
41149 views
/*1* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 468238626* @summary Tests for PropertyChangeSupport refactoring27* @author Mark Davidson28*/2930import java.beans.Beans;31import java.beans.IntrospectionException;32import java.beans.Introspector;33import java.beans.PropertyChangeEvent;34import java.beans.PropertyChangeListener;35import java.beans.PropertyChangeSupport;36import java.beans.PropertyDescriptor;3738import java.lang.reflect.Method;3940import javax.swing.JApplet;41import javax.swing.JButton;42import javax.swing.JCheckBox;43import javax.swing.JComboBox;44import javax.swing.JComponent;45import javax.swing.JLabel;46import javax.swing.JList;47import javax.swing.JMenuItem;48import javax.swing.JProgressBar;49import javax.swing.JTextArea;50import javax.swing.JTextPane;51import javax.swing.JTextField;52import javax.swing.JToolBar;53import javax.swing.JTabbedPane;54import javax.swing.JTree;55import javax.swing.JTable;5657/**58* This class tests the multi-threaded access to PropertyChangeSupport and59* will also use reflection to test propertyChanges on Swing components.60* <p/>61* There is no new functionality from the implementation of this RFE.62* Semantically, it should be equivalent.63*/64public class Test4682386 {65private static final String FOO = "foo";66private static final String BAR = "bar";6768private static final int NUM_LISTENERS = 100;69private static final boolean DEBUG = true;7071private static final Class[] TYPES = {72JApplet.class,73JButton.class,74JCheckBox.class,75JComboBox.class,76JLabel.class,77JList.class,78JMenuItem.class,79JProgressBar.class,80JTextArea.class,81JTextPane.class,82JTextField.class,83JToolBar.class,84JTabbedPane.class,85JTree.class,86JTable.class,87};8889public static void main(String[] args) {90testSwingProperties();9192// tests the multi-threaded access9394TestBean bean = new TestBean();9596Thread add = new Thread(new AddThread(bean));97Thread remove = new Thread(new RemoveThread(bean));98Thread prop = new Thread(new PropertyThread(bean));99100add.start();101prop.start();102remove.start();103}104105/**106* Should be exectuted with $JAVA_HOME/lib/dt.jar in the classpath107* so that there will be a lot more bound properties.108* <p/>109* This test isn't really appropriate for automated testing.110*/111private static void testSwingProperties() {112long start = System.currentTimeMillis();113for (Class type : TYPES) {114try {115Object bean = Beans.instantiate(type.getClassLoader(), type.getName());116117JComponent comp = (JComponent) bean;118for (int k = 0; k < NUM_LISTENERS; k++) {119comp.addPropertyChangeListener(new PropertyListener());120}121122for (PropertyDescriptor pd : getPropertyDescriptors(type)) {123if (pd.isBound()) {124if (DEBUG) {125System.out.println("Bound property found: " + pd.getName());126}127128Method read = pd.getReadMethod();129Method write = pd.getWriteMethod();130try {131write.invoke(132bean,133getValue(134pd.getPropertyType(),135read.invoke(bean)));136} catch (Exception ex) {137// do nothing - just move on.138if (DEBUG) {139System.out.println("Reflective method invocation Exception for " + type + " : " + ex.getMessage());140}141}142}143}144} catch (Exception ex) {145// do nothing - just move on.146if (DEBUG) {147System.out.println("Exception for " + type.getName() +148" : " + ex.getMessage());149}150}151}152System.out.println("Exec time (ms): " + (System.currentTimeMillis() - start));153}154155/**156* Gets a fake value from a type and old value;157*/158public static Object getValue(Class type, Object value) {159if (String.class.equals(type)) {160return "test string";161}162if (value instanceof Integer) {163Integer i = (Integer) value;164return Integer.valueOf(i + 1);165}166if (value instanceof Boolean) {167Boolean b = (Boolean) value;168return Boolean.valueOf(!b);169}170return null;171}172173public static PropertyDescriptor[] getPropertyDescriptors(Class type) {174try {175return Introspector.getBeanInfo(type).getPropertyDescriptors();176} catch (IntrospectionException exception) {177throw new Error("unexpected exception", exception);178}179}180181private static void sleep(long ms) {182try {183Thread.sleep(ms);184} catch (InterruptedException exception) {185}186}187188private static class AddThread implements Runnable {189private final TestBean bean;190191AddThread(TestBean bean) {192this.bean = bean;193}194195public void run() {196for (int i = 0; i < NUM_LISTENERS; i++) {197for (int j = 0; j < 10; j++) {198this.bean.addPropertyChangeListener(new PropertyListener());199}200if (DEBUG) {201System.out.println("10 listeners added");202}203sleep(25L);204}205}206}207208private static class RemoveThread implements Runnable {209private final TestBean bean;210211RemoveThread(TestBean bean) {212this.bean = bean;213}214215public void run() {216for (int k = 0; k < NUM_LISTENERS; k++) {217sleep(100L);218PropertyChangeListener[] listeners = this.bean.getPropertyChangeListners();219for (int i = listeners.length - 1; i >= 0; i--) {220this.bean.removePropertyChangeListener(listeners[i]);221}222if (DEBUG) {223System.out.println(listeners.length + " listeners removed");224}225}226}227}228229private static class PropertyThread implements Runnable {230private final TestBean bean;231232PropertyThread(TestBean bean) {233this.bean = bean;234}235236public void run() {237for (int i = 0; i < NUM_LISTENERS; i++) {238boolean flag = this.bean.isFoo();239this.bean.setFoo(!flag);240this.bean.setBar(Boolean.toString(flag));241if (DEBUG) {242System.out.println("Executed property changes");243}244sleep(40L);245}246}247}248249/**250* Handler for the property change events.251*/252private static class PropertyListener implements PropertyChangeListener {253public void propertyChange(PropertyChangeEvent event) {254// blank since this should execute as fast as possible.255}256}257258/**259* A simple bean to test multi-threaded acccess to the listeners.260*/261public static class TestBean {262private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);263private boolean foo;264private String bar;265266public void addPropertyChangeListener(PropertyChangeListener listener) {267this.pcs.addPropertyChangeListener(listener);268}269270public void removePropertyChangeListener(PropertyChangeListener listener) {271this.pcs.removePropertyChangeListener(listener);272}273274public PropertyChangeListener[] getPropertyChangeListners() {275return this.pcs.getPropertyChangeListeners();276}277278public boolean isFoo() {279return this.foo;280}281282public void setFoo(boolean foo) {283boolean old = this.foo;284this.foo = foo;285this.pcs.firePropertyChange(FOO, old, foo);286}287288public String getBar() {289return this.bar;290}291292public void setBar(String bar) {293String old = this.bar;294this.bar = bar;295this.pcs.firePropertyChange(BAR, old, bar);296}297}298}299300301