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