View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krms.impl.ui;
17  
18  import org.apache.commons.collections.CollectionUtils;
19  import org.apache.commons.lang.StringUtils;
20  import org.kuali.rice.core.api.criteria.QueryByCriteria;
21  import org.kuali.rice.core.api.criteria.QueryResults;
22  import org.kuali.rice.core.api.util.ConcreteKeyValue;
23  import org.kuali.rice.core.api.util.KeyValue;
24  import org.kuali.rice.krad.service.KRADServiceLocator;
25  import org.kuali.rice.krad.uif.control.UifKeyValuesFinderBase;
26  import org.kuali.rice.krad.uif.view.ViewModel;
27  import org.kuali.rice.krad.web.form.MaintenanceDocumentForm;
28  import org.kuali.rice.krms.impl.repository.CategoryBo;
29  import org.kuali.rice.krms.impl.repository.ContextValidTermBo;
30  import org.kuali.rice.krms.impl.repository.PropositionBo;
31  import org.kuali.rice.krms.impl.repository.TermBo;
32  import org.kuali.rice.krms.impl.repository.TermResolverBo;
33  import org.kuali.rice.krms.impl.repository.TermSpecificationBo;
34  import org.kuali.rice.krms.impl.util.KrmsImplConstants;
35  
36  import java.util.ArrayList;
37  import java.util.Collection;
38  import java.util.HashMap;
39  import java.util.List;
40  import java.util.Map;
41  
42  /**
43   * ValuesFinder used to populate the list of available Terms when creating/editing a proposition in a
44   * KRMS Rule.
45   *
46   * @author Kuali Rice Team (rice.collab@kuali.org)
47   */
48  public class ValidTermsValuesFinder extends UifKeyValuesFinderBase {
49  
50      /**
51       * get the value list for the Term dropdown in the KRMS rule editing UI
52       * @param model
53       * @return
54       */
55      @Override
56      public List<KeyValue> getKeyValues(ViewModel model) {
57          List<KeyValue> keyValues = new ArrayList<KeyValue>();
58  
59          MaintenanceDocumentForm maintenanceForm = (MaintenanceDocumentForm) model;
60          AgendaEditor agendaEditor = ((AgendaEditor) maintenanceForm.getDocument().getNewMaintainableObject().getDataObject());
61          String contextId = agendaEditor.getAgenda().getContextId();
62  
63          String selectedPropId = agendaEditor.getSelectedPropositionId();
64  
65          PropositionBo rootProposition = agendaEditor.getAgendaItemLine().getRule().getProposition();
66          PropositionBo editModeProposition = findPropositionUnderEdit(rootProposition);
67          String selectedCategoryId = (editModeProposition != null) ? editModeProposition.getCategoryId() : null;
68  
69          // Get all valid terms
70  
71          QueryByCriteria criteria = QueryByCriteria.Builder.forAttribute("contextId", contextId).build();
72  
73          Collection<ContextValidTermBo> contextValidTerms =
74                  KRADServiceLocator.getDataObjectService().findMatching(ContextValidTermBo.class, criteria).getResults();
75  
76          List<String> termSpecIds = new ArrayList();
77          for (ContextValidTermBo validTerm : contextValidTerms) {
78              termSpecIds.add(validTerm.getTermSpecificationId());
79          }
80  
81          if (termSpecIds.size() > 0) { // if we don't have any valid terms, skip it
82              QueryResults<TermBo> terms = null;
83              Map<String,Object> critMap = new HashMap<String,Object>();
84              critMap.put("specificationId", termSpecIds);
85              QueryByCriteria.Builder critBuilder = QueryByCriteria.Builder.forAttribute("specificationId", termSpecIds);
86              critBuilder.setOrderByAscending("description");
87  
88              terms = KRADServiceLocator.getDataObjectService().findMatching(TermBo.class, critBuilder.build());
89  
90              // add all terms that are in the selected category (or else add 'em all if no category is selected)
91              if (!CollectionUtils.isEmpty(terms.getResults())) for (TermBo term : terms.getResults()) {
92                  String selectName = term.getDescription();
93  
94                  if (StringUtils.isBlank(selectName) || "null".equals(selectName)) {
95                      selectName = term.getSpecification().getName();
96                  }
97  
98                  if (!StringUtils.isBlank(selectedCategoryId)) {
99                      // 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 }