1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krms.impl.rule;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.kuali.rice.core.api.uif.RemotableAttributeError;
21 import org.kuali.rice.core.api.util.RiceKeyConstants;
22 import org.kuali.rice.krad.bo.GlobalBusinessObject;
23 import org.kuali.rice.krad.bo.PersistableBusinessObject;
24 import org.kuali.rice.krad.maintenance.MaintenanceDocument;
25 import org.kuali.rice.krad.rules.MaintenanceDocumentRuleBase;
26 import org.kuali.rice.krad.util.KRADConstants;
27 import org.kuali.rice.krms.api.KrmsConstants;
28 import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
29 import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
30 import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
31 import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService;
32 import org.kuali.rice.krms.framework.type.ActionTypeService;
33 import org.kuali.rice.krms.framework.type.AgendaTypeService;
34 import org.kuali.rice.krms.impl.authorization.AgendaAuthorizationService;
35 import org.kuali.rice.krms.impl.repository.ActionBo;
36 import org.kuali.rice.krms.impl.repository.AgendaBo;
37 import org.kuali.rice.krms.impl.repository.AgendaBoService;
38 import org.kuali.rice.krms.impl.repository.AgendaItemBo;
39 import org.kuali.rice.krms.impl.repository.ContextBoService;
40 import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
41 import org.kuali.rice.krms.impl.repository.RuleBo;
42 import org.kuali.rice.krms.impl.repository.RuleBoService;
43 import org.kuali.rice.krms.impl.ui.AgendaEditor;
44 import org.kuali.rice.krms.impl.util.KRMSPropertyConstants;
45
46 import java.util.List;
47 import java.util.Map;
48
49
50
51
52 public class AgendaEditorBusRule extends MaintenanceDocumentRuleBase {
53
54 @Override
55 protected boolean primaryKeyCheck(MaintenanceDocument document) {
56
57 boolean success = true;
58 Class<?> dataObjectClass = document.getNewMaintainableObject().getDataObjectClass();
59
60
61 Object oldBo = ((AgendaEditor) document.getOldMaintainableObject().getDataObject()).getAgenda();
62 Object newDataObject = ((AgendaEditor) document.getNewMaintainableObject().getDataObject()).getAgenda();
63
64
65
66
67
68
69 if (newDataObject instanceof GlobalBusinessObject) {
70 return success;
71 }
72
73
74
75 if (document.isEdit()) {
76 if (!getDataObjectMetaDataService().equalsByPrimaryKeys(oldBo, newDataObject)) {
77
78 putDocumentError(KRADConstants.DOCUMENT_ERRORS,
79 RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_PRIMARY_KEYS_CHANGED_ON_EDIT,
80 getHumanReadablePrimaryKeyFieldNames(dataObjectClass));
81 success &= false;
82 }
83 }
84
85
86
87 else if (document.isNew()) {
88
89
90 if (newDataObject instanceof PersistableBusinessObject) {
91
92
93 Map<String, ?> newPkFields = getDataObjectMetaDataService().getPrimaryKeyFieldValues(newDataObject);
94
95
96
97
98
99
100
101 PersistableBusinessObject testBo = getBoService()
102 .findByPrimaryKey(dataObjectClass.asSubclass(PersistableBusinessObject.class), newPkFields);
103
104
105
106 if (testBo != null) {
107 putDocumentError(KRADConstants.DOCUMENT_ERRORS,
108 RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_KEYS_ALREADY_EXIST_ON_CREATE_NEW,
109 getHumanReadablePrimaryKeyFieldNames(dataObjectClass));
110 success &= false;
111 }
112 }
113 }
114
115 return success;
116 }
117
118
119
120 @Override
121 protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) {
122 boolean isValid = true;
123
124 AgendaEditor agendaEditor = (AgendaEditor) document.getNewMaintainableObject().getDataObject();
125 AgendaEditor oldAgendaEditor = (AgendaEditor) document.getOldMaintainableObject().getDataObject();
126 isValid &= validContext(agendaEditor);
127 isValid &= validAgendaName(agendaEditor);
128 isValid &= validContextAgendaNamespace(agendaEditor);
129 isValid &= validAgendaTypeAndAttributes(oldAgendaEditor, agendaEditor);
130
131 return isValid;
132 }
133
134
135
136
137
138
139 public boolean validContext(AgendaEditor agendaEditor) {
140 boolean isValid = true;
141
142 try {
143 if (getContextBoService().getContextByContextId(agendaEditor.getAgenda().getContextId()) == null) {
144 this.putFieldError(KRMSPropertyConstants.Agenda.CONTEXT, "error.agenda.invalidContext");
145 isValid = false;
146 } else {
147 if (!getAgendaAuthorizationService().isAuthorized(KrmsConstants.MAINTAIN_KRMS_AGENDA,
148 agendaEditor.getAgenda().getContextId())) {
149 this.putFieldError(KRMSPropertyConstants.Agenda.CONTEXT, "error.agenda.unauthorizedContext");
150 isValid = false;
151 }
152 }
153 }
154 catch (IllegalArgumentException e) {
155 this.putFieldError(KRMSPropertyConstants.Agenda.CONTEXT, "error.agenda.invalidContext");
156 isValid = false;
157 }
158
159 return isValid;
160 }
161
162
163
164
165
166
167 public boolean validContextAgendaNamespace(AgendaEditor agendaEditor) {
168
169 if (StringUtils.isBlank(agendaEditor.getNamespace())) {
170 this.putFieldError(KRMSPropertyConstants.Context.NAMESPACE, "error.context.invalidNamespace");
171 return false;
172 }
173 return true;
174 }
175
176 private boolean validAgendaTypeAndAttributes( AgendaEditor oldAgendaEditor, AgendaEditor newAgendaEditor) {
177 if (validAgendaType(newAgendaEditor.getAgenda().getTypeId(), newAgendaEditor.getAgenda().getContextId())) {
178 return validAgendaAttributes(oldAgendaEditor, newAgendaEditor);
179 } else {
180 return false;
181 }
182 }
183 private boolean validAgendaType(String typeId, String contextId) {
184 boolean isValid = true;
185
186 if (!StringUtils.isBlank(typeId) && !StringUtils.isBlank(contextId)) {
187 if (getKrmsTypeRepositoryService().getAgendaTypeByAgendaTypeIdAndContextId(typeId, contextId) != null) {
188 return true;
189 } else {
190 this.putFieldError(KRMSPropertyConstants.Agenda.TYPE, "error.agenda.invalidType");
191 return false;
192 }
193 }
194
195 return isValid;
196 }
197
198 private boolean validAgendaAttributes(AgendaEditor oldAgendaEditor, AgendaEditor newAgendaEditor) {
199 boolean isValid = true;
200
201 String typeId = newAgendaEditor.getAgenda().getTypeId();
202
203 if (!StringUtils.isEmpty(typeId)) {
204 KrmsTypeDefinition typeDefinition = getKrmsTypeRepositoryService().getTypeById(typeId);
205
206 if (typeDefinition == null) {
207 throw new IllegalStateException("agenda typeId must match the id of a valid krms type");
208 } else if (StringUtils.isBlank(typeDefinition.getServiceName())) {
209 throw new IllegalStateException("agenda type definition must have a non-blank service name");
210 } else {
211 AgendaTypeService agendaTypeService =
212 (AgendaTypeService)KrmsRepositoryServiceLocator.getService(typeDefinition.getServiceName());
213
214 if (agendaTypeService == null) {
215 throw new IllegalStateException("typeDefinition must have a valid serviceName");
216 } else {
217
218 List<RemotableAttributeError> errors;
219 if (oldAgendaEditor == null) {
220 errors = agendaTypeService.validateAttributes(typeId, newAgendaEditor.getCustomAttributesMap());
221 } else {
222 errors = agendaTypeService.validateAttributesAgainstExisting(typeId, newAgendaEditor.getCustomAttributesMap(), oldAgendaEditor.getCustomAttributesMap());
223 }
224
225 if (!CollectionUtils.isEmpty(errors)) {
226 isValid = false;
227 for (RemotableAttributeError error : errors) {
228 for (String errorStr : error.getErrors()) {
229 this.putFieldError(
230 KRMSPropertyConstants.AgendaEditor.CUSTOM_ATTRIBUTES_MAP +
231 "['" + error.getAttributeName() + "']",
232 errorStr
233 );
234 }
235 }
236 }
237 }
238 }
239 }
240 return isValid;
241 }
242
243
244
245
246
247
248 public boolean validAgendaName(AgendaEditor agendaEditor) {
249 try {
250 AgendaDefinition agendaFromDataBase = getAgendaBoService().getAgendaByNameAndContextId(
251 agendaEditor.getAgenda().getName(), agendaEditor.getAgenda().getContextId());
252 if ((agendaFromDataBase != null) && !StringUtils.equals(agendaFromDataBase.getId(), agendaEditor.getAgenda().getId())) {
253 this.putFieldError(KRMSPropertyConstants.Agenda.NAME, "error.agenda.duplicateName");
254 return false;
255 }
256 }
257 catch (IllegalArgumentException e) {
258 this.putFieldError(KRMSPropertyConstants.Agenda.NAME, "error.agenda.invalidName");
259 return false;
260 }
261 return true;
262 }
263
264
265
266
267
268
269
270 public boolean processAgendaItemBusinessRules(MaintenanceDocument document) {
271 boolean isValid = true;
272
273 AgendaEditor newAgendaEditor = (AgendaEditor) document.getNewMaintainableObject().getDataObject();
274 AgendaEditor oldAgendaEditor = (AgendaEditor) document.getOldMaintainableObject().getDataObject();
275 RuleBo rule = newAgendaEditor.getAgendaItemLine().getRule();
276 isValid &= validateRuleName(rule, newAgendaEditor.getAgenda());
277 isValid &= validRuleType(rule.getTypeId(), newAgendaEditor.getAgenda().getContextId());
278 isValid &= validateRuleAction(oldAgendaEditor, newAgendaEditor);
279
280 return isValid;
281 }
282
283
284
285
286
287
288
289 private boolean validateRuleName(RuleBo rule, AgendaBo agenda) {
290 if (StringUtils.isBlank(rule.getName())) {
291 this.putFieldError(KRMSPropertyConstants.Rule.NAME, "error.rule.invalidName");
292 return false;
293 }
294
295 for (AgendaItemBo agendaItem : agenda.getItems()) {
296 if (!StringUtils.equals(agendaItem.getRule().getId(), rule.getId()) && StringUtils.equals(agendaItem.getRule().getName(), rule.getName())
297 && StringUtils.equals(agendaItem.getRule().getNamespace(), rule.getNamespace())) {
298 this.putFieldError(KRMSPropertyConstants.Rule.NAME, "error.rule.duplicateName");
299 return false;
300 }
301 }
302
303
304 if (StringUtils.isNotBlank(rule.getNamespace())) {
305 RuleDefinition ruleFromDatabase = getRuleBoService().getRuleByNameAndNamespace(rule.getName(), rule.getNamespace());
306 try {
307 if ((ruleFromDatabase != null) && !StringUtils.equals(ruleFromDatabase.getId(), rule.getId())) {
308 this.putFieldError(KRMSPropertyConstants.Rule.NAME, "error.rule.duplicateName");
309 return false;
310 }
311 }
312 catch (IllegalArgumentException e) {
313 this.putFieldError(KRMSPropertyConstants.Rule.NAME, "error.rule.invalidName");
314 return false;
315 }
316 }
317 return true;
318 }
319
320
321
322
323
324
325
326 private boolean validRuleType(String ruleTypeId, String contextId) {
327 if (StringUtils.isBlank(ruleTypeId)) {
328 return true;
329 }
330
331 if (getKrmsTypeRepositoryService().getRuleTypeByRuleTypeIdAndContextId(ruleTypeId, contextId) != null) {
332 return true;
333 } else {
334 this.putFieldError(KRMSPropertyConstants.Rule.TYPE, "error.rule.invalidType");
335 return false;
336 }
337 }
338
339 private boolean validateRuleAction(AgendaEditor oldAgendaEditor, AgendaEditor newAgendaEditor) {
340 boolean isValid = true;
341 ActionBo newActionBo = newAgendaEditor.getAgendaItemLineRuleAction();
342
343 isValid &= validRuleActionType(newActionBo.getTypeId(), newAgendaEditor.getAgenda().getContextId());
344 if (isValid && StringUtils.isNotBlank(newActionBo.getTypeId())) {
345 isValid &= validRuleActionName(newActionBo.getName());
346 isValid &= validRuleActionAttributes(oldAgendaEditor, newAgendaEditor);
347 }
348 return isValid;
349 }
350
351
352
353
354
355
356
357 private boolean validRuleActionType(String typeId, String contextId) {
358 if (StringUtils.isBlank(typeId)) {
359 return true;
360 }
361
362 if (getKrmsTypeRepositoryService().getActionTypeByActionTypeIdAndContextId(typeId, contextId) != null) {
363 return true;
364 } else {
365 this.putFieldError(KRMSPropertyConstants.Action.TYPE, "error.action.invalidType");
366 return false;
367 }
368 }
369
370
371
372
373 private boolean validRuleActionName(String name) {
374 if (StringUtils.isNotBlank(name)) {
375 return true;
376 } else {
377 this.putFieldError(KRMSPropertyConstants.Action.NAME, "error.action.missingName");
378 return false;
379 }
380 }
381
382 private boolean validRuleActionAttributes(AgendaEditor oldAgendaEditor, AgendaEditor newAgendaEditor) {
383 boolean isValid = true;
384
385 String typeId = newAgendaEditor.getAgendaItemLineRuleAction().getTypeId();
386
387 if (!StringUtils.isBlank(typeId)) {
388 KrmsTypeDefinition typeDefinition = getKrmsTypeRepositoryService().getTypeById(typeId);
389
390 if (typeDefinition == null) {
391 throw new IllegalStateException("rule action typeId must match the id of a valid krms type");
392 } else if (StringUtils.isBlank(typeDefinition.getServiceName())) {
393 throw new IllegalStateException("rule action type definition must have a non-blank service name");
394 } else {
395 ActionTypeService actionTypeService = getActionTypeService(typeDefinition.getServiceName());
396
397 if (actionTypeService == null) {
398 throw new IllegalStateException("typeDefinition must have a valid serviceName");
399 } else {
400
401 List<RemotableAttributeError> errors;
402 if (oldAgendaEditor == null) {
403 errors = actionTypeService.validateAttributes(typeId,
404 newAgendaEditor.getCustomRuleActionAttributesMap());
405 } else {
406 errors = actionTypeService.validateAttributesAgainstExisting(typeId,
407 newAgendaEditor.getCustomRuleActionAttributesMap(), oldAgendaEditor.getCustomRuleActionAttributesMap());
408 }
409
410 if (!CollectionUtils.isEmpty(errors)) {
411 isValid = false;
412 for (RemotableAttributeError error : errors) {
413 for (String errorStr : error.getErrors()) {
414 this.putFieldError(
415 KRMSPropertyConstants.AgendaEditor.CUSTOM_RULE_ACTION_ATTRIBUTES_MAP +
416 "['" + error.getAttributeName() + "']",
417 errorStr
418 );
419 }
420 }
421 }
422 }
423 }
424 }
425 return isValid;
426 }
427
428 public ContextBoService getContextBoService() {
429 return KrmsRepositoryServiceLocator.getContextBoService();
430 }
431
432 public AgendaBoService getAgendaBoService() {
433 return KrmsRepositoryServiceLocator.getAgendaBoService();
434 }
435
436 public RuleBoService getRuleBoService() {
437 return KrmsRepositoryServiceLocator.getRuleBoService();
438 }
439
440 public KrmsTypeRepositoryService getKrmsTypeRepositoryService() {
441 return KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService();
442 }
443
444 public ActionTypeService getActionTypeService(String serviceName) {
445 return (ActionTypeService)KrmsRepositoryServiceLocator.getService(serviceName);
446 }
447 public AgendaAuthorizationService getAgendaAuthorizationService() {
448 return KrmsRepositoryServiceLocator.getAgendaAuthorizationService();
449 }
450
451 }
452