1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.data.provider.impl;
17
18 import java.util.Collection;
19 import java.util.List;
20 import java.util.Map;
21
22 import org.apache.commons.lang.StringUtils;
23 import org.kuali.rice.krad.data.metadata.DataObjectAttribute;
24 import org.kuali.rice.krad.data.metadata.DataObjectMetadata;
25 import org.kuali.rice.krad.data.metadata.MetadataMergeAction;
26 import org.kuali.rice.krad.data.metadata.impl.DataObjectAttributeInternal;
27 import org.kuali.rice.krad.data.metadata.impl.DataObjectMetadataInternal;
28 import org.kuali.rice.krad.data.provider.CompositeMetadataProvider;
29 import org.kuali.rice.krad.data.provider.MetadataProvider;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class CompositeMetadataProviderImpl extends MetadataProviderBase implements CompositeMetadataProvider {
45 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
46 .getLogger(CompositeMetadataProviderImpl.class);
47
48 protected List<MetadataProvider> providers;
49
50
51
52
53 @Override
54 protected synchronized void initializeMetadata(Collection<Class<?>> types) {
55 if (LOG.isInfoEnabled()) {
56 LOG.info("Initializing Metadata from sources: " + providers);
57 }
58 masterMetadataMap.clear();
59 if (!providers.isEmpty()) {
60
61
62
63
64
65 for (MetadataProvider provider : providers) {
66 if (LOG.isInfoEnabled()) {
67 LOG.info(" *** Processing MetadataProvider: " + provider);
68 }
69
70
71
72 Map<Class<?>, DataObjectMetadata> metadata = null;
73 if (provider.requiresListOfExistingTypes()) {
74 metadata = provider.provideMetadataForTypes(masterMetadataMap.keySet());
75 } else {
76 metadata = provider.provideMetadata();
77 }
78
79
80 for (Class<?> dataObjectType : metadata.keySet()) {
81 DataObjectMetadata existingMetadata = masterMetadataMap.get(dataObjectType);
82 DataObjectMetadata newMetadata = metadata.get(dataObjectType);
83 mergeMetadataForType(newMetadata, existingMetadata);
84 }
85 }
86
87
88
89
90
91 mergeInheritedAttributes();
92 }
93 }
94
95
96
97
98 protected void mergeInheritedAttributes() {
99 for (DataObjectMetadata metadata : masterMetadataMap.values()) {
100 for (DataObjectAttribute attr : metadata.getAttributes()) {
101 if (attr.isInherited()) {
102 if (LOG.isDebugEnabled()) {
103 LOG.debug("Processing inherited attribute on " + metadata.getType() + "." + attr.getName()
104 + " : " + attr.getInheritedFromType() + " / "
105 + attr.getInheritedFromParentAttributeName() + "."
106 + attr.getInheritedFromAttributeName());
107 }
108
109
110
111 DataObjectAttribute originalDataObjectAttribute = attr.getOriginalDataObjectAttribute();
112 if (originalDataObjectAttribute == null) {
113
114 LOG.error("originalDataObjectAttribute was null for " + attr);
115 continue;
116 }
117
118 if (!(originalDataObjectAttribute instanceof DataObjectAttributeInternal)) {
119 LOG.warn("The originalDataObjectAttribute does not implement the DataObjectAttributeInternal interface, we have no access to the embeddedAttribute property: "
120 + originalDataObjectAttribute);
121 }
122 Class<?> inheritedFromType = originalDataObjectAttribute.getInheritedFromType();
123 String inheritedFromAttributeName = originalDataObjectAttribute.getInheritedFromAttributeName();
124 if (inheritedFromType == null || StringUtils.isBlank(inheritedFromAttributeName)) {
125
126 LOG.error("inheritedFromType/inheritedFromAttributeName not completely populated for "
127 + originalDataObjectAttribute);
128 continue;
129 }
130
131 DataObjectMetadata inheritedMetadata = masterMetadataMap.get(inheritedFromType);
132 if (inheritedMetadata == null) {
133
134
135 LOG.warn("The metadata object for the inheritance does not exist, skipping: "
136 + inheritedFromType);
137 continue;
138 }
139 DataObjectAttribute inheritedAttribute = inheritedMetadata.getAttribute(inheritedFromAttributeName);
140 if (inheritedAttribute == null) {
141
142 LOG.warn("The attribute on the metadata object for the inheritance does not exist, skipping: "
143 + inheritedFromType + "." + inheritedFromAttributeName);
144 continue;
145 }
146
147 ((DataObjectAttributeInternal) originalDataObjectAttribute)
148 .setEmbeddedAttribute(inheritedAttribute);
149 }
150 }
151 }
152 }
153
154
155
156
157
158
159
160 protected void mergeMetadataForType(DataObjectMetadata newMetadata, DataObjectMetadata existingMetadata) {
161 if (LOG.isDebugEnabled()) {
162 LOG.debug("Type: " + newMetadata.getType() + " : " + newMetadata);
163 }
164
165
166 if (existingMetadata == null) {
167 if (newMetadata.getMergeAction() != MetadataMergeAction.REMOVE) {
168 LOG.debug("New Type - Adding metadata to masterMetadataMap");
169 masterMetadataMap.put(newMetadata.getType(), newMetadata);
170 } else {
171
172
173
174
175
176 LOG.warn("Attempt to REMOVE a DataObjectMetadata which did not exist: " + newMetadata.getType());
177 }
178 } else {
179 if (LOG.isDebugEnabled()) {
180 LOG.debug("Type already exists. Merging previously retrieved metadata using action "
181 + newMetadata.getMergeAction() + " : " + newMetadata.getType());
182 }
183 if (newMetadata.getMergeAction() == MetadataMergeAction.MERGE) {
184
185
186
187 if (newMetadata instanceof DataObjectMetadataInternal
188 && existingMetadata instanceof DataObjectMetadataInternal) {
189 ((DataObjectMetadataInternal) newMetadata)
190 .setEmbedded((DataObjectMetadataInternal) existingMetadata);
191 masterMetadataMap.put(newMetadata.getType(), newMetadata);
192 } else {
193 LOG.warn("New or existing Metadata object does not implement the DataObjectMetadataInternal interface, unable to embed the previously retrieved metadata. REPLACING the entry in the masterMetadataMap ("
194 + existingMetadata + ") with the new version: " + newMetadata);
195 masterMetadataMap.put(newMetadata.getType(), newMetadata);
196 }
197 } else if (newMetadata.getMergeAction() == MetadataMergeAction.REPLACE) {
198
199 masterMetadataMap.put(newMetadata.getType(), newMetadata);
200 } else if (newMetadata.getMergeAction() == MetadataMergeAction.REMOVE) {
201 masterMetadataMap.remove(newMetadata.getType());
202 } else if (newMetadata.getMergeAction() == MetadataMergeAction.NO_OVERRIDE) {
203
204
205 } else {
206 LOG.warn("Unsupported MetadataMergeAction: " + newMetadata.getMergeAction() + " on " + newMetadata);
207 }
208 }
209
210 }
211
212
213
214
215 @Override
216 public List<MetadataProvider> getProviders() {
217 return providers;
218 }
219
220
221
222
223
224
225 public void setProviders(List<MetadataProvider> providers) {
226 this.providers = providers;
227 }
228
229 }