001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)MEPOutputStream.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.binding.proxy.util;
030:
031: import com.sun.jbi.binding.proxy.ExchangeEntry;
032: import com.sun.jbi.binding.proxy.ProxyBinding;
033: import com.sun.jbi.binding.proxy.LocalStringKeys;
034: import com.sun.jbi.binding.proxy.util.Translator;
035:
036: import java.io.OutputStream;
037: import java.io.ObjectOutputStream;
038: import java.io.ByteArrayOutputStream;
039:
040: import java.util.Iterator;
041: import java.util.Map;
042: import java.util.Set;
043:
044: import java.util.logging.Logger;
045:
046: import javax.activation.DataHandler;
047:
048: import javax.jbi.messaging.ExchangeStatus;
049: import javax.jbi.messaging.Fault;
050: import javax.jbi.messaging.MessageExchange;
051: import javax.jbi.messaging.NormalizedMessage;
052:
053: import javax.jbi.servicedesc.ServiceEndpoint;
054:
055: import javax.xml.namespace.QName;
056:
057: import javax.xml.transform.Source;
058: import javax.xml.transform.Transformer;
059: import javax.xml.transform.TransformerFactory;
060: import javax.xml.transform.dom.DOMSource;
061: import javax.xml.transform.stream.StreamResult;
062:
063: /**
064: * Implementation of an output stream that can serialize a MEP.
065: * @author Sun Microsystems, Inc
066: */
067: public class MEPOutputStream extends java.io.OutputStream {
068: private ByteArrayOutputStream mOS;
069: private ObjectOutputStream mOOS;
070: private int mCount;
071: private int mStreams;
072: private byte[] mBytes;
073: private Transformer mTransform;
074: static private Logger mLog;
075:
076: public MEPOutputStream(ProxyBinding proxyBinding)
077: throws javax.jbi.messaging.MessagingException {
078: mOS = new ByteArrayOutputStream();
079:
080: mCount = 0;
081: mBytes = new byte[MEPInputStream.BUFFER_SIZE];
082: if (mLog == null) {
083: mLog = proxyBinding.getLogger("output");
084: }
085:
086: try {
087: // initialize transformer details
088: mTransform = TransformerFactory.newInstance()
089: .newTransformer();
090: } catch (javax.xml.transform.TransformerFactoryConfigurationError tfcEx) {
091: throw new javax.jbi.messaging.MessagingException(
092: Translator
093: .translate(LocalStringKeys.MEPOUTPUT_TRANSFORMER_ERROR),
094: tfcEx);
095: } catch (javax.xml.transform.TransformerConfigurationException cfgEx) {
096: throw new javax.jbi.messaging.MessagingException(
097: Translator
098: .translate(LocalStringKeys.MEPOUTPUT_TRANSFORMER_ERROR),
099: cfgEx);
100: }
101: }
102:
103: public byte[] writeException(String id, Exception e) {
104: byte[] bytes;
105:
106: try {
107: mOOS = new ObjectOutputStream(this );
108:
109: //
110: // Type Exception
111: //
112: mOOS.writeByte(MEPInputStream.TYPE_EXCEPTION);
113:
114: //
115: // Version 1
116: //
117: mOOS.writeByte(MEPInputStream.VERSION_1);
118:
119: //
120: // We always write the exchangeId.
121: //
122: mOOS.writeUTF(id);
123:
124: //
125: // The exception info.
126: //
127: mOOS.writeObject(e);
128:
129: //
130: // Get the resulting bytes.
131: //
132: mOOS.close();
133: mOOS = null;
134: bytes = mOS.toByteArray();
135: mOS.reset();
136: return (bytes);
137: } catch (java.io.IOException ioEx) {
138: return (null);
139: }
140: }
141:
142: public byte[] writeIsMEPOk(ExchangeEntry ee)
143: throws javax.jbi.messaging.MessagingException {
144: byte[] bytes;
145: boolean send;
146: NormalizedMessage msg;
147: Set props;
148:
149: try {
150: mOOS = new ObjectOutputStream(this );
151:
152: //
153: // Type Exchange
154: //
155: mOOS.writeByte(MEPInputStream.TYPE_ISMEPOK);
156:
157: //
158: // Version 1.
159: //
160: mOOS.writeByte(MEPInputStream.VERSION_1);
161:
162: //
163: // Send the related exchangeId.
164: //
165: mOOS.writeUTF(ee.getRelatedExchange().getExchangeId());
166:
167: //
168: // Send the contents of the Exchange.
169: //
170: writeExchange(ee.getMessageExchange(), ee);
171:
172: //
173: // Get the resulting bytes.
174: //
175: mOOS.close();
176: mOOS = null;
177: bytes = mOS.toByteArray();
178: mOS.reset();
179: ee.sendBytes(bytes.length);
180: return (bytes);
181: } catch (java.io.IOException ioEx) {
182: throw new javax.jbi.messaging.MessagingException(Translator
183: .translate(LocalStringKeys.MEPOUTPUT_IO_ERROR),
184: ioEx);
185: }
186: }
187:
188: public byte[] writeMEPOk(String id, boolean okay) {
189: byte[] bytes;
190:
191: try {
192: mOOS = new ObjectOutputStream(this );
193: //
194: // Type Exception
195: //
196: mOOS.writeByte(MEPInputStream.TYPE_MEPOK);
197:
198: //
199: // Version 1
200: //
201: mOOS.writeByte(MEPInputStream.VERSION_1);
202:
203: //
204: // We always write the exchangeId.
205: //
206: mOOS.writeUTF(id);
207:
208: //
209: // The exception info.
210: //
211: mOOS.writeBoolean(okay);
212:
213: //
214: // Get the resulting bytes.
215: //
216: mOOS.close();
217: mOOS = null;
218: bytes = mOS.toByteArray();
219: mOS.reset();
220: return (bytes);
221: } catch (java.io.IOException ioEx) {
222: return (null);
223: }
224:
225: }
226:
227: public byte[] writeMEP(MessageExchange me, ExchangeEntry ee)
228: throws javax.jbi.messaging.MessagingException {
229: byte[] bytes;
230: boolean send;
231: NormalizedMessage msg;
232: Set props;
233:
234: try {
235: mOOS = new ObjectOutputStream(this );
236:
237: //
238: // Type Exchange
239: //
240: mOOS.writeByte(MEPInputStream.TYPE_MEP);
241:
242: //
243: // Version 1.
244: //
245: mOOS.writeByte(MEPInputStream.VERSION_1);
246:
247: //
248: // Send the contents of the Exchange.
249: //
250: writeExchange(me, ee);
251:
252: //
253: // Get the resulting bytes.
254: //
255: mOOS.close();
256: mOOS = null;
257: bytes = mOS.toByteArray();
258: mOS.reset();
259: ee.sendBytes(bytes.length);
260: return (bytes);
261: } catch (java.io.IOException ioEx) {
262: throw new javax.jbi.messaging.MessagingException(Translator
263: .translate(LocalStringKeys.MEPOUTPUT_IO_ERROR),
264: ioEx);
265: }
266: }
267:
268: void writeExchange(MessageExchange me, ExchangeEntry ee)
269: throws javax.jbi.messaging.MessagingException {
270: boolean send;
271: NormalizedMessage msg;
272: Set props;
273:
274: try {
275: //
276: // We always write the exchangeId.
277: //
278: mOOS.writeUTF(me.getExchangeId());
279:
280: //
281: // The following are only sent the first time.
282: //
283: mOOS.writeBoolean(send = !ee
284: .checkStatus(ExchangeEntry.STATUS_FIRSTSENT));
285: if (send) {
286: mOOS.writeUTF(me.getPattern().toString());
287: writeQName(me.getEndpoint().getServiceName());
288: mOOS.writeUTF(me.getEndpoint().getEndpointName());
289: writeQName(me.getOperation());
290: ee.setStatus(ExchangeEntry.STATUS_FIRSTSENT);
291: }
292:
293: //
294: // Conditional send of the status.
295: //
296: send = (me.getStatus() != ExchangeStatus.ACTIVE)
297: && !ee.checkStatus(ExchangeEntry.STATUS_STATUSSENT);
298: mOOS.writeBoolean(send);
299: if (send) {
300: mOOS.writeUTF(me.getStatus().toString());
301: ee.setStatus(ExchangeEntry.STATUS_STATUSSENT);
302: }
303:
304: //
305: // Conditional send of the exception.
306: //
307: send = (me.getError() != null)
308: && !ee.checkStatus(ExchangeEntry.STATUS_ERRORSENT);
309: mOOS.writeBoolean(send);
310: if (send) {
311: mOOS.writeObject(me.getError());
312: ee.setStatus(ExchangeEntry.STATUS_ERRORSENT);
313: }
314:
315: //
316: // Conditional send of the fault message
317: //
318: send = ((msg = me.getFault()) != null)
319: && !ee.checkStatus(ExchangeEntry.STATUS_FAULTSENT);
320: mOOS.writeBoolean(send);
321: if (send) {
322: writeMessage(msg);
323: ee.setStatus(ExchangeEntry.STATUS_FAULTSENT);
324: }
325:
326: //
327: // Conditional send of the in message
328: //
329: send = ((msg = me.getMessage("in")) != null)
330: && !ee.checkStatus(ExchangeEntry.STATUS_INSENT);
331: mOOS.writeBoolean(send);
332: if (send) {
333: writeMessage(msg);
334: ee.setStatus(ExchangeEntry.STATUS_INSENT);
335: }
336:
337: //
338: // Conditional send of the out message
339: //
340: send = ((msg = me.getMessage("out")) != null)
341: && !ee.checkStatus(ExchangeEntry.STATUS_OUTSENT);
342: mOOS.writeBoolean(send);
343: if (send) {
344: writeMessage(msg);
345: ee.setStatus(ExchangeEntry.STATUS_OUTSENT);
346: }
347:
348: //
349: // See if any properties have changed during this step of the exchange.
350: //
351: send = (props = ((com.sun.jbi.messaging.MessageExchange) me)
352: .getDeltaProperties()).size() > 0;
353: mOOS.writeBoolean(send);
354: if (send) {
355: writeMEProperties(props);
356: }
357: } catch (java.io.IOException ioEx) {
358: throw new javax.jbi.messaging.MessagingException(Translator
359: .translate(LocalStringKeys.MEPOUTPUT_IO_ERROR),
360: ioEx);
361: }
362:
363: }
364:
365: void writeMEProperties(Set props)
366: throws javax.jbi.messaging.MessagingException {
367: Map.Entry entry = null;
368: Object value;
369: boolean writeProps;
370:
371: try {
372: mOOS.writeInt(props.size());
373: for (Iterator i = props.iterator(); i.hasNext();) {
374: entry = (Map.Entry) i.next();
375: mOOS.writeUTF((String) entry.getKey());
376: mOOS.writeObject(entry.getValue());
377: }
378: } catch (java.io.NotSerializableException nsEx) {
379: throw new javax.jbi.messaging.MessagingException(Translator
380: .translate(LocalStringKeys.MEPOUTPUT_ME_PROP_ERROR,
381: entry.getKey()), nsEx);
382:
383: } catch (java.io.IOException ioEx) {
384: throw new javax.jbi.messaging.MessagingException(Translator
385: .translate(LocalStringKeys.MEPOUTPUT_ME_PROP_ERROR,
386: entry.getKey()), ioEx);
387: }
388: }
389:
390: void writeMessage(NormalizedMessage nm) throws java.io.IOException,
391: javax.jbi.messaging.MessagingException {
392: mOOS.writeBoolean(nm != null);
393: if (nm != null) {
394: mOOS.writeBoolean(!(nm instanceof Fault));
395: writeNMProperties(nm);
396: try {
397: Source c = nm.getContent();
398:
399: mOOS.writeBoolean(c != null);
400: if (c != null) {
401: String systemId = c.getSystemId();
402:
403: mOOS.writeBoolean(systemId != null);
404: if (systemId != null) {
405: mOOS.writeUTF(systemId);
406: }
407: // {
408: // ByteArrayOutputStream baos;
409: // mTransform.transform(c, new StreamResult(baos = new ByteArrayOutputStream()));
410: // MEPInputStream.dumpBuffer("Normalized Message: ", baos.toByteArray(), baos.size());
411: // }
412: startStream();
413: mTransform.transform(c, new StreamResult(this ));
414: endStream();
415: }
416: } catch (javax.xml.transform.TransformerException tEx) {
417: throw new javax.jbi.messaging.MessagingException(tEx);
418: }
419: writeAttachments(nm);
420: }
421:
422: }
423:
424: void writeNMProperties(NormalizedMessage nm)
425: throws javax.jbi.messaging.MessagingException {
426: Set props = nm.getPropertyNames();
427: String name = null;
428: Object value;
429:
430: try {
431: mOOS.writeInt(props.size());
432: for (Iterator i = props.iterator(); i.hasNext();) {
433: name = (String) i.next();
434: value = nm.getProperty(name);
435: mOOS.writeUTF(name);
436: mOOS.writeObject(value);
437: }
438: } catch (java.io.NotSerializableException nsEx) {
439: throw new javax.jbi.messaging.MessagingException(Translator
440: .translate(LocalStringKeys.MEPOUTPUT_NM_PROP_ERROR,
441: name), nsEx);
442:
443: } catch (java.io.IOException ioEx) {
444: throw new javax.jbi.messaging.MessagingException(Translator
445: .translate(LocalStringKeys.MEPOUTPUT_NM_PROP_ERROR,
446: name), ioEx);
447: }
448: }
449:
450: void writeAttachments(NormalizedMessage nm)
451: throws javax.jbi.messaging.MessagingException {
452: Set props = nm.getAttachmentNames();
453: String name = null;
454: DataHandler value;
455:
456: try {
457: mOOS.writeInt(props.size());
458: for (Iterator i = props.iterator(); i.hasNext();) {
459: name = (String) i.next();
460: value = nm.getAttachment(name);
461: mOOS.writeUTF(name);
462: mOOS.writeUTF(value.getContentType());
463: mOOS.writeUTF(value.getName());
464: startStream();
465: value.writeTo(this );
466: endStream();
467: }
468: } catch (java.io.NotSerializableException nsEx) {
469: throw new javax.jbi.messaging.MessagingException(Translator
470: .translate(
471: LocalStringKeys.MEPOUTPUT_ME_ATTACH_ERROR,
472: name), nsEx);
473: } catch (java.io.IOException ioEx) {
474: throw new javax.jbi.messaging.MessagingException(Translator
475: .translate(
476: LocalStringKeys.MEPOUTPUT_ME_ATTACH_ERROR,
477: name), ioEx);
478: }
479: }
480:
481: void writeQName(QName qname) throws java.io.IOException {
482: mOOS.writeUTF(qname.getNamespaceURI());
483: mOOS.writeUTF(qname.getLocalPart());
484: mOOS.writeUTF(qname.getPrefix());
485:
486: }
487:
488: public void close() throws java.io.IOException {
489: while (mStreams > 0) {
490: endStream();
491: }
492: flush();
493: mOS.write(0);
494: mOS.write(0);
495: mOS.write(0);
496: mOS.flush();
497: mOS.close();
498: }
499:
500: public void flush() throws java.io.IOException {
501: if (mStreams == 0) {
502: if (mCount != 0) {
503: blockFlush();
504: }
505: mCount = 0;
506: }
507: }
508:
509: public void write(byte[] b) throws java.io.IOException {
510: write(b, 0, b.length);
511: }
512:
513: public void write(byte[] b, int off, int len)
514: throws java.io.IOException {
515: while (mCount + len >= MEPInputStream.BUFFER_SIZE) {
516: System.arraycopy(b, off, mBytes, mCount,
517: MEPInputStream.BUFFER_SIZE - mCount);
518: off += MEPInputStream.BUFFER_SIZE - mCount;
519: len -= MEPInputStream.BUFFER_SIZE - mCount;
520: mCount = MEPInputStream.BUFFER_SIZE;
521: blockFlush();
522: }
523: if (len != 0) {
524: System.arraycopy(b, off, mBytes, mCount, len);
525: mCount += len;
526: }
527: }
528:
529: public void write(int b) throws java.io.IOException {
530: mBytes[mCount++] = (byte) b;
531: if (mCount >= MEPInputStream.BUFFER_SIZE) {
532: blockFlush();
533: }
534: }
535:
536: private void startStream() throws java.io.IOException {
537: mOOS.flush();
538: blockFlush();
539: mStreams++;
540: write(mStreams);
541: }
542:
543: private void endStream() throws java.io.IOException {
544: mOOS.flush();
545: blockFlush();
546: mStreams--;
547: }
548:
549: private void blockFlush() throws java.io.IOException {
550: if (mCount != 0) {
551: if (mLog.isLoggable(java.util.logging.Level.FINE)) {
552: MEPInputStream.dumpBuffer("MEPOutputStream ("
553: + mStreams + ") Len (" + mCount + ")", mBytes,
554: mCount);
555: }
556: mOS.write(mStreams);
557: mOS.write(mCount >> 8);
558: mOS.write(mCount & 255);
559: mOS.write(mBytes, 0, mCount);
560: mCount = 0;
561: }
562: }
563: }
|