View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.module.xml.config;
8   
9   import org.mule.config.spring.parsers.assembly.BeanAssembler;
10  import org.mule.config.spring.parsers.generic.ChildDefinitionParser;
11  import org.mule.module.xml.util.XMLUtils;
12  
13  import javax.xml.transform.Result;
14  import javax.xml.transform.Source;
15  import javax.xml.transform.dom.DOMSource;
16  import javax.xml.transform.stream.StreamResult;
17  
18  import org.apache.commons.io.output.ByteArrayOutputStream;
19  import org.springframework.beans.factory.xml.ParserContext;
20  import org.w3c.dom.Element;
21  import org.w3c.dom.Node;
22  import org.w3c.dom.NodeList;
23  
24  /**
25   * TODO
26   */
27  public class XsltTextDefinitionParser extends ChildDefinitionParser
28  {
29      public static final String STYLESHEET = "stylesheet";
30      public static final int UNDEFINED = -1;
31  
32      /**
33       * The class will be inferred from the class attribute
34       *
35       * @param setterMethod The target method (where the child will be injected)
36       */
37      public XsltTextDefinitionParser(String setterMethod)
38      {
39          super(setterMethod);
40      }
41  
42      /**
43       * @param setterMethod The target method (where the child will be injected)
44       * @param clazz        The class created by this element/parser
45       */
46      public XsltTextDefinitionParser(String setterMethod, Class clazz)
47      {
48          super(setterMethod, clazz);
49      }
50  
51      protected void postProcess(ParserContext context, BeanAssembler assembler, Element element)
52      {
53          NodeList children = element.getChildNodes();
54          if (0 != children.getLength())
55          {
56              Element stylesheet = null;
57              for (int i = 0; i < children.getLength(); i++)
58              {
59                  if (Node.ELEMENT_NODE == children.item(i).getNodeType())
60                  {
61                      assertArgument(null == stylesheet, "XSLT transformer can have at most one child element");
62                      stylesheet = (Element) children.item(i);
63                  }
64              }
65              if (null != stylesheet)
66              {
67                  assertArgument(STYLESHEET.equals(stylesheet.getLocalName()),
68                          "XSLT transformer child element must be named " + STYLESHEET);
69                  assembler.extendTarget("xslt", domToString(stylesheet), false);
70                  // block processing by Spring
71                  element.removeChild(stylesheet);
72              }
73          }
74          super.postProcess(context, assembler, element);
75      }
76  
77      @Override
78      public String getPropertyName(Element e)
79      {
80          //We need to set this to null since we have already set the property on the parent in the postProcess() method
81          return null;
82      }
83  
84      protected String domToString(Element dom)
85      {
86          try
87          {
88              // maybe change the transformer to avoid this step?
89              Source source = new DOMSource(dom);
90              ByteArrayOutputStream output = new ByteArrayOutputStream();
91              Result result = new StreamResult(output);
92              XMLUtils.getTransformer().transform(source, result);
93              return output.toString();
94          }
95          catch (Exception e)
96          {
97              throw (IllegalStateException) new IllegalStateException(e.getMessage()).initCause(e);
98          }
99      }
100 
101     protected void assertArgument(boolean condition, String message)
102     {
103         if (!condition)
104         {
105             throw new IllegalArgumentException(message);
106         }
107     }
108 }