package jadex.rules.state; import jadex.commons.IPropertyObject; import jadex.commons.SReflect; import jadex.commons.SUtil; import java.beans.PropertyDescriptor; import java.lang.reflect.Array; import java.lang.reflect.Method; /** * Attribute type for Java object types. */ public class OAVJavaAttributeType extends OAVAttributeType { //-------- attributes -------- /** The property descriptor. */ protected PropertyDescriptor propdesc; /** The property object read method. */ protected static Method propreadmethod; //-------- constructors -------- /** * Create a new OAV attribute type. * @param otype The object type holding the attribute. * @param name The name of the OAV attribute type. * @param mult The multiplicity. * @param type The type. * @param def The default value. */ public OAVJavaAttributeType(OAVObjectType otype, String name, OAVObjectType type, String mult, Object def, PropertyDescriptor propdesc) { super(otype, name, type, mult, def, null); this.propdesc = propdesc; } //-------- methods -------- /** * Compute the hashcode. * @return The hashcode. */ // Hack!!! Do not include otype in hashcode, as attribute can be inherited. protected int calcHashCode() { final int prime = 31; int result = prime + name.hashCode(); // result = prime * result + otype.hashCode(); result = prime * result + type.hashCode(); return result; } /** * Test for equality. * @return True, if equal. */ public boolean equals(Object obj) { boolean ret = this==obj; if(!ret && obj instanceof OAVJavaAttributeType) { OAVJavaAttributeType attr = (OAVJavaAttributeType)obj; if(SUtil.equals(name, attr.getName())) { Class clazz1 = ((OAVJavaType)otype).getClazz(); Class clazz2 = ((OAVJavaType)attr.getObjectType()).getClazz(); ret = SReflect.isSupertype(clazz1, clazz2) || SReflect.isSupertype(clazz2, clazz1); } } return ret; } /** * Get the attribute value from a given object. * @param object The object. * @return The value. */ public Object accessProperty(Object object) { Object ret; // Length of arrays. if("length".equals(getName()) && ((OAVJavaType)getObjectType()).getClazz().isArray()) { ret = new Integer(Array.getLength(object)); } // A property of an IPropertyObject. else if(IPropertyObject.class.isAssignableFrom(((OAVJavaType)getObjectType()).getClazz())) { try { if(propreadmethod==null) propreadmethod = IPropertyObject.class.getMethod("getProperty", new Class[]{String.class}); ret = propreadmethod.invoke(object, new Object[]{name}); } catch(Exception e) { throw new RuntimeException(e); } } // Bean method. else { Method rm = propdesc.getReadMethod(); if(rm==null) throw new RuntimeException("No attribute accessor found: "+this); try { ret = rm.invoke(object, new Object[0]); } catch(Exception e) { throw new RuntimeException(e); } } return ret; } }