1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.beanmerger;
35
36 import info.magnolia.cms.core.Content;
37
38 import java.util.ArrayList;
39 import java.util.Collection;
40 import java.util.List;
41 import java.util.Map;
42
43 import javax.jcr.Node;
44
45 import org.apache.commons.collections.CollectionUtils;
46 import org.apache.commons.collections.functors.NotNullPredicate;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50
51
52
53
54
55
56 public abstract class BeanMergerBase implements BeanMerger {
57
58 protected Logger log = LoggerFactory.getLogger(this.getClass());
59
60 @Override
61 public Object merge(List sources) {
62 CollectionUtils.filter(sources, NotNullPredicate.INSTANCE);
63 if (sources.isEmpty()) {
64 return null;
65 }
66
67 if (sources.size() == 1 || isSimpleType(sources.get(0).getClass())) {
68 return sources.get(0);
69 }
70
71 if (sources.get(0) instanceof Collection) {
72 return mergeCollections(sources);
73 }
74
75 if (sources.get(0) instanceof Map) {
76 return mergeMaps(sources);
77 }
78
79 return mergeBean(sources);
80 }
81
82 protected abstract Object mergeBean(List sources);
83
84 protected Map mergeMaps(List<Map> sources) {
85 Map mergedMap;
86 try {
87 mergedMap = sources.get(0).getClass().newInstance();
88
89 for (Map map : sources) {
90 for (Object key : map.keySet()) {
91 List values = new ArrayList();
92 for (Map map2 : sources) {
93 if (map2.containsKey(key)) {
94 values.add(map2.get(key));
95 }
96 }
97 mergedMap.put(key, merge(values));
98 }
99 }
100 return mergedMap;
101 }
102 catch (Exception e) {
103 log.error("", e);
104 return sources.get(0);
105 }
106 }
107
108 protected Collection mergeCollections(List<Collection> sources) {
109 try {
110 Collection mergedCol = sources.get(0).getClass().newInstance();
111 for (Collection col : sources) {
112 mergedCol.addAll(col);
113 }
114 return mergedCol;
115 }
116 catch (Exception e) {
117 log.error("", e);
118 return sources.get(0);
119 }
120 }
121
122 protected boolean isSimpleType(Class type) {
123 return type.isPrimitive() ||
124 type == Boolean.class ||
125 type == Byte.class ||
126 type == Character.class ||
127 type == Short.class ||
128 type == Integer.class ||
129 type == Long.class ||
130 type == Float.class ||
131 type == Double.class ||
132 type == Void.class ||
133
134 type == String.class ||
135 type == Class.class ||
136
137 Content.class.isAssignableFrom(type) ||
138 Node.class.isAssignableFrom(type);
139 }
140
141 }