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.document.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 | 0 | public class AgendaEditorBusRule extends MaintenanceDocumentRuleBase { |
53 | |
|
54 | |
@Override |
55 | |
protected boolean primaryKeyCheck(MaintenanceDocument document) { |
56 | |
|
57 | 0 | boolean success = true; |
58 | 0 | Class<?> dataObjectClass = document.getNewMaintainableObject().getDataObjectClass(); |
59 | |
|
60 | |
|
61 | 0 | Object oldBo = ((AgendaEditor) document.getOldMaintainableObject().getDataObject()).getAgenda(); |
62 | 0 | Object newDataObject = ((AgendaEditor) document.getNewMaintainableObject().getDataObject()).getAgenda(); |
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
|
68 | |
|
69 | 0 | if (newDataObject instanceof GlobalBusinessObject) { |
70 | 0 | return success; |
71 | |
} |
72 | |
|
73 | |
|
74 | |
|
75 | 0 | if (document.isEdit()) { |
76 | 0 | if (!getDataObjectMetaDataService().equalsByPrimaryKeys(oldBo, newDataObject)) { |
77 | |
|
78 | 0 | putDocumentError(KRADConstants.DOCUMENT_ERRORS, |
79 | |
RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_PRIMARY_KEYS_CHANGED_ON_EDIT, |
80 | |
getHumanReadablePrimaryKeyFieldNames(dataObjectClass)); |
81 | 0 | success &= false; |
82 | |
} |
83 | |
} |
84 | |
|
85 | |
|
86 | |
|
87 | 0 | else if (document.isNew()) { |
88 | |
|
89 | |
|
90 | 0 | if (newDataObject instanceof PersistableBusinessObject) { |
91 | |
|
92 | |
|
93 | 0 | Map<String, ?> newPkFields = getDataObjectMetaDataService().getPrimaryKeyFieldValues(newDataObject); |
94 | |
|
95 | |
|
96 | |
|
97 | |
|
98 | |
|
99 | |
|
100 | |
|
101 | 0 | PersistableBusinessObject testBo = getBoService() |
102 | |
.findByPrimaryKey(dataObjectClass.asSubclass(PersistableBusinessObject.class), newPkFields); |
103 | |
|
104 | |
|
105 | |
|
106 | 0 | if (testBo != null) { |
107 | 0 | putDocumentError(KRADConstants.DOCUMENT_ERRORS, |
108 | |
RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_KEYS_ALREADY_EXIST_ON_CREATE_NEW, |
109 | |
getHumanReadablePrimaryKeyFieldNames(dataObjectClass)); |
110 | 0 | success &= false; |
111 | |
} |
112 | |
} |
113 | |
} |
114 | |
|
115 | 0 | return success; |
116 | |
} |
117 | |
|
118 | |
|
119 | |
|
120 | |
@Override |
121 | |
protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) { |
122 | 0 | boolean isValid = true; |
123 | |
|
124 | 0 | AgendaEditor agenda = (AgendaEditor) document.getNewMaintainableObject().getDataObject(); |
125 | 0 | AgendaEditor oldAgenda = (AgendaEditor) document.getOldMaintainableObject().getDataObject(); |
126 | 0 | isValid &= validContext(agenda); |
127 | 0 | isValid &= validAgendaName(agenda); |
128 | 0 | isValid &= validAgendaAttributes(oldAgenda, agenda); |
129 | |
|
130 | 0 | return isValid; |
131 | |
} |
132 | |
|
133 | |
|
134 | |
|
135 | |
|
136 | |
|
137 | |
|
138 | |
private boolean validContext(AgendaEditor agenda) { |
139 | 0 | boolean isValid = true; |
140 | |
|
141 | |
try { |
142 | 0 | if (getContextBoService().getContextByContextId(agenda.getAgenda().getContextId()) == null) { |
143 | 0 | this.putFieldError(KRMSPropertyConstants.Agenda.CONTEXT, "error.agenda.invalidContext"); |
144 | 0 | isValid = false; |
145 | |
} else { |
146 | 0 | if (!getAgendaAuthorizationService().isAuthorized(KrmsConstants.MAINTAIN_KRMS_AGENDA, |
147 | |
agenda.getAgenda().getContextId())) { |
148 | 0 | this.putFieldError(KRMSPropertyConstants.Agenda.CONTEXT, "error.agenda.unauthorizedContext"); |
149 | 0 | isValid = false; |
150 | |
} |
151 | |
} |
152 | |
} |
153 | 0 | catch (IllegalArgumentException e) { |
154 | 0 | this.putFieldError(KRMSPropertyConstants.Agenda.CONTEXT, "error.agenda.invalidContext"); |
155 | 0 | isValid = false; |
156 | 0 | } |
157 | |
|
158 | 0 | return isValid; |
159 | |
} |
160 | |
|
161 | |
private boolean validAgendaAttributes(AgendaEditor oldAgenda, AgendaEditor newAgenda) { |
162 | 0 | boolean isValid = true; |
163 | |
|
164 | 0 | String typeId = newAgenda.getAgenda().getTypeId(); |
165 | |
|
166 | 0 | if (!StringUtils.isEmpty(typeId)) { |
167 | 0 | KrmsTypeDefinition typeDefinition = getKrmsTypeRepositoryService().getTypeById(typeId); |
168 | |
|
169 | 0 | if (typeDefinition == null) { |
170 | 0 | throw new IllegalStateException("agenda typeId must match the id of a valid krms type"); |
171 | 0 | } else if (StringUtils.isBlank(typeDefinition.getServiceName())) { |
172 | 0 | throw new IllegalStateException("agenda type definition must have a non-blank service name"); |
173 | |
} else { |
174 | 0 | AgendaTypeService agendaTypeService = |
175 | |
(AgendaTypeService)KrmsRepositoryServiceLocator.getService(typeDefinition.getServiceName()); |
176 | |
|
177 | 0 | if (agendaTypeService == null) { |
178 | 0 | throw new IllegalStateException("typeDefinition must have a valid serviceName"); |
179 | |
} else { |
180 | |
|
181 | |
List<RemotableAttributeError> errors; |
182 | 0 | if (oldAgenda == null) { |
183 | 0 | errors = agendaTypeService.validateAttributes(typeId, newAgenda.getCustomAttributesMap()); |
184 | |
} else { |
185 | 0 | errors = agendaTypeService.validateAttributesAgainstExisting(typeId, newAgenda.getCustomAttributesMap(), oldAgenda.getCustomAttributesMap()); |
186 | |
} |
187 | |
|
188 | 0 | if (!CollectionUtils.isEmpty(errors)) { |
189 | 0 | isValid = false; |
190 | 0 | for (RemotableAttributeError error : errors) { |
191 | 0 | for (String errorStr : error.getErrors()) { |
192 | 0 | this.putFieldError( |
193 | |
KRMSPropertyConstants.AgendaEditor.CUSTOM_ATTRIBUTES_MAP + |
194 | |
"['" + error.getAttributeName() + "']", |
195 | |
errorStr |
196 | |
); |
197 | |
} |
198 | |
} |
199 | |
} |
200 | |
} |
201 | |
} |
202 | |
} |
203 | 0 | return isValid; |
204 | |
} |
205 | |
|
206 | |
|
207 | |
|
208 | |
|
209 | |
|
210 | |
|
211 | |
private boolean validAgendaName(AgendaEditor agenda) { |
212 | |
try { |
213 | 0 | AgendaDefinition agendaFromDataBase = getAgendaBoService().getAgendaByNameAndContextId(agenda.getAgenda().getName(), |
214 | |
agenda.getAgenda().getContextId()); |
215 | 0 | if ((agendaFromDataBase != null) && !StringUtils.equals(agendaFromDataBase.getId(), agenda.getAgenda().getId())) { |
216 | 0 | this.putFieldError(KRMSPropertyConstants.Agenda.NAME, "error.agenda.duplicateName"); |
217 | 0 | return false; |
218 | |
} |
219 | |
} |
220 | 0 | catch (IllegalArgumentException e) { |
221 | 0 | this.putFieldError(KRMSPropertyConstants.Agenda.NAME, "error.agenda.invalidName"); |
222 | 0 | return false; |
223 | 0 | } |
224 | 0 | return true; |
225 | |
} |
226 | |
|
227 | |
public boolean processAgendaItemBusinessRules(MaintenanceDocument document) { |
228 | 0 | boolean isValid = true; |
229 | |
|
230 | 0 | AgendaEditor newAgendaEditor = (AgendaEditor) document.getNewMaintainableObject().getDataObject(); |
231 | 0 | AgendaEditor oldAgendaEditor = (AgendaEditor) document.getOldMaintainableObject().getDataObject(); |
232 | 0 | RuleBo rule = newAgendaEditor.getAgendaItemLine().getRule(); |
233 | 0 | isValid &= validateRuleName(rule, newAgendaEditor.getAgenda()); |
234 | 0 | isValid &= validateRuleAction(oldAgendaEditor, newAgendaEditor); |
235 | |
|
236 | 0 | return isValid; |
237 | |
} |
238 | |
|
239 | |
|
240 | |
|
241 | |
|
242 | |
|
243 | |
|
244 | |
|
245 | |
private boolean validateRuleName(RuleBo rule, AgendaBo agenda) { |
246 | 0 | if (StringUtils.isBlank(rule.getName())) { |
247 | 0 | this.putFieldError(KRMSPropertyConstants.Rule.NAME, "error.rule.invalidName"); |
248 | 0 | return false; |
249 | |
} |
250 | |
|
251 | 0 | for (AgendaItemBo agendaItem : agenda.getItems()) { |
252 | 0 | if (!StringUtils.equals(agendaItem.getRule().getId(), rule.getId()) && StringUtils.equals(agendaItem.getRule().getName(), rule.getName()) |
253 | |
&& StringUtils.equals(agendaItem.getRule().getNamespace(), rule.getNamespace())) { |
254 | 0 | this.putFieldError(KRMSPropertyConstants.Rule.NAME, "error.rule.duplicateName"); |
255 | 0 | return false; |
256 | |
} |
257 | |
} |
258 | |
|
259 | |
|
260 | 0 | if (StringUtils.isNotBlank(rule.getNamespace())) { |
261 | 0 | RuleDefinition ruleFromDatabase = getRuleBoService().getRuleByNameAndNamespace(rule.getName(), rule.getNamespace()); |
262 | |
try { |
263 | 0 | if ((ruleFromDatabase != null) && !StringUtils.equals(ruleFromDatabase.getId(), rule.getId())) { |
264 | 0 | this.putFieldError(KRMSPropertyConstants.Rule.NAME, "error.rule.duplicateName"); |
265 | 0 | return false; |
266 | |
} |
267 | |
} |
268 | 0 | catch (IllegalArgumentException e) { |
269 | 0 | this.putFieldError(KRMSPropertyConstants.Rule.NAME, "error.rule.invalidName"); |
270 | 0 | return false; |
271 | 0 | } |
272 | |
} |
273 | 0 | return true; |
274 | |
} |
275 | |
|
276 | |
private boolean validateRuleAction(AgendaEditor oldAgendaEditor, AgendaEditor newAgendaEditor) { |
277 | 0 | boolean isValid = true; |
278 | 0 | ActionBo newActionBo = newAgendaEditor.getAgendaItemLineRuleAction(); |
279 | |
|
280 | 0 | isValid &= validRuleActionType(newActionBo.getTypeId()); |
281 | 0 | if (isValid && StringUtils.isNotBlank(newActionBo.getTypeId())) { |
282 | 0 | isValid &= validRuleActionName(newActionBo.getName()); |
283 | 0 | isValid &= validRuleActionAttributes(oldAgendaEditor, newAgendaEditor); |
284 | 0 | isValid &= validRuleActionDescription(newActionBo.getDescription()); |
285 | |
} |
286 | 0 | return isValid; |
287 | |
} |
288 | |
|
289 | |
|
290 | |
|
291 | |
|
292 | |
private boolean validRuleActionType(String typeId) { |
293 | 0 | if (StringUtils.isBlank(typeId) || (getKrmsTypeRepositoryService().getTypeById(typeId) != null)) { |
294 | 0 | return true; |
295 | |
} else { |
296 | 0 | this.putFieldError(KRMSPropertyConstants.Action.TYPE, "error.action.invalidType"); |
297 | 0 | return false; |
298 | |
} |
299 | |
} |
300 | |
|
301 | |
|
302 | |
|
303 | |
|
304 | |
private boolean validRuleActionName(String name) { |
305 | 0 | if (StringUtils.isNotBlank(name)) { |
306 | 0 | return true; |
307 | |
} else { |
308 | 0 | this.putFieldError(KRMSPropertyConstants.Action.NAME, "error.action.missingName"); |
309 | 0 | return false; |
310 | |
} |
311 | |
} |
312 | |
|
313 | |
private boolean validRuleActionAttributes(AgendaEditor oldAgenda, AgendaEditor newAgenda) { |
314 | 0 | boolean isValid = true; |
315 | |
|
316 | 0 | String typeId = newAgenda.getAgendaItemLineRuleAction().getTypeId(); |
317 | |
|
318 | 0 | if (!StringUtils.isBlank(typeId)) { |
319 | 0 | KrmsTypeDefinition typeDefinition = getKrmsTypeRepositoryService().getTypeById(typeId); |
320 | |
|
321 | 0 | if (typeDefinition == null) { |
322 | 0 | throw new IllegalStateException("action typeId must match the id of a valid krms type"); |
323 | 0 | } else if (StringUtils.isBlank(typeDefinition.getServiceName())) { |
324 | 0 | throw new IllegalStateException("action type definition must have a non-blank service name"); |
325 | |
} else { |
326 | 0 | ActionTypeService actionTypeService = getActionTypeService(typeDefinition.getServiceName()); |
327 | |
|
328 | 0 | if (actionTypeService == null) { |
329 | 0 | throw new IllegalStateException("typeDefinition must have a valid serviceName"); |
330 | |
} else { |
331 | |
|
332 | |
List<RemotableAttributeError> errors; |
333 | 0 | if (oldAgenda == null) { |
334 | 0 | errors = actionTypeService.validateAttributes(typeId, newAgenda.getCustomRuleActionAttributesMap()); |
335 | |
} else { |
336 | 0 | errors = actionTypeService.validateAttributesAgainstExisting(typeId, newAgenda.getCustomRuleActionAttributesMap(), oldAgenda.getCustomRuleActionAttributesMap()); |
337 | |
} |
338 | |
|
339 | 0 | if (!CollectionUtils.isEmpty(errors)) { |
340 | 0 | isValid = false; |
341 | 0 | for (RemotableAttributeError error : errors) { |
342 | 0 | for (String errorStr : error.getErrors()) { |
343 | 0 | this.putFieldError( |
344 | |
KRMSPropertyConstants.AgendaEditor.CUSTOM_RULE_ACTION_ATTRIBUTES_MAP + |
345 | |
"['" + error.getAttributeName() + "']", |
346 | |
errorStr |
347 | |
); |
348 | |
} |
349 | |
} |
350 | |
} |
351 | |
} |
352 | |
} |
353 | |
} |
354 | 0 | return isValid; |
355 | |
} |
356 | |
|
357 | |
|
358 | |
|
359 | |
|
360 | |
private boolean validRuleActionDescription(String description) { |
361 | 0 | if (StringUtils.isNotBlank(description)) { |
362 | 0 | return true; |
363 | |
} else { |
364 | 0 | this.putFieldError(KRMSPropertyConstants.Action.DESCRIPTION, "error.action.missingDescription"); |
365 | 0 | return false; |
366 | |
} |
367 | |
} |
368 | |
|
369 | |
|
370 | |
public ContextBoService getContextBoService() { |
371 | 0 | return KrmsRepositoryServiceLocator.getContextBoService(); |
372 | |
} |
373 | |
|
374 | |
public AgendaBoService getAgendaBoService() { |
375 | 0 | return KrmsRepositoryServiceLocator.getAgendaBoService(); |
376 | |
} |
377 | |
|
378 | |
public RuleBoService getRuleBoService() { |
379 | 0 | return KrmsRepositoryServiceLocator.getRuleBoService(); |
380 | |
} |
381 | |
|
382 | |
public KrmsTypeRepositoryService getKrmsTypeRepositoryService() { |
383 | 0 | return KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService(); |
384 | |
} |
385 | |
|
386 | |
public ActionTypeService getActionTypeService(String serviceName) { |
387 | 0 | return (ActionTypeService)KrmsRepositoryServiceLocator.getService(serviceName); |
388 | |
} |
389 | |
private AgendaAuthorizationService getAgendaAuthorizationService() { |
390 | 0 | return KrmsRepositoryServiceLocator.getAgendaAuthorizationService(); |
391 | |
} |
392 | |
|
393 | |
} |
394 | |
|