001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: SerializerSwitcher.java 468645 2006-10-28 06:57:24Z minchau $ 020 */ 021 package org.apache.xalan.transformer; 022 023 import java.io.OutputStream; 024 import java.io.Writer; 025 import java.util.Properties; 026 027 import javax.xml.transform.OutputKeys; 028 import javax.xml.transform.TransformerException; 029 030 import org.apache.xml.serializer.Serializer; 031 import org.apache.xml.serializer.SerializerFactory; 032 import org.apache.xml.serializer.Method; 033 import org.apache.xalan.templates.OutputProperties; 034 035 import org.xml.sax.ContentHandler; 036 037 /** 038 * This is a helper class that decides if Xalan needs to switch 039 * serializers, based on the first output element. 040 */ 041 public class SerializerSwitcher 042 { 043 044 /** 045 * Switch to HTML serializer if element is HTML 046 * 047 * 048 * @param transformer Non-null transformer instance 049 * @param ns Namespace URI of the element 050 * @param localName Local part of name of element 051 * 052 * @throws TransformerException 053 */ 054 public static void switchSerializerIfHTML( 055 TransformerImpl transformer, String ns, String localName) 056 throws TransformerException 057 { 058 059 if (null == transformer) 060 return; 061 062 if (((null == ns) || (ns.length() == 0)) 063 && localName.equalsIgnoreCase("html")) 064 { 065 // System.out.println("transformer.getOutputPropertyNoDefault(OutputKeys.METHOD): "+ 066 // transformer.getOutputPropertyNoDefault(OutputKeys.METHOD)); 067 // Access at level of hashtable to see if the method has been set. 068 if (null != transformer.getOutputPropertyNoDefault(OutputKeys.METHOD)) 069 return; 070 071 // Getting the output properties this way won't cause a clone of 072 // the properties. 073 Properties prevProperties = transformer.getOutputFormat().getProperties(); 074 075 // We have to make sure we get an output properties with the proper 076 // defaults for the HTML method. The easiest way to do this is to 077 // have the OutputProperties class do it. 078 OutputProperties htmlOutputProperties = new OutputProperties(Method.HTML); 079 080 htmlOutputProperties.copyFrom(prevProperties, true); 081 Properties htmlProperties = htmlOutputProperties.getProperties(); 082 083 try 084 { 085 // Serializer oldSerializer = transformer.getSerializer(); 086 Serializer oldSerializer = null; 087 088 if (null != oldSerializer) 089 { 090 Serializer serializer = 091 SerializerFactory.getSerializer(htmlProperties); 092 093 Writer writer = oldSerializer.getWriter(); 094 095 if (null != writer) 096 serializer.setWriter(writer); 097 else 098 { 099 OutputStream os = oldSerializer.getOutputStream(); 100 101 if (null != os) 102 serializer.setOutputStream(os); 103 } 104 105 // transformer.setSerializer(serializer); 106 107 ContentHandler ch = serializer.asContentHandler(); 108 109 transformer.setContentHandler(ch); 110 } 111 } 112 catch (java.io.IOException e) 113 { 114 throw new TransformerException(e); 115 } 116 } 117 } 118 119 /** 120 * Get the value of a property, without using the default properties. This 121 * can be used to test if a property has been explicitly set by the stylesheet 122 * or user. 123 * 124 * @param name The property name, which is a fully-qualified URI. 125 * 126 * @return The value of the property, or null if not found. 127 * 128 * @throws IllegalArgumentException If the property is not supported, 129 * and is not namespaced. 130 */ 131 private static String getOutputPropertyNoDefault(String qnameString, Properties props) 132 throws IllegalArgumentException 133 { 134 String value = (String)props.get(qnameString); 135 136 return value; 137 } 138 139 /** 140 * Switch to HTML serializer if element is HTML 141 * 142 * 143 * @param ns Namespace URI of the element 144 * @param localName Local part of name of element 145 * 146 * @throws TransformerException 147 * @return new contentHandler. 148 */ 149 public static Serializer switchSerializerIfHTML( 150 String ns, String localName, Properties props, Serializer oldSerializer) 151 throws TransformerException 152 { 153 Serializer newSerializer = oldSerializer; 154 155 if (((null == ns) || (ns.length() == 0)) 156 && localName.equalsIgnoreCase("html")) 157 { 158 // System.out.println("transformer.getOutputPropertyNoDefault(OutputKeys.METHOD): "+ 159 // transformer.getOutputPropertyNoDefault(OutputKeys.METHOD)); 160 // Access at level of hashtable to see if the method has been set. 161 if (null != getOutputPropertyNoDefault(OutputKeys.METHOD, props)) 162 return newSerializer; 163 164 // Getting the output properties this way won't cause a clone of 165 // the properties. 166 Properties prevProperties = props; 167 168 // We have to make sure we get an output properties with the proper 169 // defaults for the HTML method. The easiest way to do this is to 170 // have the OutputProperties class do it. 171 OutputProperties htmlOutputProperties = new OutputProperties(Method.HTML); 172 173 htmlOutputProperties.copyFrom(prevProperties, true); 174 Properties htmlProperties = htmlOutputProperties.getProperties(); 175 176 // try 177 { 178 if (null != oldSerializer) 179 { 180 Serializer serializer = 181 SerializerFactory.getSerializer(htmlProperties); 182 183 Writer writer = oldSerializer.getWriter(); 184 185 if (null != writer) 186 serializer.setWriter(writer); 187 else 188 { 189 OutputStream os = serializer.getOutputStream(); 190 191 if (null != os) 192 serializer.setOutputStream(os); 193 } 194 newSerializer = serializer; 195 } 196 } 197 // catch (java.io.IOException e) 198 // { 199 // throw new TransformerException(e); 200 // } 201 } 202 return newSerializer; 203 } 204 205 }