View Javadoc

1   /*
2    * $Id: StringToXMLMessage.java 7976 2007-08-21 14:26:13Z dirk.olmes $
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 CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.providers.oracle.jms.transformers;
12  
13  import org.mule.config.i18n.MessageFactory;
14  import org.mule.providers.jms.JmsConnector;
15  import org.mule.providers.oracle.jms.OracleJmsConnector;
16  import org.mule.transformers.AbstractEventAwareTransformer;
17  import org.mule.umo.UMOEventContext;
18  import org.mule.umo.transformer.TransformerException;
19  import org.mule.util.StringMessageUtils;
20  
21  import java.io.IOException;
22  import java.io.Writer;
23  import java.sql.SQLException;
24  
25  import javax.jms.JMSException;
26  import javax.jms.Session;
27  
28  import oracle.jms.AQjmsSession;
29  import oracle.jms.AdtMessage;
30  import oracle.sql.CLOB;
31  import oracle.xdb.XMLType;
32  
33  /**
34   * Transformer for use with the Oracle Jms Connector. Expects a string containing
35   * properly-formed XML. Creates a JMS message whose payload is Oracle's native XML
36   * data type.
37   * 
38   * @see OracleJmsConnector
39   * @see <a href="http://otn.oracle.com/pls/db102/">XML DB Developer's Guide</a>
40   */
41  public class StringToXMLMessage extends AbstractEventAwareTransformer
42  {
43      public StringToXMLMessage()
44      {
45          super();
46          registerSourceType(String.class);
47          registerSourceType(byte[].class);
48          setReturnClass(AdtMessage.class);
49      }
50  
51      /**
52       * @param src - String or byte[] containing properly-formed XML.
53       * @return JMS message whose payload is Oracle's native XML data type
54       */
55      public Object transform(Object src, String encoding, UMOEventContext context) throws TransformerException
56      {
57          Session session;
58          AdtMessage message;
59          XMLType xmltype;
60  
61          try
62          {
63              // Get the Oracle AQ session for this event.
64              if (endpoint.getTransactionConfig().isTransacted() == false)
65              {
66                  // The tranformation _must_ occur within the same session used previously by the 
67                  // dispatcher, otherwise we get "JMS-204: An error occurred in the AQ JNI layer"
68                  // Using a transacted endpoint should ensure that the same session is used.
69                  throw new TransformerException(MessageFactory.createStaticMessage("This transformer may only be used with a transacted endpoint.  Refer to http://mule.codehaus.org/display/MULE/Transaction+Management for more information."), this);
70              }
71              session = ((JmsConnector) endpoint.getConnector()).getSessionFromTransaction();
72              if (session == null) {
73                  throw new TransformerException(MessageFactory.createStaticMessage("No JMS session associated with this endpoint."), this);
74              }
75              if ((session instanceof AQjmsSession) == false) {
76                  throw new TransformerException(MessageFactory.createStaticMessage("Endpoint must be an OracleAQ session."), this);
77              }
78  
79              // Prepare the XML string.
80              String xml;
81              if (src instanceof byte[]) {
82                  xml = new String((byte[]) src, encoding);
83              }
84              else if (src instanceof String) {
85                  xml = (String) src;
86              }
87              else throw new TransformerException(MessageFactory.createStaticMessage("Object to transform is not one of the supported types for this transformer."), this);
88  
89              logger.debug("Creating an Oracle XMLType based on the following XML:\n" + StringMessageUtils.truncate(xml, 200, false));
90  
91              // Create a temporary CLOB and pass this to the XMLType.createXML() factory.
92              // Note: if we pass the xml string directly to XMLType.createXML() as a
93              // parameter, the character set is not preserved properly (probably a bug
94              // in the Oracle library).
95              CLOB clob = CLOB.createTemporary(((AQjmsSession) session).getDBConnection(), true, CLOB.DURATION_SESSION);
96              try {
97                  Writer clobStream = clob.getCharacterOutputStream();
98                  try {
99                      clobStream.write(xml);
100                 } finally {
101                     clobStream.close();
102                 }
103                 xmltype = XMLType.createXML(((AQjmsSession) session).getDBConnection(), clob);
104 
105                 // Create the JMS message.
106                 message = ((AQjmsSession) session).createAdtMessage();
107                 message.setAdtPayload(xmltype);
108                 return message;
109             } finally {
110                 // TODO Need to put this somewhere but apparently not here...
111                 //clob.freeTemporary();
112             }
113         }
114         catch (JMSException e) { throw new TransformerException(this, e); }
115         catch (SQLException e) { throw new TransformerException(this, e); }
116         catch (IOException e) { throw new TransformerException(this, e); }
117     }
118 }