View Javadoc
1   /**
2    * Copyright 2005-2015 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.kew.impl.document;
17  
18  import org.kuali.rice.coreservice.api.CoreServiceApiServiceLocator;
19  import org.kuali.rice.coreservice.api.parameter.Parameter;
20  import org.kuali.rice.coreservice.api.parameter.ParameterKey;
21  import org.kuali.rice.kew.doctype.ApplicationDocumentStatus;
22  import org.kuali.rice.kew.doctype.bo.DocumentType;
23  import org.kuali.rice.kew.service.KEWServiceLocator;
24  import org.springframework.util.CollectionUtils;
25  
26  import java.util.ArrayList;
27  import java.util.Collections;
28  import java.util.Comparator;
29  import java.util.LinkedHashMap;
30  import java.util.List;
31  import java.util.regex.Matcher;
32  import java.util.regex.Pattern;
33  
34  /**
35   * Utility class for assisting with application document status
36   */
37  public class ApplicationDocumentStatusUtils {
38  
39      /**
40       * @see {@link #getApplicationDocumentStatusCategories(org.kuali.rice.kew.doctype.bo.DocumentType)}
41       */
42      public static LinkedHashMap<String, List<String>> getApplicationDocumentStatusCategories(String documentTypeName) {
43          DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName);
44          return getApplicationDocumentStatusCategories(documentType);
45      }
46  
47      /**
48       * <p>Returns the categories defined for the given DocumentType.  The returned ordered map's keys
49       * are the category names, and the values are Lists of the status values within the category.  Ordering is
50       * maintained so that the form field can reflect the configuration in the parameter. </p>
51       *
52       * <p>Note that the hierarchy for the given document type will be walked until application document statuses are
53       * found, or the available ancestry is exhausted.</p>
54       *
55       * @param documentType the document type for which to retrieve the defined application document status categories
56       * @return the application document status categories, or an empty map if there are none defined for the given
57       * document type
58       */
59      public static LinkedHashMap<String, List<String>> getApplicationDocumentStatusCategories(DocumentType documentType) {
60          LinkedHashMap<String, List<String>> results = new LinkedHashMap<String, List<String>>();
61  
62          if (documentType != null) {
63              // check the hierarchy until we find an ancestor with app doc statuses configured, or we exhaust the
64              // ancestry in which case the docTypeAncestor will be null
65  //            DocumentType docTypeAncestor = documentType;
66  //            while (docTypeAncestor != null) {
67  //                // save a potentially un-needed fetch of the parent doc type fetch
68  //                if (!CollectionUtils.isEmpty(docTypeAncestor.getValidApplicationStatuses())) {
69  //                    break;
70  //                }
71  //
72  //                // walk up the hierarchy
73  //                docTypeAncestor = docTypeAncestor.getParentDocType();
74  //            }
75  //
76  //            if (docTypeAncestor != null) {
77              // if you un-comment the hierarchy traversal logic above, you'll also need to replace
78              // documentType with docTypeAncestor in this conditional block:
79              if (!CollectionUtils.isEmpty(documentType.getValidApplicationStatuses())) {
80                      sortBySequenceNumber(documentType.getValidApplicationStatuses());
81                  // build data structure for groupings and create headings
82                  for (ApplicationDocumentStatus status : documentType.getValidApplicationStatuses()) {
83                      if (status.getCategoryName() != null) {
84                          if (!results.containsKey(status.getCategoryName())) {
85                               results.put(status.getCategoryName(), new ArrayList<String>());
86                          }
87                          results.get(status.getCategoryName()).add(status.getStatusName());
88                      }
89                  }
90              }
91          }
92          return results;
93      }
94  
95      /**
96       * <p>Sorts a List of {@link org.kuali.rice.kew.doctype.ApplicationDocumentStatus}es by their sequenceNumber
97       * properties.  The sequenceNumber for a status may be null, and this Comparator considers a null sequenceNumber
98       * to be &lt; any non-null sequenceNumber.</p>
99       *
100      * @param statuses the List of statuses to sort
101      * @throws IllegalArgumentException if either of the given
102      * {@link org.kuali.rice.kew.doctype.ApplicationDocumentStatus} arguments is null.
103      *
104      * @see Comparator#compare(Object, Object)
105      */
106     private static void sortBySequenceNumber(List<ApplicationDocumentStatus> statuses) {
107         Collections.sort(statuses, new Comparator<ApplicationDocumentStatus>() {
108             @Override
109             public int compare(ApplicationDocumentStatus o1, ApplicationDocumentStatus o2) {
110                 if (o1 == null || o2 == null) throw new IllegalArgumentException();
111                 // cover null sequence number cases
112                 if (o1.getSequenceNumber() == null) {
113                     if (o2.getSequenceNumber() == null) {
114                         return 0;
115                     } else {
116                         return -1; // consider null to always be less than non-null
117                     }
118                 }
119                 if (o2.getSequenceNumber() == null) {
120                     return 1; // consider null to always be less than non-null
121                 }
122                 return o1.getSequenceNumber().compareTo(o2.getSequenceNumber());
123             }
124         });
125     }
126 
127 }