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 import javax.xml.transform.TransformerFactoryConfigurationError;
26
27 import org.springframework.util.Assert;
28
29 /**
30 * Helper class for {@link Transformer} usage. Provides {@link #createTransformer()} and {@link #transform(Source,
31 * Result)}.
32 *
33 * @author Arjen Poutsma
34 * @since 3.0
35 */
36 public class TransformerHelper {
37
38 private volatile TransformerFactory transformerFactory;
39
40 private Class<? extends TransformerFactory> transformerFactoryClass;
41
42 /**
43 * Initializes a new instance of the {@code TransformerHelper}.
44 */
45 public TransformerHelper() {
46 }
47
48 /**
49 * Initializes a new instance of the {@code TransformerHelper} with the specified {@link TransformerFactory}.
50 */
51 public TransformerHelper(TransformerFactory transformerFactory) {
52 this.transformerFactory = transformerFactory;
53 }
54
55 /**
56 * Initializes a new instance of the {@code TransformerHelper} with the specified {@link TransformerFactory} class.
57 */
58 public TransformerHelper(Class<? extends TransformerFactory> transformerFactoryClass) {
59 setTransformerFactoryClass(transformerFactoryClass);
60 }
61
62 /**
63 * Specify the {@code TransformerFactory} class to use.
64 */
65 public void setTransformerFactoryClass(Class<? extends TransformerFactory> transformerFactoryClass) {
66 Assert.isAssignable(TransformerFactory.class, transformerFactoryClass);
67 this.transformerFactoryClass = transformerFactoryClass;
68 }
69
70 /**
71 * Instantiate a new TransformerFactory.
72 * <p/>
73 * The default implementation simply calls {@link TransformerFactory#newInstance()}. If a {@link
74 * #setTransformerFactoryClass transformerFactoryClass} has been specified explicitly, the default constructor of
75 * the specified class will be called instead.
76 * <p/>
77 * Can be overridden in subclasses.
78 *
79 * @param transformerFactoryClass the specified factory class (if any)
80 * @return the new TransactionFactory instance
81 * @see #setTransformerFactoryClass
82 * @see #getTransformerFactory()
83 */
84 protected TransformerFactory newTransformerFactory(Class<? extends TransformerFactory> transformerFactoryClass) {
85 if (transformerFactoryClass != null) {
86 try {
87 return transformerFactoryClass.newInstance();
88 }
89 catch (Exception ex) {
90 throw new TransformerFactoryConfigurationError(ex,
91 "Could not instantiate TransformerFactory [" + transformerFactoryClass + "]");
92 }
93 }
94 else {
95 return TransformerFactory.newInstance();
96 }
97 }
98
99 /**
100 * Returns the {@code TransformerFactory}.
101 *
102 * @return the transformer factory
103 */
104 public TransformerFactory getTransformerFactory() {
105 TransformerFactory result = transformerFactory;
106 if (result == null) {
107 synchronized (this) {
108 result = transformerFactory;
109 if (result == null) {
110 transformerFactory = result = newTransformerFactory(transformerFactoryClass);
111 }
112 }
113 }
114 return result;
115 }
116
117 /**
118 * Creates a new {@code Transformer}. Must be called per thread, as transformers are not thread-safe.
119 *
120 * @return the created transformer
121 * @throws TransformerConfigurationException
122 * if thrown by JAXP methods
123 */
124 public Transformer createTransformer() throws TransformerConfigurationException {
125 return getTransformerFactory().newTransformer();
126 }
127
128 /**
129 * Transforms the given {@link Source} to the given {@link Result}. Creates a new {@link Transformer} for every
130 * call, as transformers are not thread-safe.
131 *
132 * @param source the source to transform from
133 * @param result the result to transform to
134 * @throws TransformerException if thrown by JAXP methods
135 */
136 public void transform(Source source, Result result) throws TransformerException {
137 Transformer transformer = createTransformer();
138 transformer.transform(source, result);
139 }
140
141 }