EMMA Coverage Report (generated Sun May 02 20:42:29 CEST 2010)
[all classes][hu.netmind.beankeeper.model.impl]

COVERAGE SUMMARY FOR SOURCE FILE [StrictDynamicHandler.java]

nameclass, %method, %block, %line, %
StrictDynamicHandler.java100% (1/1)100% (10/10)81%  (422/518)87%  (77.7/89)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class StrictDynamicHandler100% (1/1)100% (10/10)81%  (422/518)87%  (77.7/89)
getPersistenceAttributeTypes (ClassEntry): Map 100% (1/1)69%  (68/99)78%  (14/18)
setAttributeValue (Object, String, Object): void 100% (1/1)75%  (197/262)82%  (33.7/41)
<static initializer> 100% (1/1)100% (4/4)100% (1/1)
StrictDynamicHandler (ClassTracker, ClassEntry): void 100% (1/1)100% (18/18)100% (7/7)
getAttributeNames (): List 100% (1/1)100% (17/17)100% (4/4)
getAttributeTypes (): Map 100% (1/1)100% (14/14)100% (4/4)
getAttributeValue (Object, String): Object 100% (1/1)100% (18/18)100% (3/3)
hasChanged (): boolean 100% (1/1)100% (36/36)100% (4/4)
isStatic (String): boolean 100% (1/1)100% (5/5)100% (1/1)
update (): void 100% (1/1)100% (45/45)100% (6/6)

