001    /**
002     * Attribute.java
003     * jCOLIBRI2 framework. 
004     * @author Juan A. Recio-García.
005     * GAIA - Group for Artificial Intelligence Applications
006     * http://gaia.fdi.ucm.es
007     * 03/01/2007
008     */
009    package jcolibri.cbrcore;
010    
011    import java.lang.reflect.Field;
012    
013    import jcolibri.exception.AttributeAccessException;
014    
015    /**
016     * This class identifies an attribute of a CaseComponent (Java Bean). Attributes are part of CaseComponents and CaseComponentes build a case. 
017     * Note that each CaseComponent must be a Java Bean, so this class represents a field of a Java Bean (with its getXXX() and setXXX() methods).
018     * 
019     * @see jcolibri.cbrcore.CaseComponent
020     * @author Juan A. Recio-García
021     */
022    public class Attribute {
023    
024            private Field field;
025            
026            /**
027             * Creates an Attribute using the Field obtained with Reflection (getClass.getDeclaredField(name)). It is recommended to use the other constructor.
028             */
029            public Attribute(Field f)
030            {
031                    field = f;
032            }
033            
034            /**
035             * Creates an attribute. The attribute name must be an existing field of the class and have the get/set() methods.
036             * @param attributeName Name of the field
037             * @param _class Class that the attribute belongs to.
038             */
039            public Attribute(String attributeName, Class _class)
040            {
041                    try {
042                            field = _class.getDeclaredField(attributeName);
043                    } catch (Exception e) {
044                            org.apache.commons.logging.LogFactory.getLog(this.getClass()).error(e + "Attribute: "+ attributeName+ " Class:" + _class.getName());
045                    }
046            }
047            
048            /**
049             * Returns the name of the field.
050             */
051            public String getName()
052            {
053                    return field.getName();
054            }
055            
056            /**
057             * Returns the class that this attribute belongs to.
058             */
059            public Class<?> getDeclaringClass()
060            {
061                    return field.getDeclaringClass();
062            }
063            
064            /**
065             * Returns the type of the attribute.
066             */
067            public Class<?> getType()
068            {
069                    return field.getType();
070            }
071            
072            /**
073             * Returns the value of the attribute for a concrete object. Of course, the object must be instance of the class that this attribute belongs to.
074             * @param obj Instance to obtain the attribute from
075             * @throws AttributeAccessException
076             */
077            public Object getValue(Object obj) throws AttributeAccessException
078            {
079                    Object res = null;
080                    try{
081                            res = field.get(obj);
082                            return res;
083                    }catch(Exception e)
084                    {}
085    
086                    try{
087                            java.beans.PropertyDescriptor pd = new java.beans.PropertyDescriptor(field.getName(),field.getDeclaringClass());
088                            res = pd.getReadMethod().invoke(obj, (Object[])null);
089                            return res;
090                    }catch(Exception e)
091                    {}
092                    throw new AttributeAccessException("Error getting value from object: "+obj+", attribute: "+field.getName());
093    
094            }
095            
096            /**
097             * Sets the value of the attribute in a concrete object.
098             * @param obj Object that defines the attribute to set.
099             * @param value Value to set.
100             * @throws AttributeAccessException
101             */
102            public void setValue(Object obj, Object value) throws AttributeAccessException
103            {
104                    try{
105                            field.set(obj, value);
106                    }catch(Exception e)
107                    {}
108    
109                    try{
110                            java.beans.PropertyDescriptor pd = new java.beans.PropertyDescriptor(field.getName(),field.getDeclaringClass());
111                            Object[] args = {value};
112                            pd.getWriteMethod().invoke(obj, args);
113                    }catch(Exception e)
114                    {
115                            throw new AttributeAccessException("Error setting value from object: "+obj+", attribute: "+field.getName());
116                    }
117    
118            }
119            
120            /**
121             * Returns the hashCode of the attribute.
122             */
123            public int hashCode()
124            {
125                    return field.getName().hashCode();
126            }
127            
128            
129            public boolean equals(Object o)
130            {
131                    if(! (o instanceof Attribute))
132                            return false;
133                    return  (field.getName().equals(((Attribute)o).getName()))
134                                    &&(field.getDeclaringClass().equals(((Attribute)o).getDeclaringClass()));
135            }
136            
137            
138    }