Return-Path: Delivered-To: apmail-synapse-commits-archive@locus.apache.org Received: (qmail 37125 invoked from network); 20 Aug 2008 04:23:51 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 20 Aug 2008 04:23:51 -0000 Received: (qmail 12597 invoked by uid 500); 20 Aug 2008 04:23:49 -0000 Delivered-To: apmail-synapse-commits-archive@synapse.apache.org Received: (qmail 12526 invoked by uid 500); 20 Aug 2008 04:23:48 -0000 Mailing-List: contact commits-help@synapse.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@synapse.apache.org Delivered-To: mailing list commits@synapse.apache.org Received: (qmail 12448 invoked by uid 99); 20 Aug 2008 04:23:48 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 19 Aug 2008 21:23:48 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 20 Aug 2008 04:22:58 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id B61D1238899E; Tue, 19 Aug 2008 21:23:27 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r687237 - in /synapse/trunk/java/modules/transports/src/main/java/org/apache/synapse/transport/fix: FIXConstants.java FIXUtils.java Date: Wed, 20 Aug 2008 04:23:27 -0000 To: commits@synapse.apache.org From: hiranya@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080820042327.B61D1238899E@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: hiranya Date: Tue Aug 19 21:23:27 2008 New Revision: 687237 URL: http://svn.apache.org/viewvc?rev=687237&view=rev Log: Added support for FIX 4.4 repeating groups (see SYNAPSE-420). Ideally this issue should be resolved at the QFJ side and this fix is supposed to be only temporary. Comments are included in the code where the clean up should be done once the issue is resolved in QFJ. Patch was submitted by Asanka A. Modified: synapse/trunk/java/modules/transports/src/main/java/org/apache/synapse/transport/fix/FIXConstants.java synapse/trunk/java/modules/transports/src/main/java/org/apache/synapse/transport/fix/FIXUtils.java Modified: synapse/trunk/java/modules/transports/src/main/java/org/apache/synapse/transport/fix/FIXConstants.java URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/src/main/java/org/apache/synapse/transport/fix/FIXConstants.java?rev=687237&r1=687236&r2=687237&view=diff ============================================================================== --- synapse/trunk/java/modules/transports/src/main/java/org/apache/synapse/transport/fix/FIXConstants.java (original) +++ synapse/trunk/java/modules/transports/src/main/java/org/apache/synapse/transport/fix/FIXConstants.java Tue Aug 19 21:23:27 2008 @@ -33,6 +33,8 @@ public static final String FIX_BODY = "body"; public static final String FIX_TRAILER = "trailer"; public static final String FIX_FIELD_ID = "id"; + public static final String FIX_GROUPS = "groups"; + public static final String FIX_GROUP = "group"; public static final String FIX_MESSAGE_SERVICE = "service"; public static final String FIX_MESSAGE_APPLICATION = "fixApplication"; public static final String FIX_BINARY_FIELD = "rawdata"; Modified: synapse/trunk/java/modules/transports/src/main/java/org/apache/synapse/transport/fix/FIXUtils.java URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/src/main/java/org/apache/synapse/transport/fix/FIXUtils.java?rev=687237&r1=687236&r2=687237&view=diff ============================================================================== --- synapse/trunk/java/modules/transports/src/main/java/org/apache/synapse/transport/fix/FIXUtils.java (original) +++ synapse/trunk/java/modules/transports/src/main/java/org/apache/synapse/transport/fix/FIXUtils.java Tue Aug 19 21:23:27 2008 @@ -38,6 +38,7 @@ import javax.xml.namespace.QName; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.*; @@ -114,28 +115,8 @@ } } //process FIX body - iter = message.iterator(); - if (iter != null) { - while (iter.hasNext()) { - Field field = iter.next(); - OMElement msgField = soapFactory.createOMElement(FIXConstants.FIX_FIELD, null); - msgField.addAttribute(soapFactory. - createOMAttribute(FIXConstants.FIX_FIELD_ID, null, String.valueOf(field.getTag()))); - Object value = field.getObject(); - if (value instanceof byte[]) { - DataSource dataSource = new ByteArrayDataSource((byte[]) value); - DataHandler dataHandler = new DataHandler(dataSource); - String contentID = msgCtx.addAttachment(dataHandler); - OMElement binaryData = soapFactory.createOMElement(FIXConstants.FIX_BINARY_FIELD, null); - String binaryCID = "cid:" + contentID; - binaryData.addAttribute(FIXConstants.FIX_MESSAGE_REFERENCE, binaryCID, null); - msgField.addChild(binaryData); - } else { - soapFactory.createOMText(msgField, value.toString(), OMElement.CDATA_SECTION_NODE); - } - body.addChild(msgField); - } - } + convertFIXBodyToXML(message, body, soapFactory, msgCtx); + //process FIX trailer iter = message.getTrailer().iterator(); if (iter != null) { @@ -168,6 +149,149 @@ envelope.getBody().addChild(msg); msgCtx.setEnvelope(envelope); } + + + /** + * Constructs the XML infoset for the FIX message body + * + * @param message the FIX message + * @param body the body element of the XML infoset + * @param soapFactory the SOAP factory to create XML elements + * @param msgCtx the Axis2 Message context + * @throws AxisFault on error + */ + private void convertFIXBodyToXML(FieldMap message, OMElement body, SOAPFactory soapFactory, + MessageContext msgCtx) throws AxisFault{ + + if (log.isDebugEnabled()) { + log.debug("Generating FIX message body (Message ID: " + msgCtx.getMessageID() + ")"); + } + + Iterator> iter = message.iterator(); + if (iter != null) { + while (iter.hasNext()) { + Field field = iter.next(); + OMElement msgField = soapFactory.createOMElement(FIXConstants.FIX_FIELD, null); + msgField.addAttribute(soapFactory. + createOMAttribute(FIXConstants.FIX_FIELD_ID, null, String.valueOf(field.getTag()))); + Object value = field.getObject(); + + if (value instanceof byte[]) { + DataSource dataSource = new ByteArrayDataSource((byte[]) value); + DataHandler dataHandler = new DataHandler(dataSource); + String contentID = msgCtx.addAttachment(dataHandler); + OMElement binaryData = soapFactory.createOMElement(FIXConstants.FIX_BINARY_FIELD, null); + String binaryCID = "cid:" + contentID; + binaryData.addAttribute(FIXConstants.FIX_MESSAGE_REFERENCE, binaryCID, null); + msgField.addChild(binaryData); + } else { + soapFactory.createOMText(msgField, value.toString(), OMElement.CDATA_SECTION_NODE); + } + + body.addChild(msgField); + } + } + + //process FIX repeating groups + Iterator groupKeyItr = message.groupKeyIterator(); + if (groupKeyItr != null){ + while (groupKeyItr.hasNext()) { + try { + int groupKey = groupKeyItr.next(); + OMElement groupsField = soapFactory.createOMElement(FIXConstants.FIX_GROUPS, null); + groupsField.addAttribute(FIXConstants.FIX_FIELD_ID,String.valueOf(groupKey),null); + // TODO: Folowing section uses reflections to access the FieldMap.getGroups(Field) method. + // Once QFJ accept the QFJ-330 patch can remove the folowing section. + Class fieldMap; + // Package access method getGroups(int) is a method of FieldMap the parent class of Group , Message and Message + if (message.getClass().getName().equals("quickfix.Group")){ // Not added to constants subject to remove with QFJ-330 + fieldMap = message.getClass().getSuperclass(); + } else if (message.getClass().getName().equals("quickfix.Message")){ // Not added to constants subject to remove with QFJ-330 + fieldMap = message.getClass().getSuperclass(); + } else { + fieldMap = message.getClass().getSuperclass().getSuperclass().getSuperclass(); + } + + Class[] types = new Class[] { int.class }; + Method getGroups = fieldMap.getDeclaredMethod("getGroups", types); // Not added to constants subject to remove with QFJ-330 + getGroups.setAccessible(true); + List groupList = (List) getGroups.invoke(message, groupKey); + Iterator groupIterator = groupList.iterator(); + while(groupIterator.hasNext()){ + Group msgGroup = groupIterator.next(); + OMElement groupField = soapFactory.createOMElement(FIXConstants.FIX_GROUP, null); + convertFIXBodyToXML(msgGroup, groupField, soapFactory, msgCtx); // rec. call the method to process the repeating groups + groupsField.addChild(groupField); + } + body.addChild(groupsField); + + } catch (Exception e) { + throw new AxisFault("Exception occured in FIX message processing : " + e.toString()); + } + } + } + } + + + private void generateFIXBody(OMElement node, FieldMap message, MessageContext msgCtx, boolean withNs, + String nsURI, String nsPrefix) throws IOException { + + Iterator bodyElements = node.getChildElements(); + while (bodyElements.hasNext()) { + OMElement bodyNode = bodyElements.next(); + String nodeLocalName = bodyNode.getLocalName(); + + //handle repeating groups + if (nodeLocalName.equals(FIXConstants.FIX_GROUPS)){ + int groupsKey = Integer.parseInt(bodyNode.getAttributeValue(new QName(FIXConstants.FIX_FIELD_ID))); + Group group; + Iterator groupElements = bodyNode.getChildElements(); + while (groupElements.hasNext()){ + OMElement groupNode = groupElements.next(); + OMElement delimNode = groupNode.getFirstElement(); + int delimKey = Integer.parseInt(delimNode. getAttributeValue(new QName(FIXConstants.FIX_FIELD_ID))); + group = new Group(groupsKey,delimKey); + generateFIXBody(groupNode, group, msgCtx, withNs, nsURI, nsPrefix); + message.addGroup(group); + } + + } else { + String tag; + if (withNs) { + tag = bodyNode.getAttributeValue(new QName(nsURI, FIXConstants.FIX_FIELD_ID, nsPrefix)); + } else { + tag = bodyNode.getAttributeValue(new QName(FIXConstants.FIX_FIELD_ID)); + } + + String value = null; + OMElement child = bodyNode.getFirstElement(); + if (child != null) { + String href; + if (withNs) { + href = bodyNode.getFirstElement(). + getAttributeValue(new QName(nsURI, FIXConstants.FIX_FIELD_ID, nsPrefix)) ; + } else { + href = bodyNode.getFirstElement(). + getAttributeValue(new QName(FIXConstants.FIX_MESSAGE_REFERENCE)); + } + + if (href != null) { + DataHandler binaryDataHandler = msgCtx.getAttachment(href.substring(4)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + binaryDataHandler.writeTo(outputStream); + value = new String(outputStream.toByteArray()); + } + } + else { + value = bodyNode.getText(); + } + + if (value != null) { + message.setString(Integer.parseInt(tag), value); + } + } + } + } /** @@ -251,43 +375,8 @@ } else if (node.getQName().getLocalPart().equals(FIXConstants.FIX_BODY)) { //create FIX body - Iterator bodyElements = node.getChildElements(); - while (bodyElements.hasNext()) { - OMElement bodyNode = bodyElements.next(); - String tag; - if (withNs) { - tag = bodyNode.getAttributeValue(new QName(nsURI, FIXConstants.FIX_FIELD_ID, - nsPrefix)); - } else { - tag = bodyNode.getAttributeValue(new QName(FIXConstants.FIX_FIELD_ID)); - } - - String value = null; - - OMElement child = bodyNode.getFirstElement(); - if (child != null) { - String href; - if (withNs) { - href = bodyNode.getFirstElement(). - getAttributeValue(new QName(nsURI, FIXConstants.FIX_FIELD_ID, nsPrefix)) ; - } else { - href = bodyNode.getFirstElement(). - getAttributeValue(new QName(FIXConstants.FIX_MESSAGE_REFERENCE)); - } - if (href != null) { - DataHandler binaryDataHandler = msgCtx.getAttachment(href.substring(4)); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - binaryDataHandler.writeTo(outputStream); - value = new String(outputStream.toByteArray()); - } - } else { - value = bodyNode.getText(); - } - - if (value != null) { - message.setString(Integer.parseInt(tag), value); - } - } + generateFIXBody(node, message, msgCtx, withNs, nsURI, nsPrefix); + } else if (node.getQName().getLocalPart().equals(FIXConstants.FIX_TRAILER)) { //create FIX trailer Iterator trailerElements = node.getChildElements();