1 10 11 package org.mule.routing.outbound; 12 13 import org.apache.commons.lang.exception.ExceptionUtils; 14 import org.dom4j.Document; 15 import org.dom4j.DocumentHelper; 16 import org.dom4j.Element; 17 import org.dom4j.Node; 18 import org.dom4j.XPath; 19 import org.dom4j.io.SAXReader; 20 import org.mule.impl.MuleMessage; 21 import org.mule.umo.UMOMessage; 22 import org.mule.umo.endpoint.UMOEndpoint; 23 import org.mule.util.IOUtils; 24 import org.mule.util.StringUtils; 25 import org.xml.sax.SAXException ; 26 27 import java.io.InputStream ; 28 import java.io.StringReader ; 29 import java.util.ArrayList ; 30 import java.util.HashMap ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.Map ; 34 35 46 public class FilteringXmlMessageSplitter extends AbstractMessageSplitter 47 { 48 private static final String APACHE_XML_FEATURES_VALIDATION_SCHEMA = "http://apache.org/xml/features/validation/schema"; 50 private static final String APACHE_XML_FEATURES_VALIDATION_SCHEMA_FULL_CHECKING = "http://apache.org/xml/features/validation/schema-full-checking"; 51 52 private static final String JAXP_PROPERTIES_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; 54 55 private static final String JAXP_PROPERTIES_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; 58 private static final String JAXP_PROPERTIES_SCHEMA_LANGUAGE_VALUE = "http://www.w3.org/2001/XMLSchema"; 59 60 protected static ThreadLocal properties = new ThreadLocal (); 61 protected static ThreadLocal nodes = new ThreadLocal (); 62 protected String splitExpression = ""; 63 protected Map namespaces = null; 64 protected boolean validateSchema = false; 65 protected String externalSchemaLocation = ""; 66 67 public void setSplitExpression(String splitExpression) 68 { 69 this.splitExpression = StringUtils.trimToEmpty(splitExpression); 70 } 71 72 public void setNamespaces(Map namespaces) 73 { 74 this.namespaces = namespaces; 75 } 76 77 public String getSplitExpression() 78 { 79 return splitExpression; 80 } 81 82 public boolean isValidateSchema() 83 { 84 return validateSchema; 85 } 86 87 public void setValidateSchema(boolean validateSchema) 88 { 89 this.validateSchema = validateSchema; 90 } 91 92 public String getExternalSchemaLocation() 93 { 94 return externalSchemaLocation; 95 } 96 97 103 public void setExternalSchemaLocation(String externalSchemaLocation) 104 { 105 this.externalSchemaLocation = externalSchemaLocation; 106 } 107 108 114 protected void initialise(UMOMessage message) 115 { 116 if (logger.isDebugEnabled()) 117 { 118 if (splitExpression.length() == 0) 119 { 120 logger.warn("splitExpression is not specified, no processing will take place"); 121 } 122 else 123 { 124 logger.debug("splitExpression is " + splitExpression); 125 } 126 } 127 128 Object src = message.getPayload(); 129 130 try 131 { 132 if (src instanceof byte[]) 133 { 134 src = new String ((byte[])src); 135 } 136 137 Document dom4jDoc; 138 139 if (src instanceof String ) 140 { 141 String xml = (String )src; 142 SAXReader reader = new SAXReader(); 143 setDoSchemaValidation(reader, isValidateSchema()); 144 145 InputStream xsdAsStream = IOUtils.getResourceAsStream(getExternalSchemaLocation(), getClass()); 146 if (xsdAsStream == null) 147 { 148 throw new IllegalArgumentException ("Couldn't find schema at " 149 + getExternalSchemaLocation()); 150 } 151 152 reader.setProperty(JAXP_PROPERTIES_SCHEMA_LANGUAGE, JAXP_PROPERTIES_SCHEMA_LANGUAGE_VALUE); 155 156 reader.setProperty(JAXP_PROPERTIES_SCHEMA_SOURCE, xsdAsStream); 158 159 dom4jDoc = reader.read(new StringReader (xml)); 160 } 161 else if (src instanceof org.dom4j.Document) 162 { 163 dom4jDoc = (org.dom4j.Document)src; 164 } 165 else 166 { 167 logger.error("Non-xml message payload: " + src.getClass().toString()); 168 return; 169 } 170 171 if (dom4jDoc != null) 172 { 173 if (splitExpression.length() > 0) 174 { 175 XPath xpath = dom4jDoc.createXPath(splitExpression); 176 if (namespaces != null) 177 { 178 xpath.setNamespaceURIs(namespaces); 179 } 180 List foundNodes = xpath.selectNodes(dom4jDoc); 181 if (logger.isDebugEnabled()) 182 { 183 logger.debug("Split into " + foundNodes.size()); 184 } 185 List parts = new ArrayList (); 186 for (Iterator iterator = foundNodes.iterator(); iterator.hasNext();) 190 { 191 Node node = (Node)iterator.next(); 192 if (node instanceof Element) 193 { 194 node = (Node)node.clone(); 197 parts.add(DocumentHelper.createDocument((Element)node)); 198 } 199 else 200 { 201 logger.warn("Dcoument node: " + node.asXML() 202 + " is not an element and thus is not a valid part"); 203 } 204 } 205 FilteringXmlMessageSplitter.nodes.set(parts); 206 } 207 } 208 else 209 { 210 logger.warn("Unsupported message type, ignoring"); 211 } 212 } 213 catch (Exception ex) 214 { 215 throw new IllegalArgumentException ("Failed to initialise the payload: " 216 + ExceptionUtils.getStackTrace(ex)); 217 } 218 219 Map theProperties = new HashMap (); 220 for (Iterator iterator = message.getPropertyNames().iterator(); iterator.hasNext();) 221 { 222 String propertyKey = (String )iterator.next(); 223 theProperties.put(propertyKey, message.getProperty(propertyKey)); 224 } 225 properties.set(theProperties); 226 } 227 228 237 protected UMOMessage getMessagePart(UMOMessage message, UMOEndpoint endpoint) 238 { 239 List nodes = (List )FilteringXmlMessageSplitter.nodes.get(); 240 241 if (nodes == null) 242 { 243 logger.error("Error: nodes are null"); 244 return null; 245 } 246 247 for (int i = 0; i < nodes.size(); i++) 248 { 249 Document doc = (Document)nodes.get(i); 250 251 try 252 { 253 Map theProperties = (Map )properties.get(); 254 UMOMessage result = new MuleMessage(doc, new HashMap (theProperties)); 255 256 if (endpoint.getFilter() == null || endpoint.getFilter().accept(result)) 257 { 258 if (logger.isDebugEnabled()) 259 { 260 logger.debug("Endpoint filter matched for node " + i + " of " + nodes.size() 261 + ". Routing message over: " + endpoint.getEndpointURI().toString()); 262 } 263 nodes.remove(i); 264 return result; 265 } 266 else 267 { 268 if (logger.isDebugEnabled()) 269 { 270 logger.debug("Endpoint filter did not match, returning null"); 271 } 272 } 273 } 274 catch (Exception e) 275 { 276 logger.error("Unable to create message for node at position " + i, e); 277 return null; 278 } 279 } 280 281 return null; 282 } 283 284 protected void setDoSchemaValidation(SAXReader reader, boolean validate) throws SAXException 285 { 286 reader.setValidation(validate); 287 reader.setFeature(APACHE_XML_FEATURES_VALIDATION_SCHEMA, validate); 288 reader.setFeature(APACHE_XML_FEATURES_VALIDATION_SCHEMA_FULL_CHECKING, true); 289 } 290 } 291 | Popular Tags |