001/** 002 * Copyright 2005-2016 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 */ 016package org.kuali.rice.kns.workflow.attribute; 017 018import org.kuali.rice.kew.engine.RouteContext; 019import org.kuali.rice.kns.service.KNSServiceLocator; 020import org.kuali.rice.krad.datadictionary.DocumentEntry; 021import org.kuali.rice.krad.datadictionary.RoutingTypeDefinition; 022import org.kuali.rice.krad.datadictionary.WorkflowAttributes; 023import org.kuali.rice.krad.document.Document; 024import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 025 026import java.util.ArrayList; 027import java.util.HashMap; 028import java.util.List; 029import java.util.Map; 030 031/** 032 * QualifierResolver which uses Data Dictionary defined workflow attributes to gather a collection 033 * of qualifiers to use to determine the responsibility for a document at a given workflow route node. 034 * 035 * WorkflowAttributes can be defined in the data dictionary like so (this has been abbreviated): 036 * 037 * <!-- Exported Workflow Attributes --> 038 * <bean id="DisbursementVoucherDocument-workflowAttributes" parent="DisbursementVoucherDocument-workflowAttributes-parentBean"/> 039 * 040 * <bean id="DisbursementVoucherDocument-workflowAttributes-parentBean" abstract="true" parent="WorkflowAttributes"> 041 * <property name="routingTypeDefinitions"> 042 * <map> 043 * <!-- no qualifiers for purchasing node --> 044 * <entry key="Account" value-ref="RoutingType-AccountingDocument-Account-sourceOnly"/> 045 * <entry key="AccountingOrganizationHierarchy" value-ref="RoutingType-AccountingDocument-OrganizationHierarchy-sourceOnly"/> 046 * <entry key="Campus" value-ref="DisbursementVoucherDocument-RoutingType-Campus"/> 047 * <!-- no qualifiers for tax review --> 048 * <!-- no qualifiers for travel review --> 049 * <entry key="PaymentMethod" value-ref="DisbursementVoucherDocument-RoutingType-PaymentMethod"/> 050 * <entry key="Award" value-ref="RoutingType-AccountingDocument-Award"/> 051 * </map> 052 * </property> 053 * </bean> 054 * 055 * <bean id="DisbursementVoucherDocument-RoutingType-PaymentMethod" class="org.kuali.rice.krad.datadictionary.RoutingTypeDefinition"> 056 * <property name="routingAttributes"> 057 * <list> 058 * <bean class="org.kuali.rice.krad.datadictionary.RoutingAttribute"> 059 * <property name="qualificationAttributeName" value="disbVchrPaymentMethodCode"/> 060 * </bean> 061 * </list> 062 * </property> 063 * <property name="documentValuePathGroups"> 064 * <list> 065 * <bean class="org.kuali.rice.krad.datadictionary.DocumentValuePathGroup"> 066 * <property name="documentValues"> 067 * <list> 068 * <value>disbVchrPaymentMethodCode</value> 069 * </list> 070 * </property> 071 * </bean> 072 * </list> 073 * </property> 074 * </bean> 075 * 076 * At the PaymentMethod node of the document, the DisbursementVoucherDocument-RoutingType-PaymentMethod RoutingTypeDefinition will be 077 * consulted; it will pull values from the document (in this case, document.disbVchrPaymentMethodCode) and populate those 078 * into the role qualifier Map<String, String>, with the key being the qualificationAttributeName and the value being the value of the property 079 * listed in the documentValuePathGroups in the document. 080 * 081 * @deprecated Only used by KNS classes, no replacement. 082 */ 083@Deprecated 084public class DataDictionaryQualifierResolver extends QualifierResolverBase { 085// private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DataDictionaryQualifierResolver.class); 086 087 088 /** 089 * Given the RouteContext, determines the document type of the document being routed and the current 090 * route nodes; generates a List of qualifier Map<String, String>s based on the the contents of the document. 091 * @see org.kuali.rice.kew.role.QualifierResolver#resolve(org.kuali.rice.kew.engine.RouteContext) 092 */ 093 public List<Map<String, String>> resolve(RouteContext context) { 094 final String routeLevel = context.getNodeInstance().getName(); 095 final DocumentEntry documentEntry = getDocumentEntry(context); 096 final RoutingTypeDefinition routingTypeDefinition = getWorkflowAttributeDefintion(documentEntry, routeLevel); 097 final Document document = getDocument(context); 098 List<Map<String, String>> qualifiers = null; 099 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}