View Javadoc
1   /**
2    * Copyright 2005-2014 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;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Properties;
22  
23  import javax.xml.xpath.XPath;
24  import javax.xml.xpath.XPathExpressionException;
25  import javax.xml.xpath.XPathFactory;
26  
27  import org.apache.commons.lang.StringUtils;
28  import org.kuali.rice.kew.engine.RouteContext;
29  import org.kuali.rice.kew.rule.xmlrouting.WorkflowFunctionResolver;
30  import org.kuali.rice.kew.rule.xmlrouting.WorkflowNamespaceContext;
31  import org.kuali.rice.kns.util.FieldUtils;
32  import org.kuali.rice.kns.web.ui.Field;
33  import org.kuali.rice.kns.web.ui.Row;
34  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
35  import org.kuali.rice.krad.util.KRADConstants;
36  import org.kuali.rice.krad.util.KRADPropertyConstants;
37  import org.kuali.rice.krad.util.UrlFactory;
38  import org.w3c.dom.Document;
39  
40  /**
41   * @author Kuali Rice Team (rice.collab@kuali.org)
42   *
43   * @deprecated Only used by KNS classes, no replacement.
44   */
45  @Deprecated
46  public final class WorkflowUtils {
47      private static final String XPATH_ROUTE_CONTEXT_KEY = "_xpathKey";
48      public static final String XSTREAM_SAFE_PREFIX = "wf:xstreamsafe('";
49      public static final String XSTREAM_SAFE_SUFFIX = "')";
50      public static final String XSTREAM_MATCH_ANYWHERE_PREFIX = "//";
51      public static final String XSTREAM_MATCH_RELATIVE_PREFIX = "./";
52  
53  	private WorkflowUtils() {
54  		throw new UnsupportedOperationException("do not call");
55  	}
56      
57      /**
58       *
59       * This method sets up the XPath with the correct workflow namespace and resolver initialized. This ensures that the XPath
60       * statements can use required workflow functions as part of the XPath statements.
61       *
62       * @param document - document
63       * @return a fully initialized XPath instance that has access to the workflow resolver and namespace.
64       *
65       */
66      public final static XPath getXPath(Document document) {
67          XPath xpath = getXPath(RouteContext.getCurrentRouteContext());
68          xpath.setNamespaceContext(new WorkflowNamespaceContext());
69          WorkflowFunctionResolver resolver = new WorkflowFunctionResolver();
70          resolver.setXpath(xpath);
71          resolver.setRootNode(document);
72          xpath.setXPathFunctionResolver(resolver);
73          return xpath;
74      }
75  
76      public final static XPath getXPath(RouteContext routeContext) {
77          if (routeContext == null) {
78              return XPathFactory.newInstance().newXPath();
79          }
80          if (!routeContext.getParameters().containsKey(XPATH_ROUTE_CONTEXT_KEY)) {
81              routeContext.getParameters().put(XPATH_ROUTE_CONTEXT_KEY, XPathFactory.newInstance().newXPath());
82          }
83          return (XPath) routeContext.getParameters().get(XPATH_ROUTE_CONTEXT_KEY);
84      }
85  
86      /**
87       * This method will do a simple XPath.evaluate, while wrapping your xpathExpression with the xstreamSafe function. It assumes a
88       * String result, and will return such. If an XPathExpressionException is thrown, this will be re-thrown within a
89       * RuntimeException.
90       *
91       * @param xpath A correctly initialized XPath instance.
92       * @param xpathExpression Your XPath Expression that needs to be wrapped in an xstreamSafe wrapper and run.
93       * @param item The document contents you will be searching within.
94       * @return The string value of the xpath.evaluate().
95       */
96      public static final String xstreamSafeEval(XPath xpath, String xpathExpression, Object item) {
97          String xstreamSafeXPath = xstreamSafeXPath(xpathExpression);
98          String evalResult = "";
99          try {
100             evalResult = xpath.evaluate(xstreamSafeXPath, item);
101         }
102         catch (XPathExpressionException e) {
103             throw new RuntimeException("XPathExpressionException occurred on xpath: " + xstreamSafeXPath, e);
104         }
105         return evalResult;
106     }
107 
108     /**
109      * This method wraps the passed-in XPath expression in XStream Safe wrappers, so that XStream generated reference links will be
110      * handled correctly.
111      *
112      * @param xpathExpression The XPath Expression you wish to use.
113      * @return Your XPath Expression wrapped in the XStreamSafe wrapper.
114      */
115     public static final String xstreamSafeXPath(String xpathExpression) {
116         return new StringBuilder(XSTREAM_SAFE_PREFIX).append(xpathExpression).append(XSTREAM_SAFE_SUFFIX).toString();
117     }
118 
119     /**
120      * This method returns a label from the data dictionary service
121      *
122      * @param businessObjectClass - class where the label should come from
123      * @param attributeName - name of the attribute you need the label for
124      * @return the label from the data dictionary for the given Class and attributeName or null if not found
125      */
126     public static final String getBusinessObjectAttributeLabel(Class businessObjectClass, String attributeName) {
127         return KRADServiceLocatorWeb.getDataDictionaryService().getAttributeLabel(businessObjectClass, attributeName);
128     }
129 
130 
131     /**
132      * This method builds a workflow-lookup-screen Row of type TEXT, with no quickfinder/lookup.
133      *
134      * @param propertyClass The Class of the BO that this row is based on. For example, Account.class for accountNumber.
135      * @param boPropertyName The property name on the BO that this row is based on. For example, accountNumber for
136      *        Account.accountNumber.
137      * @param workflowPropertyKey The workflow-lookup-screen property key. For example, account_nbr for Account.accountNumber. This
138      *        key can be anything, but needs to be consistent with what is used for the row/field key on the java attribute, so
139      *        everything links up correctly.
140      * @return A populated and ready-to-use workflow lookupable.Row.
141      */
142     public static Row buildTextRow(Class propertyClass, String boPropertyName, String workflowPropertyKey) {
143         if (propertyClass == null) {
144             throw new IllegalArgumentException("Method parameter 'propertyClass' was passed a NULL value.");
145         }
146         if (StringUtils.isBlank(boPropertyName)) {
147             throw new IllegalArgumentException("Method parameter 'boPropertyName' was passed a NULL or blank value.");
148         }
149         if (StringUtils.isBlank(workflowPropertyKey)) {
150             throw new IllegalArgumentException("Method parameter 'workflowPropertyKey' was passed a NULL or blank value.");
151         }
152         List<Field> fields = new ArrayList<Field>();
153         Field field;
154         field = FieldUtils.getPropertyField(propertyClass, boPropertyName, false);
155         fields.add(field);
156         return new Row(fields);
157     }
158 
159     /**
160      * This method builds a workflow-lookup-screen Row of type TEXT, with the attached lookup icon and functionality.
161      *
162      * @param propertyClass The Class of the BO that this row is based on. For example, Account.class for accountNumber.
163      * @param boPropertyName The property name on the BO that this row is based on. For example, accountNumber for
164      *        Account.accountNumber.
165      * @param workflowPropertyKey The workflow-lookup-screen property key. For example, account_nbr for Account.accountNumber. This
166      *        key can be anything, but needs to be consistent with what is used for the row/field key on the java attribute, so
167      *        everything links up correctly.
168      * @return A populated and ready-to-use workflow lookupable.Row, which includes both the property field and the lookup icon.
169      */
170     public static Row buildTextRowWithLookup(Class propertyClass, String boPropertyName, String workflowPropertyKey) {
171         return buildTextRowWithLookup(propertyClass, boPropertyName, workflowPropertyKey, null);
172     }
173 
174     /**
175      * This method builds a workflow-lookup-screen Row of type TEXT, with the attached lookup icon and functionality.
176      *
177      * @param propertyClass The Class of the BO that this row is based on. For example, Account.class for accountNumber.
178      * @param boPropertyName The property name on the BO that this row is based on. For example, accountNumber for
179      *        Account.accountNumber.
180      * @param workflowPropertyKey The workflow-lookup-screen property key. For example, account_nbr for Account.accountNumber. This
181      *        key can be anything, but needs to be consistent with what is used for the row/field key on the java attribute, so
182      *        everything links up correctly.
183      * @param fieldConversionsByBoPropertyName A list of extra field conversions where the key is the business object property name
184      *        and the value is the workflow property key
185      * @return A populated and ready-to-use workflow lookupable.Row, which includes both the property field and the lookup icon.
186      */
187     public static Row buildTextRowWithLookup(Class propertyClass, String boPropertyName, String workflowPropertyKey, Map fieldConversionsByBoPropertyName) {
188         if (propertyClass == null) {
189             throw new IllegalArgumentException("Method parameter 'propertyClass' was passed a NULL value.");
190         }
191         if (StringUtils.isBlank(boPropertyName)) {
192             throw new IllegalArgumentException("Method parameter 'boPropertyName' was passed a NULL or blank value.");
193         }
194         if (StringUtils.isBlank(workflowPropertyKey)) {
195             throw new IllegalArgumentException("Method parameter 'workflowPropertyKey' was passed a NULL or blank value.");
196         }
197         Field field;
198         field = FieldUtils.getPropertyField(propertyClass, boPropertyName, false);
199 
200         List<Field> fields = new ArrayList<Field>();
201         fields.add(field);
202         return new Row(fields);
203     }
204 
205     /**
206      * This method builds a workflow-lookup-screen Row of type DROPDOWN.
207      *
208      * @param propertyClass The Class of the BO that this row is based on. For example, Account.class for accountNumber.
209      * @param boPropertyName The property name on the BO that this row is based on. For example, accountNumber for
210      *        Account.accountNumber.
211      * @param workflowPropertyKey The workflow-lookup-screen property key. For example, account_nbr for Account.accountNumber. This
212      *        key can be anything, but needs to be consistent with what is used for the row/field key on the java attribute, so
213      *        everything links up correctly.
214      * @param optionMap The map of value, text pairs that will be used to constuct the dropdown list.
215      * @return A populated and ready-to-use workflow lookupable.Row.
216      */
217     public static Row buildDropdownRow(Class propertyClass, String boPropertyName, String workflowPropertyKey, Map<String, String> optionMap, boolean addBlankRow) {
218         if (propertyClass == null) {
219             throw new IllegalArgumentException("Method parameter 'propertyClass' was passed a NULL value.");
220         }
221         if (StringUtils.isBlank(boPropertyName)) {
222             throw new IllegalArgumentException("Method parameter 'boPropertyName' was passed a NULL or blank value.");
223         }
224         if (StringUtils.isBlank(workflowPropertyKey)) {
225             throw new IllegalArgumentException("Method parameter 'workflowPropertyKey' was passed a NULL or blank value.");
226         }
227         if (optionMap == null) {
228             throw new IllegalArgumentException("Method parameter 'optionMap' was passed a NULL value.");
229         }
230         List<Field> fields = new ArrayList<Field>();
231         Field field;
232         field = FieldUtils.getPropertyField(propertyClass, boPropertyName, false);
233         fields.add(field);
234         return new Row(fields);
235     }
236 }