Source code: org/apache/axis/encoding/ser/BaseSerializerFactory.java
1 /*
2 * Copyright 2001-2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.axis.encoding.ser;
18
19 import org.apache.axis.Constants;
20 import org.apache.axis.components.logger.LogFactory;
21 import org.apache.axis.encoding.Serializer;
22 import org.apache.axis.encoding.SerializerFactory;
23 import org.apache.axis.utils.Messages;
24 import org.apache.commons.logging.Log;
25
26 import javax.xml.namespace.QName;
27 import javax.xml.rpc.JAXRPCException;
28 import java.lang.reflect.Constructor;
29 import java.lang.reflect.InvocationTargetException;
30 import java.lang.reflect.Method;
31 import java.util.Iterator;
32 import java.util.Vector;
33
34 /**
35 * Base class for Axis Serialization Factory classes for code reuse
36 *
37 * @author Rich Scheuerle <scheu@us.ibm.com>
38 */
39 public abstract class BaseSerializerFactory extends BaseFactory
40 implements SerializerFactory {
41
42 protected static Log log =
43 LogFactory.getLog(BaseSerializerFactory.class.getName());
44
45 transient static Vector mechanisms = null;
46
47 protected Class serClass = null;
48 protected QName xmlType = null;
49 protected Class javaType = null;
50
51 transient protected Serializer ser = null;
52 transient protected Constructor serClassConstructor = null;
53 transient protected Method getSerializer = null;
54
55 /**
56 * Constructor
57 * @param serClass is the class of the Serializer
58 * Sharing is only valid for xml primitives.
59 */
60 public BaseSerializerFactory(Class serClass) {
61 if (!Serializer.class.isAssignableFrom(serClass)) {
62 throw new ClassCastException(
63 Messages.getMessage("BadImplementation00",
64 serClass.getName(),
65 Serializer.class.getName()));
66 }
67 this.serClass = serClass;
68 }
69
70 public BaseSerializerFactory(Class serClass,
71 QName xmlType, Class javaType) {
72 this(serClass);
73 this.xmlType = xmlType;
74 this.javaType = javaType;
75 }
76
77 public javax.xml.rpc.encoding.Serializer
78 getSerializerAs(String mechanismType)
79 throws JAXRPCException {
80 synchronized (this) {
81 if (ser==null) {
82 ser = getSerializerAsInternal(mechanismType);
83 }
84 return ser;
85 }
86 }
87
88 protected Serializer getSerializerAsInternal(String mechanismType)
89 throws JAXRPCException {
90 // Try getting a specialized Serializer
91 Serializer serializer = getSpecialized(mechanismType);
92
93 // Try getting a general purpose Serializer via constructor
94 // invocation
95 if (serializer == null) {
96 serializer = getGeneralPurpose(mechanismType);
97 }
98
99 try {
100 // If not successfull, try newInstance
101 if (serializer == null) {
102 serializer = (Serializer) serClass.newInstance();
103 }
104 } catch (Exception e) {
105 throw new JAXRPCException(
106 Messages.getMessage("CantGetSerializer",
107 serClass.getName()),
108 e);
109 }
110 return serializer;
111 }
112
113 /**
114 * Obtains a serializer by invoking <constructor>(javaType, xmlType)
115 * on the serClass.
116 */
117 protected Serializer getGeneralPurpose(String mechanismType) {
118 if (javaType != null && xmlType != null) {
119 Constructor serClassConstructor = getSerClassConstructor();
120 if (serClassConstructor != null) {
121 try {
122 return (Serializer)
123 serClassConstructor.newInstance(
124 new Object[] {javaType, xmlType});
125 } catch (InstantiationException e) {
126 if(log.isDebugEnabled()) {
127 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
128 }
129 } catch (IllegalAccessException e) {
130 if(log.isDebugEnabled()) {
131 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
132 }
133 } catch (InvocationTargetException e) {
134 if(log.isDebugEnabled()) {
135 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
136 }
137 }
138 }
139 }
140 return null;
141 }
142
143
144 private static final Class[] CLASS_QNAME_CLASS = new Class[] { Class.class, QName.class };
145
146 /**
147 * return constructor for class if any
148 */
149 private Constructor getConstructor(Class clazz) {
150 try {
151 return clazz.getConstructor(CLASS_QNAME_CLASS);
152 } catch (NoSuchMethodException e) {}
153 return null;
154 }
155
156 /**
157 * Obtains a serializer by invoking getSerializer method in the
158 * javaType class or its Helper class.
159 */
160 protected Serializer getSpecialized(String mechanismType) {
161 if (javaType != null && xmlType != null) {
162 Method getSerializer = getGetSerializer();
163 if (getSerializer != null) {
164 try {
165 return (Serializer)
166 getSerializer.invoke(
167 null,
168 new Object[] {mechanismType,
169 javaType,
170 xmlType});
171 } catch (IllegalAccessException e) {
172 if(log.isDebugEnabled()) {
173 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
174 }
175 } catch (InvocationTargetException e) {
176 if(log.isDebugEnabled()) {
177 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
178 }
179 }
180 }
181 }
182 return null;
183 }
184
185 /**
186 * Returns a list of all XML processing mechanism types supported
187 * by this SerializerFactory.
188 *
189 * @return List of unique identifiers for the supported XML
190 * processing mechanism types
191 */
192 public Iterator getSupportedMechanismTypes() {
193 if (mechanisms == null) {
194 mechanisms = new Vector(1);
195 mechanisms.add(Constants.AXIS_SAX);
196 }
197 return mechanisms.iterator();
198 }
199
200 /**
201 * get xmlType
202 * @return xmlType QName for this factory
203 */
204 public QName getXMLType() {
205 return xmlType;
206 }
207
208 /**
209 * get javaType
210 * @return javaType Class for this factory
211 */
212 public Class getJavaType() {
213 return javaType;
214 }
215
216 /**
217 * Utility method that intospects on a factory class to decide how to
218 * create the factory. Tries in the following order:
219 * public static create(Class javaType, QName xmlType)
220 * public <constructor>(Class javaType, QName xmlType)
221 * public <constructor>()
222 * @param factory class
223 * @param xmlType
224 * @param javaType
225 */
226 public static SerializerFactory createFactory(Class factory,
227 Class javaType,
228 QName xmlType) {
229 if (factory == null) {
230 return null;
231 }
232
233 try {
234 if (factory == BeanSerializerFactory.class) {
235 return new BeanSerializerFactory(javaType, xmlType);
236 } else if (factory == SimpleSerializerFactory.class) {
237 return new SimpleSerializerFactory(javaType, xmlType);
238 } else if (factory == EnumSerializerFactory.class) {
239 return new EnumSerializerFactory(javaType, xmlType);
240 } else if (factory == ElementSerializerFactory.class) {
241 return new ElementSerializerFactory();
242 } else if (factory == SimpleListSerializerFactory.class) {
243 return new SimpleListSerializerFactory(javaType, xmlType);
244 }
245 } catch (Exception e) {
246 if (log.isDebugEnabled()) {
247 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
248 }
249 return null;
250 }
251
252 SerializerFactory sf = null;
253 try {
254 Method method =
255 factory.getMethod("create", CLASS_QNAME_CLASS);
256 sf = (SerializerFactory)
257 method.invoke(null,
258 new Object[] {javaType, xmlType});
259 } catch (NoSuchMethodException e) {
260 if(log.isDebugEnabled()) {
261 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
262 }
263 } catch (IllegalAccessException e) {
264 if(log.isDebugEnabled()) {
265 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
266 }
267 } catch (InvocationTargetException e) {
268 if(log.isDebugEnabled()) {
269 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
270 }
271 }
272
273 if (sf == null) {
274 try {
275 Constructor constructor =
276 factory.getConstructor(CLASS_QNAME_CLASS);
277 sf = (SerializerFactory)
278 constructor.newInstance(
279 new Object[] {javaType, xmlType});
280 } catch (NoSuchMethodException e) {
281 if(log.isDebugEnabled()) {
282 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
283 }
284 } catch (InstantiationException e) {
285 if(log.isDebugEnabled()) {
286 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
287 }
288 } catch (IllegalAccessException e) {
289 if(log.isDebugEnabled()) {
290 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
291 }
292 } catch (InvocationTargetException e) {
293 if(log.isDebugEnabled()) {
294 log.debug(org.apache.axis.utils.Messages.getMessage("exception00"), e);
295 }
296 }
297 }
298
299 if (sf == null) {
300 try {
301 sf = (SerializerFactory) factory.newInstance();
302 } catch (InstantiationException e) {
303 } catch (IllegalAccessException e) {}
304 }
305 return sf;
306 }
307
308 /**
309 * Returns the getSerializer.
310 * @return Method
311 */
312 protected Method getGetSerializer() {
313 if (getSerializer == null) {
314 getSerializer = getMethod(javaType, "getSerializer");
315 }
316 return getSerializer;
317 }
318
319 /**
320 * Returns the serClassConstructor.
321 * @return Constructor
322 */
323 protected Constructor getSerClassConstructor() {
324 if (serClassConstructor == null) {
325 serClassConstructor = getConstructor(serClass);
326 }
327 return serClassConstructor;
328 }
329
330 }