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

COVERAGE SUMMARY FOR SOURCE FILE [ClassInfoImpl.java]

nameclass, %method, %block, %line, %
ClassInfoImpl.java100% (1/1)86%  (25/29)91%  (411/454)93%  (88/95)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ClassInfoImpl100% (1/1)86%  (25/29)91%  (411/454)93%  (88/95)
getAttributeTypes (ClassEntry): Map 0%   (0/1)0%   (0/5)0%   (0/1)
hasDynamicAttributes (): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
hasStaticAttributes (): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
hashCode (): int 0%   (0/1)0%   (0/5)0%   (0/1)
equals (Object): boolean 100% (1/1)86%  (12/14)67%  (2/3)
ClassInfoImpl (ClassTracker, ClassEntry): void 100% (1/1)87%  (139/160)94%  (32/34)
<static initializer> 100% (1/1)100% (4/4)100% (1/1)
getAttributeClassEntry (String): ClassEntry 100% (1/1)100% (5/5)100% (1/1)
getAttributeNames (): List 100% (1/1)100% (7/7)100% (1/1)
getAttributeNames (ClassEntry): List 100% (1/1)100% (5/5)100% (1/1)
getAttributeType (String): Class 100% (1/1)100% (15/15)100% (4/4)
getAttributeValue (Object, String): Object 100% (1/1)100% (7/7)100% (1/1)
getClassEntries (): List 100% (1/1)100% (3/3)100% (1/1)
getHandler (ClassEntry): StrictClassHandler 100% (1/1)100% (6/6)100% (1/1)
getHandler (String): StrictClassHandler 100% (1/1)100% (7/7)100% (1/1)
getSourceEntry (): ClassEntry 100% (1/1)100% (3/3)100% (1/1)
hasChanged (): boolean 100% (1/1)100% (20/20)100% (7/7)
hasDynamicAttributes (ClassEntry): boolean 100% (1/1)100% (7/7)100% (1/1)
hasStaticAttributes (ClassEntry): boolean 100% (1/1)100% (3/3)100% (1/1)
isEmpty (): boolean 100% (1/1)100% (5/5)100% (1/1)
isEmpty (ClassEntry): boolean 100% (1/1)100% (20/20)100% (5/5)
isPrimitive (): boolean 100% (1/1)100% (5/5)100% (1/1)
isPrimitive (ClassEntry): boolean 100% (1/1)100% (11/11)100% (1/1)
isStorable (): boolean 100% (1/1)100% (5/5)100% (1/1)
isStorable (ClassEntry): boolean 100% (1/1)100% (31/31)100% (7/7)
newInstance (Map): Object 100% (1/1)100% (30/30)100% (6/6)
setAttributeValue (Object, String, Object): void 100% (1/1)100% (8/8)100% (2/2)
toString (): String 100% (1/1)100% (13/13)100% (1/1)
update (): void 100% (1/1)100% (40/40)100% (7/7)

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 java.util.*;
22import java.lang.reflect.Field;
23import java.lang.reflect.Modifier;
24import org.apache.log4j.Logger;
25import hu.netmind.beankeeper.model.*;
26 
27/**
28 * Information and transformations on a given class.
29 * @author Brautigam Robert
30 * @version Revision: $Revision$
31 */
32public class ClassInfoImpl implements ClassInfo
33{
34   private static Logger logger = Logger.getLogger(ClassInfoImpl.class);
35  
36   private ClassEntry sourceEntry;
37   private Map handlersByAttribute;
38   private Map<ClassEntry,StrictClassHandler> handlersByEntry;
39   private ArrayList classEntries;
40 
41   private ClassTracker classTracker = null; 
42 
43   public ClassInfoImpl(ClassTracker classTracker, ClassEntry sourceEntry)
44   {
45      this.classTracker=classTracker;
46      this.sourceEntry=sourceEntry;
47      // Assemble the attribute list
48      handlersByAttribute = new HashMap();
49      handlersByEntry = new HashMap<ClassEntry,StrictClassHandler>();
50      classEntries = new ArrayList();
51      // Assemble the attribute list
52      ClassEntry localEntry = sourceEntry;
53      while ( localEntry != null )
54      {
55         if ( logger.isDebugEnabled() )
56            logger.debug("analyzing entry for class info: "+localEntry);
57         // Add to all class entries, if it is storable
58         if ( isStorable(localEntry) )
59         {
60            if ( logger.isDebugEnabled() )
61               logger.debug("entry is storable, adding to class entries: "+classEntries);
62            classEntries.add(localEntry);
63         }
64         // Determine handler for strict class, there are
65         // four kinds of handlers:
66         // - Null handler: has no attributes ever
67         // - Static handler: attributes are determined from reflection
68         // - Dynamic handler: attributes are determined with call to dynamic object
69         // - Primitive handler: primitive types
70         StrictClassHandler handler;
71         if ( isEmpty(localEntry) )
72            handler = new StrictNullHandler(localEntry);
73         else if ( hasDynamicAttributes(localEntry) )
74            handler = new StrictDynamicHandler(classTracker,localEntry);
75         else if ( isPrimitive(localEntry) )
76            handler = new StrictPrimitiveHandler(localEntry);
77         else
78            handler = new StrictStaticHandler(localEntry);
79         logger.debug("handler for entry will be: "+handler);
80         // Add this class' attribute to sets
81         Map strictAttributeTypes = handler.getAttributeTypes();
82         Iterator attributeTypeIterator = strictAttributeTypes.keySet().iterator();
83         while ( attributeTypeIterator.hasNext() )
84         {
85            String attributeName = attributeTypeIterator.next().toString().toLowerCase();
86            handlersByAttribute.put(attributeName,handler);
87         }
88         handlersByEntry.put(localEntry,handler);
89         // Get super
90         localEntry = localEntry.getSuperEntry();
91      }
92      logger.debug("analized class: "+sourceEntry+", attributes: "+getAttributeNames());
93   }
94 
95   private StrictClassHandler getHandler(ClassEntry entry)
96   {
97      return (StrictClassHandler) handlersByEntry.get(entry);
98   }
99   
100   private StrictClassHandler getHandler(String attributeName)
101   {
102      return (StrictClassHandler) handlersByAttribute.get(attributeName.toLowerCase());
103   }
104   
105   /**
106    * Get the attribute types for a strict class.
107    */
108   public Map getAttributeTypes(ClassEntry entry)
109   {
110      return getHandler(entry).getAttributeTypes();
111   }
112 
113   /**
114    * Get all classes and superclasses of the source class.
115    */
116   public List getClassEntries()
117   {
118      return classEntries;
119   }
120 
121   /**
122    * Get the attributes declared in the class given.
123    */
124   public List getAttributeNames(ClassEntry entry)
125   {
126      return getHandler(entry).getAttributeNames();
127   }
128 
129   /**
130    * Instantiate an object of this info entity. If the object in question
131    * is a dynamic object, it's dynamic name will be set.
132    * @param marshalledValues The values for which this object will be created.
133    */
134   public Object newInstance(Map marshalledValues)
135      throws InstantiationException, IllegalAccessException
136   {
137      // If primitive type, then construct with primitive value
138      if ( isPrimitive() )
139         return ((StrictPrimitiveHandler)getHandler(getSourceEntry())).newInstance(marshalledValues);
140      // It's a custom object, create it
141      Object result = sourceEntry.getSourceClass().newInstance();
142      // If it's a dynamic object, then set it's dynamic name
143      if ( DynamicObject.class.isAssignableFrom(sourceEntry.getSourceClass()) )
144         ((DynamicObject) result).setPersistenceDynamicName(sourceEntry.getDynamicName());
145      return result;
146   }
147 
148   /**
149    * Get the exact class a member attribute is declared in.
150    * @param attributeName The attribute to search for.
151    * @return The class the attribute is declared in, which is either the
152    * source class, or a superclass, or null if no such attribute is found.
153    */
154   public ClassEntry getAttributeClassEntry(String attributeName)
155   {
156      return getHandler(attributeName).getSourceEntry();
157   }
158 
159   /**
160    * Get the attribute names in a list of this class.
161    */
162   public List getAttributeNames()
163   {
164      return new ArrayList(handlersByAttribute.keySet());
165   }
166 
167   /**
168    * Get the type of the attribute given.
169    * @return The type marker as defined in ClassTracker.
170    */
171   public Class getAttributeType(String attributeName)
172   {
173      StrictClassHandler handler = getHandler(attributeName);
174      if ( handler == null )
175         return null;
176      return (Class) handler.getAttributeTypes().get(attributeName.toLowerCase());
177   }
178 
179   /**
180    * Get the attribute value from a given object of this class and 
181    * from given attribute.
182    */
183   public Object getAttributeValue(Object obj, String attributeName)
184   {
185      return getHandler(attributeName).getAttributeValue(obj,attributeName);
186   }
187 
188   /**
189    * Set an object as value into object given.
190    */
191   public void setAttributeValue(Object obj, String attributeName, Object value)
192   {
193      getHandler(attributeName).setAttributeValue(obj,attributeName,value);
194   }
195 
196   /**
197    * Return whether the information changed in info class.
198    */
199   public boolean hasChanged()
200   {
201      Iterator handlerIterator = handlersByEntry.values().iterator();
202      while ( handlerIterator.hasNext() )
203      {
204         StrictClassHandler handler = (StrictClassHandler) handlerIterator.next();
205         if ( handler.hasChanged() )
206            return true;
207      }
208      return false;
209   }
210 
211   /**
212    * Update, so that this class info reflects the current model.
213    */
214   public void update()
215   {
216      // Update all handlers and update attribute mapping
217      Map handlersByAttributeNew = new HashMap();
218      for ( StrictClassHandler handler : handlersByEntry.values() )
219      {
220         // Update the handler first
221         handler.update();
222         // Go through attribute names, and link it in
223         for ( String attributeName : (List<String>)handler.getAttributeNames() )
224            handlersByAttributeNew.put(attributeName,handler);
225      }
226      // Switch to new mapping
227      handlersByAttribute = handlersByAttributeNew;
228   }
229 
230   public ClassEntry getSourceEntry()
231   {
232      return sourceEntry;
233   }
234 
235   public int hashCode()
236   {
237      return sourceEntry.getFullName().hashCode();
238   }
239 
240   private boolean isPrimitive(ClassEntry entry)
241   {
242      return classTracker.getType(entry.getSourceClass()) == ClassTracker.ClassType.TYPE_PRIMITIVE;
243   }
244  
245   public boolean isPrimitive()
246   {
247      return isPrimitive(getSourceEntry());
248   }
249  
250   public boolean isEmpty(ClassEntry entry)
251   {
252      if ( isPrimitive(entry) )
253         return false; // Primitive classes are saved
254      if ( (entry.getSourceClass().isInterface()) || (entry.getSourceClass().getName().startsWith("java")) )
255         return true; // Intefaces or java.** classes will never have attributes
256      return false;
257   }
258 
259   public boolean isEmpty()
260   {
261      return isEmpty(getSourceEntry());
262   }
263 
264   private boolean isStorable(ClassEntry entry)
265   {
266      if ( isPrimitive(entry) )
267         return true; // Primitive classes are saved
268      if ( (entry.getSourceClass().isInterface()) || 
269            (entry.getSourceClass().getName().startsWith("java")) )
270         return false; // Intefaces or java.** classes are non-storable
271      if ( (Modifier.isAbstract(entry.getSourceClass().getModifiers())) && (!hasStaticAttributes(entry)) )
272         return false; // Abstract superclasses which have no attributes
273      return true;
274   }
275   
276   public boolean isStorable()
277   {
278      return isStorable(getSourceEntry());
279   }
280 
281   public boolean hasDynamicAttributes(ClassEntry entry)
282   {
283      return StrictDynamicHandler.getPersistenceAttributeTypes(entry) != null;
284   }
285 
286   public boolean hasDynamicAttributes()
287   {
288      return hasDynamicAttributes(getSourceEntry());
289   }
290 
291   private boolean hasStaticAttributes(ClassEntry entry)
292   {
293      return StrictStaticHandler.hasStaticAttributes(entry);
294   }
295 
296   public boolean hasStaticAttributes()
297   {
298      return hasStaticAttributes(getSourceEntry());
299   }
300 
301   public boolean equals(Object obj)
302   {
303      if ( ! (obj instanceof ClassInfoImpl) )
304         return false;
305      return ((ClassInfoImpl) obj).sourceEntry.getFullName().equals(sourceEntry.getFullName());
306   }
307 
308   public String toString()
309   {
310      return "[ClassInfo: "+sourceEntry.getFullName()+"]";
311   }
312}
313 
314 

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