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