1/**
2 * Copyright (C) 2006 NetMind Consulting Bt.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18 
19package hu.netmind.beankeeper.model.impl;
20 
21import hu.netmind.beankeeper.service.StoreContext;
22import java.util.*;
23import java.lang.reflect.Method;
24import org.apache.log4j.Logger;
25import hu.netmind.beankeeper.common.StoreException;
26import hu.netmind.beankeeper.model.*;
27 
28/**
29 * Information and transformations on a given class.
30 * @author Brautigam Robert
31 * @version Revision: $Revision$
32 */
33public class StrictDynamicHandler extends StrictStaticHandler
34{
35   private static Logger logger = Logger.getLogger(StrictDynamicHandler.class);
36 
37   private Map<String,Class> dynamicAttributes = null;;
38   private Map<String,String> dynamicAttributeCase = null;
39 
40   private ClassTracker classTracker = null;
41   
42   StrictDynamicHandler(ClassTracker classTracker, ClassEntry sourceEntry)
43   {
44      // Init static attributes
45      super(sourceEntry);
46      this.classTracker=classTracker;
47      update();
48   }
49 
50   public void update()
51   {
52      dynamicAttributes = new HashMap<String,Class>();
53      dynamicAttributeCase = new HashMap<String,String>();
54      for ( Map.Entry<String,Class> entry : getPersistenceAttributeTypes(getSourceEntry()).entrySet() )
55      {
56         dynamicAttributeCase.put(entry.getKey().toLowerCase(),entry.getKey());
57         dynamicAttributes.put(entry.getKey().toLowerCase(),entry.getValue());
58      }
59   }
60 
61   /**
62    * Get the dynamic attributes types of an object.
63    * @return The dynamic types map, or null, if object is not dynamic.
64    */
65   public static Map<String,Class> getPersistenceAttributeTypes(ClassEntry entry)
66   {
67      Method method = null;
68      Class current = entry.getSourceClass();
69      while ( (current != null) && (method==null) )
70      {
71         try
72         {
73            method = current.getDeclaredMethod("getPersistenceAttributeTypes",new Class[] { Class.class, String.class });
74         } catch ( NoSuchMethodException e ) {
75            // No problem
76            if ( logger.isDebugEnabled() )
77               logger.debug("given class had no getPersistenceAttributeTypes method for dynamic attributes: "+entry);
78         }
79         current = current.getSuperclass();
80      }
81      if ( method == null )
82      {
83         logger.debug("dyanmic attributes method not found in "+entry);
84         return null; // If no such method, then this has no dynamic attrs
85      }
86      try
87      {
88         Map result = (Map) method.invoke(null,new Object[] { entry.getSourceClass(), entry.getDynamicName() });
89         if ( logger.isDebugEnabled() )
90            logger.debug("determined dynamic attributes for '"+entry+"': "+result);
91         return result;
92      } catch ( Exception e ) {
93         throw new StoreException("error while getting dynamic attribute types",e);
94      }
95   }
96 
97   public Map getAttributeTypes()
98   {
99      Map result = new HashMap();
100      result.putAll(super.getAttributeTypes());
101      result.putAll(dynamicAttributes);
102      return result;
103   }
104 
105   public List getAttributeNames()
106   {
107      List result = new ArrayList();
108      result.addAll(super.getAttributeNames());
109      result.addAll(dynamicAttributes.keySet());
110      return result;
111   }
112 
113   public boolean hasChanged()
114   {
115      // Generate lower case attribute names map
116      Map<String,Class> currentAttributes = new HashMap<String,Class>();
117      for ( Map.Entry<String,Class> entry : getPersistenceAttributeTypes(getSourceEntry()).entrySet() )
118         currentAttributes.put(entry.getKey().toLowerCase(),entry.getValue());
119      // Compare
120      return ! currentAttributes.equals(dynamicAttributes);
121   }
122 
123   /**
124    * Return whether given attribute is a static attribute, which has priority.
125    */
126   private boolean isStatic(String attributeName)
127   {
128      return super.getAttributeNames().contains(attributeName);
129   }
130      
131   /**
132    * Get the attribute value from a given object of this class and 
133    * from given attribute.
134    */
135   public Object getAttributeValue(Object obj, String attributeName)
136   {
137      if ( isStatic(attributeName) )
138         return super.getAttributeValue(obj,attributeName);
139      return ((Map) obj).get(dynamicAttributeCase.get(attributeName.toLowerCase()));
140   }
141 
142   /**
143    * Set an object as value into object given.
144    */
145   public void setAttributeValue(Object obj, String attributeName, Object value)
146   {
147      // Handle static attribute
148      if ( isStatic(attributeName) )
149      {
150         super.setAttributeValue(obj,attributeName,value);
151         return;
152      }
153      // Get data
154      attributeName = attributeName.toLowerCase();
155      String realAttributeName = dynamicAttributeCase.get(attributeName);
156      Class attributeClass = dynamicAttributes.get(attributeName);
157      // Check if value is null. Remove the key, if the value is null.
158      Map map = (Map) obj;
159      Class valueClass = null;
160      if ( value == null )
161      {
162         map.remove(realAttributeName);
163         return;
164      }
165      valueClass = value.getClass();
166      // Handle primitive types with exceptional circumstances
167      if ( (attributeClass.equals(Character.class)) || (attributeClass.equals(char.class)) 
168            && (valueClass.equals(String.class)) )
169      {
170         if ( ((String) value).length() > 0 )
171            map.put(realAttributeName, new Character(((String) value).charAt(0)));
172      }
173      // Byte array
174      else if ( attributeClass.equals(byte[].class) )
175         map.put(realAttributeName,value);
176      // Boolean
177      else if ( (attributeClass.equals(Boolean.class) || attributeClass.equals(boolean.class))
178            && ((valueClass.equals(Integer.class)) || 
179               (valueClass.equals(Long.class))) )
180      {
181         map.put(realAttributeName, new Boolean(((Number) value).intValue() > 0));
182      }
183      // Easy primitive classes
184      else if ( valueClass.equals(String.class) || 
185           valueClass.equals(Date.class) || 
186           valueClass.equals(Boolean.class)
187         )
188         map.put(realAttributeName,value);
189      // Container classes
190      else if ( (value instanceof Map) || (value instanceof List) )
191         map.put(realAttributeName,value);
192      // Not easy number classes
193      else if ( value instanceof Number )
194      {
195         Number number = (Number) value;
196         if ( attributeClass.equals(Byte.class) || attributeClass.equals(byte.class) )
197            map.put(realAttributeName,new Byte(number.byteValue()));
198         if ( attributeClass.equals(Double.class) || attributeClass.equals(double.class) )
199            map.put(realAttributeName,new Double(number.doubleValue()));
200         if ( attributeClass.equals(Float.class) || attributeClass.equals(float.class) )
201            map.put(realAttributeName,new Float(number.floatValue()));
202         if ( attributeClass.equals(Integer.class) || attributeClass.equals(int.class) )
203            map.put(realAttributeName,new Integer(number.intValue()));
204         if ( attributeClass.equals(Long.class) || attributeClass.equals(long.class) )
205            map.put(realAttributeName,new Long(number.longValue()));
206         if ( attributeClass.equals(Short.class) || attributeClass.equals(short.class) )
207            map.put(realAttributeName,new Short(number.shortValue()));
208      }
209      // All other objects
210      else {
211         if ( (value!=null) || 
212               (classTracker.getType(attributeClass)!=ClassTracker.ClassType.TYPE_PRIMITIVE) )
213            map.put(realAttributeName,value);
214      }
215   }
216}
217 
218 

[all classes][hu.netmind.beankeeper.model.impl]
EMMA 2.0.5312debian (C) Vladimir Roubtsov