001/** 002 * Copyright 2005-2013 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krms.service.impl; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader; 020import org.kuali.rice.core.api.util.tree.Node; 021import org.kuali.rice.core.api.util.tree.Tree; 022import org.kuali.rice.krad.bo.Note; 023import org.kuali.rice.krad.maintenance.MaintenanceDocument; 024import org.kuali.rice.krad.uif.container.CollectionGroup; 025import org.kuali.rice.krad.uif.util.ObjectPropertyUtils; 026import org.kuali.rice.krad.uif.view.View; 027import org.kuali.rice.krad.util.KRADConstants; 028import org.kuali.rice.krad.web.form.MaintenanceDocumentForm; 029import org.kuali.rice.krms.api.KrmsConstants; 030import org.kuali.rice.krms.api.repository.RuleManagementService; 031import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition; 032import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition; 033import org.kuali.rice.krms.api.repository.context.ContextDefinition; 034import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate; 035import org.kuali.rice.krms.api.repository.proposition.PropositionType; 036import org.kuali.rice.krms.api.repository.reference.ReferenceObjectBinding; 037import org.kuali.rice.krms.api.repository.rule.RuleDefinition; 038import org.kuali.rice.krms.api.repository.term.TermDefinition; 039import org.kuali.rice.krms.api.repository.term.TermRepositoryService; 040import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition; 041import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService; 042import org.kuali.rice.krms.api.repository.typerelation.TypeTypeRelation; 043import org.kuali.rice.krms.dto.*; 044import org.kuali.rice.krms.builder.ComponentBuilder; 045import org.kuali.rice.krms.service.TemplateRegistry; 046import org.kuali.rice.krms.tree.RuleCompareTreeBuilder; 047import org.kuali.rice.krms.tree.RuleViewTreeBuilder; 048import org.kuali.rice.krms.tree.node.RuleEditorTreeNode; 049import org.kuali.rice.krms.service.RuleEditorMaintainable; 050import org.kuali.rice.krms.util.AlphaIterator; 051import org.kuali.student.common.uif.service.impl.KSMaintainableImpl; 052import org.kuali.rice.krms.util.PropositionTreeUtil; 053import org.kuali.student.r1.common.rice.StudentIdentityConstants; 054import org.kuali.student.r2.core.constants.KSKRMSServiceConstants; 055 056import javax.xml.namespace.QName; 057import java.util.*; 058 059/** 060 * {@link org.kuali.rice.krad.maintenance.Maintainable} 061 * 062 * @author Kuali Student Team (rice.collab@kuali.org) 063 */ 064public class RuleEditorMaintainableImpl extends KSMaintainableImpl implements RuleEditorMaintainable { 065 066 private static final long serialVersionUID = 1L; 067 068 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RuleEditorMaintainableImpl.class); 069 070 private transient RuleManagementService ruleManagementService; 071 private transient KrmsTypeRepositoryService krmsTypeRepositoryService; 072 private transient TermRepositoryService termRepositoryService; 073 074 private transient TemplateRegistry templateRegistry; 075 private AlphaIterator alphaIterator = new AlphaIterator(StringUtils.EMPTY); 076 077 public static final String NEW_AGENDA_EDITOR_DOCUMENT_TEXT = "New Agenda Editor Document"; 078 079 public String getViewTypeName() { 080 return "kuali.krms.agenda.type"; 081 } 082 083 /** 084 * Get the AgendaEditor out of the MaintenanceDocumentForm's newMaintainableObject 085 * 086 * @param model the MaintenanceDocumentForm 087 * @return the AgendaEditor 088 */ 089 private RuleEditor getRuleEditor(Object model) { 090 MaintenanceDocumentForm maintenanceDocumentForm = (MaintenanceDocumentForm) model; 091 return (RuleEditor) maintenanceDocumentForm.getDocument().getNewMaintainableObject().getDataObject(); 092 } 093 094 @Override 095 public Object retrieveObjectForEditOrCopy(MaintenanceDocument document, Map<String, String> dataObjectKeys) { 096 RuleManagementWrapper dataObject = new RuleManagementWrapper(); 097 098 String refObjectId = dataObjectKeys.get("refObjectId"); 099 dataObject.setRefObjectId(refObjectId); 100 101 dataObject.setAgendas(this.getAgendasForRef("", refObjectId)); 102 103 dataObject.setCompareTree(RuleCompareTreeBuilder.initCompareTree()); 104 105 return dataObject; 106 } 107 108 protected List<AgendaEditor> getAgendasForRef(String discriminatorType, String refObjectId) { 109 // Initialize new array lists. 110 List<AgendaEditor> agendas = new ArrayList<AgendaEditor>(); 111 List<AgendaEditor> sortedAgendas = new ArrayList<AgendaEditor>(); 112 List<AgendaEditor> parentAgendas = new ArrayList<AgendaEditor>(); 113 114 // Get the list of existing agendas 115 LOG.info("Retrieving reference object binding for refobjectid: " + refObjectId); 116 List<ReferenceObjectBinding> refObjectsBindings = this.getRuleManagementService().findReferenceObjectBindingsByReferenceObject(discriminatorType, refObjectId); 117 for (ReferenceObjectBinding referenceObjectBinding : refObjectsBindings) { 118 LOG.info("Retrieved reference object binding with id: " + referenceObjectBinding); 119 agendas.add(this.getAgendaEditor(referenceObjectBinding.getKrmsObjectId())); 120 } 121 122 // Get the list of parent agendas 123 List<ReferenceObjectBinding> parentRefObjects = this.getParentRefOjbects(refObjectId); 124 for (ReferenceObjectBinding referenceObject : parentRefObjects) { 125 parentAgendas.add(this.getAgendaEditor(referenceObject.getKrmsObjectId())); 126 } 127 128 // Lookup existing agenda by type 129 for (AgendaTypeInfo agendaTypeInfo : this.getTypeRelationships()) { 130 AgendaEditor agenda = null; 131 for (AgendaEditor existingAgenda : agendas) { 132 if (existingAgenda.getTypeId().equals(agendaTypeInfo.getId())) { 133 agenda = existingAgenda; 134 break; 135 } 136 } 137 if (agenda == null) { 138 agenda = new AgendaEditor(); 139 agenda.setTypeId(agendaTypeInfo.getId()); 140 } 141 142 //Set the parent agenda. 143 for (AgendaEditor parent : parentAgendas) { 144 if (agenda.getTypeId().equals(agenda.getTypeId())) { 145 agenda.setParent(parent); 146 break; 147 } 148 } 149 150 agenda.setAgendaTypeInfo(agendaTypeInfo); 151 agenda.setRuleEditors(this.getRulesForAgendas(agenda)); 152 sortedAgendas.add(agenda); 153 } 154 155 return sortedAgendas; 156 } 157 158 protected AgendaEditor getAgendaEditor(String agendaId) { 159 LOG.info("Retrieving agenda for id: " + agendaId); 160 AgendaDefinition agenda = this.getRuleManagementService().getAgenda(agendaId); 161 LOG.info("Retrieved agenda for id: " + agendaId); 162 return new AgendaEditor(agenda); 163 } 164 165 public Map<String, RuleEditor> getRulesForAgendas(AgendaEditor agenda) { 166 167 //Get all existing rules. 168 List<RuleEditor> existingRules = null; 169 if (agenda.getId() != null) { 170 LOG.info("Retrieving agenda item for id: " + agenda.getFirstItemId()); 171 AgendaItemDefinition firstItem = this.getRuleManagementService().getAgendaItem(agenda.getFirstItemId()); 172 LOG.info("Retrieved agenda item for id: " + agenda.getFirstItemId()); 173 existingRules = getRuleEditorsFromTree(firstItem, true); 174 } 175 176 //Get the parent rules 177 List<RuleEditor> parentRules = null; 178 if (agenda.getParent() != null) { 179 AgendaItemDefinition parentItem = this.getRuleManagementService().getAgendaItem(agenda.getParent().getFirstItemId()); 180 parentRules = getRuleEditorsFromTree(parentItem, false); 181 } 182 183 //Add dummy RuleEditors for empty rule types. 184 Map<String, RuleEditor> ruleEditors = new LinkedHashMap<String, RuleEditor>(); 185 for (RuleTypeInfo ruleType : agenda.getAgendaTypeInfo().getRuleTypes()) { 186 RuleEditor ruleEditor = null; 187 188 // Add all existing rules of this type. 189 if (existingRules != null) { 190 for (RuleEditor rule : existingRules) { 191 if (rule.getTypeId().equals(ruleType.getId()) && (!rule.isDummy())) { 192 ruleEditor = rule; 193 } 194 } 195 } 196 197 // If the ruletype does not exist, add an empty rule section 198 if (ruleEditor == null) { 199 ruleEditor = createDummyRuleEditor(ruleType.getId()); 200 } 201 202 ruleEditor.setKey((String) alphaIterator.next()); 203 ruleEditor.setRuleTypeInfo(ruleType); 204 ruleEditors.put(ruleEditor.getKey(), ruleEditor); 205 206 //Set the parent agenda. 207 if (parentRules != null) { 208 for (RuleEditor parent : parentRules) { 209 if (ruleEditor.getTypeId().equals(parent.getTypeId())) { 210 ruleEditor.setParent(parent); 211 break; 212 } 213 } 214 } 215 } 216 217 return ruleEditors; 218 } 219 220 protected RuleEditor createDummyRuleEditor(String ruleTypeId) { 221 RuleEditor ruleEditor = new RuleEditor(); 222 ruleEditor.setDummy(true); 223 ruleEditor.setTypeId(ruleTypeId); 224 return ruleEditor; 225 } 226 227 protected List<RuleEditor> getRuleEditorsFromTree(AgendaItemDefinition agendaItem, boolean initProps) { 228 229 List<RuleEditor> rules = new ArrayList<RuleEditor>(); 230 if (agendaItem.getRule() != null) { 231 RuleEditor ruleEditor = new RuleEditor(agendaItem.getRule()); 232 if (initProps) { 233 this.initPropositionEditor(ruleEditor.getPropositionEditor()); 234 ruleEditor.setViewTree(this.getViewTreeBuilder().buildTree(ruleEditor)); 235 } 236 rules.add(ruleEditor); 237 } 238 239 if (agendaItem.getWhenTrue() != null) { 240 rules.addAll(getRuleEditorsFromTree(agendaItem.getWhenTrue(), initProps)); 241 } 242 243 return rules; 244 } 245 246 /** 247 * Override this method to return the reference object id of the parent object. 248 * 249 * @param refObjectId 250 * @return 251 */ 252 @Override 253 public List<ReferenceObjectBinding> getParentRefOjbects(String refObjectId) { 254 return null; 255 } 256 257 protected RuleViewTreeBuilder getViewTreeBuilder() { 258 return new RuleViewTreeBuilder(); 259 } 260 261 /** 262 * Setup a map with all the type information required to build an agenda management page. 263 * 264 * @return 265 */ 266 protected List<AgendaTypeInfo> getTypeRelationships() { 267 List<AgendaTypeInfo> agendaTypeInfos = new ArrayList<AgendaTypeInfo>(); 268 269 // Get Instruction Usage Id 270 String instructionUsageId = getRuleManagementService().getNaturalLanguageUsageByNameAndNamespace(KSKRMSServiceConstants.KRMS_NL_TYPE_INSTRUCTION, 271 StudentIdentityConstants.KS_NAMESPACE_CD).getId(); 272 273 // Get Description Usage Id 274 String descriptionUsageId = getRuleManagementService().getNaturalLanguageUsageByNameAndNamespace(KSKRMSServiceConstants.KRMS_NL_TYPE_DESCRIPTION, 275 StudentIdentityConstants.KS_NAMESPACE_CD).getId(); 276 277 // Get the super type. 278 KrmsTypeDefinition requisitesType = this.getKrmsTypeRepositoryService().getTypeByName(StudentIdentityConstants.KS_NAMESPACE_CD, this.getViewTypeName()); 279 280 // Get all agenda types linked to super type. 281 List<TypeTypeRelation> agendaRelationships = this.getKrmsTypeRepositoryService().findTypeTypeRelationsByFromType(requisitesType.getId()); 282 for (TypeTypeRelation agendaRelationship : agendaRelationships) { 283 AgendaTypeInfo agendaTypeInfo = new AgendaTypeInfo(); 284 agendaTypeInfo.setId(agendaRelationship.getToTypeId()); 285 KrmsTypeDefinition agendaType = this.getKrmsTypeRepositoryService().getTypeById(agendaTypeInfo.getId()); 286 agendaTypeInfo.setType(agendaType.getName()); 287 agendaTypeInfo.setDescription(this.getDescriptionForTypeAndUsage(agendaRelationship.getToTypeId(), descriptionUsageId)); 288 289 // Get all rule types for each agenda type 290 List<TypeTypeRelation> ruleRelationships = this.getKrmsTypeRepositoryService().findTypeTypeRelationsByFromType(agendaRelationship.getToTypeId()); 291 // order rules 292 List<TypeTypeRelation> sortedRuleRelationships = new ArrayList<TypeTypeRelation>(); 293 sortedRuleRelationships.addAll(ruleRelationships); 294 Collections.sort(sortedRuleRelationships, new Comparator<TypeTypeRelation>() { 295 @Override 296 public int compare(TypeTypeRelation typeTypeRelation1, TypeTypeRelation typeTypeRelation2) { 297 return typeTypeRelation1.getSequenceNumber().compareTo(typeTypeRelation2.getSequenceNumber()); 298 } 299 }); 300 301 List<RuleTypeInfo> ruleTypes = new ArrayList<RuleTypeInfo>(); 302 for (TypeTypeRelation ruleRelationship : sortedRuleRelationships) { 303 RuleTypeInfo ruleTypeInfo = new RuleTypeInfo(); 304 ruleTypeInfo.setId(ruleRelationship.getToTypeId()); 305 KrmsTypeDefinition ruleType = this.getKrmsTypeRepositoryService().getTypeById(ruleTypeInfo.getId()); 306 ruleTypeInfo.setType(ruleType.getName()); 307 ruleTypeInfo.setDescription(this.getDescriptionForTypeAndUsage(ruleRelationship.getToTypeId(), descriptionUsageId)); 308 if (ruleTypeInfo.getDescription().isEmpty()) { 309 ruleTypeInfo.setDescription("Description is unset rule type"); 310 } 311 ruleTypeInfo.setInstruction(this.getDescriptionForTypeAndUsage(ruleRelationship.getToTypeId(), instructionUsageId)); 312 if (ruleTypeInfo.getInstruction().isEmpty()) { 313 ruleTypeInfo.setInstruction("Instruction is unset for rule type"); 314 } 315 // Add rule types to list. 316 ruleTypes.add(ruleTypeInfo); 317 } 318 agendaTypeInfo.setRuleTypes(ruleTypes); 319 agendaTypeInfos.add(agendaTypeInfo); 320 } 321 322 return agendaTypeInfos; 323 } 324 325 private String getDescriptionForTypeAndUsage(String typeId, String usageId) { 326 NaturalLanguageTemplate template = null; 327 try { 328 template = getRuleManagementService().findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId("en", typeId, usageId); 329 return template.getTemplate(); 330 } catch (Exception e) { 331 return StringUtils.EMPTY; 332 } 333 } 334 335 /** 336 * {@inheritDoc} 337 */ 338 @Override 339 public void processAfterNew(MaintenanceDocument document, Map<String, String[]> requestParameters) { 340 super.processAfterNew(document, requestParameters); 341 document.getDocumentHeader().setDocumentDescription(NEW_AGENDA_EDITOR_DOCUMENT_TEXT); 342 } 343 344 @Override 345 public void processAfterEdit(MaintenanceDocument document, Map<String, String[]> requestParameters) { 346 super.processAfterEdit(document, requestParameters); 347 document.getDocumentHeader().setDocumentDescription("Modify Agenda Editor Document"); 348 } 349 350 @Override 351 public void saveDataObject() { 352 RuleManagementWrapper ruleWrapper = (RuleManagementWrapper) getDataObject(); 353 354 for (AgendaEditor agenda : ruleWrapper.getAgendas()) { 355 356 //Check if this agenda has anything to save 357 if (agenda.isDummyAgenda()) { 358 continue; 359 } 360 361 //Set the agenda name. 362 agenda.setName(ruleWrapper.getRefObjectId() + ":" + agenda.getAgendaTypeInfo().getId() + ":1"); 363 364 //Retrieve the context and set the id on the agenda. 365 if (agenda.getContextId() == null) { 366 ContextDefinition context = this.getRuleManagementService().getContextByNameAndNamespace("Course Requirements", ruleWrapper.getNamespace()); 367 agenda.setContextId(context.getId()); 368 } 369 370 //Create or update the agenda. 371 if (agenda.getId() == null) { 372 AgendaDefinition.Builder agendaBldr = AgendaDefinition.Builder.create(agenda); 373 AgendaDefinition agendaDfn = this.getRuleManagementService().createAgenda(agendaBldr.build()); 374 375 //Set the id and versionnumber for a possible update. 376 agenda.setId(agendaDfn.getId()); 377 agenda.setVersionNumber(agendaDfn.getVersionNumber()); 378 agenda.setFirstItemId(agendaDfn.getFirstItemId()); 379 380 //Create the reference object binding only on create agenda, no need to update. 381 ReferenceObjectBinding.Builder refBuilder = ReferenceObjectBinding.Builder.create("Agenda", 382 agendaDfn.getId(), ruleWrapper.getNamespace(), ruleWrapper.getRefDiscriminatorType(), ruleWrapper.getRefObjectId()); 383 this.getRuleManagementService().createReferenceObjectBinding(refBuilder.build()); 384 } 385 386 //Set the first agenda item id and save the agenda items 387 AgendaItemDefinition firstItem = maintainAgendaItems(agenda, ruleWrapper.getRefObjectId() + ":", ruleWrapper.getNamespace()); 388 389 //If no more rules linked to agenda, delete it. 390 if (firstItem.getRule() == null) { 391 List<ReferenceObjectBinding> refObjectsBindings = this.getRuleManagementService().findReferenceObjectBindingsByReferenceObject(ruleWrapper.getRefDiscriminatorType(), ruleWrapper.getRefObjectId()); 392 for (ReferenceObjectBinding referenceObjectBinding : refObjectsBindings) { 393 if (referenceObjectBinding.getKrmsObjectId().equals(agenda.getId())) { 394 LOG.info("Deleting reference object binding for id: " + referenceObjectBinding.getId()); 395 this.getRuleManagementService().deleteReferenceObjectBinding(referenceObjectBinding.getId()); 396 } 397 } 398 LOG.info("Deleting agenda item for id: " + firstItem.getId()); 399 this.getRuleManagementService().deleteAgendaItem(firstItem.getId()); 400 LOG.info("Deleting agenda for id: " + agenda.getId()); 401 this.getRuleManagementService().deleteAgenda(agenda.getId()); 402 } 403 404 } 405 406 } 407 408 public AgendaItemDefinition maintainAgendaItems(AgendaEditor agenda, String namePrefix, String nameSpace) { 409 410 Queue<RuleEditor> rules = new LinkedList<RuleEditor>(); 411 for (RuleEditor rule : agenda.getRuleEditors().values()) { 412 if (!rule.isDummy()) { 413 rules.add(rule); 414 } 415 } 416 417 // Clear the first item and update. 418 AgendaItemDefinition firstItem = manageFirstItem(agenda); 419 420 //Delete rules 421 for (RuleEditor deletedRule : agenda.getDeletedRules()) { 422 this.getRuleManagementService().deleteRule(deletedRule.getId()); 423 } 424 425 AgendaItemDefinition.Builder rootItemBuilder = AgendaItemDefinition.Builder.create(firstItem); 426 AgendaItemDefinition.Builder itemBuilder = rootItemBuilder; 427 while (rules.peek() != null) { 428 itemBuilder.setRule(this.finRule(rules.poll(), namePrefix, nameSpace)); 429 itemBuilder.setRuleId(itemBuilder.getRule().getId()); 430 if (rules.peek() != null) { 431 itemBuilder.setWhenTrue(AgendaItemDefinition.Builder.create(null, agenda.getId())); 432 itemBuilder = itemBuilder.getWhenTrue(); 433 } 434 } 435 436 //Update the root item. 437 AgendaItemDefinition updateItem = rootItemBuilder.build(); 438 this.getRuleManagementService().updateAgendaItem(updateItem); 439 440 return updateItem; 441 } 442 443 protected AgendaItemDefinition manageFirstItem(AgendaEditor agenda) { 444 AgendaItemDefinition firstItem; 445 AgendaItemDefinition.Builder firstItemBuilder = AgendaItemDefinition.Builder.create(agenda.getFirstItemId(), agenda.getId()); 446 if (agenda.getFirstItemId() != null) { 447 firstItem = this.getRuleManagementService().getAgendaItem(agenda.getFirstItemId()); 448 firstItemBuilder.setVersionNumber(firstItem.getVersionNumber()); 449 this.getRuleManagementService().updateAgendaItem(firstItemBuilder.build()); 450 451 //Delete current agenda items to rebuild the tree. 452 this.deleteAgendaItems(firstItem.getWhenTrue()); 453 this.deleteAgendaItems(firstItem.getWhenFalse()); 454 this.deleteAgendaItems(firstItem.getAlways()); 455 } else { 456 firstItem = this.getRuleManagementService().createAgendaItem(firstItemBuilder.build()); 457 agenda.setFirstItemId(firstItem.getId()); 458 AgendaDefinition.Builder agendaBldr = AgendaDefinition.Builder.create(agenda); 459 this.getRuleManagementService().updateAgenda(agendaBldr.build()); 460 } 461 return this.getRuleManagementService().getAgendaItem(agenda.getFirstItemId()); 462 } 463 464 public void deleteAgendaItems(AgendaItemDefinition agendaItem) { 465 if (agendaItem != null) { 466 this.getRuleManagementService().deleteAgendaItem(agendaItem.getId()); 467 deleteAgendaItems(agendaItem.getWhenFalse()); 468 deleteAgendaItems(agendaItem.getWhenTrue()); 469 deleteAgendaItems(agendaItem.getAlways()); 470 } 471 } 472 473 public RuleDefinition.Builder finRule(RuleEditor rule, String rulePrefix, String namespace) { 474 // handle saving new parameterized terms 475 if (rule.getPropositionEditor() != null) { 476 this.finPropositionEditor(rule.getPropositionEditor()); 477 } 478 479 if (rule.getNamespace() == null) { 480 rule.setNamespace(namespace); 481 } 482 rule.setName(rulePrefix + rule.getRuleTypeInfo().getId() + ":1"); 483 484 return RuleDefinition.Builder.create(rule); 485 } 486 487 public void finPropositionEditor(PropositionEditor propositionEditor) { 488 if (PropositionType.SIMPLE.getCode().equalsIgnoreCase(propositionEditor.getPropositionTypeCode())) { 489 490 //Call onsubmit on the associated builder. 491 ComponentBuilder builder = this.getTemplateRegistry().getComponentBuilderForType(propositionEditor.getType()); 492 if (builder != null) { 493 builder.onSubmit(propositionEditor); 494 } 495 496 //Set the default operation and value 497 TemplateInfo template = this.getTemplateRegistry().getTemplateForType(propositionEditor.getType()); 498 PropositionTreeUtil.getOperatorParameter(propositionEditor.getParameters()).setValue(template.getOperator()); 499 500 if (!"n".equals(template.getValue())) { 501 PropositionTreeUtil.getConstantParameter(propositionEditor.getParameters()).setValue(template.getValue()); 502 } 503 504 if (propositionEditor.getTerm() != null) { 505 TermDefinition.Builder termBuilder = TermDefinition.Builder.create(propositionEditor.getTerm()); 506 PropositionTreeUtil.getTermParameter(propositionEditor.getParameters()).setTermValue(termBuilder.build()); 507 } 508 509 } else { 510 511 //If not a simple node, recursively finalize the child proposition editors. 512 for (PropositionEditor child : propositionEditor.getCompoundEditors()) { 513 finPropositionEditor(child); 514 } 515 516 } 517 } 518 519 public void initPropositionEditor(PropositionEditor propositionEditor) { 520 if (propositionEditor == null) { 521 return; 522 } 523 524 if (PropositionType.SIMPLE.getCode().equalsIgnoreCase(propositionEditor.getPropositionTypeCode())) { 525 526 if (propositionEditor.getType() == null) { 527 KrmsTypeDefinition type = this.getKrmsTypeRepositoryService().getTypeById(propositionEditor.getTypeId()); 528 propositionEditor.setType(type.getName()); 529 } 530 531 Map<String, String> termParameters = this.getTermParameters(propositionEditor); 532 ComponentBuilder builder = this.getTemplateRegistry().getComponentBuilderForType(propositionEditor.getType()); 533 if (builder != null) { 534 builder.resolveTermParameters(propositionEditor, termParameters); 535 } 536 } else { 537 for (PropositionEditor child : propositionEditor.getCompoundEditors()) { 538 initPropositionEditor(child); 539 } 540 541 } 542 } 543 544 protected Map<String, String> getTermParameters(PropositionEditor proposition) { 545 546 Map<String, String> termParameters = new HashMap<String, String>(); 547 if (proposition.getTerm() == null) { 548 PropositionParameterEditor termParameter = PropositionTreeUtil.getTermParameter(proposition.getParameters()); 549 if (termParameter != null) { 550 551 if (termParameter.getTermValue() == null) { 552 proposition.setTerm(new TermEditor()); 553 } else { 554 proposition.setTerm(new TermEditor(termParameter.getTermValue())); 555 } 556 557 } else { 558 return termParameters; 559 } 560 } 561 562 for (TermParameterEditor parameter : proposition.getTerm().getEditorParameters()) { 563 termParameters.put(parameter.getName(), parameter.getValue()); 564 } 565 566 return termParameters; 567 } 568 569 /** 570 * In the case of edit maintenance adds a new blank line to the old side 571 * <p/> 572 * 573 * @see org.kuali.rice.krad.uif.service.impl.ViewHelperServiceImpl#processAfterAddLine(org.kuali.rice.krad.uif.view.View, 574 * org.kuali.rice.krad.uif.container.CollectionGroup, Object, 575 * Object, boolean) 576 */ 577 @Override 578 protected void processAfterAddLine(View view, CollectionGroup collectionGroup, Object model, Object addLine, boolean isValidLine) { 579 // Check for maintenance documents in edit but exclude notes 580 if (model instanceof MaintenanceDocumentForm && KRADConstants.MAINTENANCE_EDIT_ACTION.equals(((MaintenanceDocumentForm) model).getMaintenanceAction()) && !(addLine instanceof Note)) { 581 582 // Figure out which rule is being edited 583 RuleEditor rule = getRuleEditor(model); 584 // Figure out which proposition is being edited 585 Tree<RuleEditorTreeNode, String> propositionTree = rule.getEditTree(); 586 Node<RuleEditorTreeNode, String> editedPropositionNode = PropositionTreeUtil.findEditedProposition(propositionTree.getRootElement()); 587 588 // get the old object's collection 589 Collection<Object> oldCollection = ObjectPropertyUtils 590 .getPropertyValue(editedPropositionNode.getData(), 591 collectionGroup.getPropertyName()); 592 593 try { 594 Object blankLine = collectionGroup.getCollectionObjectClass().newInstance(); 595 //Add a blank line to the top of the collection 596 if (oldCollection instanceof List) { 597 ((List) oldCollection).add(0, blankLine); 598 } else { 599 oldCollection.add(blankLine); 600 } 601 } catch (Exception e) { 602 throw new RuntimeException("Unable to create new line instance for old maintenance object", e); 603 } 604 } 605 } 606 607 public RuleManagementService getRuleManagementService() { 608 if (ruleManagementService == null) { 609 ruleManagementService = (RuleManagementService) GlobalResourceLoader.getService(new QName(KrmsConstants.Namespaces.KRMS_NAMESPACE_2_0, "ruleManagementService")); 610 } 611 return ruleManagementService; 612 } 613 614 public KrmsTypeRepositoryService getKrmsTypeRepositoryService() { 615 if (krmsTypeRepositoryService == null) { 616 krmsTypeRepositoryService = (KrmsTypeRepositoryService) GlobalResourceLoader.getService(new QName(KrmsConstants.Namespaces.KRMS_NAMESPACE_2_0, "krmsTypeRepositoryService")); 617 } 618 return krmsTypeRepositoryService; 619 } 620 621 public TermRepositoryService getTermRepositoryService() { 622 if (termRepositoryService == null) { 623 termRepositoryService = (TermRepositoryService) GlobalResourceLoader.getService(new QName(KrmsConstants.Namespaces.KRMS_NAMESPACE_2_0, "termRepositoryService")); 624 } 625 return termRepositoryService; 626 } 627 628 private TemplateRegistry getTemplateRegistry() { 629 if (templateRegistry == null) { 630 templateRegistry = (TemplateRegistry) GlobalResourceLoader.getService(new QName("http://student.kuali.org/wsdl/templateResolverService", "templateResolverService")); 631 } 632 return templateRegistry; 633 } 634}