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 * @author Alejandro Abdelnur
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 System.out.println(ex);
67 ex.printStackTrace(System.out);
68 throw new RuntimeException("Could not do a copyFrom "+ex);
69 }
70 }
71
72 private CopyFrom createInstance(Class interfaceClass) throws Exception {
73 return (CopyFrom) ((Class)_baseImplMap.get(interfaceClass)).newInstance();
74 }
75
76 private Object doCopy(Object value,Class baseInterface) throws Exception {
77 if (value!=null) {
78 Class vClass = value.getClass();
79 if (vClass.isArray()) {
80 value = doCopyArray(value,baseInterface);
81 }
82 else
83 if (value instanceof Collection) {
84 value = doCopyCollection((Collection)value,baseInterface);
85 }
86 else
87 if (value instanceof Map) {
88 value = doCopyMap((Map)value,baseInterface);
89 }
90 else
91 if (isBasicType(vClass)) {
92
93 if (value instanceof Date) {
94 value = ((Date)value).clone();
95 }
96 }
97 else {
98 if (value instanceof CopyFrom) {
99 CopyFrom source = (CopyFrom)value;
100 CopyFrom target = createInstance(source.getInterface());
101 target.copyFrom(source);
102 value = target;
103 }
104 else {
105 throw new Exception("unsupported class for 'copyFrom' "+value.getClass());
106 }
107 }
108 }
109 return value;
110 }
111
112 private Object doCopyArray(Object array,Class baseInterface) throws Exception {
113 Class elementClass = array.getClass().getComponentType();
114 int length = Array.getLength(array);
115 Object newArray = Array.newInstance(elementClass,length);
116 for (int i=0;i<length;i++) {
117 Object element = doCopy(Array.get(array,i),baseInterface);
118 Array.set(newArray,i,element);
119 }
120 return newArray;
121 }
122
123 private Object doCopyCollection(Collection collection,Class baseInterface) throws Exception {
124
125 Collection newColl = (collection instanceof Set) ? (Collection)new HashSet() : (Collection)new ArrayList();
126 Iterator i = collection.iterator();
127 while (i.hasNext()) {
128 Object element = doCopy(i.next(),baseInterface);
129 newColl.add(element);
130 }
131 return newColl;
132 }
133
134 private Object doCopyMap(Map map,Class baseInterface) throws Exception {
135 Map newMap = new HashMap();
136 Iterator entries = map.entrySet().iterator();
137 while (entries.hasNext()) {
138 Map.Entry entry = (Map.Entry) entries.next();
139 Object key = entry.getKey();
140 Object element = doCopy(entry.getValue(),baseInterface);
141 newMap.put(key,element);
142 }
143 return newMap;
144 }
145
146 private static final Set BASIC_TYPES = new HashSet();
147
148 static {
149 BASIC_TYPES.add(Boolean.class);
150 BASIC_TYPES.add(Byte.class);
151 BASIC_TYPES.add(Character.class);
152 BASIC_TYPES.add(Double.class);
153 BASIC_TYPES.add(Float.class);
154 BASIC_TYPES.add(Integer.class);
155 BASIC_TYPES.add(Long.class);
156 BASIC_TYPES.add(Short.class);
157 BASIC_TYPES.add(String.class);
158 BASIC_TYPES.add(Date.class);
159 }
160
161 private boolean isBasicType(Class vClass) {
162 return BASIC_TYPES.contains(vClass);
163 }
164
165 }