1 package org.kuali.rice.krms.impl.util;
2
3 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
4 import org.kuali.rice.core.api.exception.RiceIllegalStateException;
5 import org.kuali.rice.krms.api.repository.RuleManagementService;
6 import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
7 import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
8 import org.kuali.rice.krms.api.repository.agenda.AgendaTreeDefinition;
9 import org.kuali.rice.krms.api.repository.agenda.AgendaTreeEntryDefinitionContract;
10 import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
11 import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
12 import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType;
13 import org.kuali.rice.krms.api.repository.proposition.PropositionType;
14 import org.kuali.rice.krms.api.repository.reference.ReferenceObjectBinding;
15 import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
16 import org.kuali.rice.krms.api.repository.term.TermDefinition;
17 import org.kuali.rice.krms.api.repository.term.TermParameterDefinition;
18
19 import java.util.ArrayList;
20 import java.util.List;
21 import javax.xml.namespace.QName;
22 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
23 import org.kuali.rice.krms.api.KrmsConstants;
24 import org.kuali.rice.krms.api.repository.term.TermRepositoryService;
25 import org.kuali.student.r2.common.exceptions.DataValidationErrorException;
26 import org.kuali.student.r2.common.exceptions.DoesNotExistException;
27 import org.kuali.student.r2.common.exceptions.InvalidParameterException;
28 import org.kuali.student.r2.common.exceptions.MissingParameterException;
29 import org.kuali.student.r2.common.exceptions.OperationFailedException;
30 import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
31 import org.kuali.student.r2.common.exceptions.ReadOnlyException;
32 import org.kuali.student.r2.common.exceptions.UnsupportedActionException;
33 import org.kuali.student.common.util.security.ContextUtils;
34 import org.kuali.student.r2.core.constants.KSKRMSServiceConstants;
35 import org.kuali.student.r2.core.krms.naturallanguage.TermParameterTypes;
36 import org.kuali.student.r2.lum.clu.dto.CluSetInfo;
37 import org.kuali.student.r2.lum.clu.service.CluService;
38 import org.kuali.student.r2.lum.util.constants.CluServiceConstants;
39
40
41
42
43
44
45 public class KrmsRuleManagementCopyMethodsImpl implements KrmsRuleManagementCopyMethods {
46
47 private RuleManagementService ruleManagementService;
48 private TermRepositoryService termRepositoryService;
49 private CluService cluService;
50
51 @Override
52 public List<ReferenceObjectBinding> deepCopyReferenceObjectBindingsFromTo(String fromReferenceDiscriminatorType,
53 String fromReferenceObjectId,
54 String toReferenceDiscriminatorType,
55 String toReferenceObjectId,
56 List<String> optionKeys)
57 throws RiceIllegalArgumentException,
58 RiceIllegalStateException, PermissionDeniedException, MissingParameterException, InvalidParameterException, OperationFailedException {
59 _checkEmptyParam(fromReferenceDiscriminatorType, "fromReferenceDiscriminatorType");
60 _checkEmptyParam(fromReferenceObjectId, "fromReferenceObjectId");
61 _checkEmptyParam(toReferenceDiscriminatorType, "toReferenceDiscriminatorType");
62 _checkEmptyParam(toReferenceObjectId, "toReferenceObjectId");
63 List<ReferenceObjectBinding> copiedRefList = new ArrayList<ReferenceObjectBinding>();
64 List<ReferenceObjectBinding> refsToCopy = this.getRuleManagementService().findReferenceObjectBindingsByReferenceObject(fromReferenceDiscriminatorType, fromReferenceObjectId);
65 for (ReferenceObjectBinding reference : refsToCopy) {
66 ReferenceObjectBinding.Builder refBldr = null;
67
68 if (reference.getKrmsDiscriminatorType().equals(KSKRMSServiceConstants.KRMS_DISCRIMINATOR_TYPE_AGENDA)) {
69 AgendaTreeDefinition agendaTree = getRuleManagementService().getAgendaTree(reference.getKrmsObjectId());
70
71 AgendaDefinition copiedAgenda = deepCopyAgenda(agendaTree, toReferenceObjectId);
72 refBldr = ReferenceObjectBinding.Builder.create(reference);
73 refBldr.setId(null);
74 refBldr.setVersionNumber(null);
75 refBldr.setReferenceObjectId(toReferenceObjectId);
76 refBldr.setReferenceDiscriminatorType(toReferenceDiscriminatorType);
77 refBldr.setKrmsObjectId(copiedAgenda.getId());
78 } else {
79
80 throw new RiceIllegalStateException("unknown/unhandled KRMS discriminator type " + reference.getKrmsDiscriminatorType());
81 }
82 ReferenceObjectBinding refBinding = getRuleManagementService().createReferenceObjectBinding(refBldr.build());
83 copiedRefList.add(refBinding);
84 }
85 return copiedRefList;
86 }
87
88 private AgendaDefinition deepCopyAgenda(AgendaTreeDefinition agendaTree, String refObjectId) throws MissingParameterException, InvalidParameterException, OperationFailedException, PermissionDeniedException {
89
90 AgendaDefinition oldAgenda = getRuleManagementService().getAgenda(agendaTree.getAgendaId());
91 AgendaDefinition.Builder copiedAgendaBldr = AgendaDefinition.Builder.create(oldAgenda);
92 copiedAgendaBldr.setId(null);
93 copiedAgendaBldr.setVersionNumber(null);
94 copiedAgendaBldr.setFirstItemId(null);
95 copiedAgendaBldr.setName(refObjectId + ":" + oldAgenda.getTypeId() + ":1");
96 AgendaDefinition copiedAgenda = getRuleManagementService().createAgenda(copiedAgendaBldr.build());
97
98 AgendaItemDefinition.Builder previousAgendaItemBldr = null;
99 AgendaItemDefinition.Builder firstAgendaItemBldr = AgendaItemDefinition.Builder.create(null, copiedAgenda.getId());
100 AgendaItemDefinition firstAgendaItem = getRuleManagementService().createAgendaItem(firstAgendaItemBldr.build());
101 copiedAgendaBldr = AgendaDefinition.Builder.create(copiedAgenda);
102 copiedAgendaBldr.setFirstItemId(firstAgendaItem.getId());
103 getRuleManagementService().updateAgenda(copiedAgendaBldr.build());
104 copiedAgenda = getRuleManagementService().getAgenda(copiedAgenda.getId());
105
106 boolean isFirstItem = true;
107 for (AgendaTreeEntryDefinitionContract entry : agendaTree.getEntries()) {
108 AgendaItemDefinition currentAgendaItem = getRuleManagementService().getAgendaItem(entry.getAgendaItemId());
109 AgendaItemDefinition.Builder copiedAgendaItemBldr = AgendaItemDefinition.Builder.create(currentAgendaItem);
110 deepUpdateAgendaItem(copiedAgendaItemBldr, copiedAgenda.getId(), refObjectId);
111 if (isFirstItem) {
112 copiedAgendaItemBldr.setId(firstAgendaItem.getId());
113 copiedAgendaItemBldr.setVersionNumber(firstAgendaItem.getVersionNumber());
114 firstAgendaItemBldr = copiedAgendaItemBldr;
115 previousAgendaItemBldr = firstAgendaItemBldr;
116 isFirstItem = false;
117 } else {
118 copiedAgendaItemBldr.setId(null);
119 copiedAgendaItemBldr.setVersionNumber(null);
120 previousAgendaItemBldr.setWhenTrue(copiedAgendaItemBldr);
121 previousAgendaItemBldr = copiedAgendaItemBldr;
122 }
123 }
124 getRuleManagementService().updateAgendaItem(firstAgendaItemBldr.build());
125 return copiedAgenda;
126 }
127
128 private void deepUpdateAgendaItem(AgendaItemDefinition.Builder copiedAgendaItemBldr, String copiedAgendaID, String refObjectId) throws MissingParameterException, PermissionDeniedException, InvalidParameterException, OperationFailedException {
129 copiedAgendaItemBldr.setId(null);
130 copiedAgendaItemBldr.setVersionNumber(null);
131 copiedAgendaItemBldr.setAgendaId(copiedAgendaID);
132 if (copiedAgendaItemBldr.getWhenTrueId() != null) {
133 deepUpdateAgendaItem(copiedAgendaItemBldr.getWhenTrue(), copiedAgendaID, refObjectId);
134 copiedAgendaItemBldr.setWhenTrueId(null);
135 }
136 if (copiedAgendaItemBldr.getWhenFalseId() != null) {
137 deepUpdateAgendaItem(copiedAgendaItemBldr.getWhenFalse(), copiedAgendaID, refObjectId);
138 copiedAgendaItemBldr.setWhenFalseId(null);
139 }
140 if (copiedAgendaItemBldr.getAlwaysId() != null) {
141 deepUpdateAgendaItem(copiedAgendaItemBldr.getAlways(), copiedAgendaID, refObjectId);
142 copiedAgendaItemBldr.setAlwaysId(null);
143 }
144 copiedAgendaItemBldr.setRuleId(null);
145 RuleDefinition.Builder copiedRuleBldr = copiedAgendaItemBldr.getRule();
146 copiedRuleBldr.setId(null);
147 copiedRuleBldr.setVersionNumber(null);
148 copiedRuleBldr.setPropId(null);
149 copiedRuleBldr.setName(refObjectId + ":" + copiedRuleBldr.getTypeId() + ":1");
150 if (copiedRuleBldr.getProposition() != null){
151 deepUpdateForProposition(copiedRuleBldr.getProposition());
152 }
153
154 }
155
156 private void deepUpdateForProposition(PropositionDefinition.Builder propBldr) throws PermissionDeniedException, MissingParameterException, InvalidParameterException, OperationFailedException {
157 propBldr.setId(null);
158 propBldr.setRuleId(null);
159 propBldr.setVersionNumber(null);
160 for (PropositionParameter.Builder propParmBldr : propBldr.getParameters()) {
161 propParmBldr.setId(null);
162 propParmBldr.setPropId(null);
163 propParmBldr.setVersionNumber(null);
164 if (PropositionParameterType.TERM.getCode().equals(propParmBldr.getParameterType())) {
165 TermDefinition termDef = null;
166 if (propParmBldr.getTermValue() != null) {
167 termDef = propParmBldr.getTermValue();
168 } else {
169 termDef = getTermRepositoryService().getTerm(propParmBldr.getValue());
170 }
171 propParmBldr.setValue(null);
172 TermDefinition.Builder termBldr = TermDefinition.Builder.create(termDef);
173 termBldr.setId(null);
174 termBldr.setVersionNumber(null);
175 for (TermParameterDefinition.Builder termParmBldr : termBldr.getParameters()) {
176 termParmBldr.setId(null);
177 termParmBldr.setTermId(null);
178 termParmBldr.setVersionNumber(null);
179 if (TermParameterTypes.COURSE_CLUSET_KEY.getId().equals(termParmBldr.getName()) || TermParameterTypes.PROGRAM_CLUSET_KEY.getId().equals(termParmBldr.getName()) || TermParameterTypes.CLUSET_KEY.getId().equals(termParmBldr.getName())) {
180 termParmBldr.setValue(createAdhocCluSet(termParmBldr.getValue()));
181 }
182 }
183 propParmBldr.setTermValue(termBldr.build());
184 }
185 }
186 if (PropositionType.COMPOUND.getCode().equals(propBldr.getPropositionTypeCode())) {
187 for (PropositionDefinition.Builder subPropBldr : propBldr.getCompoundComponents()) {
188 deepUpdateForProposition(subPropBldr);
189 }
190 }
191 }
192
193 private String createAdhocCluSet(String cluSetId) throws InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
194 try {
195
196 CluSetInfo cluSet = getCluService().getCluSet(cluSetId, ContextUtils.createDefaultContextInfo());
197
198
199 if(!cluSet.getIsReusable()){
200 cluSet.setId(null);
201
202 if (cluSet.getMembershipQuery() != null) {
203 cluSet.getCluIds().clear();
204 cluSet.getCluSetIds().clear();
205 } else {
206 List<String> subCluSetIds = new ArrayList<String>();
207 for(String subCluSetid : cluSet.getCluSetIds()){
208 subCluSetIds.add(createAdhocCluSet(subCluSetid));
209 }
210 cluSet.setCluSetIds(subCluSetIds);
211 }
212
213 cluSet = getCluService().createCluSet(cluSet.getTypeKey(), cluSet, ContextUtils.createDefaultContextInfo());
214 return cluSet.getId();
215 }
216 } catch (DoesNotExistException e) {
217 throw new OperationFailedException(e.getMessage());
218 } catch (UnsupportedActionException e) {
219 throw new OperationFailedException(e.getMessage());
220 } catch (DataValidationErrorException e) {
221 throw new OperationFailedException(e.getMessage());
222 } catch (ReadOnlyException e) {
223 throw new OperationFailedException(e.getMessage());
224 }
225 return cluSetId;
226 }
227
228 @Override
229 public int deleteReferenceObjectBindingsCascade(String referenceDiscriminatorType,
230 String referenceObjectId)
231 throws RiceIllegalArgumentException, RiceIllegalStateException {
232 _checkEmptyParam(referenceDiscriminatorType, "referenceDiscriminatorType");
233 _checkEmptyParam(referenceObjectId, "referenceObjectId");
234
235 List<ReferenceObjectBinding> refsToDelete = this.getRuleManagementService().findReferenceObjectBindingsByReferenceObject(referenceDiscriminatorType,
236 referenceObjectId);
237 for (ReferenceObjectBinding refToDelete : refsToDelete) {
238 if (refToDelete.getKrmsDiscriminatorType().equals(KSKRMSServiceConstants.KRMS_DISCRIMINATOR_TYPE_AGENDA)) {
239 this._deleteAgendaCascade(refToDelete.getKrmsObjectId());
240 } else {
241 throw new RiceIllegalStateException("unknown/unhandled KRMS discriminator type " + refToDelete.getKrmsDiscriminatorType());
242 }
243 }
244 for (ReferenceObjectBinding refToDelete : refsToDelete) {
245 this.getRuleManagementService().deleteReferenceObjectBinding(refToDelete.getId());
246 }
247 return refsToDelete.size();
248 }
249
250 private int _deleteAgendaCascade(String agendaId) {
251 AgendaDefinition agenda = this.getRuleManagementService().getAgenda(agendaId);
252 this._deleteAgendaItemCascade(agenda.getFirstItemId());
253 this.getRuleManagementService().deleteAgenda(agendaId);
254 return 1;
255 }
256
257 private int _deleteAgendaItemCascade(String agendaItemId) {
258 AgendaItemDefinition item = this.getRuleManagementService().getAgendaItem(agendaItemId);
259 if (item.getAlwaysId() != null) {
260 AgendaItemDefinition.Builder bldr = AgendaItemDefinition.Builder.create(item);
261 bldr.setAlways(null);
262 bldr.setAlwaysId(null);
263 this.getRuleManagementService().updateAgendaItem(bldr.build());
264 this._deleteAgendaItemCascade(item.getAlwaysId());
265 item = this.getRuleManagementService().getAgendaItem(agendaItemId);
266 }
267 if (item.getWhenTrueId() != null) {
268 AgendaItemDefinition.Builder bldr = AgendaItemDefinition.Builder.create(item);
269 bldr.setWhenTrue(null);
270 bldr.setWhenTrueId(null);
271 this.getRuleManagementService().updateAgendaItem(bldr.build());
272 this._deleteAgendaItemCascade(item.getWhenTrueId());
273 item = this.getRuleManagementService().getAgendaItem(agendaItemId);
274 }
275 if (item.getWhenFalseId() != null) {
276 AgendaItemDefinition.Builder bldr = AgendaItemDefinition.Builder.create(item);
277 bldr.setWhenFalse(null);
278 bldr.setWhenFalseId(null);
279 this.getRuleManagementService().updateAgendaItem(bldr.build());
280 this._deleteAgendaItemCascade(item.getWhenFalseId());
281 item = this.getRuleManagementService().getAgendaItem(agendaItemId);
282 }
283 if (item.getSubAgendaId() != null) {
284 this._deleteAgendaCascade(item.getSubAgendaId());
285 }
286 if (item.getRuleId() != null) {
287 AgendaItemDefinition.Builder bldr = AgendaItemDefinition.Builder.create(item);
288 bldr.setRule(null);
289 bldr.setRuleId(null);
290 this.getRuleManagementService().updateAgendaItem(bldr.build());
291 this._deleteRuleCascade(item.getRuleId());
292 }
293 this.getRuleManagementService().deleteAgendaItem(agendaItemId);
294 return 1;
295 }
296
297
298 private int _deleteRuleCascade(String ruleId) {
299 RuleDefinition rule = this.getRuleManagementService().getRule(ruleId);
300
301 this.getRuleManagementService().deleteRule(ruleId);
302 return 1;
303 }
304
305 private void _checkEmptyParam(String param, String message)
306 throws RiceIllegalArgumentException {
307 if (param == null) {
308 throw new RiceIllegalArgumentException(message);
309 }
310 if (param.trim().isEmpty()) {
311 throw new RiceIllegalArgumentException(message);
312 }
313 }
314
315 public RuleManagementService getRuleManagementService() {
316 if (ruleManagementService == null) {
317 ruleManagementService = (RuleManagementService) GlobalResourceLoader.getService(new QName(KrmsConstants.Namespaces.KRMS_NAMESPACE_2_0, "ruleManagementService"));
318 }
319 return ruleManagementService;
320 }
321
322 public void setRuleManagementService(RuleManagementService ruleManagementService) {
323 this.ruleManagementService = ruleManagementService;
324 }
325
326 public TermRepositoryService getTermRepositoryService() {
327 if (termRepositoryService == null) {
328 termRepositoryService = (TermRepositoryService) GlobalResourceLoader.getService(new QName(KrmsConstants.Namespaces.KRMS_NAMESPACE_2_0, "termRepositoryService"));
329 }
330 return termRepositoryService;
331 }
332
333 public void setTermRepositoryService(TermRepositoryService termRepositoryService) {
334 this.termRepositoryService = termRepositoryService;
335 }
336
337 public CluService getCluService() {
338 if (cluService == null) {
339 cluService = (CluService) GlobalResourceLoader.getService(new QName(CluServiceConstants.NAMESPACE, "CluService"));
340 }
341 return cluService;
342 }
343
344 public void setCluService(CluService cluService) {
345 this.cluService = cluService;
346 }
347 }