001/* 002 * Copyright 2002-2017 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; 020 021import javax.xml.transform.ErrorListener; 022import javax.xml.transform.URIResolver; 023 024import org.springframework.lang.Nullable; 025import org.springframework.web.servlet.view.AbstractUrlBasedView; 026import org.springframework.web.servlet.view.UrlBasedViewResolver; 027 028/** 029 * {@link org.springframework.web.servlet.ViewResolver} implementation that 030 * resolves instances of {@link XsltView} by translating the supplied view name 031 * into the URL of the XSLT stylesheet. 032 * 033 * @author Rob Harrop 034 * @author Juergen Hoeller 035 * @since 2.0 036 */ 037public class XsltViewResolver extends UrlBasedViewResolver { 038 039 @Nullable 040 private String sourceKey; 041 042 @Nullable 043 private URIResolver uriResolver; 044 045 @Nullable 046 private ErrorListener errorListener; 047 048 private boolean indent = true; 049 050 @Nullable 051 private Properties outputProperties; 052 053 private boolean cacheTemplates = true; 054 055 056 public XsltViewResolver() { 057 setViewClass(requiredViewClass()); 058 } 059 060 061 @Override 062 protected Class<?> requiredViewClass() { 063 return XsltView.class; 064 } 065 066 /** 067 * Set the name of the model attribute that represents the XSLT Source. 068 * If not specified, the model map will be searched for a matching value type. 069 * <p>The following source types are supported out of the box: 070 * {@link javax.xml.transform.Source}, {@link org.w3c.dom.Document}, 071 * {@link org.w3c.dom.Node}, {@link java.io.Reader}, {@link java.io.InputStream} 072 * and {@link org.springframework.core.io.Resource}. 073 */ 074 public void setSourceKey(String sourceKey) { 075 this.sourceKey = sourceKey; 076 } 077 078 /** 079 * Set the URIResolver used in the transform. 080 * <p>The URIResolver handles calls to the XSLT {@code document()} function. 081 */ 082 public void setUriResolver(URIResolver uriResolver) { 083 this.uriResolver = uriResolver; 084 } 085 086 /** 087 * Set an implementation of the {@link javax.xml.transform.ErrorListener} 088 * interface for custom handling of transformation errors and warnings. 089 * <p>If not set, a default 090 * {@link org.springframework.util.xml.SimpleTransformErrorListener} is 091 * used that simply logs warnings using the logger instance of the view class, 092 * and rethrows errors to discontinue the XML transformation. 093 * @see org.springframework.util.xml.SimpleTransformErrorListener 094 */ 095 public void setErrorListener(ErrorListener errorListener) { 096 this.errorListener = errorListener; 097 } 098 099 /** 100 * Set whether the XSLT transformer may add additional whitespace when 101 * outputting the result tree. 102 * <p>Default is {@code true} (on); set this to {@code false} (off) 103 * to not specify an "indent" key, leaving the choice up to the stylesheet. 104 * @see javax.xml.transform.OutputKeys#INDENT 105 */ 106 public void setIndent(boolean indent) { 107 this.indent = indent; 108 } 109 110 /** 111 * Set arbitrary transformer output properties to be applied to the stylesheet. 112 * <p>Any values specified here will override defaults that this view sets 113 * programmatically. 114 * @see javax.xml.transform.Transformer#setOutputProperty 115 */ 116 public void setOutputProperties(Properties outputProperties) { 117 this.outputProperties = outputProperties; 118 } 119 120 /** 121 * Turn on/off the caching of the XSLT templates. 122 * <p>The default value is "true". Only set this to "false" in development, 123 * where caching does not seriously impact performance. 124 */ 125 public void setCacheTemplates(boolean cacheTemplates) { 126 this.cacheTemplates = cacheTemplates; 127 } 128 129 130 @Override 131 protected AbstractUrlBasedView buildView(String viewName) throws Exception { 132 XsltView view = (XsltView) super.buildView(viewName); 133 if (this.sourceKey != null) { 134 view.setSourceKey(this.sourceKey); 135 } 136 if (this.uriResolver != null) { 137 view.setUriResolver(this.uriResolver); 138 } 139 if (this.errorListener != null) { 140 view.setErrorListener(this.errorListener); 141 } 142 view.setIndent(this.indent); 143 if (this.outputProperties != null) { 144 view.setOutputProperties(this.outputProperties); 145 } 146 view.setCacheTemplates(this.cacheTemplates); 147 return view; 148 } 149 150}