View Javadoc

1   /**
2    * 
3    */
4   package org.kuali.student.lum.workflow.qualifierresolver;
5   
6   import java.util.*;
7   
8   import javax.xml.namespace.QName;
9   import javax.xml.xpath.XPath;
10  import javax.xml.xpath.XPathConstants;
11  import javax.xml.xpath.XPathExpressionException;
12  
13  import org.apache.commons.lang.StringUtils;
14  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
15  import org.kuali.rice.core.api.util.xml.XmlJotter;
16  import org.kuali.rice.kew.engine.RouteContext;
17  import org.kuali.rice.kew.engine.node.RouteNodeUtils;
18  import org.kuali.rice.kew.role.QualifierResolver;
19  import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
20  import org.kuali.rice.kew.api.KewApiConstants;
21  import org.kuali.rice.student.bo.KualiStudentKimAttributes;
22  import org.kuali.student.r2.common.dto.ContextInfo;
23  import org.kuali.student.r2.core.search.dto.*;
24  import org.kuali.student.r2.core.search.dto.SearchParamInfo;
25  import org.kuali.student.r2.core.organization.service.OrganizationService;
26  import org.w3c.dom.Document;
27  import org.w3c.dom.Element;
28  import org.w3c.dom.Node;
29  import org.w3c.dom.NodeList;
30  
31  /**
32   * An abstract base class that consolidates convenience methods for using the {@link OrganizationService} class.
33   * 
34   */
35  public abstract class AbstractOrganizationServiceQualifierResolver implements QualifierResolver {
36      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AbstractOrganizationServiceQualifierResolver.class);
37      
38      protected static final String DOCUMENT_CONTENT_XML_DEFAULT_ORG_ID_KEY = "orgId";
39      protected static final String DOCUMENT_CONTENT_XML_ORG_ID_KEY = "organizationIdDocumentContentKey";
40  
41      // below string MUST match
42      // org.kuali.student.common.assembly.transform.ProposalWorkflowFilter.DOCUMENT_CONTENT_XML_ROOT_ELEMENT_NAME constant
43      public static final String DOCUMENT_CONTENT_XML_ROOT_ELEMENT_NAME = "info";
44  
45      public static final String KUALI_ORG_TYPE_CURRICULUM_PARENT = "kuali.org.CurriculumParent";
46      public static final String KUALI_ORG_HIERARCHY_CURRICULUM  = "kuali.org.hierarchy.Curriculum";
47      public static final String KUALI_ORG_DEPARTMENT               = "kuali.org.Department";
48      public static final String KUALI_ORG_COLLEGE                  = "kuali.org.College";
49      public static final String KUALI_ORG_COC                      = "kuali.org.COC";
50      public static final String KUALI_ORG_DIVISION                 = "kuali.org.Division";
51      public static final String KUALI_ORG_PROGRAM                  = "kuali.org.Program";
52  
53      private OrganizationService organizationService;
54  
55      protected OrganizationService getOrganizationService() {
56          if (null == organizationService) {
57              organizationService = (OrganizationService) GlobalResourceLoader.getService(new QName("http://student.kuali.org/wsdl/organization", "OrganizationService"));
58          }
59          return organizationService;
60      }
61  
62      protected void setOrganizationService(OrganizationService orgSvc) {
63          organizationService = orgSvc;
64      }
65  
66      /**
67       * Method to fetch the organization ids from the KEW document content XML
68       * 
69       * @param context
70       *            - RouteContext class that holds data about the current document's routing and data
71       * @return A list of organization ids that are listed in the XML (may have duplicates if duplicates are allowed by
72       *         KS code)
73       */
74      protected Set<String> getOrganizationIdsFromDocumentContent(RouteContext context) {
75          String baseXpathExpression = "/" + KewApiConstants.DOCUMENT_CONTENT_ELEMENT + "/" + KewApiConstants.APPLICATION_CONTENT_ELEMENT + "/" + DOCUMENT_CONTENT_XML_ROOT_ELEMENT_NAME;
76          String orgXpathExpression = "./" + getOrganizationIdDocumentContentFieldKey(context);
77          Document xmlContent = context.getDocumentContent().getDocument();
78          XPath xPath = XPathHelper.newXPath();
79          try {
80              NodeList baseElements = (NodeList) xPath.evaluate(baseXpathExpression, xmlContent, XPathConstants.NODESET);
81              if (LOG.isDebugEnabled()) {
82                  LOG.debug("Found " + baseElements.getLength() + " baseElements to parse for AttributeSets using document XML:" + XmlJotter.jotDocument(xmlContent));
83              }
84              Set<String> distinctiveOrganizationIds = new HashSet<String>();
85              for (int i = 0; i < baseElements.getLength(); i++) {
86                  Node baseNode = baseElements.item(i);
87                  NodeList attributes = (NodeList) xPath.evaluate(orgXpathExpression, baseNode, XPathConstants.NODESET);
88                  for (int j = 0; j < attributes.getLength(); j++) {
89                      Element attributeElement = (Element) attributes.item(j);
90                      distinctiveOrganizationIds.add(attributeElement.getTextContent());
91                  }
92              }
93              return distinctiveOrganizationIds;
94          } catch (XPathExpressionException e) {
95              throw new RuntimeException("Encountered an issue executing XPath.", e);
96          }
97      }
98  
99      protected String getOrganizationIdDocumentContentFieldKey(RouteContext context) {
100         String organizationIdFieldKey = RouteNodeUtils.getValueOfCustomProperty(context.getNodeInstance().getRouteNode(), DOCUMENT_CONTENT_XML_ORG_ID_KEY);
101         if (StringUtils.isBlank(organizationIdFieldKey)) {
102             LOG.info("Cannot find element '" + DOCUMENT_CONTENT_XML_ORG_ID_KEY + "' on Route Node XML configuration. Will use default value of '" + DOCUMENT_CONTENT_XML_DEFAULT_ORG_ID_KEY + "'.");
103             organizationIdFieldKey = DOCUMENT_CONTENT_XML_DEFAULT_ORG_ID_KEY;
104         }
105         return organizationIdFieldKey;
106     }
107 
108     protected List<SearchResultRowInfo> relatedOrgsFromOrgId(String orgId, String relationType, String relatedOrgType) {
109         List<SearchResultRowInfo> results = null;
110         if (null != orgId) {
111             List<SearchParamInfo> queryParamValues = new ArrayList<SearchParamInfo>(3);
112             SearchParamInfo qpRelType = new SearchParamInfo();
113             qpRelType.setKey("org.queryParam.relationType");
114             qpRelType.getValues().add(relationType);
115             queryParamValues.add(qpRelType);
116 
117             SearchParamInfo qpOrgId = new SearchParamInfo();
118             qpOrgId.setKey("org.queryParam.orgId");
119             qpOrgId.getValues().add(orgId);
120             queryParamValues.add(qpOrgId);
121 
122             SearchParamInfo qpRelOrgType = new SearchParamInfo();
123             qpRelOrgType.setKey("org.queryParam.relatedOrgType");
124             qpRelOrgType.getValues().add(relatedOrgType);
125             queryParamValues.add(qpRelOrgType);
126 
127             SearchRequestInfo searchRequest = new SearchRequestInfo();
128             searchRequest.setSearchKey("org.search.orgQuickViewByRelationTypeRelatedOrgTypeOrgId");
129             searchRequest.setParams(queryParamValues);
130             try {
131                 SearchResultInfo result = null;
132                 // TODO: Fix the ContextInfo.
133                 result = getOrganizationService().search(searchRequest, new ContextInfo());
134                 results = result.getRows();
135             } catch (Exception e) {
136                 LOG.error("Error calling org service");
137                 throw new RuntimeException(e);
138             }
139         }
140         return results;
141     }
142     
143     /*
144      *  Add attributes for derived role and adhoc routing participants to the results
145      */
146     protected List<Map<String,String>> attributeSetFromSearchResult(List<SearchResultRowInfo> results, String orgIdKey) {
147         List<Map<String,String>> returnAttrSetList = new ArrayList<Map<String,String>>();
148         if (results != null) {
149             for (SearchResultRowInfo result : results) {
150                 Map<String,String> attributeSet = new LinkedHashMap<String,String>();
151                 String resolvedOrgId = "";
152                 String resolvedOrgShortName = "";
153                 for (SearchResultCellInfo resultCell : result.getCells()) {
154                     if ("org.resultColumn.orgId".equals(resultCell.getKey())) {
155                         resolvedOrgId = resultCell.getValue();
156                     } else if ("org.resultColumn.orgShortName".equals(resultCell.getKey())) {
157                         resolvedOrgShortName = resultCell.getValue();
158                     }
159                 }
160                 if (orgIdKey != null) {
161                     attributeSet.put(orgIdKey, resolvedOrgId);
162                 }
163                 attributeSet.put(KualiStudentKimAttributes.QUALIFICATION_ORG_ID, resolvedOrgId);
164                 returnAttrSetList.add(attributeSet);
165             }
166         }
167         return returnAttrSetList;
168     }
169 
170 }