View Javadoc
1   /*
2    * reserved comment block
3    * DO NOT REMOVE OR ALTER!
4    */
5   /*
6    * Copyright 1999-2004 The Apache Software Foundation.
7    *
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  /*
21   * $Id: SerializerFactory.java,v 1.2.4.1 2005/09/15 08:15:24 suresh_emailid Exp $
22   */
23  package com.sun.org.apache.xml.internal.serializer;
24  
25  import java.util.Hashtable;
26  import java.util.Properties;
27  
28  import javax.xml.transform.OutputKeys;
29  
30  import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
31  import com.sun.org.apache.xml.internal.serializer.utils.Utils;
32  import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
33  import org.xml.sax.ContentHandler;
34  
35  /**
36   * This class is a public API, it is a factory for creating serializers.
37     *
38     * The properties object passed to the getSerializer() method should be created by
39     * the OutputPropertiesFactory. Although the properties object
40     * used to create a serializer does not need to be obtained
41     * from OutputPropertiesFactory,
42     * using this factory ensures that the default key/value properties
43     * are set for the given output "method".
44     *
45     * <p>
46     * The standard property keys supported are: "method", "version", "encoding",
47     * "omit-xml-declaration", "standalone", doctype-public",
48     * "doctype-system", "cdata-section-elements", "indent", "media-type".
49     * These property keys and their values are described in the XSLT recommendation,
50     * see {@link <a href="http://www.w3.org/TR/1999/REC-xslt-19991116"> XSLT 1.0 recommendation</a>}
51     *
52     * <p>
53     * The value of the "cdata-section-elements" property key is a whitespace
54     * separated list of elements. If the element is in a namespace then
55     * value is passed in this format: {uri}localName
56     *
57     * <p>
58     * The non-standard property keys supported are defined in {@link OutputPropertiesFactory}.
59     *
60     * @see OutputPropertiesFactory
61     * @see Method
62     * @see Serializer
63     */
64  public final class SerializerFactory
65  {
66    /**
67     * This constructor is private just to prevent the creation of such an object.
68     */
69  
70    private SerializerFactory() {
71  
72    }
73    /**
74     * Associates output methods to default output formats.
75     */
76    private static Hashtable m_formats = new Hashtable();
77  
78    /**
79     * Returns a serializer for the specified output method. The output method
80     * is specified by the value of the property associated with the "method" key.
81     * If no implementation exists that supports the specified output method
82     * an exception of some type will be thrown.
83     * For a list of the output "method" key values see {@link Method}.
84     *
85     * @param format The output format, minimally the "method" property must be set.
86     * @return A suitable serializer.
87     * @throws IllegalArgumentException if method is
88     * null or an appropriate serializer can't be found
89     * @throws Exception if the class for the serializer is found but does not
90     * implement ContentHandler.
91     * @throws WrappedRuntimeException if an exception is thrown while trying to find serializer
92     */
93    public static Serializer getSerializer(Properties format)
94    {
95        Serializer ser;
96  
97        try
98        {
99          String method = format.getProperty(OutputKeys.METHOD);
100 
101         if (method == null) {
102             String msg = Utils.messages.createMessage(
103                 MsgKey.ER_FACTORY_PROPERTY_MISSING,
104                 new Object[] { OutputKeys.METHOD});
105             throw new IllegalArgumentException(msg);
106         }
107 
108         String className =
109             format.getProperty(OutputPropertiesFactory.S_KEY_CONTENT_HANDLER);
110 
111 
112         if (null == className)
113         {
114             // Missing Content Handler property, load default using OutputPropertiesFactory
115             Properties methodDefaults =
116                 OutputPropertiesFactory.getDefaultMethodProperties(method);
117             className =
118             methodDefaults.getProperty(OutputPropertiesFactory.S_KEY_CONTENT_HANDLER);
119             if (null == className) {
120                 String msg = Utils.messages.createMessage(
121                     MsgKey.ER_FACTORY_PROPERTY_MISSING,
122                     new Object[] { OutputPropertiesFactory.S_KEY_CONTENT_HANDLER});
123                 throw new IllegalArgumentException(msg);
124             }
125 
126         }
127 
128 
129 
130         Class cls = ObjectFactory.findProviderClass(className, true);
131 
132         // _serializers.put(method, cls);
133 
134         Object obj = cls.newInstance();
135 
136         if (obj instanceof SerializationHandler)
137         {
138               // this is one of the supplied serializers
139             ser = (Serializer) cls.newInstance();
140             ser.setOutputFormat(format);
141         }
142         else
143         {
144               /*
145                *  This  must be a user defined Serializer.
146                *  It had better implement ContentHandler.
147                */
148                if (obj instanceof ContentHandler)
149                {
150 
151                   /*
152                    * The user defined serializer defines ContentHandler,
153                    * but we need to wrap it with ToXMLSAXHandler which
154                    * will collect SAX-like events and emit true
155                    * SAX ContentHandler events to the users handler.
156                    */
157                   className = SerializerConstants.DEFAULT_SAX_SERIALIZER;
158                   cls = ObjectFactory.findProviderClass(className, true);
159                   SerializationHandler sh =
160                       (SerializationHandler) cls.newInstance();
161                   sh.setContentHandler( (ContentHandler) obj);
162                   sh.setOutputFormat(format);
163 
164                   ser = sh;
165                }
166                else
167                {
168                   // user defined serializer does not implement
169                   // ContentHandler, ... very bad
170                    throw new Exception(
171                        Utils.messages.createMessage(
172                            MsgKey.ER_SERIALIZER_NOT_CONTENTHANDLER,
173                                new Object[] { className}));
174                }
175 
176         }
177       }
178       catch (Exception e)
179       {
180         throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(e);
181       }
182 
183       // If we make it to here ser is not null.
184       return ser;
185   }
186 }