001: /*
002: * ChainBuilder ESB
003: * Visual Enterprise Integration
004: *
005: * Copyright (C) 2006 Bostech Corporation
006: *
007: * This program is free software; you can redistribute it and/or modify
008: * it under the terms of the GNU General Public License as published by
009: * the Free Software Foundation; either version 2 of the License, or
010: * (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc.,59 Temple Place, Suite 330, Boston, MA 02111-1307
020: * USA
021: *
022: *
023: * $Id: XsltProviderProcessor.java 12126 2008-02-28 15:48:05Z mpreston $
024: */
025: package com.bostechcorp.cbesb.runtime.component.xslt.processors;
026:
027: import java.io.ByteArrayOutputStream;
028: import java.io.File;
029: import java.io.IOException;
030: import java.io.InputStream;
031: import java.io.StringWriter;
032:
033: import javax.jbi.JBIException;
034: import javax.jbi.messaging.InOnly;
035: import javax.jbi.messaging.MessageExchange;
036: import javax.jbi.messaging.NormalizedMessage;
037: import javax.xml.namespace.QName;
038: import javax.xml.parsers.DocumentBuilder;
039: import javax.xml.parsers.DocumentBuilderFactory;
040: import javax.xml.parsers.ParserConfigurationException;
041: import javax.xml.transform.Source;
042: import javax.xml.transform.Transformer;
043: import javax.xml.transform.TransformerConfigurationException;
044: import javax.xml.transform.TransformerException;
045: import javax.xml.transform.TransformerFactory;
046: import javax.xml.transform.dom.DOMSource;
047: import javax.xml.transform.stream.StreamResult;
048: import javax.xml.transform.stream.StreamSource;
049:
050: import org.apache.commons.logging.Log;
051: import org.apache.commons.logging.LogFactory;
052: import org.w3c.dom.Document;
053: import org.w3c.dom.Node;
054: import org.xml.sax.SAXException;
055:
056: import com.bostechcorp.cbesb.common.constant.MetadataConstants;
057: import com.bostechcorp.cbesb.runtime.ccsl.jbi.messaging.CbProviderProcessor;
058: import com.bostechcorp.cbesb.runtime.ccsl.nmhandler.ByteArraySource;
059: import com.bostechcorp.cbesb.runtime.ccsl.nmhandler.NormalizedMessageHandler;
060: import com.bostechcorp.cbesb.runtime.ccsl.nmhandler.SourceHelper;
061: import com.bostechcorp.cbesb.runtime.ccsl.nmhandler.StringSource;
062: import com.bostechcorp.cbesb.common.runtime.CbesbException;
063: import com.bostechcorp.cbesb.common.runtime.DataContentException;
064: import com.bostechcorp.cbesb.common.util.EsbPathHelper;
065: import com.bostechcorp.cbesb.runtime.component.xslt.XsltEndpoint;
066:
067: /**
068: * @author j.zhang
069: * @version 1.0.0
070: */
071: public class XsltProviderProcessor extends CbProviderProcessor {
072: protected final transient Log logger = LogFactory
073: .getLog(getClass());
074:
075: private XsltEndpoint endpoint;
076:
077: /**
078: * @param ep
079: */
080: public XsltProviderProcessor(XsltEndpoint ep) {
081: super (ep);
082: this .endpoint = ep;
083: }
084:
085: /* (non-Javadoc)
086: * @see com.bostechcorp.cbesb.runtime.component.util.jbimessaging.BaseComponentProcessor#processInMessage(javax.xml.namespace.QName, javax.xml.namespace.QName, javax.jbi.messaging.NormalizedMessage)
087: */
088: public void processInMessage(QName service, QName operation,
089: NormalizedMessage in, MessageExchange exchange)
090: throws JBIException {
091: String exchangeType;
092: if (exchange instanceof InOnly) {
093: exchangeType = "InOnly";
094: } else {
095: exchangeType = "RobustInOnly";
096: }
097: throw new JBIException(
098: "Xslt component only support In-Out message exchanges, received "
099: + exchangeType + " message exchange.");
100:
101: }
102:
103: /* (non-Javadoc)
104: * @see com.bostechcorp.cbesb.runtime.component.util.jbimessaging.BaseComponentProcessor#processInOutMessage(javax.xml.namespace.QName, javax.xml.namespace.QName, javax.jbi.messaging.NormalizedMessage, javax.jbi.messaging.NormalizedMessage, boolean)
105: */
106: public boolean processInOutMessage(QName service, QName operation,
107: NormalizedMessage in, NormalizedMessage out,
108: boolean operationOut, MessageExchange exchange)
109: throws JBIException, CbesbException {
110: Source result = null;
111: String xsltConfigXslLocation = "";
112:
113: if (exchange
114: .getProperty(MetadataConstants.XSLT_CONFIG_XSLLOCATION) != null) {
115: xsltConfigXslLocation = exchange.getProperty(
116: MetadataConstants.XSLT_CONFIG_XSLLOCATION)
117: .toString();
118: }
119: NormalizedMessageHandler dmu = new NormalizedMessageHandler(in);
120: NormalizedMessageHandler dataMessageUtil = new NormalizedMessageHandler(
121: out, getProviderSvcDescHandlerInstance());
122:
123: for (int i = 0; i < dmu.getRecordCount(); i++) {
124: Source src = dmu.getRecordAtIndex(i);
125: result = processXslt(src, xsltConfigXslLocation);
126: dataMessageUtil.addRecord(result);
127: }
128: out = dataMessageUtil.generateMessageContent();
129: return true;
130: }
131:
132: private Source processXslt(Source src, String xsltConfigXslLocation)
133: throws CbesbException {
134: String xslLocation = endpoint.getXslLocation();
135: if (!"".equals(xsltConfigXslLocation)) {
136: xslLocation = xsltConfigXslLocation;
137: }
138: String fullPath = EsbPathHelper.getFullPathForDef(xslLocation);
139: File xsltFile = new File(fullPath);
140: Source xsltSource = new StreamSource(xsltFile);
141:
142: StringWriter sw = new StringWriter();
143: Source returnSource = null;
144: StreamResult result = new StreamResult(sw);
145: TransformerFactory transFact = TransformerFactory.newInstance();
146: Transformer trans;
147: Source inputSrc = prepareInputSource(src);
148:
149: try {
150: trans = transFact.newTransformer(xsltSource);
151: trans.transform(inputSrc, result);
152: } catch (TransformerException te) {
153: DataContentException dce = new DataContentException(
154: "XSLT Component failed transformation using XSLT file '"
155: + xslLocation + "'. - " + te.getMessage(),
156: te);
157: dce.setRemedy("Check the XSLT file for errors");
158: throw dce;
159: }
160:
161: String str = new String(sw.toString());
162: if (str != null && !("".equals(str))) {
163: returnSource = SourceHelper.createSource(str);
164: }
165:
166: return returnSource;
167: }
168:
169: private Source prepareInputSource(Source src)
170: throws DataContentException {
171: Source returnSrc = null;
172: if (src instanceof DOMSource) {
173: //Make sure the DOMSource is constructed using the Document and not an element
174: Node node = ((DOMSource) src).getNode();
175: if (node.getNodeType() == Node.DOCUMENT_NODE) {
176: returnSrc = src;
177: } else {
178: returnSrc = new DOMSource(node.getOwnerDocument());
179: }
180: } else if (src instanceof StringSource
181: || src instanceof ByteArraySource) {
182: //Pre-parse these types so we get a chance to return a
183: //friendly error message
184: try {
185: InputStream is;
186: if (src instanceof StringSource) {
187: is = ((StringSource) src).getInputStream();
188: } else {
189: is = ((ByteArraySource) src).getInputStream();
190: }
191: DocumentBuilderFactory dbf = DocumentBuilderFactory
192: .newInstance();
193: dbf.setNamespaceAware(true);
194: DocumentBuilder db = dbf.newDocumentBuilder();
195: Document doc = db.parse(is);
196: returnSrc = new DOMSource(doc);
197: } catch (Exception e) {
198: DataContentException dce = new DataContentException(
199: "XSLT Component could not parse input message - "
200: + e.getMessage(), e);
201: dce
202: .setRemedy("Verify the input message is well-formed XML.");
203: throw dce;
204: }
205: } else {
206: //Pass any other source back without modification
207: returnSrc = src;
208: }
209:
210: return returnSrc;
211: }
212:
213: }
|