KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mule > transformers > AbstractTransformer


1 /*
2  * $Id: AbstractTransformer.java 4323 2006-12-19 15:55:15Z lajos $
3  * --------------------------------------------------------------------------------------
4  * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
5  *
6  * The software in this package is published under the terms of the MuleSource MPL
7  * license, a copy of which has been included with this distribution in the
8  * LICENSE.txt file.
9  */

10
11 package org.mule.transformers;
12
13 import org.mule.MuleManager;
14 import org.mule.config.i18n.Message;
15 import org.mule.config.i18n.Messages;
16 import org.mule.providers.NullPayload;
17 import org.mule.umo.UMOMessage;
18 import org.mule.umo.endpoint.UMOImmutableEndpoint;
19 import org.mule.umo.lifecycle.InitialisationException;
20 import org.mule.umo.transformer.TransformerException;
21 import org.mule.umo.transformer.UMOTransformer;
22 import org.mule.util.ClassUtils;
23 import org.mule.util.StringMessageUtils;
24
25 import java.util.ArrayList JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28
29 import org.apache.commons.beanutils.BeanUtils;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32
33 /**
34  * <code>AbstractTransformer</code> Is a base class for all transformers.
35  * Transformations transform one object into another.
36  */

37
38 public abstract class AbstractTransformer implements UMOTransformer
39 {
40     /**
41      * The fully qualified class name of the fallback <code>Transformer</code>
42      * implementation class to use, if no other can be found.
43      */

44     public static final String JavaDoc TRANSFORMER_DEFAULT = "org.mule.transformers.NoActionTransformer";
45
46     /**
47      * logger used by this class
48      */

49     protected transient Log logger = LogFactory.getLog(getClass());
50
51     protected Class JavaDoc returnClass = null;
52
53     protected String JavaDoc name = null;
54
55     protected UMOImmutableEndpoint endpoint = null;
56
57     protected List JavaDoc sourceTypes = new ArrayList JavaDoc();
58
59     /**
60      * This is the following transformer in the chain of transformers.
61      */

62     protected UMOTransformer nextTransformer;
63
64     private boolean ignoreBadInput = false;
65
66     /**
67      * default constructor required for discovery
68      */

69     public AbstractTransformer()
70     {
71         name = generateTransformerName();
72     }
73
74     protected Object JavaDoc checkReturnClass(Object JavaDoc object) throws TransformerException
75     {
76         if (returnClass != null)
77         {
78             if (!returnClass.isInstance(object))
79             {
80                 throw new TransformerException(new Message(Messages.TRANSFORM_X_UNEXPECTED_TYPE_X, object
81                     .getClass().getName(), returnClass.getName()), this);
82             }
83         }
84
85         if (logger.isDebugEnabled())
86         {
87             logger.debug("The transformed object is of expected type. Type is: "
88                             + object.getClass().getName());
89         }
90
91         return object;
92     }
93
94     protected synchronized void registerSourceType(Class JavaDoc aClass)
95     {
96         if (aClass.equals(Object JavaDoc.class))
97         {
98             logger.debug("java.lang.Object has been added as an acceptable sourcetype for this transformer, there will be no source type checking performed");
99         }
100
101         sourceTypes.add(aClass);
102     }
103
104     protected synchronized void unregisterSourceType(Class JavaDoc aClass)
105     {
106         sourceTypes.remove(aClass);
107     }
108
109     /**
110      * @deprecated simply iterate over sourceTypes directly
111      */

112     protected Iterator JavaDoc getSourceTypeClassesIterator()
113     {
114         return sourceTypes.iterator();
115     }
116
117     /**
118      * @return transformer name
119      */

120     public String JavaDoc getName()
121     {
122         if (name == null)
123         {
124             setName(ClassUtils.getShortClassName(getClass()));
125         }
126         return name;
127     }
128
129     /**
130      * @param string
131      */

132     public void setName(String JavaDoc string)
133     {
134         logger.debug("Setting transformer name to: " + name);
135         name = string;
136     }
137
138     /*
139      * (non-Javadoc)
140      *
141      * @see org.mule.transformers.Transformer#getReturnClass()
142      */

143     public Class JavaDoc getReturnClass()
144     {
145         return returnClass;
146     }
147
148     /*
149      * (non-Javadoc)
150      *
151      * @see org.mule.transformers.Transformer#setReturnClass(java.lang.String)
152      */

153     public void setReturnClass(Class JavaDoc newClass)
154     {
155         returnClass = newClass;
156     }
157
158     public boolean isSourceTypeSupported(Class JavaDoc aClass)
159     {
160         return isSourceTypeSupported(aClass, false);
161     }
162
163     public boolean isSourceTypeSupported(Class JavaDoc aClass, boolean exactMatch)
164     {
165         int numTypes = sourceTypes.size();
166
167         if (numTypes == 0)
168         {
169             return !exactMatch;
170         }
171
172         for (int i = 0; i < numTypes; i++)
173         {
174             Class JavaDoc anotherClass = (Class JavaDoc)sourceTypes.get(i);
175             if (exactMatch)
176             {
177                 if (anotherClass.equals(aClass))
178                 {
179                     return true;
180                 }
181             }
182             else if (anotherClass.isAssignableFrom(aClass))
183             {
184                 return true;
185             }
186         }
187
188         return false;
189     }
190
191     /**
192      * Transforms the object.
193      *
194      * @param src The source object to transform.
195      * @return The transformed object
196      */

197     public final Object JavaDoc transform(Object JavaDoc src) throws TransformerException
198     {
199         String JavaDoc encoding = null;
200
201         if (src instanceof UMOMessage && !isSourceTypeSupported(UMOMessage.class))
202         {
203             encoding = ((UMOMessage)src).getEncoding();
204             src = ((UMOMessage)src).getPayload();
205         }
206
207         if (encoding == null && endpoint != null)
208         {
209             encoding = endpoint.getEncoding();
210         }
211
212         // last resort
213
if (encoding == null)
214         {
215             encoding = MuleManager.getConfiguration().getEncoding();
216         }
217
218         if (!isSourceTypeSupported(src.getClass()))
219         {
220             if (ignoreBadInput)
221             {
222                 logger.debug("Source type is incompatible with this transformer and property 'ignoreBadInput' is set to true, so the transformer chain will continue.");
223                 return src;
224             }
225             else
226             {
227                 throw new TransformerException(new Message(Messages.TRANSFORM_X_UNSUPORTED_TYPE_X_ENDPOINT_X,
228                     getName(), src.getClass().getName(), endpoint.getEndpointURI()), this);
229             }
230         }
231
232         if (logger.isDebugEnabled())
233         {
234             logger.debug("Applying transformer " + getName() + " (" + getClass().getName() + ")");
235             logger.debug("Object before transform: "
236                             + StringMessageUtils.truncate(StringMessageUtils.toString(src), 200, false));
237         }
238
239         Object JavaDoc result = doTransform(src, encoding);
240         if (result == null)
241         {
242             result = new NullPayload();
243         }
244
245         if (logger.isDebugEnabled())
246         {
247             logger.debug("Object after transform: "
248                             + StringMessageUtils.truncate(StringMessageUtils.toString(result), 200, false));
249         }
250
251         result = checkReturnClass(result);
252
253         if (nextTransformer != null)
254         {
255             logger.debug("Following transformer in the chain is " + nextTransformer.getName() + " ("
256                             + nextTransformer.getClass().getName() + ")");
257             result = nextTransformer.transform(result);
258         }
259
260         return result;
261     }
262
263     public UMOImmutableEndpoint getEndpoint()
264     {
265         return endpoint;
266     }
267
268     /*
269      * (non-Javadoc)
270      *
271      * @see org.mule.umo.transformer.UMOTransformer#setConnector(org.mule.umo.provider.UMOConnector)
272      */

273     public void setEndpoint(UMOImmutableEndpoint endpoint)
274     {
275         this.endpoint = endpoint;
276         UMOTransformer trans = nextTransformer;
277         while (trans != null && endpoint != null)
278         {
279             trans.setEndpoint(endpoint);
280             trans = trans.getNextTransformer();
281         }
282     }
283
284     protected abstract Object JavaDoc doTransform(Object JavaDoc src, String JavaDoc encoding) throws TransformerException;
285
286     /*
287      * (non-Javadoc)
288      *
289      * @see org.mule.umo.transformer.UMOTransformer#getNextTransformer()
290      */

291     public UMOTransformer getNextTransformer()
292     {
293         return nextTransformer;
294     }
295
296     /*
297      * (non-Javadoc)
298      *
299      * @see org.mule.umo.transformer.UMOTransformer#setNextTransformer(org.mule.umo.transformer.UMOTransformer)
300      */

301     public void setNextTransformer(UMOTransformer nextTransformer)
302     {
303         this.nextTransformer = nextTransformer;
304     }
305
306     /*
307      * (non-Javadoc)
308      *
309      * @see java.lang.Object#clone()
310      */

311     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc
312     {
313         try
314         {
315             return BeanUtils.cloneBean(this);
316         }
317         catch (Exception JavaDoc e)
318         {
319             throw new CloneNotSupportedException JavaDoc("Failed to clone transformer: " + e.getMessage());
320         }
321     }
322
323     /**
324      * Will return the return type for the last transformer in the chain
325      *
326      * @return the last transformers return type
327      */

328     public Class JavaDoc getFinalReturnClass()
329     {
330         UMOTransformer tempTrans = this;
331         UMOTransformer returnTrans = this;
332         while (tempTrans != null)
333         {
334             returnTrans = tempTrans;
335             tempTrans = tempTrans.getNextTransformer();
336         }
337         return returnTrans.getReturnClass();
338     }
339
340     /**
341      * Template method were deriving classes can do any initialisation after the
342      * properties have been set on this transformer
343      *
344      * @throws InitialisationException
345      */

346     public void initialise() throws InitialisationException
347     {
348         // nothing to do
349
}
350
351     protected String JavaDoc generateTransformerName()
352     {
353         String JavaDoc name = getClass().getName();
354         int i = name.lastIndexOf(".");
355         if (i > -1)
356         {
357             name = name.substring(i + 1);
358         }
359         return name;
360     }
361
362     /**
363      * Convenience method to register source types using a bean property setter
364      *
365      * @param type the fully qualified class name
366      * @throws ClassNotFoundException is thrown if the class is not on theclasspath
367      */

368     public void setSourceType(String JavaDoc type) throws ClassNotFoundException JavaDoc
369     {
370         Class JavaDoc clazz = ClassUtils.loadClass(type, getClass());
371         registerSourceType(clazz);
372     }
373
374     /**
375      * Where multiple source types are listed, this method only returns the first
376      * one. The full list of supported source types can also be obtained using
377      * <code>getSourceTypesIterator()</code>
378      *
379      * @return the first SourceType on the transformer or java.lang.Object if there
380      * is no source type set
381      */

382     public String JavaDoc getSourceType()
383     {
384         Class JavaDoc c = null;
385         if (sourceTypes.size() > 0)
386         {
387             c = (Class JavaDoc)sourceTypes.get(0);
388         }
389         if (c == null)
390         {
391             c = Object JavaDoc.class;
392         }
393         return c.getName();
394     }
395
396     public boolean isIgnoreBadInput()
397     {
398         return ignoreBadInput;
399     }
400
401     public void setIgnoreBadInput(boolean ignoreBadInput)
402     {
403         this.ignoreBadInput = ignoreBadInput;
404     }
405
406     public String JavaDoc toString()
407     {
408         return "Transformer{" + "name='" + name + "'" + ", returnClass=" + ignoreBadInput + ", returnClass="
409                         + ignoreBadInput + ", sourceTypes=" + sourceTypes + "}";
410     }
411
412     public boolean isAcceptNull()
413     {
414         return false;
415     }
416 }
417
Popular Tags