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.kns.workflow.attribute;
17
18 import org.kuali.rice.kew.engine.RouteContext;
19 import org.kuali.rice.kns.service.KNSServiceLocator;
20 import org.kuali.rice.krad.datadictionary.DocumentEntry;
21 import org.kuali.rice.krad.datadictionary.RoutingTypeDefinition;
22 import org.kuali.rice.krad.datadictionary.WorkflowAttributes;
23 import org.kuali.rice.krad.document.Document;
24 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
25
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30
31 /**
32 * QualifierResolver which uses Data Dictionary defined workflow attributes to gather a collection
33 * of qualifiers to use to determine the responsibility for a document at a given workflow route node.
34 *
35 * WorkflowAttributes can be defined in the data dictionary like so (this has been abbreviated):
36 *
37 * <!-- Exported Workflow Attributes -->
38 * <bean id="DisbursementVoucherDocument-workflowAttributes" parent="DisbursementVoucherDocument-workflowAttributes-parentBean"/>
39 *
40 * <bean id="DisbursementVoucherDocument-workflowAttributes-parentBean" abstract="true" parent="WorkflowAttributes">
41 * <property name="routingTypeDefinitions">
42 * <map>
43 * <!-- no qualifiers for purchasing node -->
44 * <entry key="Account" value-ref="RoutingType-AccountingDocument-Account-sourceOnly"/>
45 * <entry key="AccountingOrganizationHierarchy" value-ref="RoutingType-AccountingDocument-OrganizationHierarchy-sourceOnly"/>
46 * <entry key="Campus" value-ref="DisbursementVoucherDocument-RoutingType-Campus"/>
47 * <!-- no qualifiers for tax review -->
48 * <!-- no qualifiers for travel review -->
49 * <entry key="PaymentMethod" value-ref="DisbursementVoucherDocument-RoutingType-PaymentMethod"/>
50 * <entry key="Award" value-ref="RoutingType-AccountingDocument-Award"/>
51 * </map>
52 * </property>
53 * </bean>
54 *
55 * <bean id="DisbursementVoucherDocument-RoutingType-PaymentMethod" class="org.kuali.rice.krad.datadictionary.RoutingTypeDefinition">
56 * <property name="routingAttributes">
57 * <list>
58 * <bean class="org.kuali.rice.krad.datadictionary.RoutingAttribute">
59 * <property name="qualificationAttributeName" value="disbVchrPaymentMethodCode"/>
60 * </bean>
61 * </list>
62 * </property>
63 * <property name="documentValuePathGroups">
64 * <list>
65 * <bean class="org.kuali.rice.krad.datadictionary.DocumentValuePathGroup">
66 * <property name="documentValues">
67 * <list>
68 * <value>disbVchrPaymentMethodCode</value>
69 * </list>
70 * </property>
71 * </bean>
72 * </list>
73 * </property>
74 * </bean>
75 *
76 * At the PaymentMethod node of the document, the DisbursementVoucherDocument-RoutingType-PaymentMethod RoutingTypeDefinition will be
77 * consulted; it will pull values from the document (in this case, document.disbVchrPaymentMethodCode) and populate those
78 * into the role qualifier Map<String, String>, with the key being the qualificationAttributeName and the value being the value of the property
79 * listed in the documentValuePathGroups in the document.
80 *
81 * @deprecated Only used by KNS classes, no replacement.
82 */
83 @Deprecated
84 public class DataDictionaryQualifierResolver extends QualifierResolverBase {
85 // private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DataDictionaryQualifierResolver.class);
86
87
88 /**
89 * Given the RouteContext, determines the document type of the document being routed and the current
90 * route nodes; generates a List of qualifier Map<String, String>s based on the the contents of the document.
91 * @see org.kuali.rice.kew.role.QualifierResolver#resolve(org.kuali.rice.kew.engine.RouteContext)
92 */
93 public List<Map<String, String>> resolve(RouteContext context) {
94 final String routeLevel = context.getNodeInstance().getName();
95 final DocumentEntry documentEntry = getDocumentEntry(context);
96 final RoutingTypeDefinition routingTypeDefinition = getWorkflowAttributeDefintion(documentEntry, routeLevel);
97 final Document document = getDocument(context);
98 List<Map<String, String>> qualifiers = null;
99
100 if (document != null && routingTypeDefinition != null) {
101 qualifiers = KNSServiceLocator.getWorkflowAttributePropertyResolutionService().resolveRoutingTypeQualifiers(document, routingTypeDefinition);
102 } else {
103 qualifiers = new ArrayList<Map<String, String>>();
104 Map<String, String> basicQualifier = new HashMap<String, String>();
105 qualifiers.add(basicQualifier);
106 }
107 decorateWithCommonQualifiers(qualifiers, document, documentEntry, routeLevel);
108 return qualifiers;
109 }
110
111 /**
112 * Retrieves the data dictionary entry for the document being operated on by the given route context
113 * @param context the current route context
114 * @return the data dictionary document entry
115 */
116 protected DocumentEntry getDocumentEntry(RouteContext context) {
117 return KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getDocumentEntry(context.getDocument().getDocumentType().getName());
118 }
119
120 /**
121 * Retrieves the proper List of WorkflowAttributes for the given route level from the data dictionary
122 * document entry
123 * @param documentEntry the data dictionary document entry for the currently routed document
124 * @param routeLevelName the name of the route level
125 * @return a WorkflowAttributeDefinition if one could be found for the route level; otherwise, nothing
126 */
127 protected RoutingTypeDefinition getWorkflowAttributeDefintion(DocumentEntry documentEntry, String routeLevelName) {
128 final WorkflowAttributes workflowAttributes = documentEntry.getWorkflowAttributes();
129 if ( workflowAttributes == null ) {
130 return null;
131 }
132 final Map<String, RoutingTypeDefinition> routingTypeMap = workflowAttributes.getRoutingTypeDefinitions();
133 if (routingTypeMap.containsKey(routeLevelName)) return routingTypeMap.get(routeLevelName);
134 return null;
135 }
136
137 /**
138 * Add common qualifiers to every Map<String, String> in the given List of Map<String, String>
139 * @param qualifiers a List of Map<String, String>s to add common qualifiers to
140 * @param document the document currently being routed
141 * @param documentEntry the data dictionary entry of the type of document currently being routed
142 * @param routeLevel the document's current route level
143 */
144 protected void decorateWithCommonQualifiers(List<Map<String, String>> qualifiers, Document document, DocumentEntry documentEntry, String routeLevel) {
145 for (Map<String, String> qualifier : qualifiers) {
146 addCommonQualifiersToMap(qualifier, document, documentEntry, routeLevel);
147 }
148 }
149
150 /**
151 * Adds common qualifiers to a given Map<String, String>
152 * @param qualifier an Map<String, String> to add common qualifiers to
153 * @param document the document currently being routed
154 * @param documentEntry the data dictionary entry of the type of document currently being routed
155 * @param routeLevel the document's current route level
156 */
157 protected void addCommonQualifiersToMap(Map<String, String> qualifier, Document document, DocumentEntry documentEntry, String routeLevel) {
158 if ( document != null ) {
159 qualifier.put(KIM_ATTRIBUTE_DOCUMENT_NUMBER, document.getDocumentNumber());
160 }
161 if ( documentEntry != null ) {
162 qualifier.put(KIM_ATTRIBUTE_DOCUMENT_TYPE_NAME, documentEntry.getDocumentTypeName());
163 }
164 qualifier.put(KIM_ATTRIBUTE_ROUTE_LEVEL_NAME, routeLevel);
165 }
166 }