View Javadoc
1   /**
2    * Copyright 2005-2016 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.kew.rule;
17  
18  import org.apache.log4j.Logger;
19  import org.kuali.rice.core.api.util.xml.XmlJotter;
20  import org.w3c.dom.Element;
21  import org.w3c.dom.Node;
22  import org.w3c.dom.NodeList;
23  
24  import javax.xml.xpath.XPath;
25  import javax.xml.xpath.XPathConstants;
26  import javax.xml.xpath.XPathExpression;
27  import javax.xml.xpath.XPathExpressionException;
28  import javax.xml.xpath.XPathFactory;
29  import java.util.ArrayList;
30  import java.util.HashMap;
31  import java.util.List;
32  import java.util.Map;
33  
34  
35  /**
36   * Helper class that can parse and generate generic attribute content
37   * from Map<String,String> values.
38   * 
39   * @author Kuali Rice Team (rice.collab@kuali.org)
40   */
41  public class GenericAttributeContent {
42      private static final XPathExpression NAME_EXPR;
43      private static final XPathExpression VALUE_EXPR;
44      private static final XPathExpression FIELD_EXPR;
45      static {
46          XPath xpath = XPathFactory.newInstance().newXPath();
47          try {
48              NAME_EXPR = xpath.compile("name");
49              VALUE_EXPR = xpath.compile("value");
50              FIELD_EXPR = xpath.compile("field");
51          } catch (XPathExpressionException xpee) {
52              throw new RuntimeException(xpee);
53          }
54      }
55  
56      private final Logger log;
57  
58      private final String elementName;
59      private final XPathExpression attr_expr;
60  
61      public GenericAttributeContent(Class clazz) {
62          this(clazz.getName());
63      }
64      public GenericAttributeContent(String elementName) {
65          this.elementName = elementName;
66          log = Logger.getLogger(GenericAttributeContent.class + "[" + elementName + "]");
67          try {
68              attr_expr = XPathFactory.newInstance().newXPath().compile(elementName);
69          } catch (XPathExpressionException xpee) {
70              throw new RuntimeException(xpee);
71          }
72      }
73  
74      public String generateContent(Map<String, String> properties) {
75          if (properties.size() == 0) return "<" + elementName + "/>";
76  
77          StringBuilder sb = new StringBuilder();
78          sb.append("<" + elementName + ">\r\n");
79          for (Map.Entry<String, String> entry: properties.entrySet()) {
80              String key = entry.getKey();
81              sb.append("  <field>\r\n");
82              if (key != null) {
83                  sb.append("    <name>" + key + "</name>\r\n");
84              } else {
85                  log.warn("null key encountered");
86              }
87              String value = entry.getValue();
88              if (value != null) {
89                  sb.append("    <value>" + entry.getValue() + "</value>\r\n");
90              } else {
91                  log.warn("null value encountered for key: " + key);
92              }
93              sb.append("  </field>\r\n");
94          }
95          sb.append("</" + elementName + ">\r\n");
96  
97          return sb.toString();
98      }
99  
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 }