1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.sun.syndication.feed.impl;
18
19 import com.sun.syndication.feed.CopyFrom;
20 import com.sun.syndication.feed.impl.BeanIntrospector;
21
22 import java.beans.PropertyDescriptor;
23 import java.lang.reflect.Array;
24 import java.lang.reflect.Method;
25 import java.util.*;
26
27
28
29
30 public class CopyFromHelper {
31 private static final Object[] NO_PARAMS = new Object[0];
32
33 private Class _beanInterfaceClass;
34 private Map _baseInterfaceMap;
35 private Map _baseImplMap;
36
37 public CopyFromHelper(Class beanInterfaceClass,Map basePropInterfaceMap,Map basePropClassImplMap) {
38 _beanInterfaceClass = beanInterfaceClass;
39 _baseInterfaceMap = basePropInterfaceMap;
40 _baseImplMap = basePropClassImplMap;
41 }
42
43 public void copy(Object target,Object source) {
44 try {
45 PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(_beanInterfaceClass);
46 if (pds!=null) {
47 for (int i=0;i<pds.length;i++) {
48 String propertyName = pds[i].getName();
49 Method pReadMethod = pds[i].getReadMethod();
50 Method pWriteMethod = pds[i].getWriteMethod();
51 if (pReadMethod!=null && pWriteMethod!=null &&
52 pReadMethod.getDeclaringClass()!=Object.class &&
53 pReadMethod.getParameterTypes().length==0 &&
54 _baseInterfaceMap.containsKey(propertyName)) {
55 Object value = pReadMethod.invoke(source,NO_PARAMS);
56 if (value!=null) {
57 Class baseInterface = (Class) _baseInterfaceMap.get(propertyName);
58 value = doCopy(value,baseInterface);
59 pWriteMethod.invoke(target,new Object[]{value});
60 }
61 }
62 }
63 }
64 }
65 catch (Exception ex) {
66 throw new RuntimeException("Could not do a copyFrom "+ex, ex);
67 }
68 }
69
70 private CopyFrom createInstance(Class interfaceClass) throws Exception {
71 if( _baseImplMap.get(interfaceClass) == null ){
72 return null;
73 }
74 else {
75 return (CopyFrom) ((Class)_baseImplMap.get(interfaceClass)).newInstance();
76 }
77 }
78
79 private Object doCopy(Object value,Class baseInterface) throws Exception {
80 if (value!=null) {
81 Class vClass = value.getClass();
82 if (vClass.isArray()) {
83 value = doCopyArray(value,baseInterface);
84 }
85 else
86 if (value instanceof Collection) {
87 value = doCopyCollection((Collection)value,baseInterface);
88 }
89 else
90 if (value instanceof Map) {
91 value = doCopyMap((Map)value,baseInterface);
92 }
93 else
94 if (isBasicType(vClass)) {
95
96 if (value instanceof Date) {
97 value = ((Date)value).clone();
98 }
99 }
100 else {
101 if (value instanceof CopyFrom) {
102 CopyFrom source = (CopyFrom) value;
103 CopyFrom target = createInstance(source.getInterface());
104 target = target == null ? (CopyFrom) value.getClass().newInstance() : target;
105 target.copyFrom(source);
106 value = target;
107 }
108 else {
109 throw new Exception("unsupported class for 'copyFrom' "+value.getClass());
110 }
111 }
112 }
113 return value;
114 }
115
116 private Object doCopyArray(Object array,Class baseInterface) throws Exception {
117 Class elementClass = array.getClass().getComponentType();
118 int length = Array.getLength(array);
119 Object newArray = Array.newInstance(elementClass,length);
120 for (int i=0;i<length;i++) {
121 Object element = doCopy(Array.get(array,i),baseInterface);
122 Array.set(newArray,i,element);
123 }
124 return newArray;
125 }
126
127 private Object doCopyCollection(Collection collection,Class baseInterface) throws Exception {
128
129 Collection newColl = (collection instanceof Set) ? (Collection)new HashSet() : (Collection)new ArrayList();
130 Iterator i = collection.iterator();
131 while (i.hasNext()) {
132 Object element = doCopy(i.next(),baseInterface);
133 newColl.add(element);
134 }
135 return newColl;
136 }
137
138 private Object doCopyMap(Map map,Class baseInterface) throws Exception {
139 Map newMap = new HashMap();
140 Iterator entries = map.entrySet().iterator();
141 while (entries.hasNext()) {
142 Map.Entry entry = (Map.Entry) entries.next();
143 Object key = entry.getKey();
144 Object element = doCopy(entry.getValue(),baseInterface);
145 newMap.put(key,element);
146 }
147 return newMap;
148 }
149
150 private static final Set BASIC_TYPES = new HashSet();
151
152 static {
153 BASIC_TYPES.add(Boolean.class);
154 BASIC_TYPES.add(Byte.class);
155 BASIC_TYPES.add(Character.class);
156 BASIC_TYPES.add(Double.class);
157 BASIC_TYPES.add(Float.class);
158 BASIC_TYPES.add(Integer.class);
159 BASIC_TYPES.add(Long.class);
160 BASIC_TYPES.add(Short.class);
161 BASIC_TYPES.add(String.class);
162 BASIC_TYPES.add(Date.class);
163 }
164
165 private boolean isBasicType(Class vClass) {
166 return BASIC_TYPES.contains(vClass);
167 }
168
169 }