1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.service.impl;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.criteria.Predicate;
20 import org.kuali.rice.core.api.criteria.PredicateFactory;
21 import org.kuali.rice.core.api.criteria.QueryByCriteria;
22 import org.kuali.rice.core.api.criteria.QueryResults;
23 import org.kuali.rice.core.api.mo.common.active.Inactivatable;
24 import org.kuali.rice.core.api.mo.common.active.MutableInactivatable;
25 import org.kuali.rice.krad.bo.BusinessObject;
26 import org.kuali.rice.krad.data.DataObjectService;
27 import org.kuali.rice.krad.data.DataObjectWrapper;
28 import org.kuali.rice.krad.data.KradDataServiceLocator;
29 import org.kuali.rice.krad.data.metadata.DataObjectAttributeRelationship;
30 import org.kuali.rice.krad.data.metadata.DataObjectMetadata;
31 import org.kuali.rice.krad.data.metadata.DataObjectRelationship;
32 import org.kuali.rice.krad.datadictionary.InactivationBlockingMetadata;
33 import org.kuali.rice.krad.datadictionary.RelationshipDefinition;
34 import org.kuali.rice.krad.service.DataObjectMetaDataService;
35 import org.kuali.rice.krad.service.InactivationBlockingDetectionService;
36 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
37 import org.kuali.rice.krad.service.LegacyDataAdapter;
38 import org.kuali.rice.krad.util.KRADUtils;
39 import org.kuali.rice.krad.util.LegacyUtils;
40 import org.springframework.transaction.annotation.Transactional;
41
42 import java.util.ArrayList;
43 import java.util.Collection;
44 import java.util.HashMap;
45 import java.util.Iterator;
46 import java.util.List;
47 import java.util.Map;
48
49
50
51
52
53
54 @Transactional
55 public class InactivationBlockingDetectionServiceImpl implements InactivationBlockingDetectionService {
56 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(InactivationBlockingDetectionServiceImpl.class);
57
58 protected DataObjectMetaDataService dataObjectMetaDataService;
59 private volatile DataObjectService dataObjectService;
60 protected LegacyDataAdapter legacyDataAdapter;
61
62
63
64
65
66
67
68
69
70 @SuppressWarnings("unchecked")
71 @Deprecated
72 @Override
73 public Collection<BusinessObject> listAllBlockerRecords(BusinessObject blockedBo, InactivationBlockingMetadata inactivationBlockingMetadata) {
74 Collection<BusinessObject> blockingRecords = new ArrayList<BusinessObject>();
75
76 Map<String, String> queryMap = buildInactivationBlockerQueryMap(blockedBo, inactivationBlockingMetadata);
77 if (LOG.isDebugEnabled()) {
78 LOG.debug("Checking for blocker records for object: " + blockedBo);
79 LOG.debug(" With Metadata: " + inactivationBlockingMetadata);
80 LOG.debug(" Resulting Query Map: " + queryMap);
81 }
82
83 if (queryMap != null) {
84 Collection potentialBlockingRecords = legacyDataAdapter.findMatching(
85 inactivationBlockingMetadata.getBlockingReferenceBusinessObjectClass(), queryMap);
86 for (Iterator iterator = potentialBlockingRecords.iterator(); iterator.hasNext();) {
87 MutableInactivatable businessObject = (MutableInactivatable) iterator.next();
88 if (businessObject.isActive()) {
89 blockingRecords.add((BusinessObject) businessObject);
90 }
91 }
92 }
93
94 return blockingRecords;
95 }
96
97
98
99
100
101
102
103
104
105
106 @Deprecated
107 @Override
108 public boolean hasABlockingRecord(BusinessObject blockedBo, InactivationBlockingMetadata inactivationBlockingMetadata) {
109 boolean hasBlockingRecord = false;
110
111 Map<String, String> queryMap = buildInactivationBlockerQueryMap(blockedBo, inactivationBlockingMetadata);
112 if (queryMap != null) {
113 Collection potentialBlockingRecords = legacyDataAdapter.findMatching(
114 inactivationBlockingMetadata.getBlockingReferenceBusinessObjectClass(), queryMap);
115 for (Iterator iterator = potentialBlockingRecords.iterator(); iterator.hasNext();) {
116 MutableInactivatable businessObject = (MutableInactivatable) iterator.next();
117 if (businessObject.isActive()) {
118 hasBlockingRecord = true;
119 break;
120 }
121 }
122 }
123
124
125 return hasBlockingRecord;
126 }
127
128 @Deprecated
129 protected Map<String, String> buildInactivationBlockerQueryMap(BusinessObject blockedBo, InactivationBlockingMetadata inactivationBlockingMetadata) {
130 BusinessObject blockingBo = (BusinessObject) KRADUtils.createNewObjectFromClass(
131 inactivationBlockingMetadata.getBlockingReferenceBusinessObjectClass());
132
133 org.kuali.rice.krad.bo.DataObjectRelationship dataObjectRelationship = legacyDataAdapter
134 .getDataObjectRelationship(blockingBo, blockedBo.getClass(),
135 inactivationBlockingMetadata.getBlockedReferencePropertyName(), "", true, false, false);
136
137 RelationshipDefinition relationshipDefinition = KRADServiceLocatorWeb.getLegacyDataAdapter().getDictionaryRelationship(blockedBo.getClass(),inactivationBlockingMetadata.getBlockedReferencePropertyName());
138
139
140 if (dataObjectRelationship != null) {
141 Map<String, String> parentToChildReferences = dataObjectRelationship.getParentToChildReferences();
142 Map<String, String> queryMap = new HashMap<String, String>();
143 for (Map.Entry<String, String> parentToChildReference : parentToChildReferences.entrySet()) {
144 String fieldName = parentToChildReference.getKey();
145 Object fieldValue = KradDataServiceLocator.getDataObjectService().wrap(blockedBo).getPropertyValueNullSafe(parentToChildReference.getValue());
146 if (fieldValue != null && StringUtils.isNotBlank(fieldValue.toString())) {
147 queryMap.put(fieldName, fieldValue.toString());
148 } else {
149 LOG.error("Found null value for foreign key field " + fieldName
150 + " while building inactivation blocking query map.");
151 throw new RuntimeException("Found null value for foreign key field '" + fieldName
152 + "' while building inactivation blocking query map.");
153 }
154 }
155
156 return queryMap;
157 }
158
159 return null;
160 }
161
162
163
164
165
166
167 @Override
168 public boolean detectBlockingRecord(Object dataObject, InactivationBlockingMetadata inactivationBlockingMetadata) {
169 if (LegacyUtils.useLegacyForObject(dataObject)) {
170 return hasABlockingRecord((BusinessObject)dataObject, inactivationBlockingMetadata);
171 }
172 QueryByCriteria criteria = buildInactivationBlockerCriteria(dataObject, inactivationBlockingMetadata);
173 if (criteria != null) {
174 Class<?> blockingType = inactivationBlockingMetadata.getBlockingDataObjectClass();
175 QueryResults<?> potentialBlockingRecords = getDataObjectService().findMatching(blockingType, criteria);
176 for (Object result : potentialBlockingRecords.getResults()) {
177 if (!(result instanceof Inactivatable)) {
178 throw new IllegalStateException("Blocking records must implement Inactivatable, but encountered one which does not: " + result);
179 }
180 Inactivatable inactivatable = (Inactivatable)result;
181 if (inactivatable.isActive()) {
182 return true;
183 }
184 }
185 }
186
187 return false;
188 }
189
190
191
192
193
194
195 @Override
196 public Collection<?> detectAllBlockingRecords(Object dataObject,
197 InactivationBlockingMetadata inactivationBlockingMetadata) {
198 if (LegacyUtils.useLegacyForObject(dataObject)) {
199 return listAllBlockerRecords((BusinessObject) dataObject, inactivationBlockingMetadata);
200 }
201 List<Object> blockingRecords = new ArrayList<Object>();
202
203 QueryByCriteria criteria = buildInactivationBlockerCriteria(dataObject, inactivationBlockingMetadata);
204 if (LOG.isDebugEnabled()) {
205 LOG.debug("Checking for blocker records for object: " + dataObject);
206 LOG.debug(" With Metadata: " + inactivationBlockingMetadata);
207 LOG.debug(" Resulting QueryByCriteria: " + criteria);
208 }
209
210 if (criteria != null) {
211 Class<?> blockingType = inactivationBlockingMetadata.getBlockingDataObjectClass();
212 QueryResults<?> potentialBlockingRecords = getDataObjectService().findMatching(blockingType, criteria);
213 for (Object result : potentialBlockingRecords.getResults()) {
214 if (!(result instanceof Inactivatable)) {
215 throw new IllegalStateException("Blocking records must implement Inactivatable, but encountered one which does not: " + result);
216 }
217 Inactivatable inactivatable = (Inactivatable)result;
218 if (inactivatable.isActive()) {
219 blockingRecords.add(result);
220 }
221 }
222 }
223
224 return blockingRecords;
225 }
226
227 protected QueryByCriteria buildInactivationBlockerCriteria(Object blockedObject, InactivationBlockingMetadata inactivationBlockingMetadata) {
228 DataObjectMetadata blockingObjectMetadata =
229 getDataObjectService().getMetadataRepository().getMetadata(inactivationBlockingMetadata.getBlockingDataObjectClass());
230 DataObjectRelationship dataObjectRelationship =
231 blockingObjectMetadata.getRelationship(inactivationBlockingMetadata.getBlockedAttributeName());
232
233
234 if (dataObjectRelationship != null && !dataObjectRelationship.getAttributeRelationships().isEmpty()) {
235 DataObjectWrapper<?> wrap = getDataObjectService().wrap(blockedObject);
236 List<Predicate> predicates = new ArrayList<Predicate>();
237 for (DataObjectAttributeRelationship relationship : dataObjectRelationship.getAttributeRelationships()) {
238 String fieldName = relationship.getParentAttributeName();
239 Object fieldValue = wrap.getPropertyValue(relationship.getChildAttributeName());
240 if (fieldValue != null && StringUtils.isNotBlank(fieldValue.toString())) {
241 predicates.add(PredicateFactory.equal(fieldName, fieldValue));
242 }
243 }
244 return QueryByCriteria.Builder.fromPredicates(predicates.toArray(new Predicate[predicates.size()]));
245 }
246 return null;
247 }
248
249
250 public void setDataObjectMetaDataService(DataObjectMetaDataService dataObjectMetaDataService) {
251 this.dataObjectMetaDataService = dataObjectMetaDataService;
252 }
253
254 public void setLegacyDataAdapter(LegacyDataAdapter legacyDataAdapter) {
255 this.legacyDataAdapter = legacyDataAdapter;
256 }
257
258 public DataObjectService getDataObjectService() {
259 if (dataObjectService == null) {
260 dataObjectService = KradDataServiceLocator.getDataObjectService();
261 }
262 return dataObjectService;
263 }
264
265 public void setDataObjectService(DataObjectService dataObjectService) {
266 this.dataObjectService = dataObjectService;
267 }
268 }