1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.workflow.attribute;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.kuali.rice.core.api.util.KeyValue;
22 import org.kuali.rice.core.api.util.xml.XmlJotter;
23 import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
24 import org.kuali.rice.krad.keyvalues.KeyValuesFinder;
25 import org.kuali.rice.krad.service.DataDictionaryService;
26 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
27 import org.w3c.dom.Element;
28 import org.w3c.dom.NamedNodeMap;
29 import org.w3c.dom.Node;
30 import org.w3c.dom.NodeList;
31
32 import javax.xml.transform.Result;
33 import javax.xml.transform.Source;
34 import javax.xml.transform.TransformerFactory;
35 import javax.xml.transform.dom.DOMSource;
36 import javax.xml.transform.stream.StreamResult;
37 import javax.xml.xpath.XPath;
38 import javax.xml.xpath.XPathConstants;
39 import javax.xml.xpath.XPathExpressionException;
40 import java.io.StringWriter;
41 import java.util.ArrayList;
42 import java.util.Iterator;
43 import java.util.List;
44 import java.util.regex.Matcher;
45 import java.util.regex.Pattern;
46
47
48
49
50 @Deprecated
51 public class KualiXmlAttributeHelper {
52 private static Log LOG = LogFactory.getLog(KualiXmlAttributeHelper.class);
53 private static XPath xpath = XPathHelper.newXPath();
54 private static final String testVal = "\'/[^\']*\'";
55 private static final String testVal2 = "/[^/]+/" + "*";
56 private static final String cleanVal = "[^/\']+";
57 private static final String ruledataVal = "ruledata[^\']*\'([^\']*)";
58
59
60
61 private static final Pattern xPathPattern = Pattern.compile(testVal);
62 private static final Pattern termPattern = Pattern.compile(testVal2);
63 private static final Pattern cleanPattern = Pattern.compile(cleanVal);
64 private static final Pattern targetPattern = Pattern.compile(ruledataVal);
65
66 public static final String ATTRIBUTE_LABEL_BO_REFERENCE_PREFIX = "kuali_dd_label(";
67 public static final String ATTRIBUTE_LABEL_BO_REFERENCE_SUFFIX = ")";
68 public static final String ATTRIBUTE_SHORT_LABEL_BO_REFERENCE_PREFIX = "kuali_dd_short_label(";
69 public static final String ATTRIBUTE_SHORT_LABEL_BO_REFERENCE_SUFFIX = ")";
70 private static final String KUALI_VALUES_FINDER_REFERENCE_PREFIX = "kuali_values_finder_class(";
71 private static final String KUALI_VALUES_FINDER_REFERENCE_SUFFIX = ")";
72 public static final String notFound = "Label Not Found";
73
74 private String lastXPath = "";
75
76
77
78
79
80
81
82
83 public Element processConfigXML(Element root) {
84 return this.processConfigXML(root, null);
85 }
86
87
88
89
90
91
92
93
94 public Element processConfigXML(Element root, String[] xpathExpressionElements) {
95
96 NodeList fields = root.getElementsByTagName("fieldDef");
97 Element theTag = null;
98 String docContent = "";
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 org.w3c.dom.Document xmlDoc = null;
115 if (!xmlDocumentContentExists(root)) {
116 fields = root.getElementsByTagName("fieldDef");
117 xmlDoc = root.getOwnerDocument();
118 }
119 for (int i = 0; i < fields.getLength(); i++) {
120 String name = null;
121 if (!xmlDocumentContentExists(root)) {
122 theTag = (Element) fields.item(i);
123
124
125
126
127
128
129
130 List<String> xPathTerms = getXPathTerms(theTag);
131 if (xPathTerms.size() != 0) {
132 Node iterNode = xmlDoc.createElement("xmlDocumentContent");
133
134
135 xmlDoc.normalize();
136
137 iterNode.normalize();
138
139
140
141
142
143 for (int j = 0; j < xPathTerms.size(); j++) {
144
145 iterNode.appendChild(xmlDoc.createElement(xPathTerms.get(j)));
146 xmlDoc.normalize();
147
148 iterNode = iterNode.getFirstChild();
149 iterNode.normalize();
150
151 }
152 iterNode.setTextContent("%" + xPathTerms.get(xPathTerms.size() - 1) + "%");
153 root.appendChild(iterNode);
154 }
155 }
156 theTag = (Element) fields.item(i);
157
158 NodeList displayTagElements = theTag.getElementsByTagName("display");
159 if (displayTagElements.getLength() == 1) {
160 Element displayTag = (Element) displayTagElements.item(0);
161 List valuesElementsToAdd = new ArrayList();
162 for (int w = 0; w < displayTag.getChildNodes().getLength(); w++) {
163 Node displayTagChildNode = (Node) displayTag.getChildNodes().item(w);
164 if ((displayTagChildNode != null) && ("values".equals(displayTagChildNode.getNodeName()))) {
165 if (displayTagChildNode.getChildNodes().getLength() > 0) {
166 String valuesNodeText = displayTagChildNode.getFirstChild().getNodeValue();
167 String potentialClassName = getPotentialKualiClassName(valuesNodeText, KUALI_VALUES_FINDER_REFERENCE_PREFIX, KUALI_VALUES_FINDER_REFERENCE_SUFFIX);
168 if (StringUtils.isNotBlank(potentialClassName)) {
169 try {
170 Class finderClass = Class.forName((String) potentialClassName);
171 KeyValuesFinder finder = (KeyValuesFinder) finderClass.newInstance();
172 NamedNodeMap valuesNodeAttributes = displayTagChildNode.getAttributes();
173 Node potentialSelectedAttribute = (valuesNodeAttributes != null) ? valuesNodeAttributes.getNamedItem("selected") : null;
174 for (Iterator iter = finder.getKeyValues().iterator(); iter.hasNext();) {
175 KeyValue keyValue = (KeyValue) iter.next();
176 Element newValuesElement = root.getOwnerDocument().createElement("values");
177 newValuesElement.appendChild(root.getOwnerDocument().createTextNode(keyValue.getKey()));
178
179 newValuesElement.setAttribute("title", keyValue.getValue());
180 if (potentialSelectedAttribute != null) {
181 newValuesElement.setAttribute("selected", potentialSelectedAttribute.getNodeValue());
182 }
183 valuesElementsToAdd.add(newValuesElement);
184 }
185 } catch (ClassNotFoundException cnfe) {
186 String errorMessage = "Caught an exception trying to find class '" + potentialClassName + "'";
187 LOG.error(errorMessage, cnfe);
188 throw new RuntimeException(errorMessage, cnfe);
189 } catch (InstantiationException ie) {
190 String errorMessage = "Caught an exception trying to instantiate class '" + potentialClassName + "'";
191 LOG.error(errorMessage, ie);
192 throw new RuntimeException(errorMessage, ie);
193 } catch (IllegalAccessException iae) {
194 String errorMessage = "Caught an access exception trying to instantiate class '" + potentialClassName + "'";
195 LOG.error(errorMessage, iae);
196 throw new RuntimeException(errorMessage, iae);
197 }
198 } else {
199 valuesElementsToAdd.add(displayTagChildNode.cloneNode(true));
200 }
201 displayTag.removeChild(displayTagChildNode);
202 }
203 }
204 }
205 for (Iterator iter = valuesElementsToAdd.iterator(); iter.hasNext();) {
206 Element valuesElementToAdd = (Element) iter.next();
207 displayTag.appendChild(valuesElementToAdd);
208 }
209 }
210 if ((xpathExpressionElements != null) && (xpathExpressionElements.length > 0)) {
211 NodeList fieldEvaluationElements = theTag.getElementsByTagName("fieldEvaluation");
212 if (fieldEvaluationElements.getLength() == 1) {
213 Element fieldEvaluationTag = (Element) fieldEvaluationElements.item(0);
214 List tagsToAdd = new ArrayList();
215 for (int w = 0; w < fieldEvaluationTag.getChildNodes().getLength(); w++) {
216 Node fieldEvaluationChildNode = (Node) fieldEvaluationTag.getChildNodes().item(w);
217 Element newTagToAdd = null;
218 if ((fieldEvaluationChildNode != null) && ("xpathexpression".equals(fieldEvaluationChildNode.getNodeName()))) {
219 newTagToAdd = root.getOwnerDocument().createElement("xpathexpression");
220 newTagToAdd.appendChild(root.getOwnerDocument().createTextNode(generateNewXpathExpression(fieldEvaluationChildNode.getFirstChild().getNodeValue(), xpathExpressionElements)));
221 tagsToAdd.add(newTagToAdd);
222 fieldEvaluationTag.removeChild(fieldEvaluationChildNode);
223 }
224 }
225 for (Iterator iter = tagsToAdd.iterator(); iter.hasNext();) {
226 Element elementToAdd = (Element) iter.next();
227 fieldEvaluationTag.appendChild(elementToAdd);
228 }
229 }
230 }
231 theTag.setAttribute("title", getBusinessObjectTitle(theTag));
232
233 }
234 if (LOG.isDebugEnabled()) {
235 LOG.debug(XmlJotter.jotNode(root));
236 StringWriter xmlBuffer = new StringWriter();
237 try {
238
239 root.normalize();
240 Source source = new DOMSource(root);
241 Result result = new StreamResult(xmlBuffer);
242 TransformerFactory.newInstance().newTransformer().transform(source, result);
243 } catch (Exception e) {
244 LOG.debug(" Exception when printing debug XML output " + e);
245 }
246 LOG.debug(xmlBuffer.getBuffer());
247 }
248
249 return root;
250 }
251
252 private String generateNewXpathExpression(String currentXpathExpression, String[] newXpathExpressionElements) {
253 StringBuffer returnableString = new StringBuffer();
254 for (int i = 0; i < newXpathExpressionElements.length; i++) {
255 String newXpathElement = newXpathExpressionElements[i];
256 returnableString.append(newXpathElement);
257
258
259
260
261
262
263 if (((i + 1) != newXpathExpressionElements.length) || (newXpathExpressionElements.length == 1)) {
264 returnableString.append(currentXpathExpression);
265 }
266 }
267 return returnableString.toString();
268 }
269
270
271
272
273
274
275
276 private String getXPathText(Element root) {
277 try {
278 String textContent = null;
279 Node node = (Node) xpath.evaluate(".//xpathexpression", root, XPathConstants.NODE);
280 if (node != null) {
281 textContent = node.getTextContent();
282 }
283 return textContent;
284 } catch (XPathExpressionException e) {
285 LOG.error("No XPath expression text found in element xpathexpression of configXML for document. " + e);
286 return null;
287
288 }
289 }
290
291
292
293
294
295
296
297 private boolean xmlDocumentContentExists(Element root) {
298 try {
299 if (((NodeList) xpath.evaluate("//xmlDocumentContent", root, XPathConstants.NODESET)).getLength() == 0) {
300 return false;
301 }
302 } catch (XPathExpressionException e) {
303 LOG.error("Error parsing xmlDocumentConfig. " + e);
304 return false;
305 }
306 return true;
307 }
308
309 public static String getPotentialKualiClassName(String testString, String prefixIndicator, String suffixIndicator) {
310 if ((StringUtils.isNotBlank(testString)) && (testString.startsWith(prefixIndicator)) && (testString.endsWith(suffixIndicator))) {
311 return testString.substring(prefixIndicator.length(), testString.lastIndexOf(suffixIndicator));
312 }
313 return null;
314 }
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336 private String getBusinessObjectTitle(Element root) {
337 String businessObjectName = null;
338 String businessObjectText = root.getAttribute("title");
339 String potentialClassNameLongLabel = getPotentialKualiClassName(businessObjectText, ATTRIBUTE_LABEL_BO_REFERENCE_PREFIX, ATTRIBUTE_LABEL_BO_REFERENCE_SUFFIX);
340 String potentialClassNameShortLabel = getPotentialKualiClassName(businessObjectText, ATTRIBUTE_SHORT_LABEL_BO_REFERENCE_PREFIX, ATTRIBUTE_SHORT_LABEL_BO_REFERENCE_SUFFIX);
341
342 boolean requestedShortLabel = false;
343
344 if (StringUtils.isNotBlank(potentialClassNameLongLabel)) {
345 businessObjectName = potentialClassNameLongLabel;
346 } else if (StringUtils.isNotBlank(potentialClassNameShortLabel)) {
347 businessObjectName = potentialClassNameShortLabel;
348 requestedShortLabel = true;
349 }
350 if (StringUtils.isNotBlank(businessObjectName)) {
351 DataDictionaryService DDService = KRADServiceLocatorWeb.getDataDictionaryService();
352
353 String title = null;
354 String targetVal = lastXPath;
355
356 if (LOG.isErrorEnabled()) {
357 LOG.debug("Finding title in BO=" + businessObjectName + " ObjectName=" + targetVal);
358 }
359
360 if (StringUtils.isNotBlank(targetVal)) {
361
362 if (requestedShortLabel) {
363 title = DDService.getAttributeShortLabel(businessObjectName, targetVal);
364 } else {
365 title = DDService.getAttributeLabel(businessObjectName, targetVal);
366 }
367 if (StringUtils.isNotBlank(title)) {
368 return title;
369 }
370 }
371
372 targetVal = getRuleData(root);
373 if (LOG.isErrorEnabled()) {
374 LOG.debug("Finding title in BO=" + businessObjectName + " ObjectName=" + targetVal);
375 }
376 if (StringUtils.isNotBlank(targetVal)) {
377 title = DDService.getAttributeLabel(businessObjectName, targetVal);
378 if (StringUtils.isNotBlank(title)) {
379 return title;
380 }
381 }
382
383
384 targetVal = root.getAttribute("name");
385 if (LOG.isErrorEnabled()) {
386 LOG.debug("Finding title in BO=" + businessObjectName + " ObjectName=" + targetVal);
387 }
388 title = DDService.getAttributeLabel(businessObjectName, targetVal);
389
390 if (StringUtils.isNotBlank(title)) {
391 return title;
392 }
393 }
394
395 else if ((StringUtils.isNotBlank(businessObjectText)) && (StringUtils.isBlank(businessObjectName))) {
396 return businessObjectText;
397 }
398 return notFound;
399
400 }
401
402
403
404
405
406
407
408 private String getRuleData(Element root) {
409 String xPathRuleTarget = getXPathText(root);
410
411
412 if (StringUtils.isNotBlank(xPathRuleTarget)) {
413 Matcher ruleTarget = targetPattern.matcher(xPathRuleTarget);
414 if (ruleTarget.find()) {
415 xPathRuleTarget = ruleTarget.group(1);
416 }
417 }
418 return xPathRuleTarget;
419 }
420
421 private List<String> getXPathTerms(Element myTag) {
422
423 Matcher xPathTarget;
424 String firstMatch;
425 List<String> xPathTerms = new ArrayList();
426 String allText = getXPathText(myTag);
427 if (StringUtils.isNotBlank(allText)) {
428 xPathTarget = xPathPattern.matcher(allText);
429 Matcher termTarget;
430 Matcher cleanTarget;
431 int theEnd = 0;
432
433 xPathTarget.find(theEnd);
434 theEnd = xPathTarget.end() - 1;
435 firstMatch = xPathTarget.group();
436
437
438 termTarget = termPattern.matcher(firstMatch);
439 int theEnd2 = 0;
440 while (termTarget.find(theEnd2)) {
441 theEnd2 = termTarget.end() - 1;
442 cleanTarget = cleanPattern.matcher(termTarget.group());
443 cleanTarget.find();
444 lastXPath = cleanTarget.group();
445 xPathTerms.add(lastXPath);
446
447 }
448 }
449 return xPathTerms;
450 }
451
452 private String getLastXPath(Element root) {
453 List<String> tempList = getXPathTerms(root);
454 return tempList.get(tempList.size());
455 }
456 }