7179078: Remove @beaninfo processing from the makefiles
Reviewed-by: erikj, alexsch
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package @(BeanPackageName);
|
||||
|
||||
import java.beans.BeanDescriptor;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.awt.Image;
|
||||
|
||||
import sun.swing.BeanInfoUtils;
|
||||
|
||||
/**
|
||||
* Descriptive information about the @(BeanClassName) class for Java
|
||||
* Beans application builders. This BeanInfo class provides descriptions
|
||||
* of each property, of the bean itself, it indicates which
|
||||
* @(BeanClassName) properties are bound, and it provides other
|
||||
* information and icons useful to builders.
|
||||
*
|
||||
* @author Auto-Generated Source Code
|
||||
*/
|
||||
|
||||
public class @(BeanClassName)BeanInfo extends javax.swing.SwingBeanInfoBase {
|
||||
private static final Class<?> class@(BeanClassName) = @(BeanClassObject);
|
||||
|
||||
/**
|
||||
* @return a @(BeanClassName) BeanDescriptor
|
||||
*/
|
||||
public BeanDescriptor getBeanDescriptor() {
|
||||
return BeanInfoUtils.createBeanDescriptor(class@(BeanClassName),
|
||||
new Object[] {
|
||||
BeanInfoUtils.PREFERRED, Boolean.TRUE,
|
||||
@(ClassDescriptors)
|
||||
BeanInfoUtils.SHORTDESCRIPTION, "@(BeanDescription)"
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a @(BeanClassName) PropertyDescriptor. This is just an internal
|
||||
* convenience method that allows one to leave the @(BeanClassName).class
|
||||
* argument out of the createPropertyDescriptor() class in the
|
||||
* getPropertyDescriptors() method below.
|
||||
*
|
||||
* @param name the name of the property
|
||||
* @param args an array java.beans.PropertyDescriptor property names and values
|
||||
* @return a @(BeanClassName) PropertyDescriptor.
|
||||
* @see BeanInfoUtils#createPropertyDescriptor
|
||||
*/
|
||||
private PropertyDescriptor createPropertyDescriptor(String name, Object[] args) {
|
||||
return BeanInfoUtils.createPropertyDescriptor(class@(BeanClassName), name, args);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns a list of bean PropertyDescriptors, one for each public
|
||||
* property in @(BeanClassName). The first property is the "default" property.
|
||||
*
|
||||
* @return a complete list of bean PropertyDescriptors for @(BeanClassName)
|
||||
* @see SwingBeanInfo
|
||||
* @see java.beans.BeanInfo#getDefaultPropertyIndex
|
||||
*/
|
||||
public PropertyDescriptor[] getPropertyDescriptors() {
|
||||
@(EnumVariables)
|
||||
return new PropertyDescriptor[] {
|
||||
@(BeanPropertyDescriptors)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return an icon of the specified kind for @(BeanClassName)
|
||||
*/
|
||||
public Image getIcon(final int kind) {
|
||||
Image i;
|
||||
switch (kind){
|
||||
case ICON_COLOR_32x32:
|
||||
i = loadStandardImage("beaninfo/images/@(BeanClassName)Color32.gif");
|
||||
return ((i == null) ? loadStandardImage("beaninfo/images/JComponentColor32.gif") : i);
|
||||
case ICON_COLOR_16x16:
|
||||
i = loadStandardImage("beaninfo/images/@(BeanClassName)Color16.gif");
|
||||
return ((i == null) ? loadStandardImage("beaninfo/images/JComponentColor16.gif") : i);
|
||||
case ICON_MONO_32x32:
|
||||
i = loadStandardImage("beaninfo/images/@(BeanClassName)Mono32.gif");
|
||||
return ((i == null) ? loadStandardImage("beaninfo/images/JComponentMono32.gif") : i);
|
||||
case ICON_MONO_16x16:
|
||||
i = loadStandardImage("beaninfo/images/@(BeanClassName)Mono16.gif");
|
||||
return ((i == null) ? loadStandardImage("beaninfo/images/JComponentMono16.gif") : i);
|
||||
default:
|
||||
return super.getIcon(kind);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a utility method to help in loading standard icon images.
|
||||
*
|
||||
* @param resourceName A pathname relative to the directory holding the
|
||||
* class file of the current class
|
||||
* @return an image object. May be null if the load failed.
|
||||
* @see java.beans.SimpleBeanInfo#loadImage(String)
|
||||
*/
|
||||
private Image loadStandardImage(final String resourceName) {
|
||||
return java.security.AccessController.doPrivileged(
|
||||
(java.security.PrivilegedAction<Image>) () -> loadImage(resourceName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing;
|
||||
|
||||
import java.beans.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.awt.Image;
|
||||
|
||||
/**
|
||||
* The superclass for all Swing BeanInfo classes. It provides
|
||||
* default implementations of <code>getIcon</code> and
|
||||
* <code>getDefaultPropertyIndex</code> as well as utility
|
||||
* methods, like createPropertyDescriptor, for writing BeanInfo
|
||||
* implementations. This classes is intended to be used along
|
||||
* with <code>GenSwingBeanInfo</code> a BeanInfo class code generator.
|
||||
*
|
||||
* @see GenSwingBeanInfo
|
||||
* @author Hans Muller
|
||||
*/
|
||||
public class SwingBeanInfoBase extends SimpleBeanInfo
|
||||
{
|
||||
/**
|
||||
* The default index is always 0. In other words the first property
|
||||
* listed in the getPropertyDescriptors() method is the one
|
||||
* to show a (JFC builder) user in a situation where just a single
|
||||
* property will be shown.
|
||||
*/
|
||||
public int getDefaultPropertyIndex() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a generic Swing icon, all icon "kinds" are supported.
|
||||
* Subclasses should defer to this method when they don't have
|
||||
* a particular beans icon kind.
|
||||
*/
|
||||
public Image getIcon(int kind) {
|
||||
// PENDING(hmuller) need generic swing icon images.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the BeanInfo for the superclass of our bean, so that
|
||||
* its PropertyDescriptors will be included.
|
||||
*/
|
||||
public BeanInfo[] getAdditionalBeanInfo() {
|
||||
Class<?> superClass = getBeanDescriptor().getBeanClass().getSuperclass();
|
||||
BeanInfo superBeanInfo = null;
|
||||
try {
|
||||
superBeanInfo = Introspector.getBeanInfo(superClass);
|
||||
} catch (IntrospectionException ie) {}
|
||||
if (superBeanInfo != null) {
|
||||
BeanInfo[] ret = new BeanInfo[1];
|
||||
ret[0] = superBeanInfo;
|
||||
return ret;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1,111 +0,0 @@
|
||||
Name: javax/swing/JApplet.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JButton.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JCheckBox.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JCheckBoxMenuItem.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JComboBox.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JDialog.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JEditorPane.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JFormattedTextField.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JInternalFrame.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JFrame.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JLabel.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JList.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JMenu.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JMenuBar.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JMenuItem.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JOptionPane.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JPanel.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JPasswordField.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JPopupMenu.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JProgressBar.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JRadioButton.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JRadioButtonMenuItem.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JScrollBar.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JScrollPane.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JSeparator.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JSlider.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JSpinner.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JSplitPane.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JTabbedPane.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JTextArea.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JTextField.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JTextPane.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JToolBar.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JTree.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JTable.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JToggleButton.class
|
||||
Java-Bean: True
|
||||
|
||||
Name: javax/swing/JWindow.class
|
||||
Java-Bean: True
|
||||
|
||||
@ -1,293 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.swing;
|
||||
|
||||
import java.beans.*;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class BeanInfoUtils
|
||||
{
|
||||
/* The values of these createPropertyDescriptor() and
|
||||
* createBeanDescriptor() keywords are the names of the
|
||||
* properties they're used to set.
|
||||
*/
|
||||
public static final String BOUND = "bound";
|
||||
public static final String CONSTRAINED = "constrained";
|
||||
public static final String PROPERTYEDITORCLASS = "propertyEditorClass";
|
||||
public static final String READMETHOD = "readMethod";
|
||||
public static final String WRITEMETHOD = "writeMethod";
|
||||
public static final String DISPLAYNAME = "displayName";
|
||||
public static final String EXPERT = "expert";
|
||||
public static final String HIDDEN = "hidden";
|
||||
public static final String PREFERRED = "preferred";
|
||||
public static final String SHORTDESCRIPTION = "shortDescription";
|
||||
public static final String CUSTOMIZERCLASS = "customizerClass";
|
||||
|
||||
static private void initFeatureDescriptor(FeatureDescriptor fd, String key, Object value)
|
||||
{
|
||||
if (DISPLAYNAME.equals(key)) {
|
||||
fd.setDisplayName((String)value);
|
||||
}
|
||||
|
||||
if (EXPERT.equals(key)) {
|
||||
fd.setExpert(((Boolean)value).booleanValue());
|
||||
}
|
||||
|
||||
if (HIDDEN.equals(key)) {
|
||||
fd.setHidden(((Boolean)value).booleanValue());
|
||||
}
|
||||
|
||||
if (PREFERRED.equals(key)) {
|
||||
fd.setPreferred(((Boolean)value).booleanValue());
|
||||
}
|
||||
|
||||
else if (SHORTDESCRIPTION.equals(key)) {
|
||||
fd.setShortDescription((String)value);
|
||||
}
|
||||
|
||||
/* Otherwise assume that we have an arbitrary FeatureDescriptor
|
||||
* "attribute".
|
||||
*/
|
||||
else {
|
||||
fd.setValue(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a beans PropertyDescriptor given an of keyword/value
|
||||
* arguments. The following sample call shows all of the supported
|
||||
* keywords:
|
||||
*<pre>
|
||||
* createPropertyDescriptor("contentPane", new Object[] {
|
||||
* BOUND, Boolean.TRUE,
|
||||
* CONSTRAINED, Boolean.TRUE,
|
||||
* PROPERTYEDITORCLASS, package.MyEditor.class,
|
||||
* READMETHOD, "getContentPane",
|
||||
* WRITEMETHOD, "setContentPane",
|
||||
* DISPLAYNAME, "contentPane",
|
||||
* EXPERT, Boolean.FALSE,
|
||||
* HIDDEN, Boolean.FALSE,
|
||||
* PREFERRED, Boolean.TRUE,
|
||||
* SHORTDESCRIPTION, "A top level window with a window manager border",
|
||||
* "random attribute","random object value"
|
||||
* }
|
||||
* );
|
||||
* </pre>
|
||||
* The keywords correspond to <code>java.beans.PropertyDescriptor</code> and
|
||||
* <code>java.beans.FeatureDescriptor</code> properties, e.g. providing a value
|
||||
* for displayName is comparable to <code>FeatureDescriptor.setDisplayName()</code>.
|
||||
* Using createPropertyDescriptor instead of the PropertyDescriptor
|
||||
* constructor and set methods is preferrable in that it regularizes
|
||||
* the code in a <code>java.beans.BeanInfo.getPropertyDescriptors()</code>
|
||||
* method implementation. One can use <code>createPropertyDescriptor</code>
|
||||
* to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
|
||||
* "random object value".
|
||||
* <p>
|
||||
* All properties should provide a reasonable value for the
|
||||
* <code>SHORTDESCRIPTION</code> keyword and should set <code>BOUND</code>
|
||||
* to <code>Boolean.TRUE</code> if neccessary. The remaining keywords
|
||||
* are optional. There's no need to provide values for keywords like
|
||||
* READMETHOD if the correct value can be computed, i.e. if the properties
|
||||
* get/is method follows the standard beans pattern.
|
||||
* <p>
|
||||
* The PREFERRED keyword is not supported by the JDK1.1 java.beans package.
|
||||
* It's still worth setting it to true for properties that are most
|
||||
* likely to be interested to the average developer, e.g. AbstractButton.title
|
||||
* is a preferred property, AbstractButton.focusPainted is not.
|
||||
*
|
||||
* @see java.beans#BeanInfo
|
||||
* @see java.beans#PropertyDescriptor
|
||||
* @see java.beans#FeatureDescriptor
|
||||
*/
|
||||
public static PropertyDescriptor createPropertyDescriptor(Class<?> cls, String name, Object[] args)
|
||||
{
|
||||
PropertyDescriptor pd = null;
|
||||
try {
|
||||
pd = new PropertyDescriptor(name, cls);
|
||||
} catch (IntrospectionException e) {
|
||||
// Try creating a read-only property, in case setter isn't defined.
|
||||
try {
|
||||
pd = createReadOnlyPropertyDescriptor(name, cls);
|
||||
} catch (IntrospectionException ie) {
|
||||
throwError(ie, "Can't create PropertyDescriptor for " + name + " ");
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < args.length; i += 2) {
|
||||
String key = (String)args[i];
|
||||
Object value = args[i + 1];
|
||||
|
||||
if (BOUND.equals(key)) {
|
||||
pd.setBound(((Boolean)value).booleanValue());
|
||||
}
|
||||
|
||||
else if (CONSTRAINED.equals(key)) {
|
||||
pd.setConstrained(((Boolean)value).booleanValue());
|
||||
}
|
||||
|
||||
else if (PROPERTYEDITORCLASS.equals(key)) {
|
||||
pd.setPropertyEditorClass((Class)value);
|
||||
}
|
||||
|
||||
else if (READMETHOD.equals(key)) {
|
||||
String methodName = (String)value;
|
||||
Method method;
|
||||
try {
|
||||
method = cls.getMethod(methodName, new Class<?>[0]);
|
||||
pd.setReadMethod(method);
|
||||
}
|
||||
catch(Exception e) {
|
||||
throwError(e, cls + " no such method as \"" + methodName + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
else if (WRITEMETHOD.equals(key)) {
|
||||
String methodName = (String)value;
|
||||
Method method;
|
||||
try {
|
||||
Class<?> type = pd.getPropertyType();
|
||||
method = cls.getMethod(methodName, new Class<?>[]{type});
|
||||
pd.setWriteMethod(method);
|
||||
}
|
||||
catch(Exception e) {
|
||||
throwError(e, cls + " no such method as \"" + methodName + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
initFeatureDescriptor(pd, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
return pd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a BeanDescriptor object given an of keyword/value
|
||||
* arguments. The following sample call shows all of the supported
|
||||
* keywords:
|
||||
*<pre>
|
||||
* createBeanDescriptor(JWindow..class, new Object[] {
|
||||
* CUSTOMIZERCLASS, package.MyCustomizer.class,
|
||||
* DISPLAYNAME, "JFrame",
|
||||
* EXPERT, Boolean.FALSE,
|
||||
* HIDDEN, Boolean.FALSE,
|
||||
* PREFERRED, Boolean.TRUE,
|
||||
* SHORTDESCRIPTION, "A top level window with a window manager border",
|
||||
* "random attribute","random object value"
|
||||
* }
|
||||
* );
|
||||
* </pre>
|
||||
* The keywords correspond to <code>java.beans.BeanDescriptor</code> and
|
||||
* <code>java.beans.FeatureDescriptor</code> properties, e.g. providing a value
|
||||
* for displayName is comparable to <code>FeatureDescriptor.setDisplayName()</code>.
|
||||
* Using createBeanDescriptor instead of the BeanDescriptor
|
||||
* constructor and set methods is preferrable in that it regularizes
|
||||
* the code in a <code>java.beans.BeanInfo.getBeanDescriptor()</code>
|
||||
* method implementation. One can use <code>createBeanDescriptor</code>
|
||||
* to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
|
||||
* "random object value".
|
||||
*
|
||||
* @see java.beans#BeanInfo
|
||||
* @see java.beans#PropertyDescriptor
|
||||
*/
|
||||
public static BeanDescriptor createBeanDescriptor(Class<?> cls, Object[] args)
|
||||
{
|
||||
Class<?> customizerClass = null;
|
||||
|
||||
/* For reasons I don't understand, customizerClass is a
|
||||
* readOnly property. So we have to find it and pass it
|
||||
* to the constructor here.
|
||||
*/
|
||||
for(int i = 0; i < args.length; i += 2) {
|
||||
if (CUSTOMIZERCLASS.equals((String)args[i])) {
|
||||
customizerClass = (Class)args[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BeanDescriptor bd = new BeanDescriptor(cls, customizerClass);
|
||||
|
||||
for(int i = 0; i < args.length; i += 2) {
|
||||
String key = (String)args[i];
|
||||
Object value = args[i + 1];
|
||||
initFeatureDescriptor(bd, key, value);
|
||||
}
|
||||
|
||||
return bd;
|
||||
}
|
||||
|
||||
static private PropertyDescriptor createReadOnlyPropertyDescriptor(
|
||||
String name, Class<?> cls) throws IntrospectionException {
|
||||
|
||||
Method readMethod = null;
|
||||
String base = capitalize(name);
|
||||
Class<?>[] parameters = new Class<?>[0];
|
||||
|
||||
// Is it a boolean?
|
||||
try {
|
||||
readMethod = cls.getMethod("is" + base, parameters);
|
||||
} catch (Exception ex) {}
|
||||
if (readMethod == null) {
|
||||
try {
|
||||
// Try normal accessor pattern.
|
||||
readMethod = cls.getMethod("get" + base, parameters);
|
||||
} catch (Exception ex2) {}
|
||||
}
|
||||
if (readMethod != null) {
|
||||
return new PropertyDescriptor(name, readMethod, null);
|
||||
}
|
||||
|
||||
try {
|
||||
// Try indexed accessor pattern.
|
||||
parameters = new Class<?>[1];
|
||||
parameters[0] = int.class;
|
||||
readMethod = cls.getMethod("get" + base, parameters);
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
throw new IntrospectionException(
|
||||
"cannot find accessor method for " + name + " property.");
|
||||
}
|
||||
return new IndexedPropertyDescriptor(name, null, null, readMethod, null);
|
||||
}
|
||||
|
||||
// Modified methods from java.beans.Introspector
|
||||
private static String capitalize(String s) {
|
||||
if (s.length() == 0) {
|
||||
return s;
|
||||
}
|
||||
char chars[] = s.toCharArray();
|
||||
chars[0] = Character.toUpperCase(chars[0]);
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fatal errors are handled by calling this method.
|
||||
*/
|
||||
public static void throwError(Exception e, String s) {
|
||||
throw new Error(e.toString() + " " + s);
|
||||
}
|
||||
}
|
||||
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package build.tools.swingbeaninfo;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Class that holds information for populating a FeatureDescriptor. For the class,
|
||||
* This information represents the BeanDescriptor, for a property, it represents
|
||||
* a PropertyDescriptor.
|
||||
*/
|
||||
public class DocBeanInfo {
|
||||
|
||||
// Values of the BeanFlags
|
||||
public static final int BOUND = 1;
|
||||
public static final int EXPERT = 2;
|
||||
public static final int CONSTRAINED = 4;
|
||||
public static final int HIDDEN = 8;
|
||||
public static final int PREFERRED = 16 ;
|
||||
|
||||
public String name;
|
||||
public int beanflags;
|
||||
public String desc;
|
||||
public String displayname;
|
||||
public String propertyeditorclass;
|
||||
public String customizerclass;
|
||||
|
||||
public HashMap attribs;
|
||||
public HashMap enums;
|
||||
|
||||
public DocBeanInfo(){}
|
||||
|
||||
public DocBeanInfo(String p, int flags, String d,
|
||||
String displayname, String pec, String cc,
|
||||
HashMap attribs, HashMap enums) {
|
||||
this.name = p;
|
||||
this.beanflags = flags;
|
||||
this.desc = d;
|
||||
this.displayname = displayname;
|
||||
this.propertyeditorclass = pec;
|
||||
this.customizerclass = cc;
|
||||
|
||||
this.attribs = attribs;
|
||||
this.enums = enums;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer("*****");
|
||||
buffer.append("\nProperty: " + name);
|
||||
buffer.append("\tDescription: " + desc);
|
||||
buffer.append("\nDisplayname: " + displayname);
|
||||
buffer.append("\nPropertyEditorClass: " + propertyeditorclass);
|
||||
buffer.append("\nCustomizerClass: " + customizerclass);
|
||||
|
||||
if ((beanflags & BOUND) != 0)
|
||||
buffer.append("\nBound: true");
|
||||
|
||||
if ((beanflags & EXPERT) != 0)
|
||||
buffer.append("\nExpert: true");
|
||||
|
||||
if ((beanflags & CONSTRAINED) != 0)
|
||||
buffer.append("\nConstrained: true");
|
||||
|
||||
if ((beanflags & HIDDEN) !=0)
|
||||
buffer.append("\nHidden: true");
|
||||
|
||||
if ((beanflags & PREFERRED) !=0)
|
||||
|
||||
if (attribs != null)
|
||||
buffer.append(attribs.toString());
|
||||
|
||||
if (enums != null)
|
||||
buffer.append(enums.toString());
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,447 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package build.tools.swingbeaninfo;
|
||||
|
||||
import com.sun.javadoc.ClassDoc;
|
||||
import com.sun.javadoc.MethodDoc;
|
||||
import com.sun.javadoc.RootDoc;
|
||||
import com.sun.javadoc.Tag;
|
||||
|
||||
import java.beans.Introspector;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.HashMap;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Properties supported and tag syntax:
|
||||
*
|
||||
* @beaninfo
|
||||
* bound: flag
|
||||
* constrained: flag
|
||||
* expert: flag
|
||||
* hidden: flag
|
||||
* preferred: flag
|
||||
* description: string
|
||||
* displayname: string
|
||||
* propertyeditorclass: string (with dots: foo.bar.MyPropertyEditor
|
||||
* customizerclass: string (w/dots: foo.bar.MyCustomizer)
|
||||
* attribute: key1 value1
|
||||
* attribute: key2 value2
|
||||
*
|
||||
* TODO: getValue and genDocletInfo needs some cleaning.
|
||||
*
|
||||
* @author Hans Muller
|
||||
* @author Rich Schiavi
|
||||
* @author Mark Davidson
|
||||
*/
|
||||
public class GenDocletBeanInfo {
|
||||
|
||||
static String[] ATTRIBUTE_NAMES = { "bound",
|
||||
"constrained",
|
||||
"expert",
|
||||
"hidden",
|
||||
"preferred",
|
||||
"displayname",
|
||||
"propertyeditorclass",
|
||||
"customizerclass",
|
||||
"displayname",
|
||||
"description",
|
||||
"enum",
|
||||
"attribute" };
|
||||
private static boolean DEBUG = false;
|
||||
|
||||
private static String fileDir = "";
|
||||
private static String templateDir = "";
|
||||
|
||||
public static final String TRUE = "true";
|
||||
public static final String FALSE = "false";
|
||||
|
||||
/**
|
||||
* Method called from the javadoc environment to determint the options length.
|
||||
* Doclet options:
|
||||
* -t template location
|
||||
* -d outputdir
|
||||
* -x true Enable debug output.
|
||||
*/
|
||||
public static int optionLength(String option) {
|
||||
// remind: this needs to be cleaned up
|
||||
if (option.equals("-t"))
|
||||
return 2;
|
||||
if (option.equals("-d"))
|
||||
return 2;
|
||||
if (option.equals("-x"))
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @beaninfo
|
||||
* bound:true
|
||||
* constrained:false
|
||||
* expert:true
|
||||
* hidden:true
|
||||
* preferred:false
|
||||
* description: the description of this method can
|
||||
* do all sorts of funky things. if it \n
|
||||
* is indented like this, we have to remove
|
||||
* all char spaces greater than 2 and also any hard-coded \n
|
||||
* newline characters and all newlines
|
||||
* displayname: theString
|
||||
* propertyeditorclass: foo.bar.MyPropertyEditorClass
|
||||
* customizerclass: foo.bar.MyCustomizerClass
|
||||
* attribute:key1 value1
|
||||
* attribute: key2 value2
|
||||
*
|
||||
*/
|
||||
public static boolean start(RootDoc doc) {
|
||||
readOptions(doc.options());
|
||||
|
||||
if (templateDir.length() == 0) {
|
||||
System.err.println("-t option not specified");
|
||||
return false;
|
||||
}
|
||||
if (fileDir.length() == 0) {
|
||||
System.err.println("-d option not specified");
|
||||
return false;
|
||||
}
|
||||
|
||||
GenSwingBeanInfo generator = new GenSwingBeanInfo(fileDir, templateDir, DEBUG);
|
||||
Hashtable dochash = new Hashtable();
|
||||
DocBeanInfo dbi;
|
||||
|
||||
/* "javadoc Foo.java Bar.java" will return:
|
||||
* "Foo Foo.I1 Foo.I2 Bar Bar.I1 Bar.I2"
|
||||
* i.e., with all the innerclasses of classes specified in the command
|
||||
* line. We don't want to generate BeanInfo for any of these inner
|
||||
* classes, so we ignore these by remembering what the last outer
|
||||
* class was. A hack, I admit, but makes the build faster.
|
||||
*/
|
||||
String previousClass = null;
|
||||
|
||||
ClassDoc[] classes = doc.classes();
|
||||
|
||||
for (int cnt = 0; cnt < classes.length; cnt++) {
|
||||
String className = classes[cnt].qualifiedName();
|
||||
if (previousClass != null &&
|
||||
className.startsWith(previousClass) &&
|
||||
className.charAt(previousClass.length()) == '.') {
|
||||
continue;
|
||||
}
|
||||
previousClass = className;
|
||||
|
||||
// XXX - debug
|
||||
System.out.println("\n>>> Generating beaninfo for " + className + "...");
|
||||
|
||||
// Examine the javadoc tags and look for the the @beaninfo tag
|
||||
// This first block looks at the javadoc for the class
|
||||
Tag[] tags = classes[cnt].tags();
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
if (tags[i].kind().equalsIgnoreCase("@beaninfo")) {
|
||||
if (DEBUG)
|
||||
System.out.println("GenDocletBeanInfo: found @beaninfo tagged Class: " + tags[i].text());
|
||||
dbi = genDocletInfo(tags[i].text(), classes[cnt].name());
|
||||
dochash.put(dbi.name, dbi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This block looks at the javadoc for the class methods.
|
||||
int startPos = -1;
|
||||
MethodDoc[] methods = classes[cnt].methods();
|
||||
for (int j = 0; j < methods.length; j++) {
|
||||
// actually don't "introspect" - look for all
|
||||
// methods with a @beaninfo tag
|
||||
tags = methods[j].tags();
|
||||
for (int x = 0; x < tags.length; x++){
|
||||
if (tags[x].kind().equalsIgnoreCase("@beaninfo")){
|
||||
if ((methods[j].name().startsWith("get")) ||
|
||||
(methods[j].name().startsWith("set")))
|
||||
startPos = 3;
|
||||
else if (methods[j].name().startsWith("is"))
|
||||
startPos = 2;
|
||||
else
|
||||
startPos = 0;
|
||||
String propDesc =
|
||||
Introspector.decapitalize((methods[j].name()).substring(startPos));
|
||||
if (DEBUG)
|
||||
System.out.println("GenDocletBeanInfo: found @beaninfo tagged Method: " + tags[x].text());
|
||||
dbi = genDocletInfo(tags[x].text(), propDesc);
|
||||
dochash.put(dbi.name, dbi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DEBUG) {
|
||||
// dump our classes doc beaninfo
|
||||
System.out.println(">>>>DocletBeanInfo for class: " + classes[cnt].name());
|
||||
Enumeration e = dochash.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
DocBeanInfo db = (DocBeanInfo)e.nextElement();
|
||||
System.out.println(db.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Use the generator to create the beaninfo code for the class.
|
||||
generator.genBeanInfo(classes[cnt].containingPackage().name(),
|
||||
classes[cnt].name(), dochash);
|
||||
// reset the values!
|
||||
dochash.clear();
|
||||
} // end for loop
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the command line options.
|
||||
* Side Effect, sets class variables templateDir, fileDir and DEBUG
|
||||
*/
|
||||
private static void readOptions(String[][] options) {
|
||||
// Parse the command line args
|
||||
for (int i = 0; i < options.length; i++){
|
||||
if (options[i][0].equals("-t")) {
|
||||
templateDir = options[i][1];
|
||||
} else if (options[i][0].equals("-d")) {
|
||||
fileDir = options[i][1];
|
||||
} else if (options[i][0].equals("-x")){
|
||||
if (options[i][1].equals("true"))
|
||||
DEBUG=true;
|
||||
else
|
||||
DEBUG=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a "BeanInfo" data structure from the tag. This is a data structure
|
||||
* which contains all beaninfo data for a method or a class.
|
||||
*
|
||||
* @param text All the text after the @beaninfo tag.
|
||||
* @param name Name of the property i.e., mnemonic for setMnemonic
|
||||
*/
|
||||
private static DocBeanInfo genDocletInfo(String text, String name) {
|
||||
int beanflags = 0;
|
||||
String desc = "null";
|
||||
String displayname = "null";
|
||||
String propertyeditorclass = "null";
|
||||
String customizerclass = "null";
|
||||
String value = "null";
|
||||
HashMap attribs = null;
|
||||
HashMap enums = null;
|
||||
|
||||
int index;
|
||||
|
||||
for (int j = 0; j < ATTRIBUTE_NAMES.length; j++){
|
||||
index = 0;
|
||||
if ((index = text.indexOf(ATTRIBUTE_NAMES[j])) != -1){
|
||||
value = getValue((text).substring(index),ATTRIBUTE_NAMES[j]);
|
||||
|
||||
if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("attribute")) {
|
||||
attribs = getAttributeMap(value, " ");
|
||||
}
|
||||
if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("enum")) {
|
||||
enums = getAttributeMap(value, " \n");
|
||||
}
|
||||
else if (ATTRIBUTE_NAMES[j].equals("displayname")){
|
||||
displayname = value;
|
||||
}
|
||||
else if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("propertyeditorclass")) {
|
||||
propertyeditorclass = value;
|
||||
}
|
||||
else if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("customizerclass")){
|
||||
customizerclass = value;
|
||||
}
|
||||
else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("bound"))
|
||||
&& (value.equalsIgnoreCase(TRUE)))
|
||||
beanflags = beanflags | DocBeanInfo.BOUND;
|
||||
else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("expert"))
|
||||
&& (value.equalsIgnoreCase(TRUE)))
|
||||
beanflags = beanflags | DocBeanInfo.EXPERT;
|
||||
else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("constrained"))
|
||||
&& (value.equalsIgnoreCase(TRUE)))
|
||||
beanflags = beanflags | DocBeanInfo.CONSTRAINED;
|
||||
else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("hidden"))
|
||||
&& (value.equalsIgnoreCase(TRUE)))
|
||||
beanflags = beanflags | DocBeanInfo.HIDDEN;
|
||||
else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("preferred"))
|
||||
&& (value.equalsIgnoreCase(TRUE)))
|
||||
beanflags = beanflags | DocBeanInfo.PREFERRED;
|
||||
else if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("description")){
|
||||
desc = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
/** here we create our doclet-beaninfo data structure, which we read in
|
||||
* later if it has anything worthwhile
|
||||
*/
|
||||
|
||||
// Construct a new Descriptor class
|
||||
return new DocBeanInfo(name, beanflags, desc,displayname,
|
||||
propertyeditorclass, customizerclass,
|
||||
attribs, enums);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the substring and returns the cleaned up value for the attribute.
|
||||
* @param substring Full String of the attrib tag.
|
||||
* i.e., "attribute: visualUpdate true" will return "visualUpdate true";
|
||||
*/
|
||||
private static String getValue(String substring, String prop) {
|
||||
StringTokenizer t;
|
||||
String value = "null";
|
||||
|
||||
try {
|
||||
/** if the ATTRIBUTE_NAMES is NOT the description, then we
|
||||
* parse until newline
|
||||
* if it is the description we read until the next token
|
||||
* and then look for a match in the last MAXMATCH index
|
||||
* and truncate the description
|
||||
* if it is the attribute we wead until no more
|
||||
*/
|
||||
if (prop.equalsIgnoreCase("attribute")){
|
||||
StringBuffer tmp = new StringBuffer();
|
||||
try {
|
||||
t = new StringTokenizer(substring, " :\n");
|
||||
t.nextToken().trim();//the prop
|
||||
// we want to return : key1 value1 key2 value2
|
||||
while (t.hasMoreTokens()){
|
||||
tmp.append(t.nextToken().trim()).append(" ");
|
||||
tmp.append(t.nextToken().trim()).append(" ");
|
||||
String test = t.nextToken().trim();
|
||||
if (!(test.equalsIgnoreCase("attribute")))
|
||||
break;
|
||||
}
|
||||
} catch (Exception e){
|
||||
}
|
||||
value = tmp.toString();
|
||||
}
|
||||
else if (prop.equalsIgnoreCase("enum")){
|
||||
t = new StringTokenizer(substring, ":");
|
||||
t.nextToken().trim(); // the prop we already know
|
||||
StringBuffer tmp = new StringBuffer(t.nextToken().trim());
|
||||
for (int i = 0; i < ATTRIBUTE_NAMES.length; i++){
|
||||
if (tmp.toString().endsWith(ATTRIBUTE_NAMES[i])){
|
||||
int len = ATTRIBUTE_NAMES[i].length();
|
||||
// trim off that
|
||||
tmp.setLength(tmp.length() - len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
value = tmp.toString();
|
||||
}
|
||||
else if (prop.equalsIgnoreCase("description")){
|
||||
t = new StringTokenizer(substring, ":");
|
||||
t.nextToken().trim(); // the prop we already know
|
||||
StringBuffer tmp = new StringBuffer(t.nextToken().trim());
|
||||
for (int i = 0; i < ATTRIBUTE_NAMES.length; i++){
|
||||
if (tmp.toString().endsWith(ATTRIBUTE_NAMES[i])){
|
||||
int len = ATTRIBUTE_NAMES[i].length();
|
||||
// trim off that
|
||||
tmp.setLength(tmp.length() - len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
value = hansalizeIt(tmp.toString());
|
||||
}
|
||||
else {
|
||||
// Single value properties like bound: true
|
||||
t = new StringTokenizer(substring, ":\n");
|
||||
t.nextToken().trim(); // the prop we already know
|
||||
value = t.nextToken().trim();
|
||||
}
|
||||
|
||||
// now we need to look for a match of any of the
|
||||
// property
|
||||
|
||||
return value;
|
||||
}
|
||||
catch (Exception e){
|
||||
return "invalidValue";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a HashMap containing the key value pair for the parsed values
|
||||
* of the "attributes" and "enum" tags.
|
||||
* ie. For attribute value: visualUpdate true
|
||||
* The HashMap will have key: visualUpdate, value: true
|
||||
*/
|
||||
private static HashMap getAttributeMap(String str, String delim) {
|
||||
StringTokenizer t = new StringTokenizer(str, delim);
|
||||
HashMap map = null;
|
||||
String key;
|
||||
String value;
|
||||
|
||||
int num = t.countTokens()/2;
|
||||
if (num > 0) {
|
||||
map = new HashMap();
|
||||
for (int i = 0; i < num; i++) {
|
||||
key = t.nextToken().trim();
|
||||
value = t.nextToken().trim();
|
||||
map.put(key, value);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// looks for extra spaces, \n hard-coded and invisible,etc
|
||||
private static String hansalizeIt(String from){
|
||||
char [] chars = from.toCharArray();
|
||||
int len = chars.length;
|
||||
int toss = 0;
|
||||
|
||||
// remove double spaces
|
||||
for (int i = 0; i < len; i++){
|
||||
if ((chars[i] == ' ')) {
|
||||
if (i+1 < len) {
|
||||
if ((chars[i+1] == ' ' ) || (chars[i+1] == '\n'))
|
||||
{
|
||||
--len;
|
||||
System.arraycopy(chars,i+1,chars,i,len-i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chars[i] == '\n'){
|
||||
chars[i] = ' ';
|
||||
i -= 2;
|
||||
}
|
||||
|
||||
if (chars[i] == '\\') {
|
||||
if (i+1 < len) {
|
||||
if (chars[i+1] == 'n'){
|
||||
chars[i+1] = ' ';
|
||||
--len;
|
||||
System.arraycopy(chars,i+1, chars,i, len-i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new String(chars,0,len);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,532 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package build.tools.swingbeaninfo;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.BeanDescriptor;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.PropertyDescriptor;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* A utlity for generating a BeanInfo source file from a template and a
|
||||
* Hashtable with hints that were generated from a doclet.
|
||||
* it's neccessary to write things like the per property descriptions
|
||||
* by hand. To run the application:
|
||||
* <pre>
|
||||
* java GenSwingBeanInfo <class name>
|
||||
* </pre>
|
||||
* Code for a bean info class is written to out. If the class is
|
||||
* swing package, you don't need to fully specify its name.
|
||||
*
|
||||
* @author Hans Muller
|
||||
* @author Rich Schiavi
|
||||
* @author Mark Davidson
|
||||
*/
|
||||
public class GenSwingBeanInfo {
|
||||
private final static String BEANINFO_SUFFIX = "BeanInfo.java";
|
||||
|
||||
// Tokens in @(...)
|
||||
private final static String TOK_BEANPACKAGE = "BeanPackageName";
|
||||
private final static String TOK_BEANCLASS = "BeanClassName";
|
||||
private final static String TOK_BEANOBJECT = "BeanClassObject";
|
||||
private final static String TOK_CLASSDESC = "ClassDescriptors";
|
||||
private final static String TOK_BEANDESC = "BeanDescription";
|
||||
private final static String TOK_PROPDESC = "BeanPropertyDescriptors";
|
||||
private final static String TOK_ENUMVARS = "EnumVariables";
|
||||
|
||||
private String enumcode; // Generated code for enumerated properties.
|
||||
|
||||
private boolean DEBUG = false;
|
||||
|
||||
private String fileDir;
|
||||
private String templateFilename;
|
||||
|
||||
/**
|
||||
* Public constructor
|
||||
* @param fileDir Location to put the generated source files.
|
||||
* @param templateFilename Location of the BeanInfo template
|
||||
* @param debug Flag to turn on debugging
|
||||
*/
|
||||
public GenSwingBeanInfo(String fileDir, String templateFilename, boolean debug) {
|
||||
this.fileDir = fileDir;
|
||||
this.templateFilename = templateFilename;
|
||||
this.DEBUG = debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a BeanInfo PrintStream for the class.
|
||||
*/
|
||||
private PrintStream initOutputFile(String classname) {
|
||||
try {
|
||||
OutputStream out = new FileOutputStream(fileDir + File.separator + classname + BEANINFO_SUFFIX);
|
||||
BufferedOutputStream bout = new BufferedOutputStream(out);
|
||||
return new PrintStream(out);
|
||||
} catch (IOException e){
|
||||
// System.err.println("GenSwingBeanInfo: " + e.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void messageAndExit(String msg) {
|
||||
System.err.println("\n" + msg);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load the contents of the BeanInfo template into a string and
|
||||
* return the string.
|
||||
*/
|
||||
private String loadTemplate() {
|
||||
String template = "<no template>";
|
||||
|
||||
try {
|
||||
File file = new File(templateFilename);
|
||||
DataInputStream stream = new DataInputStream(new FileInputStream(file));
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
int c;
|
||||
while((c = reader.read()) != -1) {
|
||||
buffer.append((char)c);
|
||||
}
|
||||
|
||||
template = buffer.toString();
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getMessage());
|
||||
messageAndExit("GenSwingBeanInfo: Couldn't load template: " + templateFilename + e);
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a string for the BeanDescriptor
|
||||
*/
|
||||
private String genBeanDescriptor(DocBeanInfo dbi) {
|
||||
String code = "";
|
||||
int beanflags = dbi.beanflags;
|
||||
|
||||
// we support export, hidden, preferred
|
||||
if ((beanflags & DocBeanInfo.EXPERT) != 0)
|
||||
code += " sun.swing.BeanInfoUtils.EXPERT, Boolean.TRUE,\n";
|
||||
if ((beanflags & DocBeanInfo.HIDDEN) !=0)
|
||||
code += " sun.swing.BeanInfoUtils.HIDDEN, Boolean.TRUE,\n";
|
||||
/* 1.2 only - make sure build flag build using 1.2 */
|
||||
if ((beanflags & DocBeanInfo.PREFERRED) !=0)
|
||||
code += " sun.swing.BeanInfoUtils.PREFERRED, Boolean.TRUE,\n";
|
||||
if (!(dbi.customizerclass.equals("null")))
|
||||
code += " sun.swing.BeanInfoUtils.CUSTOMIZERCLASS, " + dbi.customizerclass + ".class,\n";
|
||||
|
||||
if (dbi.attribs != null) {
|
||||
code += genAttributes(dbi.attribs);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the code for the attributes table.
|
||||
*/
|
||||
private String genAttributes(HashMap attribs) {
|
||||
StringBuffer code = new StringBuffer();
|
||||
String key;
|
||||
String value;
|
||||
|
||||
Iterator iterator = attribs.keySet().iterator();
|
||||
while(iterator.hasNext()) {
|
||||
key = (String)iterator.next();
|
||||
value = (String)attribs.get(key);
|
||||
|
||||
if (value.equals("true") || value.equals("false")) {
|
||||
// Substitute the "true" and "false" for codegen Boolean values.
|
||||
if(value.equals("true"))
|
||||
value = "Boolean.TRUE";
|
||||
else
|
||||
value = "Boolean.FALSE";
|
||||
|
||||
code.append(" \"").append(key).append("\", ").append(value).append(",\n");
|
||||
} else {
|
||||
code.append(" \"").append(key).append("\", \"").append(value).append("\",\n");
|
||||
}
|
||||
}
|
||||
return code.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the code for the enumeration.
|
||||
* XXX - side effect: Modifies the enumcode field variable.
|
||||
*/
|
||||
private String genEnumeration(String propName, HashMap enums) {
|
||||
String objectName = propName + "Enumeration";
|
||||
String key;
|
||||
String value;
|
||||
|
||||
StringBuffer code = new StringBuffer("\n\t\tObject[] ");
|
||||
code.append(objectName).append(" = new Object[] { \n");
|
||||
|
||||
Iterator iterator = enums.keySet().iterator();
|
||||
while(iterator.hasNext()) {
|
||||
key = (String)iterator.next();
|
||||
value = (String)enums.get(key);
|
||||
|
||||
code.append("\t\t\t\"").append(key).append("\" , new Integer(");
|
||||
code.append(value).append("), \"").append(value).append("\",\n");
|
||||
}
|
||||
// Close the statically initialized Object[]
|
||||
code.replace(code.length() - 2, code.length(), "\n\t\t};\n");
|
||||
|
||||
// Add this string to the enumeration code.
|
||||
enumcode += code.toString();
|
||||
|
||||
// Return the PropertyDescriptor init string;
|
||||
return " \"enumerationValues\", " + objectName + ",\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the createPropertyDescriptor() calls, one per property.
|
||||
* A fully specified createPropertyDescriptor() call looks like this:
|
||||
* <pre>
|
||||
* createPropertyDescriptor("contentPane", new Object[] {
|
||||
* BOUND, Boolean.TRUE,
|
||||
* CONSTRAINED, Boolean.TRUE,
|
||||
* PROPERTYEDITORCLASS, package.MyEditor.cl
|
||||
* WRITEMETHOD, "setContentPane",
|
||||
* DISPLAYNAME, "contentPane",
|
||||
* EXPERT, Boolean.FALSE,
|
||||
* HIDDEN, Boolean.FALSE,
|
||||
* PREFERRED, Boolean.TRUE,
|
||||
* SHORTDESCRIPTION, "A top level window with a window manager border",
|
||||
* "random attribute","random value"
|
||||
* }
|
||||
* );
|
||||
* </pre>
|
||||
*
|
||||
* @param info The actual BeanInfo class generated from from the Intospector.
|
||||
* @param dochash Set of DocBeanInfo pairs for each property. This information
|
||||
* is used to suplement the instrospected properties.
|
||||
* @return A snippet of source code which would construct all the PropertyDescriptors.
|
||||
*/
|
||||
private String genPropertyDescriptors(BeanInfo info, Hashtable dochash) {
|
||||
String code = "";
|
||||
enumcode = " "; // code for enumerated properties.
|
||||
PropertyDescriptor[] pds = info.getPropertyDescriptors();
|
||||
boolean hash_match = false;
|
||||
DocBeanInfo dbi = null;
|
||||
|
||||
for(int i = 0; i < pds.length; i++) {
|
||||
if (pds[i].getReadMethod() != null) {
|
||||
code += "\ncreatePropertyDescriptor(\"" + pds[i].getName() + "\", new Object[] {\n";
|
||||
|
||||
if (DEBUG)
|
||||
System.out.println("Introspected propertyDescriptor: " + pds[i].getName());
|
||||
|
||||
if (dochash.size() > 0 && dochash.containsKey(pds[i].getName())) {
|
||||
dbi = (DocBeanInfo)dochash.remove(pds[i].getName());
|
||||
// override/set properties on this *introspected*
|
||||
// BeanInfo pds using our DocBeanInfo class values
|
||||
setDocInfoProps(dbi, pds[i]);
|
||||
hash_match = true;
|
||||
if (DEBUG)
|
||||
System.out.println("DocBeanInfo class exists for propertyDescriptor: " + pds[i].getName() + "\n");
|
||||
} else {
|
||||
hash_match = false;
|
||||
}
|
||||
|
||||
// Do I need to do anything with this property descriptor
|
||||
if (hash_match) {
|
||||
if ((dbi.beanflags & DocBeanInfo.BOUND) != 0) {
|
||||
code += " sun.swing.BeanInfoUtils.BOUND, Boolean.TRUE,\n";
|
||||
} else {
|
||||
code += " sun.swing.BeanInfoUtils.BOUND, Boolean.FALSE,\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (pds[i].isConstrained()) {
|
||||
code += " sun.swing.BeanInfoUtils.CONSTRAINED, Boolean.TRUE,\n";
|
||||
}
|
||||
|
||||
if (pds[i].getPropertyEditorClass() != null) {
|
||||
String className = pds[i].getPropertyEditorClass().getName();
|
||||
code += " sun.swing.BeanInfoUtils.PROPERTYEDITORCLASS, " + className + ".class,\n";
|
||||
} else if ((hash_match) && (!(dbi.propertyeditorclass.equals("null")))) {
|
||||
code += " sun.swing.BeanInfoUtils.PROPERTYEDITORCLASS, " + dbi.propertyeditorclass + ".class,\n";
|
||||
}
|
||||
|
||||
if ((hash_match) && (!(dbi.customizerclass.equals("null")))) {
|
||||
code += " sun.swing.BeanInfoUtils.CUSTOMIZERCLASS, " + dbi.customizerclass + ".class,\n";
|
||||
}
|
||||
|
||||
if ((hash_match) && (dbi.enums != null)) {
|
||||
code += genEnumeration(pds[i].getName(), dbi.enums);
|
||||
}
|
||||
|
||||
if (!pds[i].getDisplayName().equals(pds[i].getName())) {
|
||||
code += " sun.swing.BeanInfoUtils.DISPLAYNAME, \"" + pds[i].getDisplayName() + "\",\n";
|
||||
}
|
||||
|
||||
if (pds[i].isExpert()) {
|
||||
code += " sun.swing.BeanInfoUtils.EXPERT, Boolean.TRUE,\n";
|
||||
}
|
||||
|
||||
if (pds[i].isHidden()) {
|
||||
code += " sun.swing.BeanInfoUtils.HIDDEN, Boolean.TRUE,\n";
|
||||
}
|
||||
|
||||
if (pds[i].isPreferred()) {
|
||||
code += " sun.swing.BeanInfoUtils.PREFERRED, Boolean.TRUE,\n";
|
||||
}
|
||||
|
||||
// user attributes
|
||||
if (hash_match) {
|
||||
if (dbi.attribs != null) {
|
||||
code += genAttributes(dbi.attribs);
|
||||
}
|
||||
}
|
||||
code += " sun.swing.BeanInfoUtils.SHORTDESCRIPTION, \"" + pds[i].getShortDescription() + "\",\n";
|
||||
|
||||
// Print the closing brackets. If this is the last array initializer,
|
||||
// don't print the trailing comma.
|
||||
if (i == (pds.length - 1)) {
|
||||
code += " }\n)\n";
|
||||
} else {
|
||||
code += " }\n),\n";
|
||||
}
|
||||
|
||||
} // end if ( readMethod != null )
|
||||
} // end for
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets properties from the BeanInfo supplement on the
|
||||
* introspected PropertyDescriptor
|
||||
*/
|
||||
private void setDocInfoProps(DocBeanInfo dbi, PropertyDescriptor pds) {
|
||||
int beanflags = dbi.beanflags;
|
||||
|
||||
if ((beanflags & DocBeanInfo.BOUND) != 0)
|
||||
pds.setBound(true);
|
||||
if ((beanflags & DocBeanInfo.EXPERT) != 0)
|
||||
pds.setExpert(true);
|
||||
if ((beanflags & DocBeanInfo.CONSTRAINED) != 0)
|
||||
pds.setConstrained(true);
|
||||
if ((beanflags & DocBeanInfo.HIDDEN) !=0)
|
||||
pds.setHidden(true);
|
||||
if ((beanflags & DocBeanInfo.PREFERRED) !=0)
|
||||
pds.setPreferred(true);
|
||||
|
||||
if (!(dbi.desc.equals("null"))){
|
||||
pds.setShortDescription(dbi.desc);
|
||||
}
|
||||
if (!(dbi.displayname.equals("null"))){
|
||||
pds.setDisplayName(dbi.displayname);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the BeanInfo source file using instrospection and a
|
||||
* Hashtable full of hints. This the only public method in this class.
|
||||
*
|
||||
* @param classname Root name of the class. i.e., JButton
|
||||
* @param dochash A hashtable containing the DocBeanInfo.
|
||||
*/
|
||||
public void genBeanInfo(String packageName, String classname, Hashtable dochash) {
|
||||
// The following initial values are just examples. All of these
|
||||
// fields are initialized below.
|
||||
String beanClassName = "JInternalFrame";
|
||||
String beanClassObject = "javax.swing.JInternalFrame.class";
|
||||
String beanDescription = "<A description of this component>.";
|
||||
String beanPropertyDescriptors = "<createSwingPropertyDescriptor code>";
|
||||
String classPropertyDescriptors = "<createSwingClassPropertyDescriptor code>";
|
||||
|
||||
Class cls = getClass(packageName, classname);
|
||||
if (cls == null){
|
||||
messageAndExit("Can't find class: " + classname);
|
||||
}
|
||||
|
||||
// Get the output stream.
|
||||
PrintStream out = initOutputFile(classname);
|
||||
|
||||
// Run the Introspector and initialize the variables
|
||||
|
||||
BeanInfo beanInfo = null;
|
||||
BeanDescriptor beanDescriptor = null;
|
||||
|
||||
try {
|
||||
if (cls == javax.swing.JComponent.class) {
|
||||
// Go all the way up the heirarchy for JComponent
|
||||
beanInfo = Introspector.getBeanInfo(cls);
|
||||
} else {
|
||||
beanInfo = Introspector.getBeanInfo(cls, cls.getSuperclass());
|
||||
}
|
||||
beanDescriptor = beanInfo.getBeanDescriptor();
|
||||
beanDescription = beanDescriptor.getShortDescription();
|
||||
} catch (IntrospectionException e) {
|
||||
messageAndExit("Introspection failed for " + cls.getName() + " " + e);
|
||||
}
|
||||
|
||||
beanClassName = beanDescriptor.getName();
|
||||
beanClassObject = cls.getName() + ".class";
|
||||
|
||||
if (DEBUG){
|
||||
System.out.println(">>>>GenSwingBeanInfo class: " + beanClassName);
|
||||
}
|
||||
// Generate the Class BeanDescriptor information first
|
||||
if (dochash.size() > 0) {
|
||||
if (dochash.containsKey(beanClassName)) {
|
||||
DocBeanInfo dbi = (DocBeanInfo)dochash.remove(beanClassName);
|
||||
classPropertyDescriptors = genBeanDescriptor(dbi);
|
||||
if (DEBUG)
|
||||
System.out.println("ClassPropertyDescriptors: " + classPropertyDescriptors);
|
||||
if (!(dbi.desc.equals("null")))
|
||||
beanDescription = dbi.desc;
|
||||
} else
|
||||
beanDescription = beanDescriptor.getShortDescription();
|
||||
} else
|
||||
beanDescription = beanDescriptor.getShortDescription();
|
||||
|
||||
// Generate the Property descriptors
|
||||
beanPropertyDescriptors = genPropertyDescriptors(beanInfo,dochash);
|
||||
|
||||
// Dump the template to out, substituting values for
|
||||
// @(token) tokens as they're encountered.
|
||||
|
||||
int currentIndex = 0;
|
||||
// not loading this to get around build issue for now
|
||||
String template = loadTemplate();
|
||||
|
||||
// This loop substitutes the "@(...)" tags in the template with the ones for the
|
||||
// current class.
|
||||
while (currentIndex < template.length()) {
|
||||
// Find the Token
|
||||
int tokenStart = template.indexOf("@(", currentIndex);
|
||||
if (tokenStart != -1) {
|
||||
out.print(template.substring(currentIndex, tokenStart));
|
||||
|
||||
int tokenEnd = template.indexOf(")", tokenStart);
|
||||
if (tokenEnd == -1) {
|
||||
messageAndExit("Bad @(<token>) beginning at " + tokenStart);
|
||||
}
|
||||
String token = template.substring(tokenStart+2, tokenEnd);
|
||||
|
||||
if (token.equals(TOK_BEANCLASS)) {
|
||||
out.print(beanClassName);
|
||||
} else if (token.equals(TOK_CLASSDESC)) {
|
||||
if (!(classPropertyDescriptors.equals("<createSwingClassPropertyDescriptor code>"))) {
|
||||
printDescriptors(out, classPropertyDescriptors, template, tokenStart);
|
||||
}
|
||||
} else if (token.equals(TOK_BEANPACKAGE)){
|
||||
out.print(packageName);
|
||||
} else if (token.equals(TOK_BEANOBJECT)) {
|
||||
out.print(beanClassObject);
|
||||
} else if (token.equals(TOK_BEANDESC)) {
|
||||
out.print(beanDescription);
|
||||
} else if (token.equals(TOK_ENUMVARS)){
|
||||
out.print(enumcode);
|
||||
} else if (token.equals(TOK_PROPDESC)) {
|
||||
printDescriptors(out, beanPropertyDescriptors, template, tokenStart);
|
||||
} else if (token.equals("#")) {
|
||||
// Ignore the @(#) Version Control tag if it exists.
|
||||
} else {
|
||||
messageAndExit("Unrecognized token @(" + token + ")");
|
||||
}
|
||||
currentIndex = tokenEnd + 1;
|
||||
} else {
|
||||
// tokenStart == -1 - We are finsihed.
|
||||
out.print(template.substring(currentIndex, template.length()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class from the package name and the class root name.
|
||||
*
|
||||
* @param packageName The name of the package of the containing class.
|
||||
* @param rootname The root name of the class. i.e, JButton
|
||||
* @return The class instance or null.
|
||||
*/
|
||||
private Class getClass(String packageName, String rootname) {
|
||||
Class cls = null;
|
||||
String classname = rootname;
|
||||
|
||||
if (packageName != null || !packageName.equals("")) {
|
||||
classname = packageName + "." + rootname;
|
||||
}
|
||||
|
||||
try {
|
||||
cls = Class.forName(classname);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// Fail silently.
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the formated descriptors to the PrintStream
|
||||
* @param out Open PrintStream
|
||||
* @param s String descriptor
|
||||
* @param template Template
|
||||
* @param tokenStart Index into the template
|
||||
*/
|
||||
private void printDescriptors(PrintStream out, String s,
|
||||
String template, int tokenStart) {
|
||||
String indent = "";
|
||||
|
||||
// Find the newline that preceeds @(BeanPropertyDescriptors) to
|
||||
// calculate the indent.
|
||||
for (int i = tokenStart; i >= 0; i--) {
|
||||
if (template.charAt(i) == '\n') {
|
||||
char[] chars = new char[tokenStart - i];
|
||||
for (int j = 0; j < chars.length; j++) {
|
||||
chars[j] = ' ';
|
||||
}
|
||||
indent = new String(chars);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while(i < s.length()) {
|
||||
int nlIndex = s.indexOf('\n', i);
|
||||
out.print(s.substring(i, nlIndex+1));
|
||||
out.print(indent);
|
||||
i = nlIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Before Width: | Height: | Size: 934 B After Width: | Height: | Size: 934 B |
|
Before Width: | Height: | Size: 893 B After Width: | Height: | Size: 893 B |
|
Before Width: | Height: | Size: 99 B After Width: | Height: | Size: 99 B |
|
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 148 B |
|
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 68 B |
|
Before Width: | Height: | Size: 108 B After Width: | Height: | Size: 108 B |
|
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 78 B After Width: | Height: | Size: 78 B |
|
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 330 B After Width: | Height: | Size: 330 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 66 B After Width: | Height: | Size: 66 B |
|
Before Width: | Height: | Size: 111 B After Width: | Height: | Size: 111 B |
|
Before Width: | Height: | Size: 186 B After Width: | Height: | Size: 186 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 657 B After Width: | Height: | Size: 657 B |
|
Before Width: | Height: | Size: 829 B After Width: | Height: | Size: 829 B |
|
Before Width: | Height: | Size: 71 B After Width: | Height: | Size: 71 B |
|
Before Width: | Height: | Size: 129 B After Width: | Height: | Size: 129 B |
|
Before Width: | Height: | Size: 62 B After Width: | Height: | Size: 62 B |
|
Before Width: | Height: | Size: 104 B After Width: | Height: | Size: 104 B |
|
Before Width: | Height: | Size: 582 B After Width: | Height: | Size: 582 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 78 B After Width: | Height: | Size: 78 B |
|
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 142 B |
|
Before Width: | Height: | Size: 329 B After Width: | Height: | Size: 329 B |
|
Before Width: | Height: | Size: 672 B After Width: | Height: | Size: 672 B |
|
Before Width: | Height: | Size: 63 B After Width: | Height: | Size: 63 B |
|
Before Width: | Height: | Size: 101 B After Width: | Height: | Size: 101 B |
|
Before Width: | Height: | Size: 889 B After Width: | Height: | Size: 889 B |
|
Before Width: | Height: | Size: 166 B After Width: | Height: | Size: 166 B |
|
Before Width: | Height: | Size: 273 B After Width: | Height: | Size: 273 B |
|
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 68 B |
|
Before Width: | Height: | Size: 137 B After Width: | Height: | Size: 137 B |
|
Before Width: | Height: | Size: 248 B After Width: | Height: | Size: 248 B |
|
Before Width: | Height: | Size: 414 B After Width: | Height: | Size: 414 B |
|
Before Width: | Height: | Size: 76 B After Width: | Height: | Size: 76 B |
|
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 142 B |
|
Before Width: | Height: | Size: 145 B After Width: | Height: | Size: 145 B |
|
Before Width: | Height: | Size: 225 B After Width: | Height: | Size: 225 B |
|
Before Width: | Height: | Size: 71 B After Width: | Height: | Size: 71 B |
|
Before Width: | Height: | Size: 141 B After Width: | Height: | Size: 141 B |
|
Before Width: | Height: | Size: 255 B After Width: | Height: | Size: 255 B |
|
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 435 B |
|
Before Width: | Height: | Size: 71 B After Width: | Height: | Size: 71 B |
|
Before Width: | Height: | Size: 141 B After Width: | Height: | Size: 141 B |
|
Before Width: | Height: | Size: 125 B After Width: | Height: | Size: 125 B |
|
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 192 B |
|
Before Width: | Height: | Size: 62 B After Width: | Height: | Size: 62 B |
|
Before Width: | Height: | Size: 106 B After Width: | Height: | Size: 106 B |
|
Before Width: | Height: | Size: 144 B After Width: | Height: | Size: 144 B |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 218 B |
|
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 68 B |
|
Before Width: | Height: | Size: 124 B After Width: | Height: | Size: 124 B |
|
Before Width: | Height: | Size: 114 B After Width: | Height: | Size: 114 B |
|
Before Width: | Height: | Size: 179 B After Width: | Height: | Size: 179 B |
|
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 68 B |
|
Before Width: | Height: | Size: 122 B After Width: | Height: | Size: 122 B |
|
Before Width: | Height: | Size: 88 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 130 B After Width: | Height: | Size: 130 B |
|
Before Width: | Height: | Size: 59 B After Width: | Height: | Size: 59 B |
|
Before Width: | Height: | Size: 100 B After Width: | Height: | Size: 100 B |
|
Before Width: | Height: | Size: 156 B After Width: | Height: | Size: 156 B |
|
Before Width: | Height: | Size: 270 B After Width: | Height: | Size: 270 B |
|
Before Width: | Height: | Size: 83 B After Width: | Height: | Size: 83 B |
|
Before Width: | Height: | Size: 159 B After Width: | Height: | Size: 159 B |
|
Before Width: | Height: | Size: 155 B After Width: | Height: | Size: 155 B |
|
Before Width: | Height: | Size: 265 B After Width: | Height: | Size: 265 B |
|
Before Width: | Height: | Size: 74 B After Width: | Height: | Size: 74 B |
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 140 B After Width: | Height: | Size: 140 B |
|
Before Width: | Height: | Size: 517 B After Width: | Height: | Size: 517 B |
|
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 68 B |
|
Before Width: | Height: | Size: 111 B After Width: | Height: | Size: 111 B |
|
Before Width: | Height: | Size: 112 B After Width: | Height: | Size: 112 B |
|
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 184 B |
|
Before Width: | Height: | Size: 139 B After Width: | Height: | Size: 139 B |
|
Before Width: | Height: | Size: 176 B After Width: | Height: | Size: 176 B |
|
Before Width: | Height: | Size: 69 B After Width: | Height: | Size: 69 B |
|
Before Width: | Height: | Size: 121 B After Width: | Height: | Size: 121 B |
|
Before Width: | Height: | Size: 71 B After Width: | Height: | Size: 71 B |
|
Before Width: | Height: | Size: 123 B After Width: | Height: | Size: 123 B |
|
Before Width: | Height: | Size: 236 B After Width: | Height: | Size: 236 B |
|
Before Width: | Height: | Size: 881 B After Width: | Height: | Size: 881 B |
|
Before Width: | Height: | Size: 77 B After Width: | Height: | Size: 77 B |
|
Before Width: | Height: | Size: 169 B After Width: | Height: | Size: 169 B |
|
Before Width: | Height: | Size: 99 B After Width: | Height: | Size: 99 B |
|
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 148 B |
|
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 68 B |
|
Before Width: | Height: | Size: 108 B After Width: | Height: | Size: 108 B |
|
Before Width: | Height: | Size: 130 B After Width: | Height: | Size: 130 B |
|
Before Width: | Height: | Size: 182 B After Width: | Height: | Size: 182 B |