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 */ 016 package org.kuali.rice.krms.impl.ui; 017 018 019 import org.apache.commons.collections.CollectionUtils; 020 import org.apache.commons.lang.StringUtils; 021 import org.kuali.rice.core.api.util.ConcreteKeyValue; 022 import org.kuali.rice.core.api.util.KeyValue; 023 import org.kuali.rice.krad.service.KRADServiceLocator; 024 import org.kuali.rice.krad.uif.control.UifKeyValuesFinderBase; 025 import org.kuali.rice.krad.uif.view.ViewModel; 026 import org.kuali.rice.krad.web.form.MaintenanceDocumentForm; 027 import org.kuali.rice.krms.impl.repository.*; 028 import org.kuali.rice.krms.impl.util.KrmsImplConstants; 029 030 import java.util.*; 031 032 /** 033 * ValuesFinder used to populate the list of available Terms when creating/editing a proposition in a 034 * KRMS Rule. 035 * 036 * @author Kuali Rice Team (rice.collab@kuali.org) 037 */ 038 public class ValidTermsForPropositionValuesFinder extends UifKeyValuesFinderBase { 039 040 /** 041 * get the value list for the Term dropdown in the KRMS rule editing UI 042 * @param model 043 * @return 044 */ 045 @Override 046 public List<KeyValue> getKeyValues(ViewModel model) { 047 List<KeyValue> keyValues = new ArrayList<KeyValue>(); 048 049 MaintenanceDocumentForm maintenanceForm = (MaintenanceDocumentForm) model; 050 PropositionBo rootProposition = ((PropositionBo) maintenanceForm.getDocument().getNewMaintainableObject().getDataObject()); 051 052 PropositionBo editModeProposition = findPropositionUnderEdit(rootProposition); 053 String selectedCategoryId = (editModeProposition != null) ? editModeProposition.getCategoryId() : null; 054 055 // Get all valid terms 056 057 Collection<ContextValidTermBo> contextValidTerms = null; 058 contextValidTerms = KRADServiceLocator.getBusinessObjectService() 059 .findMatching(ContextValidTermBo.class, Collections.singletonMap("contextId", "20000")); 060 061 List<String> termSpecIds = new ArrayList(); 062 for (ContextValidTermBo validTerm : contextValidTerms) { 063 termSpecIds.add(validTerm.getTermSpecificationId()); 064 } 065 066 if (termSpecIds.size() > 0) { // if we don't have any valid terms, skip it 067 Collection<TermBo> terms = null; 068 Map<String,Object> criteria = new HashMap<String,Object>(); 069 criteria.put("specificationId", termSpecIds); 070 terms = KRADServiceLocator.getBusinessObjectService().findMatchingOrderBy(TermBo.class, criteria, "description", true); 071 072 // add all terms that are in the selected category (or else add 'em all if no category is selected) 073 for (TermBo term : terms) { 074 String selectName = term.getDescription(); 075 076 if (StringUtils.isBlank(selectName) || "null".equals(selectName)) { 077 selectName = term.getSpecification().getName(); 078 } 079 080 if (!StringUtils.isBlank(selectedCategoryId)) { 081 // only add if the term has the selected category 082 if (isTermSpecificationInCategory(term.getSpecification(), selectedCategoryId)) { 083 keyValues.add(new ConcreteKeyValue(term.getId(), selectName)); 084 } 085 } else { 086 keyValues.add(new ConcreteKeyValue(term.getId(), selectName)); 087 } 088 } 089 090 // 091 // Add Parameterized Term Specs 092 // 093 094 // get term resolvers for the given term specs 095 Collection<TermResolverBo> termResolvers = 096 KRADServiceLocator.getBusinessObjectService().findMatchingOrderBy( 097 TermResolverBo.class, Collections.singletonMap("outputId", termSpecIds), "name", true 098 ); 099 100 // TODO: what if there is more than one resolver for a given term specification? 101 102 if (termResolvers != null) for (TermResolverBo termResolver : termResolvers) { 103 if (!CollectionUtils.isEmpty(termResolver.getParameterSpecifications())) { 104 TermSpecificationBo output = termResolver.getOutput(); 105 106 // filter by category 107 if (StringUtils.isBlank(selectedCategoryId) || 108 isTermSpecificationInCategory(output, selectedCategoryId)) { 109 110 // we use a special prefix to differentiate these, as they are term spec ids instead of term ids. 111 keyValues.add(new ConcreteKeyValue(KrmsImplConstants.PARAMETERIZED_TERM_PREFIX 112 + output.getId(), output.getName() 113 // build a string that indicates the number of parameters 114 + "(" + StringUtils.repeat("_", ",", termResolver.getParameterSpecifications().size()) +")")); 115 } 116 } 117 } 118 } 119 120 return keyValues; 121 } 122 123 /** 124 * @return true if the term specification is in the given category 125 */ 126 private boolean isTermSpecificationInCategory(TermSpecificationBo termSpec, String categoryId) { 127 if (termSpec.getCategories() != null) { 128 for (CategoryBo category : termSpec.getCategories()) { 129 if (categoryId.equals(category.getId())) { 130 return true; 131 } 132 } 133 } 134 return false; 135 } 136 137 /** 138 * helper method to find the proposition under edit 139 */ 140 private PropositionBo findPropositionUnderEdit(PropositionBo currentProposition) { 141 PropositionBo result = null; 142 if (currentProposition.getEditMode()) { 143 result = currentProposition; 144 } else { 145 if (currentProposition.getCompoundComponents() != null) { 146 for (PropositionBo child : currentProposition.getCompoundComponents()) { 147 result = findPropositionUnderEdit(child); 148 if (result != null) break; 149 } 150 } 151 } 152 return result; 153 } 154 155 }