1 /*
2  * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 import java.awt.Image;
25 import java.beans.BeanDescriptor;
26 import java.beans.BeanInfo;
27 import java.beans.EventSetDescriptor;
28 import java.beans.FeatureDescriptor;
29 import java.beans.IndexedPropertyDescriptor;
30 import java.beans.Introspector;
31 import java.beans.MethodDescriptor;
32 import java.beans.ParameterDescriptor;
33 import java.beans.PropertyDescriptor;
34 import java.lang.reflect.Array;
35 import java.lang.reflect.Method;
36 import java.net.URI;
37 import java.nio.file.FileSystem;
38 import java.nio.file.FileSystems;
39 import java.nio.file.FileVisitResult;
40 import java.nio.file.Files;
41 import java.nio.file.Path;
42 import java.nio.file.SimpleFileVisitor;
43 import java.nio.file.attribute.BasicFileAttributes;
44 import java.util.Arrays;
45 import java.util.Comparator;
46 import java.util.Enumeration;
47 import java.util.Map.Entry;
48 import java.util.Objects;
49 import java.util.TreeMap;
50 import java.util.TreeSet;
51 
52 /*
53  * @test
54  * @bug 4058433
55  * @summary Generates BeanInfo for public classes in AWT, Accessibility, and Swing
56  * @author Sergey Malenkov
57  */
58 public class Test4058433 implements Comparator<Object> {
59     @Override
compare(Object one, Object two)60     public int compare(Object one, Object two) {
61         if (one instanceof Method && two instanceof Method) {
62             Method oneMethod = (Method) one;
63             Method twoMethod = (Method) two;
64             int result = oneMethod.getName().compareTo(twoMethod.getName());
65             if (result != 0) {
66                 return result;
67             }
68         }
69         if (one instanceof FeatureDescriptor && two instanceof FeatureDescriptor) {
70             FeatureDescriptor oneFD = (FeatureDescriptor) one;
71             FeatureDescriptor twoFD = (FeatureDescriptor) two;
72             int result = oneFD.getName().compareTo(twoFD.getName());
73             if (result != 0) {
74                 return result;
75             }
76         }
77         return one.toString().compareTo(two.toString());
78     }
79 
main(String[] args)80     public static void main(String[] args) throws Exception {
81         FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
82         fs.getFileStores();
83 
84         TreeSet<Class<?>> types = new TreeSet<>(new Test4058433());
85         Files.walkFileTree(fs.getPath("/modules/java.desktop"), new SimpleFileVisitor<Path>() {
86             @Override
87             public FileVisitResult visitFile(Path file,
88                                              BasicFileAttributes attrs) {
89                 file = file.subpath(2, file.getNameCount());
90                 if (file.startsWith("java/awt/")
91                         || file.startsWith("javax/accessibility/")
92                         || file.startsWith("javax/swing/")) {
93                     String name =file.toString();
94                     if (name.endsWith(".class")) {
95                         name = name.substring(0, name.indexOf(".")).replace('/', '.');
96 
97                         final Class<?> type;
98                         try {
99                             type = Class.forName(name);
100                         } catch (ClassNotFoundException e) {
101                             throw new RuntimeException(e);
102                         }
103                         if (!BeanInfo.class.isAssignableFrom(type) && !type.isInterface()
104                             && !type.isEnum() && !type.isAnnotation()
105                             && !type.isAnonymousClass()) {
106                             if (null == type.getDeclaringClass()) {
107                                 types.add(type);
108                             }
109                         }
110                     }
111                 }
112                 return FileVisitResult.CONTINUE;
113             }
114         });
115 
116         System.out.println("found " + types.size() + " classes");
117         long time = -System.currentTimeMillis();
118         for (Class<?> type : types) {
119             System.out.println("========================================");
120             BeanInfo info = Introspector.getBeanInfo(type);
121 
122             BeanDescriptor bd = info.getBeanDescriptor();
123             System.out.println(bd.getBeanClass());
124             print("customizer", bd.getCustomizerClass());
125             print(bd);
126             print("mono 16x16", info.getIcon(BeanInfo.ICON_MONO_16x16));
127             print("mono 32x32", info.getIcon(BeanInfo.ICON_MONO_32x32));
128             print("color 16x16", info.getIcon(BeanInfo.ICON_COLOR_16x16));
129             print("color 32x32", info.getIcon(BeanInfo.ICON_COLOR_32x32));
130 
131             PropertyDescriptor[] pds = info.getPropertyDescriptors();
132             PropertyDescriptor dpd = getDefault(pds, info.getDefaultPropertyIndex());
133             System.out.println(pds.length + " property descriptors");
134             Arrays.sort(pds, new Test4058433());
135             for (PropertyDescriptor pd : pds) {
136                 print(pd);
137                 if (dpd == pd) {
138                     System.out.println("default property");
139                 }
140                 print("bound", pd.isBound());
141                 print("constrained", pd.isConstrained());
142                 print("property editor", pd.getPropertyEditorClass());
143                 print("property type", pd.getPropertyType());
144                 print("read method", pd.getReadMethod());
145                 print("write method", pd.getWriteMethod());
146                 if (pd instanceof IndexedPropertyDescriptor) {
147                     IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
148                     print("indexed property type", ipd.getIndexedPropertyType());
149                     print("indexed read method", ipd.getIndexedReadMethod());
150                     print("indexed write method", ipd.getIndexedWriteMethod());
151                 }
152             }
153             EventSetDescriptor[] esds = info.getEventSetDescriptors();
154             EventSetDescriptor desd = getDefault(esds, info.getDefaultEventIndex());
155             System.out.println(esds.length + " event set descriptors");
156             Arrays.sort(esds, new Test4058433());
157             for (EventSetDescriptor esd : esds) {
158                 print(esd);
159                 if (desd == esd) {
160                     System.out.println("default event set");
161                 }
162                 print("in default", esd.isInDefaultEventSet());
163                 print("unicast", esd.isUnicast());
164                 print("listener type", esd.getListenerType());
165                 print("get listener method", esd.getGetListenerMethod());
166                 print("add listener method", esd.getAddListenerMethod());
167                 print("remove listener method", esd.getRemoveListenerMethod());
168                 Method[] methods = esd.getListenerMethods();
169                 Arrays.sort(methods, new Test4058433());
170                 for (Method method : methods) {
171                     print("listener method", method);
172                 }
173                 print(esd.getListenerMethodDescriptors());
174             }
175             print(info.getMethodDescriptors());
176         }
177         time += System.currentTimeMillis();
178         System.out.println("DONE IN " + time + " MS");
179     }
180 
getDefault(T[] array, int index)181     private static <T> T getDefault(T[] array, int index) {
182         return (index == -1) ? null : array[index];
183     }
184 
print(MethodDescriptor[] mds)185     private static void print(MethodDescriptor[] mds) {
186         System.out.println(mds.length + " method descriptors");
187         Arrays.sort(mds, new Test4058433());
188         for (MethodDescriptor md : mds) {
189             print(md);
190             print("method", md.getMethod());
191             ParameterDescriptor[] pds = md.getParameterDescriptors();
192             if (pds != null) {
193                 System.out.println(pds.length + " parameter descriptors");
194                 for (ParameterDescriptor pd : pds) {
195                     print(pd);
196                 }
197             }
198         }
199     }
200 
print(FeatureDescriptor descriptor)201     private static void print(FeatureDescriptor descriptor) {
202         String name = descriptor.getName();
203         String display = descriptor.getDisplayName();
204         String description = descriptor.getShortDescription();
205         System.out.println("name: " + name);
206         if (!Objects.equals(name, display)) {
207             System.out.println("display name: " + display);
208         }
209         if (!Objects.equals(display, description)) {
210             System.out.println("description: " + description.trim());
211         }
212         print("expert", descriptor.isExpert());
213         print("hidden", descriptor.isHidden());
214         print("preferred", descriptor.isPreferred());
215         TreeMap<String,Object> map = new TreeMap<>();
216         Enumeration<String> enumeration = descriptor.attributeNames();
217         while (enumeration.hasMoreElements()) {
218             String id = enumeration.nextElement();
219             Object value = descriptor.getValue(id);
220             if (value.getClass().isArray()) {
221                 TreeSet<String> set = new TreeSet<>();
222                 int index = 0;
223                 int length = Array.getLength(value);
224                 while (index < length) {
225                     set.add(Array.get(value, index++) + ", " +
226                             Array.get(value, index++) + ", " +
227                             Array.get(value, index++));
228                 }
229                 value = set.toString();
230             }
231             map.put(id, value);
232         }
233         for (Entry<String,Object> entry : map.entrySet()) {
234             System.out.println(entry.getKey() + ": " + entry.getValue());
235         }
236     }
237 
print(String id, boolean flag)238     private static void print(String id, boolean flag) {
239         if (flag) {
240             System.out.println(id + " is set");
241         }
242     }
243 
print(String id, Class<?> type)244     private static void print(String id, Class<?> type) {
245         if (type != null) {
246             System.out.println(id + ": " + type.getName());
247         }
248     }
249 
print(String id, Method method)250     private static void print(String id, Method method) {
251         if (method != null) {
252             System.out.println(id + ": " + method);
253         }
254     }
255 
print(String name, Image image)256     private static void print(String name, Image image) {
257         if (image != null) {
258             System.out.println(name + " icon is exist");
259         }
260     }
261 }
262