001 /** 002 * Copyright 2005-2013 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 */ 016 package org.kuali.rice.kew.rule; 017 018 import org.apache.log4j.Logger; 019 import org.kuali.rice.core.api.util.xml.XmlJotter; 020 import org.w3c.dom.Element; 021 import org.w3c.dom.Node; 022 import org.w3c.dom.NodeList; 023 024 import javax.xml.xpath.XPath; 025 import javax.xml.xpath.XPathConstants; 026 import javax.xml.xpath.XPathExpression; 027 import javax.xml.xpath.XPathExpressionException; 028 import javax.xml.xpath.XPathFactory; 029 import java.util.ArrayList; 030 import java.util.HashMap; 031 import java.util.List; 032 import java.util.Map; 033 034 035 /** 036 * Helper class that can parse and generate generic attribute content 037 * from Map<String,String> values. 038 * 039 * @author Kuali Rice Team (rice.collab@kuali.org) 040 */ 041 public class GenericAttributeContent { 042 private static final XPathExpression NAME_EXPR; 043 private static final XPathExpression VALUE_EXPR; 044 private static final XPathExpression FIELD_EXPR; 045 static { 046 XPath xpath = XPathFactory.newInstance().newXPath(); 047 try { 048 NAME_EXPR = xpath.compile("name"); 049 VALUE_EXPR = xpath.compile("value"); 050 FIELD_EXPR = xpath.compile("field"); 051 } catch (XPathExpressionException xpee) { 052 throw new RuntimeException(xpee); 053 } 054 } 055 056 private final Logger log; 057 058 private final String elementName; 059 private final XPathExpression attr_expr; 060 061 public GenericAttributeContent(Class clazz) { 062 this(clazz.getName()); 063 } 064 public GenericAttributeContent(String elementName) { 065 this.elementName = elementName; 066 log = Logger.getLogger(GenericAttributeContent.class + "[" + elementName + "]"); 067 try { 068 attr_expr = XPathFactory.newInstance().newXPath().compile(elementName); 069 } catch (XPathExpressionException xpee) { 070 throw new RuntimeException(xpee); 071 } 072 } 073 074 public String generateContent(Map<String, String> properties) { 075 if (properties.size() == 0) return "<" + elementName + "/>"; 076 077 StringBuilder sb = new StringBuilder(); 078 sb.append("<" + elementName + ">\r\n"); 079 for (Map.Entry<String, String> entry: properties.entrySet()) { 080 String key = entry.getKey(); 081 sb.append(" <field>\r\n"); 082 if (key != null) { 083 sb.append(" <name>" + key + "</name>\r\n"); 084 } else { 085 log.warn("null key encountered"); 086 } 087 String value = entry.getValue(); 088 if (value != null) { 089 sb.append(" <value>" + entry.getValue() + "</value>\r\n"); 090 } else { 091 log.warn("null value encountered for key: " + key); 092 } 093 sb.append(" </field>\r\n"); 094 } 095 sb.append("</" + elementName + ">\r\n"); 096 097 return sb.toString(); 098 } 099 100 public List<Map<String, String>> parseContent(Element attributeContent) throws XPathExpressionException { 101 List<Map<String, String>> attrs = new ArrayList<Map<String, String>>(); 102 if (attributeContent == null) { 103 return attrs; 104 } 105 log.info("Parsing content: "+ XmlJotter.jotNode(attributeContent)); 106 NodeList attrNodes = (NodeList) attr_expr.evaluate(attributeContent, XPathConstants.NODESET); 107 if (attrNodes != null) { 108 for (int i = 0; i < attrNodes.getLength(); i++) { 109 Map<String, String> props = new HashMap<String, String>(); 110 attrs.add(props); 111 Node node = attrNodes.item(i); 112 log.info("Found matching attribute: " + XmlJotter.jotNode(node)); 113 NodeList fieldNodes = (NodeList) FIELD_EXPR.evaluate(node, XPathConstants.NODESET); 114 for (int j = 0; j < fieldNodes.getLength(); j++) { 115 node = fieldNodes.item(j); 116 log.info("Found matching attribute content field: " + XmlJotter.jotNode(node)); 117 Boolean b = (Boolean) NAME_EXPR.evaluate(node, XPathConstants.BOOLEAN); 118 if (!b.booleanValue()) { 119 log.error("Encountered field with no name, skipping!"); 120 continue; 121 } 122 String name = NAME_EXPR.evaluate(node); 123 b = (Boolean) VALUE_EXPR.evaluate(node, XPathConstants.BOOLEAN); 124 String value = null; 125 if (b.booleanValue()) { 126 value = VALUE_EXPR.evaluate(node); 127 } else { 128 log.warn("No value defined for transmitted field named: " + name); 129 } 130 log.info("Matching attribute content field value: " + name + "=" + value); 131 props.put(name, value); 132 } 133 } 134 } 135 return attrs; 136 } 137 }