1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the  "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18/*
19 * $Id: SerializerSwitcher.java 468645 2006-10-28 06:57:24Z minchau $
20 */
21package org.apache.xalan.transformer;
22
23import java.io.OutputStream;
24import java.io.Writer;
25import java.util.Properties;
26
27import javax.xml.transform.OutputKeys;
28import javax.xml.transform.TransformerException;
29
30import org.apache.xml.serializer.Serializer;
31import org.apache.xml.serializer.SerializerFactory;
32import org.apache.xml.serializer.Method;
33import org.apache.xalan.templates.OutputProperties;
34
35import org.xml.sax.ContentHandler;
36
37/**
38 * This is a helper class that decides if Xalan needs to switch
39 * serializers, based on the first output element.
40 */
41public class SerializerSwitcher
42{
43
44  /**
45   * Switch to HTML serializer if element is HTML
46   *
47   *
48   * @param transformer Non-null transformer instance
49   * @param ns Namespace URI of the element
50   * @param localName Local part of name of element
51   *
52   * @throws TransformerException
53   */
54  public static void switchSerializerIfHTML(
55          TransformerImpl transformer, String ns, String localName)
56            throws TransformerException
57  {
58
59    if (null == transformer)
60      return;
61
62    if (((null == ns) || (ns.length() == 0))
63            && localName.equalsIgnoreCase("html"))
64    {
65      // System.out.println("transformer.getOutputPropertyNoDefault(OutputKeys.METHOD): "+
66      //              transformer.getOutputPropertyNoDefault(OutputKeys.METHOD));
67      // Access at level of hashtable to see if the method has been set.
68      if (null != transformer.getOutputPropertyNoDefault(OutputKeys.METHOD))
69        return;
70
71      // Getting the output properties this way won't cause a clone of
72      // the properties.
73      Properties prevProperties = transformer.getOutputFormat().getProperties();
74
75      // We have to make sure we get an output properties with the proper
76      // defaults for the HTML method.  The easiest way to do this is to
77      // have the OutputProperties class do it.
78      OutputProperties htmlOutputProperties = new OutputProperties(Method.HTML);
79
80      htmlOutputProperties.copyFrom(prevProperties, true);
81      Properties htmlProperties = htmlOutputProperties.getProperties();
82
83      try
84      {
85//        Serializer oldSerializer = transformer.getSerializer();
86        Serializer oldSerializer = null;
87
88        if (null != oldSerializer)
89        {
90          Serializer serializer =
91            SerializerFactory.getSerializer(htmlProperties);
92
93          Writer writer = oldSerializer.getWriter();
94
95          if (null != writer)
96            serializer.setWriter(writer);
97          else
98          {
99            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}
206