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.CategoryBo;
028 import org.kuali.rice.krms.impl.repository.ContextValidTermBo;
029 import org.kuali.rice.krms.impl.repository.PropositionBo;
030 import org.kuali.rice.krms.impl.repository.TermBo;
031 import org.kuali.rice.krms.impl.repository.TermResolverBo;
032 import org.kuali.rice.krms.impl.repository.TermSpecificationBo;
033 import org.kuali.rice.krms.impl.util.KrmsImplConstants;
034
035 import java.util.ArrayList;
036 import java.util.Collection;
037 import java.util.Collections;
038 import java.util.HashMap;
039 import java.util.Map;
040 import java.util.List;
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 */
048 public 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 Collection<ContextValidTermBo> contextValidTerms = null;
072 contextValidTerms = KRADServiceLocator.getBusinessObjectService()
073 .findMatching(ContextValidTermBo.class, Collections.singletonMap("contextId", contextId));
074
075 List<String> termSpecIds = new ArrayList();
076 for (ContextValidTermBo validTerm : contextValidTerms) {
077 termSpecIds.add(validTerm.getTermSpecificationId());
078 }
079
080 if (termSpecIds.size() > 0) { // if we don't have any valid terms, skip it
081 Collection<TermBo> terms = null;
082 Map<String,Object> criteria = new HashMap<String,Object>();
083 criteria.put("specificationId", termSpecIds);
084 terms = KRADServiceLocator.getBusinessObjectService().findMatchingOrderBy(TermBo.class, criteria, "description", true);
085
086 // add all terms that are in the selected category (or else add 'em all if no category is selected)
087 for (TermBo term : terms) {
088 String selectName = term.getDescription();
089
090 if (StringUtils.isBlank(selectName) || "null".equals(selectName)) {
091 selectName = term.getSpecification().getName();
092 }
093
094 if (!StringUtils.isBlank(selectedCategoryId)) {
095 // only add if the term has the selected category
096 if (isTermSpecificationInCategory(term.getSpecification(), selectedCategoryId)) {
097 keyValues.add(new ConcreteKeyValue(term.getId(), selectName));
098 }
099 } else {
100 keyValues.add(new ConcreteKeyValue(term.getId(), selectName));
101 }
102 }
103
104 //
105 // Add Parameterized Term Specs
106 //
107
108 // get term resolvers for the given term specs
109 Collection<TermResolverBo> termResolvers =
110 KRADServiceLocator.getBusinessObjectService().findMatchingOrderBy(
111 TermResolverBo.class, Collections.singletonMap("outputId", termSpecIds), "name", true
112 );
113
114 // TODO: what if there is more than one resolver for a given term specification?
115
116 if (termResolvers != null) for (TermResolverBo termResolver : termResolvers) {
117 if (!CollectionUtils.isEmpty(termResolver.getParameterSpecifications())) {
118 TermSpecificationBo output = termResolver.getOutput();
119
120 // filter by category
121 if (StringUtils.isBlank(selectedCategoryId) ||
122 isTermSpecificationInCategory(output, selectedCategoryId)) {
123 String outputDescription = StringUtils.isBlank(output.getDescription())?output.getName():
124 output.getDescription();
125 // we use a special prefix to differentiate these, as they are term spec ids instead of term ids.
126 keyValues.add(new ConcreteKeyValue(KrmsImplConstants.PARAMETERIZED_TERM_PREFIX
127 + output.getId(), outputDescription
128 // build a string that indicates the number of parameters
129 + "(" + StringUtils.repeat("_", ",", termResolver.getParameterSpecifications().size()) +")"));
130 }
131 }
132 }
133 }
134
135 return keyValues;
136 }
137
138 /**
139 * @return true if the term specification is in the given category
140 */
141 private boolean isTermSpecificationInCategory(TermSpecificationBo termSpec, String categoryId) {
142 if (termSpec.getCategories() != null) {
143 for (CategoryBo category : termSpec.getCategories()) {
144 if (categoryId.equals(category.getId())) {
145 return true;
146 }
147 }
148 }
149 return false;
150 }
151
152 /**
153 * helper method to find the proposition under edit
154 */
155 private PropositionBo findPropositionUnderEdit(PropositionBo currentProposition) {
156 PropositionBo result = null;
157 if (currentProposition.getEditMode()) {
158 result = currentProposition;
159 } else {
160 if (currentProposition.getCompoundComponents() != null) {
161 for (PropositionBo child : currentProposition.getCompoundComponents()) {
162 result = findPropositionUnderEdit(child);
163 if (result != null) break;
164 }
165 }
166 }
167 return result;
168 }
169
170 }