View Javadoc

1   /**
2    * Copyright 2005-2013 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  
19  import org.apache.commons.collections.CollectionUtils;
20  import org.apache.commons.lang.StringUtils;
21  import org.kuali.rice.core.api.util.ConcreteKeyValue;
22  import org.kuali.rice.core.api.util.KeyValue;
23  import org.kuali.rice.kns.service.KNSServiceLocator;
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.Collections;
39  import java.util.HashMap;
40  import java.util.Map;
41  import java.util.List;
42  
43  /**
44   * ValuesFinder used to populate the list of available Terms when creating/editing a proposition in a
45   * KRMS Rule.
46   *
47   * @author Kuali Rice Team (rice.collab@kuali.org)
48   */
49  public class ValidTermsValuesFinder extends UifKeyValuesFinderBase {
50  
51      /**
52       * get the value list for the Term dropdown in the KRMS rule editing UI
53       * @param model
54       * @return
55       */
56      @Override
57      public List<KeyValue> getKeyValues(ViewModel model) {
58          List<KeyValue> keyValues = new ArrayList<KeyValue>();
59  
60          MaintenanceDocumentForm maintenanceForm = (MaintenanceDocumentForm) model;
61          AgendaEditor agendaEditor = ((AgendaEditor) maintenanceForm.getDocument().getNewMaintainableObject().getDataObject());
62          String contextId = agendaEditor.getAgenda().getContextId();
63  
64          String selectedPropId = agendaEditor.getSelectedPropositionId();
65  
66          PropositionBo rootProposition = agendaEditor.getAgendaItemLine().getRule().getProposition();
67          PropositionBo editModeProposition = findPropositionUnderEdit(rootProposition);
68          String selectedCategoryId = (editModeProposition != null) ? editModeProposition.getCategoryId() : null;
69  
70          // Get all valid terms
71  
72          Collection<ContextValidTermBo> contextValidTerms = null;
73          contextValidTerms = KNSServiceLocator.getBusinessObjectService()
74                  .findMatching(ContextValidTermBo.class, Collections.singletonMap("contextId", contextId));
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              Collection<TermBo> terms = null;
83              Map<String,Object> criteria = new HashMap<String,Object>();
84              criteria.put("specificationId", termSpecIds);
85              terms = KNSServiceLocator.getBusinessObjectService().findMatchingOrderBy(TermBo.class, criteria, "description", true);
86  
87              // add all terms that are in the selected category (or else add 'em all if no category is selected)
88              for (TermBo term : terms) {
89                  String selectName = term.getDescription();
90  
91                  if (StringUtils.isBlank(selectName) || "null".equals(selectName)) {
92                      selectName = term.getSpecification().getName();
93                  }
94  
95                  if (!StringUtils.isBlank(selectedCategoryId)) {
96                      // only add if the term has the selected category
97                      if (isTermSpecificationInCategory(term.getSpecification(), selectedCategoryId)) {
98                          keyValues.add(new ConcreteKeyValue(term.getId(), selectName));
99                      }
100                 } else {
101                     keyValues.add(new ConcreteKeyValue(term.getId(), selectName));
102                 }
103             }
104 
105             //
106             // Add Parameterized Term Specs
107             //
108 
109             // get term resolvers for the given term specs
110             Collection<TermResolverBo> termResolvers =
111                     KNSServiceLocator.getBusinessObjectService().findMatchingOrderBy(
112                             TermResolverBo.class, Collections.singletonMap("outputId", termSpecIds), "name", true
113                     );
114 
115             // TODO: what if there is more than one resolver for a given term specification?
116 
117             if (termResolvers != null) for (TermResolverBo termResolver : termResolvers) {
118                 if (!CollectionUtils.isEmpty(termResolver.getParameterSpecifications())) {
119                     TermSpecificationBo output = termResolver.getOutput();
120 
121                     // filter by category
122                     if (StringUtils.isBlank(selectedCategoryId) ||
123                             isTermSpecificationInCategory(output, selectedCategoryId)) {
124                     	String outputDescription = StringUtils.isBlank(output.getDescription())?output.getName():
125                     																			output.getDescription();
126                         // we use a special prefix to differentiate these, as they are term spec ids instead of term ids.
127                         keyValues.add(new ConcreteKeyValue(KrmsImplConstants.PARAMETERIZED_TERM_PREFIX
128                                 + output.getId(), outputDescription
129                                 // build a string that indicates the number of parameters
130                                 + "(" + StringUtils.repeat("_", ",", termResolver.getParameterSpecifications().size()) +")"));
131                     }
132                 }
133             }
134         }
135 
136         return keyValues;
137     }
138 
139     /**
140      * @return true if the term specification is in the given category
141      */
142     private boolean isTermSpecificationInCategory(TermSpecificationBo termSpec, String categoryId) {
143         if (termSpec.getCategories() != null) {
144             for (CategoryBo category : termSpec.getCategories()) {
145                 if (categoryId.equals(category.getId())) {
146                     return true;
147                 }
148             }
149         }
150         return false;
151     }
152 
153     /**
154      * helper method to find the proposition under edit
155      */
156     private PropositionBo findPropositionUnderEdit(PropositionBo currentProposition) {
157         PropositionBo result = null;
158         if (currentProposition.getEditMode()) {
159             result = currentProposition;
160         } else {
161             if (currentProposition.getCompoundComponents() != null) {
162                 for (PropositionBo child : currentProposition.getCompoundComponents()) {
163                     result = findPropositionUnderEdit(child);
164                     if (result != null) break;
165                 }
166             }
167         }
168         return result;
169     }
170 
171 }