summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/gnu/java/beans/IntrospectionIncubator.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/java/beans/IntrospectionIncubator.java')
-rw-r--r--libjava/classpath/gnu/java/beans/IntrospectionIncubator.java724
1 files changed, 362 insertions, 362 deletions
diff --git a/libjava/classpath/gnu/java/beans/IntrospectionIncubator.java b/libjava/classpath/gnu/java/beans/IntrospectionIncubator.java
index e0d9480e327..978429a1ec3 100644
--- a/libjava/classpath/gnu/java/beans/IntrospectionIncubator.java
+++ b/libjava/classpath/gnu/java/beans/IntrospectionIncubator.java
@@ -7,7 +7,7 @@ GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -69,373 +69,373 @@ import java.util.Vector;
**/
public class IntrospectionIncubator {
- Hashtable propertyMethods = new Hashtable();
- Hashtable listenerMethods = new Hashtable();
- Vector otherMethods = new Vector();
-
- Class propertyStopClass;
- Class eventStopClass;
- Class methodStopClass;
-
- public IntrospectionIncubator() {
- }
-
- /** Examines the given method and files it in a suitable collection.
- * It files the method as a property method if it finds:
- * <ul>
- * <li>boolean "is" getter</li>
- * <li>"get" style getter</li>
- * <li>single argument setter</li>
- * <li>indiced setter and getter</li>
- * </ul>
- * It files the method as a listener method if all of these rules apply:
- * <ul>
- * <li>the method name starts with "add" or "remove"</li>
- * <li>there is only a single argument</li>
- * <li>the argument type is a subclass of <code>java.util.EventListener</code></li>
- * </ul>
- * All public methods are filed as such.
- *
- * @param method The method instance to examine.
- */
- public void addMethod(Method method) {
- if(Modifier.isPublic(method.getModifiers())) {
- String name = ClassHelper.getTruncatedName(method.getName());
- Class retType = method.getReturnType();
- Class[] params = method.getParameterTypes();
- boolean isVoid = retType.equals(java.lang.Void.TYPE);
- Class methodClass = method.getDeclaringClass();
-
- /* Accepts the method for examination if no stop class is given or the method is declared in a subclass of the stop class.
- * The rules for this are described in {@link java.beans.Introspector.getBeanInfo(Class, Class)}.
- * This block finds out whether the method is a suitable getter or setter method (or read/write method).
- */
- if(isReachable(propertyStopClass, methodClass)) {
- /* At this point a method may regarded as a property's read or write method if its name
- * starts with "is", "get" or "set". However, if a method is static it cannot be part
- * of a property.
- */
- if(Modifier.isStatic(method.getModifiers())) {
- // files method as other because it is static
- otherMethods.addElement(method);
- } else if(name.startsWith("is")
- && retType.equals(java.lang.Boolean.TYPE)
- && params.length == 0) {
- // files method as boolean "is" style getter
- addToPropertyHash(name,method,IS);
- } else if(name.startsWith("get") && !isVoid) {
- if(params.length == 0) {
- // files as legal non-argument getter
- addToPropertyHash(name,method,GET);
- } else if(params.length == 1 && params[0].equals(java.lang.Integer.TYPE)) {
- // files as legal indiced getter
- addToPropertyHash(name,method,GET_I);
- } else {
- // files as other because the method's signature is not Bean-like
- otherMethods.addElement(method);
- }
- } else if(name.startsWith("set") && isVoid) {
- if(params.length == 1) {
- // files as legal single-argument setter method
- addToPropertyHash(name,method,SET);
- } else if(params.length == 2 && params[0].equals(java.lang.Integer.TYPE)) {
- // files as legal indiced setter method
- addToPropertyHash(name,method,SET_I);
- } else {
- // files as other because the method's signature is not Bean-like
- otherMethods.addElement(method);
- }
- }
- }
-
- if(isReachable(eventStopClass, methodClass)) {
- if(name.startsWith("add")
- && isVoid
- && params.length == 1
- && java.util.EventListener.class.isAssignableFrom(params[0])) {
- addToListenerHash(name,method,ADD);
- } else if(name.startsWith("remove")
- && isVoid
- && params.length == 1
- && java.util.EventListener.class.isAssignableFrom(params[0])) {
- addToListenerHash(name,method,REMOVE);
- }
- }
-
- if(isReachable(methodStopClass, methodClass)) {
- // files as reachable public method
- otherMethods.addElement(method);
- }
-
- }
- }
-
- public void addMethods(Method[] m) {
- for(int i=0;i<m.length;i++) {
- addMethod(m[i]);
- }
- }
-
- public void setPropertyStopClass(Class c) {
- propertyStopClass = c;
- }
-
- public void setEventStopClass(Class c) {
- eventStopClass = c;
- }
-
- public void setMethodStopClass(Class c) {
- methodStopClass = c;
- }
-
-
- public BeanInfoEmbryo getBeanInfoEmbryo() throws IntrospectionException {
- BeanInfoEmbryo b = new BeanInfoEmbryo();
- findXXX(b,IS);
- findXXXInt(b,GET_I);
- findXXXInt(b,SET_I);
- findXXX(b,GET);
- findXXX(b,SET);
- findAddRemovePairs(b);
- for(int i=0;i<otherMethods.size();i++) {
- MethodDescriptor newMethod = new MethodDescriptor((Method)otherMethods.elementAt(i));
- if(!b.hasMethod(newMethod)) {
- b.addMethod(new MethodDescriptor((Method)otherMethods.elementAt(i)));
- }
- }
- return b;
- }
-
- public BeanInfo getBeanInfo() throws IntrospectionException {
- return getBeanInfoEmbryo().getBeanInfo();
- }
-
-
- void findAddRemovePairs(BeanInfoEmbryo b) throws IntrospectionException {
- Enumeration listenerEnum = listenerMethods.keys();
- while(listenerEnum.hasMoreElements()) {
- DoubleKey k = (DoubleKey)listenerEnum.nextElement();
- Method[] m = (Method[])listenerMethods.get(k);
- if(m[ADD] != null && m[REMOVE] != null) {
- EventSetDescriptor e = new EventSetDescriptor(Introspector.decapitalize(k.getName()),
- k.getType(), k.getType().getMethods(),
- m[ADD],m[REMOVE]);
- e.setUnicast(ArrayHelper.contains(m[ADD].getExceptionTypes(),java.util.TooManyListenersException.class));
- if(!b.hasEvent(e)) {
- b.addEvent(e);
- }
- }
- }
- }
-
- void findXXX(BeanInfoEmbryo b, int funcType) throws IntrospectionException {
- Enumeration keys = propertyMethods.keys();
- while(keys.hasMoreElements()) {
- DoubleKey k = (DoubleKey)keys.nextElement();
- Method[] m = (Method[])propertyMethods.get(k);
- if(m[funcType] != null) {
- PropertyDescriptor p = new PropertyDescriptor(Introspector.decapitalize(k.getName()),
- m[IS] != null ? m[IS] : m[GET],
- m[SET]);
- if(m[SET] != null) {
- p.setConstrained(ArrayHelper.contains(m[SET].getExceptionTypes(),java.beans.PropertyVetoException.class));
- }
- if(!b.hasProperty(p)) {
- b.addProperty(p);
- }
- }
- }
- }
-
- void findXXXInt(BeanInfoEmbryo b, int funcType) throws IntrospectionException {
- Enumeration keys = propertyMethods.keys();
- while(keys.hasMoreElements()) {
- DoubleKey k = (DoubleKey)keys.nextElement();
- Method[] m = (Method[])propertyMethods.get(k);
- if(m[funcType] != null) {
- boolean constrained;
- if(m[SET_I] != null) {
- constrained = ArrayHelper.contains(m[SET_I].getExceptionTypes(),java.beans.PropertyVetoException.class);
- } else {
- constrained = false;
- }
-
- /** Find out if there is an array type get or set **/
- Class arrayType = Array.newInstance(k.getType(),0).getClass();
- DoubleKey findSetArray = new DoubleKey(arrayType,k.getName());
- Method[] m2 = (Method[])propertyMethods.get(findSetArray);
- IndexedPropertyDescriptor p;
- if(m2 == null) {
- p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()),
- null,null,
- m[GET_I],m[SET_I]);
- } else {
- if(constrained && m2[SET] != null) {
- constrained = ArrayHelper.contains(m2[SET].getExceptionTypes(),java.beans.PropertyVetoException.class);
- }
- p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()),
- m2[GET],m2[SET],
- m[GET_I],m[SET_I]);
- }
- p.setConstrained(constrained);
- if(!b.hasProperty(p)) {
- b.addProperty(p);
- }
- }
- }
- }
-
- static final int IS=0;
- static final int GET_I=1;
- static final int SET_I=2;
- static final int GET=3;
- static final int SET=4;
-
- static final int ADD=0;
- static final int REMOVE=1;
-
- void addToPropertyHash(String name, Method method, int funcType) {
- String newName;
- Class type;
-
- switch(funcType) {
- case IS:
- type = java.lang.Boolean.TYPE;
- newName = name.substring(2);
- break;
- case GET_I:
- type = method.getReturnType();
- newName = name.substring(3);
- break;
- case SET_I:
- type = method.getParameterTypes()[1];
- newName = name.substring(3);
- break;
- case GET:
- type = method.getReturnType();
- newName = name.substring(3);
- break;
- case SET:
- type = method.getParameterTypes()[0];
- newName = name.substring(3);
- break;
- default:
- return;
- }
- newName = capitalize(newName);
- if (newName.length() == 0)
- return;
-
- DoubleKey k = new DoubleKey(type,newName);
- Method[] methods = (Method[])propertyMethods.get(k);
- if(methods == null) {
- methods = new Method[5];
- propertyMethods.put(k,methods);
- }
- methods[funcType] = method;
- }
-
- void addToListenerHash(String name, Method method, int funcType) {
- String newName;
- Class type;
-
- switch(funcType) {
- case ADD:
- type = method.getParameterTypes()[0];
- newName = name.substring(3,name.length()-8);
- break;
- case REMOVE:
- type = method.getParameterTypes()[0];
- newName = name.substring(6,name.length()-8);
- break;
- default:
- return;
- }
- newName = capitalize(newName);
- if (newName.length() == 0)
- return;
-
- DoubleKey k = new DoubleKey(type,newName);
- Method[] methods = (Method[])listenerMethods.get(k);
- if(methods == null) {
- methods = new Method[2];
- listenerMethods.put(k,methods);
- }
- methods[funcType] = method;
- }
-
- /* Determines whether <code>stopClass</code> is <code>null</code>
- * or <code>declaringClass<code> is a true subclass of <code>stopClass</code>.
- * This expression is useful to detect whether a method should be introspected or not.
- * The rules for this are described in {@link java.beans.Introspector.getBeanInfo(Class, Class)}.
- */
- static boolean isReachable(Class stopClass, Class declaringClass) {
- return stopClass == null || (stopClass.isAssignableFrom(declaringClass) && !stopClass.equals(declaringClass));
- }
-
- /** Transforms a property name into a part of a method name.
- * E.g. "value" becomes "Value" which can then concatenated with
- * "set", "get" or "is" to form a valid method name.
- *
- * Implementation notes:
- * If "" is the argument, it is returned without changes.
- * If <code>null</code> is the argument, <code>null</code> is returned.
- *
- * @param name Name of a property.
- * @return Part of a method name of a property.
- */
- static String capitalize(String name) {
- try {
- if(Character.isUpperCase(name.charAt(0))) {
- return name;
- } else {
- char[] c = name.toCharArray();
- c[0] = Character.toLowerCase(c[0]);
- return new String(c);
- }
- } catch(StringIndexOutOfBoundsException E) {
- return name;
- } catch(NullPointerException E) {
- return null;
- }
- }
+ Hashtable propertyMethods = new Hashtable();
+ Hashtable listenerMethods = new Hashtable();
+ Vector otherMethods = new Vector();
+
+ Class propertyStopClass;
+ Class eventStopClass;
+ Class methodStopClass;
+
+ public IntrospectionIncubator() {
+ }
+
+ /** Examines the given method and files it in a suitable collection.
+ * It files the method as a property method if it finds:
+ * <ul>
+ * <li>boolean "is" getter</li>
+ * <li>"get" style getter</li>
+ * <li>single argument setter</li>
+ * <li>indiced setter and getter</li>
+ * </ul>
+ * It files the method as a listener method if all of these rules apply:
+ * <ul>
+ * <li>the method name starts with "add" or "remove"</li>
+ * <li>there is only a single argument</li>
+ * <li>the argument type is a subclass of <code>java.util.EventListener</code></li>
+ * </ul>
+ * All public methods are filed as such.
+ *
+ * @param method The method instance to examine.
+ */
+ public void addMethod(Method method) {
+ if(Modifier.isPublic(method.getModifiers())) {
+ String name = ClassHelper.getTruncatedName(method.getName());
+ Class retType = method.getReturnType();
+ Class[] params = method.getParameterTypes();
+ boolean isVoid = retType.equals(java.lang.Void.TYPE);
+ Class methodClass = method.getDeclaringClass();
+
+ /* Accepts the method for examination if no stop class is given or the method is declared in a subclass of the stop class.
+ * The rules for this are described in {@link java.beans.Introspector.getBeanInfo(Class, Class)}.
+ * This block finds out whether the method is a suitable getter or setter method (or read/write method).
+ */
+ if(isReachable(propertyStopClass, methodClass)) {
+ /* At this point a method may regarded as a property's read or write method if its name
+ * starts with "is", "get" or "set". However, if a method is static it cannot be part
+ * of a property.
+ */
+ if(Modifier.isStatic(method.getModifiers())) {
+ // files method as other because it is static
+ otherMethods.addElement(method);
+ } else if(name.startsWith("is")
+ && retType.equals(java.lang.Boolean.TYPE)
+ && params.length == 0) {
+ // files method as boolean "is" style getter
+ addToPropertyHash(name,method,IS);
+ } else if(name.startsWith("get") && !isVoid) {
+ if(params.length == 0) {
+ // files as legal non-argument getter
+ addToPropertyHash(name,method,GET);
+ } else if(params.length == 1 && params[0].equals(java.lang.Integer.TYPE)) {
+ // files as legal indiced getter
+ addToPropertyHash(name,method,GET_I);
+ } else {
+ // files as other because the method's signature is not Bean-like
+ otherMethods.addElement(method);
+ }
+ } else if(name.startsWith("set") && isVoid) {
+ if(params.length == 1) {
+ // files as legal single-argument setter method
+ addToPropertyHash(name,method,SET);
+ } else if(params.length == 2 && params[0].equals(java.lang.Integer.TYPE)) {
+ // files as legal indiced setter method
+ addToPropertyHash(name,method,SET_I);
+ } else {
+ // files as other because the method's signature is not Bean-like
+ otherMethods.addElement(method);
+ }
+ }
+ }
+
+ if(isReachable(eventStopClass, methodClass)) {
+ if(name.startsWith("add")
+ && isVoid
+ && params.length == 1
+ && java.util.EventListener.class.isAssignableFrom(params[0])) {
+ addToListenerHash(name,method,ADD);
+ } else if(name.startsWith("remove")
+ && isVoid
+ && params.length == 1
+ && java.util.EventListener.class.isAssignableFrom(params[0])) {
+ addToListenerHash(name,method,REMOVE);
+ }
+ }
+
+ if(isReachable(methodStopClass, methodClass)) {
+ // files as reachable public method
+ otherMethods.addElement(method);
+ }
+
+ }
+ }
+
+ public void addMethods(Method[] m) {
+ for(int i=0;i<m.length;i++) {
+ addMethod(m[i]);
+ }
+ }
+
+ public void setPropertyStopClass(Class c) {
+ propertyStopClass = c;
+ }
+
+ public void setEventStopClass(Class c) {
+ eventStopClass = c;
+ }
+
+ public void setMethodStopClass(Class c) {
+ methodStopClass = c;
+ }
+
+
+ public BeanInfoEmbryo getBeanInfoEmbryo() throws IntrospectionException {
+ BeanInfoEmbryo b = new BeanInfoEmbryo();
+ findXXX(b,IS);
+ findXXXInt(b,GET_I);
+ findXXXInt(b,SET_I);
+ findXXX(b,GET);
+ findXXX(b,SET);
+ findAddRemovePairs(b);
+ for(int i=0;i<otherMethods.size();i++) {
+ MethodDescriptor newMethod = new MethodDescriptor((Method)otherMethods.elementAt(i));
+ if(!b.hasMethod(newMethod)) {
+ b.addMethod(new MethodDescriptor((Method)otherMethods.elementAt(i)));
+ }
+ }
+ return b;
+ }
+
+ public BeanInfo getBeanInfo() throws IntrospectionException {
+ return getBeanInfoEmbryo().getBeanInfo();
+ }
+
+
+ void findAddRemovePairs(BeanInfoEmbryo b) throws IntrospectionException {
+ Enumeration listenerEnum = listenerMethods.keys();
+ while(listenerEnum.hasMoreElements()) {
+ DoubleKey k = (DoubleKey)listenerEnum.nextElement();
+ Method[] m = (Method[])listenerMethods.get(k);
+ if(m[ADD] != null && m[REMOVE] != null) {
+ EventSetDescriptor e = new EventSetDescriptor(Introspector.decapitalize(k.getName()),
+ k.getType(), k.getType().getMethods(),
+ m[ADD],m[REMOVE]);
+ e.setUnicast(ArrayHelper.contains(m[ADD].getExceptionTypes(),java.util.TooManyListenersException.class));
+ if(!b.hasEvent(e)) {
+ b.addEvent(e);
+ }
+ }
+ }
+ }
+
+ void findXXX(BeanInfoEmbryo b, int funcType) throws IntrospectionException {
+ Enumeration keys = propertyMethods.keys();
+ while(keys.hasMoreElements()) {
+ DoubleKey k = (DoubleKey)keys.nextElement();
+ Method[] m = (Method[])propertyMethods.get(k);
+ if(m[funcType] != null) {
+ PropertyDescriptor p = new PropertyDescriptor(Introspector.decapitalize(k.getName()),
+ m[IS] != null ? m[IS] : m[GET],
+ m[SET]);
+ if(m[SET] != null) {
+ p.setConstrained(ArrayHelper.contains(m[SET].getExceptionTypes(),java.beans.PropertyVetoException.class));
+ }
+ if(!b.hasProperty(p)) {
+ b.addProperty(p);
+ }
+ }
+ }
+ }
+
+ void findXXXInt(BeanInfoEmbryo b, int funcType) throws IntrospectionException {
+ Enumeration keys = propertyMethods.keys();
+ while(keys.hasMoreElements()) {
+ DoubleKey k = (DoubleKey)keys.nextElement();
+ Method[] m = (Method[])propertyMethods.get(k);
+ if(m[funcType] != null) {
+ boolean constrained;
+ if(m[SET_I] != null) {
+ constrained = ArrayHelper.contains(m[SET_I].getExceptionTypes(),java.beans.PropertyVetoException.class);
+ } else {
+ constrained = false;
+ }
+
+ /** Find out if there is an array type get or set **/
+ Class arrayType = Array.newInstance(k.getType(),0).getClass();
+ DoubleKey findSetArray = new DoubleKey(arrayType,k.getName());
+ Method[] m2 = (Method[])propertyMethods.get(findSetArray);
+ IndexedPropertyDescriptor p;
+ if(m2 == null) {
+ p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()),
+ null,null,
+ m[GET_I],m[SET_I]);
+ } else {
+ if(constrained && m2[SET] != null) {
+ constrained = ArrayHelper.contains(m2[SET].getExceptionTypes(),java.beans.PropertyVetoException.class);
+ }
+ p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()),
+ m2[GET],m2[SET],
+ m[GET_I],m[SET_I]);
+ }
+ p.setConstrained(constrained);
+ if(!b.hasProperty(p)) {
+ b.addProperty(p);
+ }
+ }
+ }
+ }
+
+ static final int IS=0;
+ static final int GET_I=1;
+ static final int SET_I=2;
+ static final int GET=3;
+ static final int SET=4;
+
+ static final int ADD=0;
+ static final int REMOVE=1;
+
+ void addToPropertyHash(String name, Method method, int funcType) {
+ String newName;
+ Class type;
+
+ switch(funcType) {
+ case IS:
+ type = java.lang.Boolean.TYPE;
+ newName = name.substring(2);
+ break;
+ case GET_I:
+ type = method.getReturnType();
+ newName = name.substring(3);
+ break;
+ case SET_I:
+ type = method.getParameterTypes()[1];
+ newName = name.substring(3);
+ break;
+ case GET:
+ type = method.getReturnType();
+ newName = name.substring(3);
+ break;
+ case SET:
+ type = method.getParameterTypes()[0];
+ newName = name.substring(3);
+ break;
+ default:
+ return;
+ }
+ newName = capitalize(newName);
+ if (newName.length() == 0)
+ return;
+
+ DoubleKey k = new DoubleKey(type,newName);
+ Method[] methods = (Method[])propertyMethods.get(k);
+ if(methods == null) {
+ methods = new Method[5];
+ propertyMethods.put(k,methods);
+ }
+ methods[funcType] = method;
+ }
+
+ void addToListenerHash(String name, Method method, int funcType) {
+ String newName;
+ Class type;
+
+ switch(funcType) {
+ case ADD:
+ type = method.getParameterTypes()[0];
+ newName = name.substring(3,name.length()-8);
+ break;
+ case REMOVE:
+ type = method.getParameterTypes()[0];
+ newName = name.substring(6,name.length()-8);
+ break;
+ default:
+ return;
+ }
+ newName = capitalize(newName);
+ if (newName.length() == 0)
+ return;
+
+ DoubleKey k = new DoubleKey(type,newName);
+ Method[] methods = (Method[])listenerMethods.get(k);
+ if(methods == null) {
+ methods = new Method[2];
+ listenerMethods.put(k,methods);
+ }
+ methods[funcType] = method;
+ }
+
+ /* Determines whether <code>stopClass</code> is <code>null</code>
+ * or <code>declaringClass<code> is a true subclass of <code>stopClass</code>.
+ * This expression is useful to detect whether a method should be introspected or not.
+ * The rules for this are described in {@link java.beans.Introspector.getBeanInfo(Class, Class)}.
+ */
+ static boolean isReachable(Class stopClass, Class declaringClass) {
+ return stopClass == null || (stopClass.isAssignableFrom(declaringClass) && !stopClass.equals(declaringClass));
+ }
+
+ /** Transforms a property name into a part of a method name.
+ * E.g. "value" becomes "Value" which can then concatenated with
+ * "set", "get" or "is" to form a valid method name.
+ *
+ * Implementation notes:
+ * If "" is the argument, it is returned without changes.
+ * If <code>null</code> is the argument, <code>null</code> is returned.
+ *
+ * @param name Name of a property.
+ * @return Part of a method name of a property.
+ */
+ static String capitalize(String name) {
+ try {
+ if(Character.isUpperCase(name.charAt(0))) {
+ return name;
+ } else {
+ char[] c = name.toCharArray();
+ c[0] = Character.toLowerCase(c[0]);
+ return new String(c);
+ }
+ } catch(StringIndexOutOfBoundsException E) {
+ return name;
+ } catch(NullPointerException E) {
+ return null;
+ }
+ }
}
/** This class is a hashmap key that consists of a <code>Class</code> and a
* <code>String</code> element.
- *
+ *
* It is used for XXX: find out what this is used for
- *
+ *
* @author John Keiser
* @author Robert Schuster
- */
+ */
class DoubleKey {
- Class type;
- String name;
-
- DoubleKey(Class type, String name) {
- this.type = type;
- this.name = name;
- }
-
- Class getType() {
- return type;
- }
-
- String getName() {
- return name;
- }
-
- public boolean equals(Object o) {
- if(o instanceof DoubleKey) {
- DoubleKey d = (DoubleKey)o;
- return d.type.equals(type) && d.name.equals(name);
- } else {
- return false;
- }
- }
-
- public int hashCode() {
- return type.hashCode() ^ name.hashCode();
- }
+ Class type;
+ String name;
+
+ DoubleKey(Class type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+
+ Class getType() {
+ return type;
+ }
+
+ String getName() {
+ return name;
+ }
+
+ public boolean equals(Object o) {
+ if(o instanceof DoubleKey) {
+ DoubleKey d = (DoubleKey)o;
+ return d.type.equals(type) && d.name.equals(name);
+ } else {
+ return false;
+ }
+ }
+
+ public int hashCode() {
+ return type.hashCode() ^ name.hashCode();
+ }
}
OpenPOWER on IntegriCloud