001/*
002 * Copyright 2002-2014 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.servlet.view.xslt;
018
019import java.util.Properties;
020import javax.xml.transform.ErrorListener;
021import javax.xml.transform.URIResolver;
022
023import org.springframework.web.servlet.view.AbstractUrlBasedView;
024import org.springframework.web.servlet.view.UrlBasedViewResolver;
025
026/**
027 * {@link org.springframework.web.servlet.ViewResolver} implementation that
028 * resolves instances of {@link XsltView} by translating the supplied view name
029 * into the URL of the XSLT stylesheet.
030 *
031 * @author Rob Harrop
032 * @author Juergen Hoeller
033 * @since 2.0
034 */
035public class XsltViewResolver extends UrlBasedViewResolver {
036
037        private String sourceKey;
038
039        private URIResolver uriResolver;
040
041        private ErrorListener errorListener;
042
043        private boolean indent = true;
044
045        private Properties outputProperties;
046
047        private boolean cacheTemplates = true;
048
049
050        public XsltViewResolver() {
051                setViewClass(requiredViewClass());
052        }
053
054
055        @Override
056        protected Class<?> requiredViewClass() {
057                return XsltView.class;
058        }
059
060        /**
061         * Set the name of the model attribute that represents the XSLT Source.
062         * If not specified, the model map will be searched for a matching value type.
063         * <p>The following source types are supported out of the box:
064         * {@link javax.xml.transform.Source}, {@link org.w3c.dom.Document},
065         * {@link org.w3c.dom.Node}, {@link java.io.Reader}, {@link java.io.InputStream}
066         * and {@link org.springframework.core.io.Resource}.
067         */
068        public void setSourceKey(String sourceKey) {
069                this.sourceKey = sourceKey;
070        }
071
072        /**
073         * Set the URIResolver used in the transform.
074         * <p>The URIResolver handles calls to the XSLT {@code document()} function.
075         */
076        public void setUriResolver(URIResolver uriResolver) {
077                this.uriResolver = uriResolver;
078        }
079
080        /**
081         * Set an implementation of the {@link javax.xml.transform.ErrorListener}
082         * interface for custom handling of transformation errors and warnings.
083         * <p>If not set, a default
084         * {@link org.springframework.util.xml.SimpleTransformErrorListener} is
085         * used that simply logs warnings using the logger instance of the view class,
086         * and rethrows errors to discontinue the XML transformation.
087         * @see org.springframework.util.xml.SimpleTransformErrorListener
088         */
089        public void setErrorListener(ErrorListener errorListener) {
090                this.errorListener = errorListener;
091        }
092
093        /**
094         * Set whether the XSLT transformer may add additional whitespace when
095         * outputting the result tree.
096         * <p>Default is {@code true} (on); set this to {@code false} (off)
097         * to not specify an "indent" key, leaving the choice up to the stylesheet.
098         * @see javax.xml.transform.OutputKeys#INDENT
099         */
100        public void setIndent(boolean indent) {
101                this.indent = indent;
102        }
103
104        /**
105         * Set arbitrary transformer output properties to be applied to the stylesheet.
106         * <p>Any values specified here will override defaults that this view sets
107         * programmatically.
108         * @see javax.xml.transform.Transformer#setOutputProperty
109         */
110        public void setOutputProperties(Properties outputProperties) {
111                this.outputProperties = outputProperties;
112        }
113
114        /**
115         * Turn on/off the caching of the XSLT templates.
116         * <p>The default value is "true". Only set this to "false" in development,
117         * where caching does not seriously impact performance.
118         */
119        public void setCacheTemplates(boolean cacheTemplates) {
120                this.cacheTemplates = cacheTemplates;
121        }
122
123
124        @Override
125        protected AbstractUrlBasedView buildView(String viewName) throws Exception {
126                XsltView view = (XsltView) super.buildView(viewName);
127                view.setSourceKey(this.sourceKey);
128                if (this.uriResolver != null) {
129                        view.setUriResolver(this.uriResolver);
130                }
131                if (this.errorListener != null) {
132                        view.setErrorListener(this.errorListener);
133                }
134                view.setIndent(this.indent);
135                view.setOutputProperties(this.outputProperties);
136                view.setCacheTemplates(this.cacheTemplates);
137                return view;
138        }
139
140}