1 /*
   2  * Copyright (c) 2014, 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.util.Arrays;
  37 import java.util.Comparator;
  38 import java.util.Enumeration;
  39 import java.util.Map.Entry;
  40 import java.util.Objects;
  41 import java.util.TreeMap;
  42 import java.util.TreeSet;
  43 import java.util.jar.JarEntry;
  44 import java.util.jar.JarFile;
  45 import java.util.regex.Matcher;
  46 import java.util.regex.Pattern;
  47 
  48 /*
  49  * @test
  50  * @bug 4058433
  51  * @summary Generates BeanInfo for public classes in AWT, Accessibility, and Swing
  52  * @author Sergey Malenkov
  53  * @run main/manual Test4058433
  54  */
  55 
  56 public class Test4058433 implements Comparator<Object> {
  57     @Override
  58     public int compare(Object one, Object two) {
  59         if (one instanceof Method && two instanceof Method) {
  60             Method oneMethod = (Method) one;
  61             Method twoMethod = (Method) two;
  62             int result = oneMethod.getName().compareTo(twoMethod.getName());
  63             if (result != 0) {
  64                 return result;
  65             }
  66         }
  67         if (one instanceof FeatureDescriptor && two instanceof FeatureDescriptor) {
  68             FeatureDescriptor oneFD = (FeatureDescriptor) one;
  69             FeatureDescriptor twoFD = (FeatureDescriptor) two;
  70             int result = oneFD.getName().compareTo(twoFD.getName());
  71             if (result != 0) {
  72                 return result;
  73             }
  74         }
  75         return one.toString().compareTo(two.toString());
  76     }
  77 
  78     public static void main(String[] args) throws Exception {
  79         String resource = ClassLoader.getSystemResource("java/lang/Object.class").toString();
  80 
  81         Pattern pattern = Pattern.compile("jar:file:(.*)!.*");
  82         Matcher matcher = pattern.matcher(resource);
  83         matcher.matches();
  84         resource = matcher.group(1);
  85 
  86         TreeSet<Class<?>> types = new TreeSet<>(new Test4058433());
  87         try (JarFile jarFile = new JarFile(resource.replaceAll("%20", " "))) {
  88             Enumeration<JarEntry> entries = jarFile.entries();
  89             while (entries.hasMoreElements()) {
  90                 String name = entries.nextElement().getName();
  91                 if (name.startsWith("java/awt/") || name.startsWith("javax/accessibility/") || name.startsWith("javax/swing/")) {
  92                     if (name.endsWith(".class")) {
  93                         name = name.substring(0, name.indexOf(".")).replace('/', '.');
  94                         Class<?> type = Class.forName(name);
  95                         if (!type.isInterface() && !type.isEnum() && !type.isAnnotation() && !type.isAnonymousClass()) {
  96                             if (null == type.getDeclaringClass()) {
  97                                 types.add(type);
  98                             }
  99                         }
 100                     }
 101                 }
 102             }
 103         }
 104         System.out.println("found " + types.size() + " classes");
 105         long time = -System.currentTimeMillis();
 106         for (Class<?> type : types) {
 107             System.out.println("========================================");
 108             BeanInfo info = Introspector.getBeanInfo(type);
 109 
 110             BeanDescriptor bd = info.getBeanDescriptor();
 111             System.out.println(bd.getBeanClass());
 112             print("customizer", bd.getCustomizerClass());
 113             print(bd);
 114             print("mono 16x16", info.getIcon(BeanInfo.ICON_MONO_16x16));
 115             print("mono 32x32", info.getIcon(BeanInfo.ICON_MONO_32x32));
 116             print("color 16x16", info.getIcon(BeanInfo.ICON_COLOR_16x16));
 117             print("color 32x32", info.getIcon(BeanInfo.ICON_COLOR_32x32));
 118 
 119             PropertyDescriptor[] pds = info.getPropertyDescriptors();
 120             PropertyDescriptor dpd = getDefault(pds, info.getDefaultPropertyIndex());
 121             System.out.println(pds.length + " property descriptors");
 122             Arrays.sort(pds, new Test4058433());
 123             for (PropertyDescriptor pd : pds) {
 124                 print(pd);
 125                 if (dpd == pd) {
 126                     System.out.println("default property");
 127                 }
 128                 print("bound", pd.isBound());
 129                 print("constrained", pd.isConstrained());
 130                 print("property editor", pd.getPropertyEditorClass());
 131                 print("property type", pd.getPropertyType());
 132                 print("read method", pd.getReadMethod());
 133                 print("write method", pd.getWriteMethod());
 134                 if (pd instanceof IndexedPropertyDescriptor) {
 135                     IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
 136                     print("indexed property type", ipd.getIndexedPropertyType());
 137                     print("indexed read method", ipd.getIndexedReadMethod());
 138                     print("indexed write method", ipd.getIndexedWriteMethod());
 139                 }
 140             }
 141             EventSetDescriptor[] esds = info.getEventSetDescriptors();
 142             EventSetDescriptor desd = getDefault(esds, info.getDefaultEventIndex());
 143             System.out.println(esds.length + " event set descriptors");
 144             Arrays.sort(esds, new Test4058433());
 145             for (EventSetDescriptor esd : esds) {
 146                 print(esd);
 147                 if (desd == esd) {
 148                     System.out.println("default event set");
 149                 }
 150                 print("in default", esd.isInDefaultEventSet());
 151                 print("unicast", esd.isUnicast());
 152                 print("listener type", esd.getListenerType());
 153                 print("get listener method", esd.getGetListenerMethod());
 154                 print("add listener method", esd.getAddListenerMethod());
 155                 print("remove listener method", esd.getRemoveListenerMethod());
 156                 Method[] methods = esd.getListenerMethods();
 157                 Arrays.sort(methods, new Test4058433());
 158                 for (Method method : methods) {
 159                     print("listener method", method);
 160                 }
 161                 print(esd.getListenerMethodDescriptors());
 162             }
 163             print(info.getMethodDescriptors());
 164         }
 165         time += System.currentTimeMillis();
 166         System.out.println("DONE IN " + time + " MS");
 167     }
 168 
 169     private static <T> T getDefault(T[] array, int index) {
 170         return (index == -1) ? null : array[index];
 171     }
 172 
 173     private static void print(MethodDescriptor[] mds) {
 174         System.out.println(mds.length + " method descriptors");
 175         Arrays.sort(mds, new Test4058433());
 176         for (MethodDescriptor md : mds) {
 177             print(md);
 178             print("method", md.getMethod());
 179             ParameterDescriptor[] pds = md.getParameterDescriptors();
 180             if (pds != null) {
 181                 System.out.println(pds.length + " parameter descriptors");
 182                 for (ParameterDescriptor pd : pds) {
 183                     print(pd);
 184                 }
 185             }
 186         }
 187     }
 188 
 189     private static void print(FeatureDescriptor descriptor) {
 190         String name = descriptor.getName();
 191         String display = descriptor.getDisplayName();
 192         String description = descriptor.getShortDescription();
 193         System.out.println("name: " + name);
 194         if (!Objects.equals(name, display)) {
 195             System.out.println("display name: " + display);
 196         }
 197         if (!Objects.equals(display, description)) {
 198             System.out.println("description: " + description.trim());
 199         }
 200         print("expert", descriptor.isExpert());
 201         print("hidden", descriptor.isHidden());
 202         print("preferred", descriptor.isPreferred());
 203         TreeMap<String,Object> map = new TreeMap<>();
 204         Enumeration<String> enumeration = descriptor.attributeNames();
 205         while (enumeration.hasMoreElements()) {
 206             String id = enumeration.nextElement();
 207             Object value = descriptor.getValue(id);
 208             if (value.getClass().isArray()) {
 209                 TreeSet<String> set = new TreeSet<>();
 210                 int index = 0;
 211                 int length = Array.getLength(value);
 212                 while (index < length) {
 213                     set.add(Array.get(value, index++) + ", " +
 214                             Array.get(value, index++) + ", " +
 215                             Array.get(value, index++));
 216                 }
 217                 value = set.toString();
 218             }
 219             map.put(id, value);
 220         }
 221         for (Entry<String,Object> entry : map.entrySet()) {
 222             System.out.println(entry.getKey() + ": " + entry.getValue());
 223         }
 224     }
 225 
 226     private static void print(String id, boolean flag) {
 227         if (flag) {
 228             System.out.println(id + " is set");
 229         }
 230     }
 231 
 232     private static void print(String id, Class<?> type) {
 233         if (type != null) {
 234             System.out.println(id + ": " + type.getName());
 235         }
 236     }
 237 
 238     private static void print(String id, Method method) {
 239         if (method != null) {
 240             System.out.println(id + ": " + method);
 241         }
 242     }
 243 
 244     private static void print(String name, Image image) {
 245         if (image != null) {
 246             System.out.println(name + " icon is exist");
 247         }
 248     }
 249 }