KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > dozer > util > mapping > util > ClassMapFinder


1 /*
2  * Copyright 2005-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package net.sf.dozer.util.mapping.util;
17
18 import java.util.ArrayList JavaDoc;
19 import java.util.Collections JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23
24 import net.sf.dozer.util.mapping.fieldmap.ClassMap;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29
30 /**
31  * @author tierney.matt
32  * @author garsombke.franz
33  */

34 public class ClassMapFinder {
35
36   private static final Log log = LogFactory.getLog(ClassMapFinder.class);
37
38   public ClassMap findClassMap(Map JavaDoc customMappings, Object JavaDoc sourceObj, Class JavaDoc destClass, String JavaDoc mapId, boolean isInstance) {
39     ClassMap mapping = (ClassMap) customMappings.get(ClassMapKeyFactory.createKey(sourceObj.getClass(), destClass,
40         mapId));
41
42     // determine if it is an Interface or Abstract Class
43
// iterate through the class maps and see if this class has any sub classes
44
// that are mapped to the source class OR
45
// any of the source classes super classes
46
// if we find a mapping don't even bother walking the tree
47
if (mapping == null) {
48       mapping = findInterfaceOrAbstractMapping(customMappings, destClass, sourceObj, mapId);
49     }
50
51     if (mapping != null) {
52       return mapping;
53     }
54
55     // one more try...
56
// if the mapId is not null looking up a map is easy
57
if (mapId != null && mapping == null) {
58       // probably a more efficient way to do this...
59
Iterator JavaDoc iter = customMappings.keySet().iterator();
60       ClassMap classMap = null;
61       while (iter.hasNext()) {
62         String JavaDoc key = (String JavaDoc) iter.next();
63         classMap = (ClassMap) customMappings.get(key);
64         if (StringUtils.equals(classMap.getMapId(), mapId)) {
65           return classMap;
66         }
67       }
68       log.warn("No ClassMap found for mapId:" + mapId);
69     }
70
71     return mapping;
72   }
73
74   public List JavaDoc findInterfaceMappings(Map JavaDoc customMappings, Class JavaDoc sourceClass, Class JavaDoc destClass) {
75     // If no existing cache entry is found, determine super type mapping and
76
// store in cache
77
// Get interfaces
78
Class JavaDoc[] sourceInterfaces = sourceClass.getInterfaces();
79     Class JavaDoc[] destInterfaces = destClass.getInterfaces();
80     List JavaDoc interfaceMaps = new ArrayList JavaDoc();
81     int size = destInterfaces.length;
82     for (int i = 0; i < size; i++) {
83       // see if the source class is mapped to the dest class
84
ClassMap interfaceClassMap = (ClassMap) customMappings.get(ClassMapKeyFactory.createKey(sourceClass,
85           destInterfaces[i]));
86       if (interfaceClassMap != null) {
87         interfaceMaps.add(interfaceClassMap);
88       }
89     }
90
91     for (int i = 0; i < sourceInterfaces.length; i++) {
92       // see if the source class is mapped to the dest class
93
ClassMap interfaceClassMap = (ClassMap) customMappings.get(ClassMapKeyFactory.createKey(sourceInterfaces[i],
94           destClass));
95       if (interfaceClassMap != null) {
96         interfaceMaps.add(interfaceClassMap);
97       }
98     }
99
100     // multiple levels of custom mapping processed in wrong order - need to
101
// reverse
102
Collections.reverse(interfaceMaps);
103
104     return interfaceMaps;
105   }
106
107   // TODO: what is logic difference between this method and
108
// checkForInterfaceMappingsInCustomMappings. By the names
109
// these methods seem to be trying to accomplish the same thing with a
110
// different implementation. Also, one takes a map-id
111
// and the other doesnt ?? somewhat confusing
112
public ClassMap findInterfaceOrAbstractMapping(Map JavaDoc customMappings, Class JavaDoc destClass, Object JavaDoc sourceObj, String JavaDoc mapId) {
113     ClassMap newClassMap = null;
114     Class JavaDoc newClass = null;
115     // Use object array for keys to avoid any rare thread synchronization
116
// issues while iterating
117
// over the custom mappings. See bug #1550275.
118
Object JavaDoc[] keys = customMappings.keySet().toArray();
119     for (int i = 0; i < keys.length; i++) {
120       ClassMap map = (ClassMap) customMappings.get(keys[i]);
121       Class JavaDoc dest = map.getDestClass().getClassToMap();
122
123       // is Assignable?
124
// now that we have the a sub class for the abstract class or
125
// interface we need to
126
// verify that the source class in the map IS a super class of the
127
// source object...or the source object itself. .
128
if (destClass.isAssignableFrom(dest)
129           && (map.getSourceClass().getClassToMap().isAssignableFrom(sourceObj.getClass()) || map.getSourceClass()
130               .getClassToMap().isInstance(sourceObj))
131           // look for most specific mapping
132
&& (newClass == null || newClass.isAssignableFrom(dest))
133           && (mapId == null || ((String JavaDoc) keys[i]).endsWith(mapId))) {
134         newClassMap = map;
135         newClass = dest;
136       }
137     }
138     return newClassMap;
139   }
140
141 }
Popular Tags