001    /**
002     * AttributeUtils.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     * 09/01/2007
008     */
009    package jcolibri.util;
010    
011    import java.lang.reflect.Field;
012    import java.util.ArrayList;
013    import java.util.Collection;
014    
015    import jcolibri.cbrcore.*;
016    import jcolibri.connector.TypeAdaptor;
017    import jcolibri.exception.AttributeAccessException;
018    
019    /**
020     * Utility methods to manage the attributes of a case.
021     * @author Juan A. Recio García
022     * @version 1.0
023     * @see jcolibri.cbrcore.Attribute
024     *
025     */
026    public class AttributeUtils {
027    
028            /**
029             * Returns the list of attributes of a class.
030             */
031            public static Attribute[] getAttributes(Class c)
032            {
033                    Field[] fields = c.getDeclaredFields();
034                    Attribute[] res = new Attribute[fields.length];
035                    int i=0;
036                    for(Field f : fields)
037                            res[i++] = new Attribute(f);
038                    return res;
039            }
040            
041            /**
042             * Returns the list of attributes of a CaseComponents and all its sub-caseComponents.
043             */
044            public static Collection<Attribute> getAttributes(CaseComponent cc)
045            {
046                    if(cc == null)
047                        return null;
048                    Collection<Attribute> res = new ArrayList<Attribute>();
049                    try
050                    {
051                        Attribute[] ats = getAttributes(cc.getClass());
052                        for(Attribute a: ats)
053                            if(a.getType().equals(CaseComponent.class))
054                                    res.addAll(getAttributes((CaseComponent)a.getValue(cc)));
055                            else
056                                    res.add(a);
057                    } catch (AttributeAccessException e)
058                    {
059                        org.apache.commons.logging.LogFactory.getLog(AttributeUtils.class).error(e);
060                    }
061                    return res;
062            }
063    
064            /**
065             * Returns the list of attributes of a CaseComponents and all its sub-caseComponents which values are instance of a given class
066             */
067            public static Collection<Attribute> getAttributes(CaseComponent cc, Class _class)
068            {
069                    if(cc == null)
070                        return null;
071                    Collection<Attribute> res = new ArrayList<Attribute>();
072                    try
073                    {
074                        Attribute[] ats = getAttributes(cc.getClass());
075                        for(Attribute a: ats)
076                            if(a.getType().equals(CaseComponent.class))
077                                    res.addAll(getAttributes((CaseComponent)a.getValue(cc)));
078                            else if(_class.isInstance(a.getValue(cc)))
079                                    res.add(a);
080                    } catch (AttributeAccessException e)
081                    {
082                        org.apache.commons.logging.LogFactory.getLog(AttributeUtils.class).error(e);
083                    }
084                    return res;
085            }
086            
087            /**
088             * Finds the belonging component of an attribute. 
089             * A case is a CaseComponent that can be composed by simple attributes or other CaseComponents.
090             * This method traverses the CaseComponents structure of a case to find the CaseComponent that an attribute belongs to.
091             */
092            public static CaseComponent findBelongingComponent(Attribute at, CaseComponent cc)
093            {
094                    try {
095                            if(at.getDeclaringClass().equals(cc.getClass()))
096                                    return cc;
097                            Attribute[] atts = getAttributes(cc.getClass());
098                            for(Attribute a : atts)
099                            {
100                                    Object o = a.getValue(cc);
101                                    if(o == null)
102                                            continue;
103                                    if(o instanceof CaseComponent)
104                                    {
105                                            CaseComponent r = findBelongingComponent(at, (CaseComponent)o);
106                                            if(r != null)
107                                                    return r;
108                                    }               
109                            }
110                    } catch (AttributeAccessException e) {
111                            org.apache.commons.logging.LogFactory.getLog(AttributeUtils.class).error(e);
112                    }
113                    return null;    
114            }
115            
116            /**
117             * Similar to findBelongingComponent(Attribute, CaseComponent) as a CBRQuery is a CaseComponent.
118             */
119            public static CaseComponent findBelongingComponent(Attribute at, CBRQuery q)
120            {
121                    return findBelongingComponent(at, q.getDescription());
122            }
123    
124            /**
125             * Similar to findBelongingComponent(Attribute, CaseComponent) as a CBRCase is a CaseComponent.
126             */
127            public static CaseComponent findBelongingComponent(Attribute at, CBRCase c)
128            {
129                    CaseComponent res = findBelongingComponent(at, c.getDescription());
130                    if(res != null)
131                            return res;
132                    res = findBelongingComponent(at, c.getSolution());
133                    if(res != null)
134                            return res;     
135                    res = findBelongingComponent(at, c.getJustificationOfSolution());
136                    if(res != null)
137                            return res;
138                    res = findBelongingComponent(at, c.getResult());
139                    if(res != null)
140                            return res;
141                    return null;
142            }
143            
144            /**
145             * Returns the value of an Attribute in a CaseComponent object.
146             */
147            public static Object findValue(Attribute at, CaseComponent cc)
148            {
149                    CaseComponent belongCC = findBelongingComponent(at, cc);
150                    if (belongCC == null)
151                            return null;
152                    else
153                            try {
154                                    return at.getValue(cc);
155                            } catch (AttributeAccessException e) {
156                                    org.apache.commons.logging.LogFactory.getLog(AttributeUtils.class).error(e);
157                            }
158                    return null;
159            }
160            
161            /**
162             * Finds the value of an Attribute in a CBRQuery object.
163             */
164            public static Object findValue(Attribute at, CBRQuery query)
165            {
166                    return findValue(at, query.getDescription());
167            }
168    
169            /**
170             * Finds the value of an Attribute in a CBRCase object.
171             */
172            public static Object findValue(Attribute at, CBRCase c)
173            {
174                    CaseComponent cc = findBelongingComponent(at, c);
175                    if(cc == null)
176                            return null;
177                    else return findValue(at,cc);
178            }
179            
180            
181            /**
182             * Returns the value of an Attribute in a CaseComponent object.
183             */
184            public static void setValue(Attribute at, CaseComponent cc, Object value)
185            {
186                    CaseComponent belongCC = findBelongingComponent(at, cc);
187                    if (belongCC == null)
188                            return;
189                    else
190                            try {
191                                    at.setValue(cc,value);
192                            } catch (AttributeAccessException e) {
193                                try{
194                                    if(TypeAdaptor.class.isAssignableFrom(at.getType()))
195                                    {
196                                        String content = value.toString();
197                                        TypeAdaptor ta = (TypeAdaptor)at.getType().newInstance();
198                                        ta.fromString(content);
199                                        at.setValue(cc, at.getType().cast(ta));
200                                    }
201                                } catch(Exception e2)
202                                {
203                                    org.apache.commons.logging.LogFactory.getLog(AttributeUtils.class).error(e2);
204                                }
205                            }
206                    return;
207            }
208    
209            
210            /**
211             * Finds the value of an Attribute in a CBRQuery object.
212             */
213            public static void setValue(Attribute at, CBRQuery query, Object value)
214            {
215                    setValue(at, query.getDescription(),value);
216            }
217    
218            /**
219             * Finds the value of an Attribute in a CBRCase object.
220             */
221            public static void setValue(Attribute at, CBRCase c, Object value)
222            {
223                    CaseComponent cc = findBelongingComponent(at, c);
224                    if(cc == null)
225                            return;
226                    else 
227                        setValue(at,cc,value);
228            }
229    }