/******************************************************************************* * Copyright (C) 2014, International Business Machines Corporation * All Rights Reserved *******************************************************************************/ package com.ibm.streamsx.messaging.jms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.List; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Session; import javax.jms.TextMessage; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import com.ibm.streams.operator.OutputTuple; import com.ibm.streams.operator.Tuple; import com.ibm.streams.operator.Type.MetaType; import com.ibm.streams.operator.types.RString; import com.ibm.streams.operator.types.ValueFactory; import com.ibm.streams.operator.types.XML; /** * * Message handler for text message class. * * For text message class, the following restrictions applies: * * Text messages must be encoded in UTF-8. For support of other encoding, use bytes message class. * * When the text message class is specified in the connection document, the native * schema must contain a single attribute of String. * * When the text message class is specified in the connection document, the input schema * for JMSSource must contain a single attribute of type rstring, ustring or xml. * When the text message class is specified in the connection document, the output schema * for JMSSink must contain a single attribute of type rstring, ustring or xml. * */ public class TextMessageHandler extends JMSMessageHandlerImpl { private int length; public TextMessageHandler(List<NativeSchema> nsa) { super(nsa); if (nsa.size() == 1) { NativeSchema nativeSchema = nsa.get(0); length = nativeSchema.getLength(); } } @Override public Message convertTupleToMessage(Tuple tuple, Session session) throws JMSException, UnsupportedEncodingException, ParserConfigurationException, TransformerException { TextMessage textMessage; synchronized (session) { textMessage = session.createTextMessage(); } MetaType attrType = tuple.getStreamSchema().getAttribute(0).getType().getMetaType(); String msgText = ""; //$NON-NLS-1$ if (attrType == MetaType.RSTRING || attrType == MetaType.USTRING) { // use getObject to avoid copying of the tuple Object tupleVal = tuple.getObject(0); if (tupleVal instanceof RString) { msgText = ((RString) tupleVal).getString(); } else if (tupleVal instanceof String) { msgText = (String) tupleVal; } } else if (attrType == MetaType.XML) { XML xmlValue = tuple.getXML(0); msgText = xmlValue.toString(); } // make sure message length is < the length specified in native schema if (length > 0 && msgText.length() > length) { msgText = msgText.substring(0, length); nTruncatedInserts.increment(); } textMessage.setText(msgText); return textMessage; } @Override public MessageAction convertMessageToTuple(Message message, OutputTuple tuple) throws JMSException, UnsupportedEncodingException { TextMessage textMessage = (TextMessage) message; // make sure message length is < the length specified in native schema String tupleStr = textMessage.getText(); if (length > 0 && tupleStr.length() > length) { tupleStr = tupleStr.substring(0, length); } MetaType attrType = tuple.getStreamSchema().getAttribute(0).getType().getMetaType(); if (attrType == MetaType.RSTRING || attrType == MetaType.USTRING) { tuple.setString(0, tupleStr); } else if (attrType == MetaType.XML) { ByteArrayInputStream inputStream = new ByteArrayInputStream(tupleStr.getBytes()); try { XML xmlValue = ValueFactory.newXML(inputStream); tuple.setXML(0, xmlValue); } catch (IOException e) { // unable to convert incoming string to xml value // discard message and continue return MessageAction.DISCARD_MESSAGE_MESSAGE_FORMAT_ERROR; } } return MessageAction.SUCCESSFUL_MESSAGE; } }