/******************************************************************************* * Copyright (C) 2013, 2014, International Business Machines Corporation * All Rights Reserved *******************************************************************************/ package com.ibm.streamsx.messaging.jms; import java.util.List; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Session; import javax.jms.TextMessage; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.ibm.streams.operator.Tuple; import com.ibm.streams.operator.metrics.Metric; //This class handles the wbe22 message type class WBETextMessageHandler extends BaseXMLMessageHandler { // the document builder private DocumentBuilder documentBuilder; // constructor public WBETextMessageHandler(List<NativeSchema> nativeSchemaObjects, String eventName) throws TransformerConfigurationException, ParserConfigurationException { // call the base class constructor to initialize the native schema // attributes and event name. super(nativeSchemaObjects, eventName); documentBuilder = DocumentBuilderFactory.newInstance() .newDocumentBuilder(); } // constructor public WBETextMessageHandler(List<NativeSchema> nativeSchemaObjects, String eventName, Metric nTruncatedInserts) throws TransformerConfigurationException, ParserConfigurationException { // call the base class constructor to initialize the native schema // attributes,nTruncatedInserts and event name super(nativeSchemaObjects, eventName, nTruncatedInserts); documentBuilder = DocumentBuilderFactory.newInstance() .newDocumentBuilder(); } // For JMSSink operator, convert the incoming tuple to a JMS TextMessage public Message convertTupleToMessage(Tuple tuple, Session session) throws JMSException, ParserConfigurationException, TransformerException { // create a new TextMessage TextMessage message; synchronized (session) { message = (TextMessage) session.createTextMessage(); } // create document element Document document; synchronized (documentBuilder) { document = documentBuilder.newDocument(); } // String to hold attribute values String stringdata = new String(); // variable to specify if any of the attributes in the message is // truncated boolean isTruncated = false; // create elements for constructing the xml document // with wbe mesage format // creates an element for root tuple Element rootElement = document.createElement("connector"); //$NON-NLS-1$ rootElement.setAttribute("xmlns", "http://wbe.ibm.com/6.2/Event/" //$NON-NLS-1$ //$NON-NLS-2$ + eventName); rootElement.setAttribute("name", "System S"); //$NON-NLS-1$ //$NON-NLS-2$ rootElement.setAttribute("version", "6.2"); //$NON-NLS-1$ //$NON-NLS-2$ Element rootEle2 = document.createElement("connector-bundle"); //$NON-NLS-1$ rootEle2.setAttribute("name", eventName); //$NON-NLS-1$ rootEle2.setAttribute("type", "Event"); //$NON-NLS-1$ //$NON-NLS-2$ rootElement.appendChild(rootEle2); Element rootEle3 = document.createElement(eventName); rootEle2.appendChild(rootEle3); for (NativeSchema currentObject : nativeSchemaObjects) { // iterate through the native schema elements // extract the name, type and length final String name = currentObject.getName(); final int length = currentObject.getLength(); Element ele = document.createElement(name); // handle based on data type switch (tuple.getStreamSchema().getAttribute(name).getType() .getMetaType()) { // BLOB is not supported for wbe22 message class case RSTRING: case USTRING: // extract the String // get its length String rdata = tuple.getString(name); int size = rdata.length(); // If no length was specified in native schema or // if the length of the String rdata is less than the length // specified in native schema if (length == LENGTH_ABSENT_IN_NATIVE_SCHEMA || size <= length) { stringdata = rdata; } // if the length of rdate is greater than the length specified // in native schema // set the isTruncated to true // truncate the String else if (size > length) { isTruncated = true; stringdata = rdata.substring(0, length); } ele.setAttribute("data-type", "string"); //$NON-NLS-1$ //$NON-NLS-2$ break; // spl types decimal32, decimal64,decimal128, timestamp are mapped // to String. case DECIMAL32: case DECIMAL64: case DECIMAL128: stringdata = tuple.getBigDecimal(name).toString(); ele.setAttribute("data-type", "string"); //$NON-NLS-1$ //$NON-NLS-2$ break; case TIMESTAMP: stringdata = tuple.getTimestamp(name).getTimeAsSeconds() .toString(); ele.setAttribute("data-type", "string"); //$NON-NLS-1$ //$NON-NLS-2$ break; case INT8: case UINT8: case INT16: case UINT16: case INT32: case UINT32: case INT64: case UINT64: stringdata = tuple.getString(name); ele.setAttribute("data-type", "integer"); //$NON-NLS-1$ //$NON-NLS-2$ break; case FLOAT32: case FLOAT64: stringdata = tuple.getString(name); ele.setAttribute("data-type", "real"); //$NON-NLS-1$ //$NON-NLS-2$ break; case BOOLEAN: if (tuple.getBoolean(name)) { stringdata = "true"; //$NON-NLS-1$ } else { stringdata = "false"; //$NON-NLS-1$ } ele.setAttribute("data-type", "boolean"); //$NON-NLS-1$ //$NON-NLS-2$ break; } ele.appendChild(document.createTextNode((stringdata))); // append to root element rootEle3.appendChild(ele); } document.appendChild(rootElement); // add the rootElement to the // document // set the message message.setText(createFinalDocument(document)); // if the isTruncated boolean is set, increment the metric // nTruncatedInserts if (isTruncated) { nTruncatedInserts.incrementValue(1); } // return the message return message; } }