Coverage Report - org.mule.transformers.xml.XsltTransformer
 
Classes in this File Line Coverage Branch Coverage Complexity
XsltTransformer
0%
0/67
0%
0/9
2.174
XsltTransformer$1
0%
0/4
N/A
2.174
XsltTransformer$DefaultErrorListener
0%
0/12
0%
0/1
2.174
XsltTransformer$PooledXsltTransformerFactory
0%
0/9
0%
0/1
2.174
 
 1  
 /*
 2  
  * $Id: XsltTransformer.java 7976 2007-08-21 14:26:13Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.transformers.xml;
 12  
 
 13  
 import org.mule.config.i18n.CoreMessages;
 14  
 import org.mule.umo.lifecycle.InitialisationException;
 15  
 import org.mule.umo.transformer.TransformerException;
 16  
 import org.mule.umo.transformer.UMOTransformer;
 17  
 import org.mule.util.ClassUtils;
 18  
 import org.mule.util.IOUtils;
 19  
 import org.mule.util.StringUtils;
 20  
 
 21  
 import java.io.IOException;
 22  
 import java.io.InputStream;
 23  
 import java.io.StringReader;
 24  
 
 25  
 import javax.xml.transform.ErrorListener;
 26  
 import javax.xml.transform.OutputKeys;
 27  
 import javax.xml.transform.Source;
 28  
 import javax.xml.transform.Transformer;
 29  
 import javax.xml.transform.TransformerFactory;
 30  
 import javax.xml.transform.URIResolver;
 31  
 import javax.xml.transform.stream.StreamSource;
 32  
 
 33  
 import org.apache.commons.pool.BasePoolableObjectFactory;
 34  
 import org.apache.commons.pool.impl.GenericObjectPool;
 35  
 
 36  
 /**
 37  
  * <code>XsltTransformer</code> performs an XSLT transform on a DOM (or other
 38  
  * XML-ish) object.
 39  
  */
 40  
 
 41  0
 public class XsltTransformer extends AbstractXmlTransformer
 42  
 {
 43  
     // keep at least 1 XSLT Transformer ready by default
 44  
     private static final int MIN_IDLE_TRANSFORMERS = 1;
 45  
     // keep max. 32 XSLT Transformers around by default
 46  
     private static final int MAX_IDLE_TRANSFORMERS = 32;
 47  
     // MAX_IDLE is also the total limit
 48  
     private static final int MAX_ACTIVE_TRANSFORMERS = MAX_IDLE_TRANSFORMERS;
 49  
 
 50  
     protected final GenericObjectPool transformerPool;
 51  
 
 52  
     private volatile String xslTransformerFactoryClassName;
 53  
     private volatile String xslFile;
 54  
     private volatile String xslt;
 55  
 
 56  
     public XsltTransformer()
 57  
     {
 58  0
         super();
 59  0
         transformerPool = new GenericObjectPool(new PooledXsltTransformerFactory());
 60  0
         transformerPool.setMinIdle(MIN_IDLE_TRANSFORMERS);
 61  0
         transformerPool.setMaxIdle(MAX_IDLE_TRANSFORMERS);
 62  0
         transformerPool.setMaxActive(MAX_ACTIVE_TRANSFORMERS);
 63  0
     }
 64  
 
 65  
     /**
 66  
      * @see org.mule.umo.lifecycle.Initialisable#initialise()
 67  
      */
 68  
     // @Override
 69  
     public void initialise() throws InitialisationException
 70  
     {
 71  
         try
 72  
         {
 73  0
             transformerPool.addObject();
 74  
         }
 75  0
         catch (Throwable te)
 76  
         {
 77  0
             throw new InitialisationException(te, this);
 78  0
         }
 79  0
     }
 80  
 
 81  
     /**
 82  
      * Transform, using XSLT, a XML String to another String.
 83  
      * 
 84  
      * @param src The source XML (String, byte[], DOM, etc.)
 85  
      * @return The result String (or DOM)
 86  
      */
 87  
     public Object doTransform(Object src, String encoding) throws TransformerException
 88  
     {
 89  
         try
 90  
         {
 91  0
             Source sourceDoc = this.getXmlSource(src);
 92  0
             if (sourceDoc == null)
 93  
             {
 94  0
                 return null;
 95  
             }
 96  
 
 97  0
             ResultHolder holder = getResultHolder(returnClass);
 98  0
             if (holder == null)
 99  
             {
 100  0
                 holder = getResultHolder(src.getClass());
 101  
             }
 102  
 
 103  0
             DefaultErrorListener errorListener = new DefaultErrorListener(this);
 104  0
             Transformer transformer = null;
 105  
             Object result;
 106  
 
 107  
             try
 108  
             {
 109  0
                 transformer = (Transformer) transformerPool.borrowObject();
 110  
 
 111  0
                 transformer.setErrorListener(errorListener);
 112  0
                 transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
 113  
 
 114  0
                 transformer.transform(sourceDoc, holder.getResult());
 115  0
                 result = holder.getResultObject();
 116  
 
 117  0
                 if (errorListener.isError())
 118  
                 {
 119  0
                     throw errorListener.getException();
 120  
                 }
 121  0
             }
 122  
             finally
 123  
             {
 124  0
                 if (transformer != null)
 125  
                 {
 126  0
                     transformerPool.returnObject(transformer);
 127  
                 }
 128  0
             }
 129  
 
 130  0
             return result;
 131  
         }
 132  0
         catch (Exception e)
 133  
         {
 134  0
             throw new TransformerException(this, e);
 135  
         }
 136  
     }
 137  
 
 138  
     /**
 139  
      * Returns the name of the currently configured javax.xml.transform.Transformer
 140  
      * factory class used to create XSLT Transformers.
 141  
      * 
 142  
      * @return a TransformerFactory class name or <code>null</code> if none has
 143  
      *         been configured
 144  
      */
 145  
     public String getXslTransformerFactory()
 146  
     {
 147  0
         return xslTransformerFactoryClassName;
 148  
     }
 149  
 
 150  
     /**
 151  
      * Configures the javax.xml.transform.Transformer factory class
 152  
      * 
 153  
      * @param xslTransformerFactory the name of the TransformerFactory class to use
 154  
      */
 155  
     public void setXslTransformerFactory(String xslTransformerFactory)
 156  
     {
 157  0
         this.xslTransformerFactoryClassName = xslTransformerFactory;
 158  0
     }
 159  
 
 160  
     /**
 161  
      * @return Returns the xslFile.
 162  
      */
 163  
     public String getXslFile()
 164  
     {
 165  0
         return xslFile;
 166  
     }
 167  
 
 168  
     /**
 169  
      * @param xslFile The xslFile to set.
 170  
      */
 171  
     public void setXslFile(String xslFile)
 172  
     {
 173  0
         this.xslFile = xslFile;
 174  0
     }
 175  
 
 176  
     public String getXslt()
 177  
     {
 178  0
         return xslt;
 179  
     }
 180  
 
 181  
     public void setXslt(String xslt)
 182  
     {
 183  0
         this.xslt = xslt;
 184  0
     }
 185  
 
 186  
     /**
 187  
      * Returns the StreamSource corresponding to xslFile
 188  
      * 
 189  
      * @return The StreamSource
 190  
      * @throws InitialisationException
 191  
      */
 192  
     protected StreamSource getStreamSource() throws InitialisationException
 193  
     {
 194  0
         if (xslt != null)
 195  
         {
 196  0
             return new StreamSource(new StringReader(xslt));
 197  
         }
 198  
 
 199  0
         if (xslFile == null)
 200  
         {
 201  0
             throw new InitialisationException(CoreMessages.objectIsNull("xslFile"), this);
 202  
         }
 203  
 
 204  
         InputStream is;
 205  
         try
 206  
         {
 207  0
             is = IOUtils.getResourceAsStream(xslFile, getClass());
 208  
         }
 209  0
         catch (IOException e)
 210  
         {
 211  0
             throw new InitialisationException(e, this);
 212  0
         }
 213  0
         if (is != null)
 214  
         {
 215  0
             return new StreamSource(is);
 216  
         }
 217  
         else
 218  
         {
 219  0
             throw new InitialisationException(CoreMessages.failedToLoad(xslFile), this);
 220  
         }
 221  
     }
 222  
 
 223  
     // @Override
 224  
     public Object clone() throws CloneNotSupportedException
 225  
     {
 226  0
         XsltTransformer clone = (XsltTransformer) super.clone();
 227  
 
 228  
         try
 229  
         {
 230  0
             if (clone.nextTransformer == null)
 231  
             {
 232  0
                 clone.initialise();
 233  
             }
 234  
         }
 235  0
         catch (Exception e)
 236  
         {
 237  0
             throw new CloneNotSupportedException(e.getMessage());
 238  0
         }
 239  
 
 240  0
         return clone;
 241  
     }
 242  
 
 243  0
     protected class PooledXsltTransformerFactory extends BasePoolableObjectFactory
 244  
     {
 245  
         public Object makeObject() throws Exception
 246  
         {
 247  0
             StreamSource source = XsltTransformer.this.getStreamSource();
 248  0
             String factoryClassName = XsltTransformer.this.getXslTransformerFactory();
 249  0
             TransformerFactory factory = null;
 250  
 
 251  0
             if (StringUtils.isNotEmpty(factoryClassName))
 252  
             {
 253  0
                 factory = (TransformerFactory) ClassUtils.instanciateClass(factoryClassName,
 254  
                     ClassUtils.NO_ARGS, this.getClass());
 255  
             }
 256  
             else
 257  
             {
 258  
                 // fall back to JDK default
 259  0
                 factory = TransformerFactory.newInstance();
 260  
             }
 261  
 
 262  0
             factory.setURIResolver(new URIResolver()
 263  
             {
 264  0
                 public Source resolve(String href, String base)
 265  
                     throws javax.xml.transform.TransformerException
 266  
                 {
 267  
                     try
 268  
                     {
 269  0
                         return new StreamSource(IOUtils.getResourceAsStream(href, getClass()));
 270  
                     }
 271  0
                     catch (IOException e)
 272  
                     {
 273  0
                         throw new javax.xml.transform.TransformerException(e);
 274  
                     }
 275  
                 }
 276  
             });
 277  0
             return factory.newTransformer(source);
 278  
         }
 279  
     }
 280  
 
 281  
     protected class DefaultErrorListener implements ErrorListener
 282  
     {
 283  0
         private TransformerException e = null;
 284  
         private final UMOTransformer trans;
 285  
 
 286  
         public DefaultErrorListener(UMOTransformer trans)
 287  0
         {
 288  0
             this.trans = trans;
 289  0
         }
 290  
 
 291  
         public TransformerException getException()
 292  
         {
 293  0
             return e;
 294  
         }
 295  
 
 296  
         public boolean isError()
 297  
         {
 298  0
             return e != null;
 299  
         }
 300  
 
 301  
         public void error(javax.xml.transform.TransformerException exception)
 302  
             throws javax.xml.transform.TransformerException
 303  
         {
 304  0
             e = new TransformerException(trans, exception);
 305  0
         }
 306  
 
 307  
         public void fatalError(javax.xml.transform.TransformerException exception)
 308  
             throws javax.xml.transform.TransformerException
 309  
         {
 310  0
             e = new TransformerException(trans, exception);
 311  0
         }
 312  
 
 313  
         public void warning(javax.xml.transform.TransformerException exception)
 314  
             throws javax.xml.transform.TransformerException
 315  
         {
 316  0
             logger.warn(exception.getMessage());
 317  0
         }
 318  
     }
 319  
 
 320  
     /**
 321  
      * @return The current maximum number of allowable idle transformer objects in
 322  
      *         the pool
 323  
      */
 324  
     public int getMaxActiveTransformers()
 325  
     {
 326  0
         return transformerPool.getMaxActive();
 327  
     }
 328  
 
 329  
     /**
 330  
      * Sets the the current maximum number of idle transformer objects allowed in the
 331  
      * pool
 332  
      * 
 333  
      * @param maxIdleTransformers New maximum size to set
 334  
      */
 335  
     public void setMaxActiveTransformers(int maxActiveTransformers)
 336  
     {
 337  0
         transformerPool.setMaxActive(maxActiveTransformers);
 338  0
     }
 339  
 
 340  
     /**
 341  
      * @return The current maximum number of allowable idle transformer objects in
 342  
      *         the pool
 343  
      */
 344  
     public int getMaxIdleTransformers()
 345  
     {
 346  0
         return transformerPool.getMaxIdle();
 347  
     }
 348  
 
 349  
     /**
 350  
      * Sets the the current maximum number of idle transformer objects allowed in the
 351  
      * pool
 352  
      * 
 353  
      * @param maxIdleTransformers New maximum size to set
 354  
      */
 355  
     public void setMaxIdleTransformers(int maxIdleTransformers)
 356  
     {
 357  0
         transformerPool.setMaxIdle(maxIdleTransformers);
 358  0
     }
 359  
 
 360  
 }