1 /*
2  * Copyright 2005-2010 the original author or authors.
3  *
4  * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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
17 package org.springframework.xml.transform;
18
19 import javax.xml.transform.Result;
20 import javax.xml.transform.Source;
21 import javax.xml.transform.Transformer;
22 import javax.xml.transform.TransformerConfigurationException;
23 import javax.xml.transform.TransformerException;
24 import javax.xml.transform.TransformerFactory;
25
26 import org.springframework.util.Assert;
27
28 /**
29  * Helper class for {@link Transformer} usage. Provides {@link #createTransformer()} and {@link #transform(Source,
30  * Result)}.
31  *
32  * @author Arjen Poutsma
33  * @since 3.0
34  */

35 public class TransformerHelper {
36
37     private volatile TransformerFactory transformerFactory;
38
39     private Class<? extends TransformerFactory> transformerFactoryClass;
40
41     /**
42      * Initializes a new instance of the {@code TransformerHelper}.
43      */

44     public TransformerHelper() {
45     }
46
47     /**
48      * Initializes a new instance of the {@code TransformerHelper} with the specified {@link TransformerFactory}.
49      */

50     public TransformerHelper(TransformerFactory transformerFactory) {
51         this.transformerFactory = transformerFactory;
52     }
53
54     /**
55      * Initializes a new instance of the {@code TransformerHelper} with the specified {@link TransformerFactory} class.
56      */

57     public TransformerHelper(Class<? extends TransformerFactory> transformerFactoryClass) {
58         setTransformerFactoryClass(transformerFactoryClass);
59     }
60
61     /**
62      * Specify the {@code TransformerFactory} class to use.
63      */

64     public void setTransformerFactoryClass(Class<? extends TransformerFactory> transformerFactoryClass) {
65         Assert.isAssignable(TransformerFactory.class, transformerFactoryClass);
66         this.transformerFactoryClass = transformerFactoryClass;
67     }
68
69     /**
70      * Instantiate a new TransformerFactory.
71      *
72      * <p>The default implementation simply calls {@link TransformerFactory#newInstance()}. If a {@link
73      * #setTransformerFactoryClass transformerFactoryClass} has been specified explicitly, the default constructor of
74      * the specified class will be called instead.
75      *
76      * <p>Can be overridden in subclasses.
77      *
78      * @param transformerFactoryClass the specified factory class (if any)
79      * @return the new TransactionFactory instance
80      * @see #setTransformerFactoryClass
81      * @see #getTransformerFactory()
82      */

83     protected TransformerFactory newTransformerFactory(Class<? extends TransformerFactory> transformerFactoryClass) {
84         if (transformerFactoryClass != null) {
85             TransformerFactory transformerFactory = TransformerFactoryUtils.newInstance(transformerFactoryClass);
86             return transformerFactory;
87         } else {
88             TransformerFactory transformerFactory = TransformerFactoryUtils.newInstance();
89             return transformerFactory;
90         }
91     }
92
93     /**
94      * Returns the {@code TransformerFactory}.
95      *
96      * @return the transformer factory
97      */

98     public TransformerFactory getTransformerFactory() {
99         TransformerFactory result = transformerFactory;
100         if (result == null) {
101             synchronized (this) {
102                 result = transformerFactory;
103                 if (result == null) {
104                     transformerFactory = result = newTransformerFactory(transformerFactoryClass);
105                 }
106             }
107         }
108         return result;
109     }
110
111     /**
112      * Creates a new {@code Transformer}. Must be called per thread, as transformers are not thread-safe.
113      *
114      * @return the created transformer
115      * @throws TransformerConfigurationException
116      *            if thrown by JAXP methods
117      */

118     public Transformer createTransformer() throws TransformerConfigurationException {
119         return getTransformerFactory().newTransformer();
120     }
121
122     /**
123      * Transforms the given {@link Source} to the given {@link Result}. Creates a new {@link Transformer} for every
124      * call, as transformers are not thread-safe.
125      *
126      * @param source the source to transform from
127      * @param result the result to transform to
128      * @throws TransformerException if thrown by JAXP methods
129      */

130     public void transform(Source source, Result result) throws TransformerException {
131         Transformer transformer = createTransformer();
132         transformer.transform(source, result);
133     }
134
135 }
136