api/core/src/org/proteios/ClassDescriptor.java

Code
Comments
Other
Rev Date Author Line
2413 21 Nov 07 gregory 1 /*
2413 21 Nov 07 gregory 2  $Id: code_templates.xml 1916 2007-08-31 09:54:00Z jari $
2413 21 Nov 07 gregory 3  
2413 21 Nov 07 gregory 4  Copyright (C) 2006, 2007 Gregory Vincic
2413 21 Nov 07 gregory 5  
2413 21 Nov 07 gregory 6  Files are copyright by their respective authors. The contributions to
2413 21 Nov 07 gregory 7  files where copyright is not explicitly stated can be traced with the
2413 21 Nov 07 gregory 8  source code revision system.
2413 21 Nov 07 gregory 9  
2413 21 Nov 07 gregory 10  This file is part of Proteios.
2413 21 Nov 07 gregory 11  Available at http://www.proteios.org/
2413 21 Nov 07 gregory 12  
2413 21 Nov 07 gregory 13  Proteios is free software; you can redistribute it and/or
2413 21 Nov 07 gregory 14  modify it under the terms of the GNU General Public License
2413 21 Nov 07 gregory 15  as published by the Free Software Foundation; either version 2
2413 21 Nov 07 gregory 16  of the License, or (at your option) any later version.
2413 21 Nov 07 gregory 17  
2413 21 Nov 07 gregory 18  Proteios is distributed in the hope that it will be useful,
2413 21 Nov 07 gregory 19  but WITHOUT ANY WARRANTY; without even the implied warranty of
2413 21 Nov 07 gregory 20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2413 21 Nov 07 gregory 21  GNU General Public License for more details.
2413 21 Nov 07 gregory 22  
2413 21 Nov 07 gregory 23  You should have received a copy of the GNU General Public License
2413 21 Nov 07 gregory 24  along with this program; if not, write to the Free Software
2413 21 Nov 07 gregory 25  Foundation, Inc., 59 Temple Place - Suite 330,
2413 21 Nov 07 gregory 26  Boston, MA  02111-1307, USA.
2413 21 Nov 07 gregory 27  */
2413 21 Nov 07 gregory 28 package org.proteios;
2413 21 Nov 07 gregory 29
2463 14 Dec 07 gregory 30 import org.proteios.core.Nameable;
3483 11 Nov 09 olle 31 import org.proteios.core.data.FileData;
2602 07 Mar 08 gregory 32 import org.proteios.props.DateReader;
2602 07 Mar 08 gregory 33 import org.proteios.props.EnumReader;
2463 14 Dec 07 gregory 34 import org.proteios.props.NameReader;
2602 07 Mar 08 gregory 35
2444 10 Dec 07 gregory 36 import java.lang.reflect.InvocationTargetException;
2413 21 Nov 07 gregory 37 import java.lang.reflect.Method;
2413 21 Nov 07 gregory 38 import java.util.ArrayList;
2602 07 Mar 08 gregory 39 import java.util.Date;
2413 21 Nov 07 gregory 40 import java.util.List;
2413 21 Nov 07 gregory 41
2413 21 Nov 07 gregory 42 /**
2413 21 Nov 07 gregory 43  * Through the ClassDescriptor you can find methods by defined attributes.
2413 21 Nov 07 gregory 44  * 
2413 21 Nov 07 gregory 45  * @author gregory
2413 21 Nov 07 gregory 46  * @see AttributeDefinition
2413 21 Nov 07 gregory 47  */
2413 21 Nov 07 gregory 48 public class ClassDescriptor
2413 21 Nov 07 gregory 49 {
2429 26 Nov 07 fredrik 50   private Class<?> describedClass;
2446 11 Dec 07 gregory 51   private TypeUtil util;
2413 21 Nov 07 gregory 52
2413 21 Nov 07 gregory 53
2413 21 Nov 07 gregory 54   /**
2413 21 Nov 07 gregory 55    * @param cls to describe
2413 21 Nov 07 gregory 56    */
2429 26 Nov 07 fredrik 57   public ClassDescriptor(Class<?> cls)
2413 21 Nov 07 gregory 58   {
2420 22 Nov 07 gregory 59     this.describedClass = cls;
2446 11 Dec 07 gregory 60     this.util = new TypeUtil();
2413 21 Nov 07 gregory 61   }
2413 21 Nov 07 gregory 62
2413 21 Nov 07 gregory 63
2413 21 Nov 07 gregory 64   public Method getReadMethod(AttributeDefinition atr)
2413 21 Nov 07 gregory 65       throws SecurityException, NoSuchMethodException
2413 21 Nov 07 gregory 66   {
2413 21 Nov 07 gregory 67     Method method = null;
2413 21 Nov 07 gregory 68     String name = atr.getReadMethodName();
2420 22 Nov 07 gregory 69     method = describedClass.getMethod(name);
2413 21 Nov 07 gregory 70     return method;
2413 21 Nov 07 gregory 71   }
2413 21 Nov 07 gregory 72
2413 21 Nov 07 gregory 73
2413 21 Nov 07 gregory 74   public Method getWriteMethod(AttributeDefinition atr)
2413 21 Nov 07 gregory 75       throws SecurityException, NoSuchMethodException
2413 21 Nov 07 gregory 76   {
2413 21 Nov 07 gregory 77     Method method = null;
2413 21 Nov 07 gregory 78     String name = atr.getWriteMethodName();
2420 22 Nov 07 gregory 79     method = describedClass.getMethod(name, atr.getAttributeType());
2413 21 Nov 07 gregory 80     return method;
2413 21 Nov 07 gregory 81   }
2413 21 Nov 07 gregory 82
2413 21 Nov 07 gregory 83
2413 21 Nov 07 gregory 84   /**
2463 14 Dec 07 gregory 85    * @param filter to apply
2463 14 Dec 07 gregory 86    * @return a list of attributes filtered through the above filter
2463 14 Dec 07 gregory 87    */
2463 14 Dec 07 gregory 88   public List<AttributeDefinition> getAttributes(AttributeFilter filter)
2463 14 Dec 07 gregory 89   {
2828 09 Sep 08 olle 90     return sort(getAttributes(), filter.getDefaultOrder());
2463 14 Dec 07 gregory 91   }
2463 14 Dec 07 gregory 92
2463 14 Dec 07 gregory 93
2463 14 Dec 07 gregory 94   /**
2828 09 Sep 08 olle 95    * Returns a filtered list of attributes.
2828 09 Sep 08 olle 96    * 
2840 11 Sep 08 gregory 97    * @param attributes List of attribute definitions to be sorted.
2840 11 Sep 08 gregory 98    * @param order List of column key strings in desired sort order.
2828 09 Sep 08 olle 99    * @return List<AttributeDefinition> Sorted list of attribute definitions.
2828 09 Sep 08 olle 100    */
2828 09 Sep 08 olle 101   public List<AttributeDefinition> sort(List<AttributeDefinition> attributes,
2828 09 Sep 08 olle 102       List<String> order)
2828 09 Sep 08 olle 103   {
2828 09 Sep 08 olle 104     List<AttributeDefinition> sorted = new ArrayList<AttributeDefinition>(
2828 09 Sep 08 olle 105       attributes.size());
2828 09 Sep 08 olle 106     for (String key : order)
2828 09 Sep 08 olle 107     {
2828 09 Sep 08 olle 108       for (int i = attributes.size() - 1; i >= 0; i--)
2828 09 Sep 08 olle 109       {
2828 09 Sep 08 olle 110         AttributeDefinition ad = attributes.get(i);
2828 09 Sep 08 olle 111         if (ad.getKey().equals(key))
2828 09 Sep 08 olle 112         {
2828 09 Sep 08 olle 113           sorted.add(ad);
2828 09 Sep 08 olle 114         }
2828 09 Sep 08 olle 115       }
2828 09 Sep 08 olle 116     }
2828 09 Sep 08 olle 117     // Remove the sorted ones from the rest
2828 09 Sep 08 olle 118     for (AttributeDefinition ad : sorted)
2828 09 Sep 08 olle 119     {
2828 09 Sep 08 olle 120       int i = attributes.indexOf(ad);
2828 09 Sep 08 olle 121       if (i != -1)
2828 09 Sep 08 olle 122         attributes.remove(i);
2828 09 Sep 08 olle 123     }
2828 09 Sep 08 olle 124     // Now append the rest of the attributes to the sorted ones
2828 09 Sep 08 olle 125     sorted.addAll(attributes);
2828 09 Sep 08 olle 126     return sorted;
2828 09 Sep 08 olle 127   }
2828 09 Sep 08 olle 128
2828 09 Sep 08 olle 129
2828 09 Sep 08 olle 130   /**
2602 07 Mar 08 gregory 131    * Currently supports Primitive, Nameable and Enumerated attributes
2424 23 Nov 07 gregory 132    * 
2413 21 Nov 07 gregory 133    * @return list of readable attributes, those with 'get' or 'is' prefixes,
2424 23 Nov 07 gregory 134    *         or null if none are found.
2413 21 Nov 07 gregory 135    */
2423 23 Nov 07 gregory 136   public List<AttributeDefinition> getAttributes()
2413 21 Nov 07 gregory 137   {
2413 21 Nov 07 gregory 138     List<AttributeDefinition> result = null;
2420 22 Nov 07 gregory 139     Method[] methods = describedClass.getMethods();
2413 21 Nov 07 gregory 140     for (Method method : methods)
2413 21 Nov 07 gregory 141     {
2413 21 Nov 07 gregory 142       String name = method.getName();
2413 21 Nov 07 gregory 143       int keyIndex = 0;
2413 21 Nov 07 gregory 144       if (method.getParameterTypes().length == 0 && method
2413 21 Nov 07 gregory 145         .getReturnType() != null)
2413 21 Nov 07 gregory 146       {
2413 21 Nov 07 gregory 147         // No parameters to this method, we assume it's a read method
2446 11 Dec 07 gregory 148         Class<?> cls = method.getReturnType();
2463 14 Dec 07 gregory 149         AttributeDefinition atr = null;
2446 11 Dec 07 gregory 150         if (util.isString(cls) || util.isBoolean(cls) || util
2446 11 Dec 07 gregory 151           .isDouble(cls) || util.isFloat(cls) || util.isInt(cls) || util
2446 11 Dec 07 gregory 152           .isLong(cls))
2413 21 Nov 07 gregory 153         {
2424 23 Nov 07 gregory 154           String writePrefix = "set";
2424 23 Nov 07 gregory 155           String readPrefix = null;
2424 23 Nov 07 gregory 156           if (name.startsWith("get"))
2424 23 Nov 07 gregory 157           {
2424 23 Nov 07 gregory 158             keyIndex = 3;
2424 23 Nov 07 gregory 159             readPrefix = "get";
2424 23 Nov 07 gregory 160           }
2424 23 Nov 07 gregory 161           else if (name.startsWith("is"))
2424 23 Nov 07 gregory 162           {
2424 23 Nov 07 gregory 163             keyIndex = 2;
2424 23 Nov 07 gregory 164             readPrefix = "is";
2424 23 Nov 07 gregory 165           }
2424 23 Nov 07 gregory 166           if (keyIndex != 0)
2424 23 Nov 07 gregory 167           {
2424 23 Nov 07 gregory 168             String key = name.substring(keyIndex);
2463 14 Dec 07 gregory 169             atr = new AttributeDefinition(describedClass, cls, key,
2463 14 Dec 07 gregory 170               readPrefix, writePrefix);
2424 23 Nov 07 gregory 171           }
2413 21 Nov 07 gregory 172         }
2463 14 Dec 07 gregory 173         else if (Nameable.class.isAssignableFrom(cls))
2463 14 Dec 07 gregory 174         {
2463 14 Dec 07 gregory 175           // Assume that the attributes are always get/set methods
2463 14 Dec 07 gregory 176           String key = name.substring(3);
2463 14 Dec 07 gregory 177           NameReader reader = new NameReader();
2463 14 Dec 07 gregory 178           atr = new AttributeDefinition(describedClass, cls, key,
2463 14 Dec 07 gregory 179             reader);
2463 14 Dec 07 gregory 180         }
3483 11 Nov 09 olle 181         else if (FileData.class.isAssignableFrom(cls))
3483 11 Nov 09 olle 182         {
3483 11 Nov 09 olle 183           // Assume that the attributes are always get/set methods
3483 11 Nov 09 olle 184           String key = name.substring(3);
3483 11 Nov 09 olle 185           NameReader reader = new NameReader();
3483 11 Nov 09 olle 186           atr = new AttributeDefinition(describedClass, cls, key,
3483 11 Nov 09 olle 187             reader);
3483 11 Nov 09 olle 188         }
2602 07 Mar 08 gregory 189         else if (cls != null && cls.isEnum())
2602 07 Mar 08 gregory 190         {
2602 07 Mar 08 gregory 191           String key = name.substring(3);
2602 07 Mar 08 gregory 192           EnumReader reader = new EnumReader();
2602 07 Mar 08 gregory 193           atr = new AttributeDefinition(describedClass, cls, key,
2602 07 Mar 08 gregory 194             reader);
2602 07 Mar 08 gregory 195         }
2602 07 Mar 08 gregory 196         else if (Date.class.isAssignableFrom(cls))
2602 07 Mar 08 gregory 197         {
2602 07 Mar 08 gregory 198           String key = name.substring(3);
2602 07 Mar 08 gregory 199           DateReader reader = new DateReader();
2602 07 Mar 08 gregory 200           atr = new AttributeDefinition(describedClass, cls, key,
2602 07 Mar 08 gregory 201             reader);
2602 07 Mar 08 gregory 202         }
2463 14 Dec 07 gregory 203         if (atr != null)
2463 14 Dec 07 gregory 204         {
2463 14 Dec 07 gregory 205           if (result == null)
2463 14 Dec 07 gregory 206             result = new ArrayList<AttributeDefinition>();
2463 14 Dec 07 gregory 207           result.add(atr);
2463 14 Dec 07 gregory 208         }
2413 21 Nov 07 gregory 209       }
2413 21 Nov 07 gregory 210     }
2413 21 Nov 07 gregory 211     return result;
2413 21 Nov 07 gregory 212   }
2420 22 Nov 07 gregory 213
2420 22 Nov 07 gregory 214
2429 26 Nov 07 fredrik 215   public Class<?> getDescribedClass()
2420 22 Nov 07 gregory 216   {
2420 22 Nov 07 gregory 217     return describedClass;
2420 22 Nov 07 gregory 218   }
2444 10 Dec 07 gregory 219
2444 10 Dec 07 gregory 220
2444 10 Dec 07 gregory 221   /**
2444 10 Dec 07 gregory 222    * @param obj to read the attribute of
2444 10 Dec 07 gregory 223    * @param attributeDefinition describing the attribute
2444 10 Dec 07 gregory 224    * @return the value of that attribute or null
2444 10 Dec 07 gregory 225    */
2444 10 Dec 07 gregory 226   public Object readValue(Object obj, AttributeDefinition attributeDefinition)
2444 10 Dec 07 gregory 227   {
2444 10 Dec 07 gregory 228     Object value = null;
4455 20 Mar 13 olle 229     if (describedClass.isAssignableFrom(obj.getClass()))
2444 10 Dec 07 gregory 230     {
2444 10 Dec 07 gregory 231       try
2444 10 Dec 07 gregory 232       {
2444 10 Dec 07 gregory 233         Method method = getReadMethod(attributeDefinition);
2444 10 Dec 07 gregory 234         value = method.invoke(obj);
2444 10 Dec 07 gregory 235       }
2444 10 Dec 07 gregory 236       catch (IllegalArgumentException e)
2444 10 Dec 07 gregory 237       {
2444 10 Dec 07 gregory 238         // TODO Auto-generated catch block
2444 10 Dec 07 gregory 239         e.printStackTrace();
2444 10 Dec 07 gregory 240       }
2444 10 Dec 07 gregory 241       catch (IllegalAccessException e)
2444 10 Dec 07 gregory 242       {
2444 10 Dec 07 gregory 243         // TODO Auto-generated catch block
2444 10 Dec 07 gregory 244         e.printStackTrace();
2444 10 Dec 07 gregory 245       }
2444 10 Dec 07 gregory 246       catch (InvocationTargetException e)
2444 10 Dec 07 gregory 247       {
2444 10 Dec 07 gregory 248         // TODO Auto-generated catch block
2444 10 Dec 07 gregory 249         e.printStackTrace();
2444 10 Dec 07 gregory 250       }
2444 10 Dec 07 gregory 251       catch (SecurityException e)
2444 10 Dec 07 gregory 252       {
2444 10 Dec 07 gregory 253         // TODO Auto-generated catch block
2444 10 Dec 07 gregory 254         e.printStackTrace();
2444 10 Dec 07 gregory 255       }
2444 10 Dec 07 gregory 256       catch (NoSuchMethodException e)
2444 10 Dec 07 gregory 257       {
2444 10 Dec 07 gregory 258         // TODO Auto-generated catch block
2444 10 Dec 07 gregory 259         e.printStackTrace();
2444 10 Dec 07 gregory 260       }
2444 10 Dec 07 gregory 261     }
2444 10 Dec 07 gregory 262     return value;
2444 10 Dec 07 gregory 263   }
2413 21 Nov 07 gregory 264 }