Just another (occasional) brain dump on technology and the technology industry...

About Me

My photo
I enjoy wine, laptops, walks, bicycling with the kids and long drives. I am constanly reading. In my heart I am a teacher a salesman and a technologist.

Thursday, February 07, 2008

SOAP With Attachments in Java CAPS

I was part of a team that did a Proof of Concept (PoC) to demonstrate the capabilities of Java CAPS at a prospective customer recently. One of the requirements of the PoC was to handle SOAP (1.1) with Attachments (SwA) from within Java CAPS. I searched high and low for an example. I was fortunate enough to find none...

I figured that the SOAP with Attachments API for Java (SAAJ) would be a good place to start. I looked through the API documentation and found that I will need a byte array and the SOAP message's MIME headers to create a SOAP message using SAAJ. All I needed to do was to expose the HTTPServer's processRequest as a JCD.

Here is the implementation:







001 package SOAP_1_u002E_1SOAP_With_Attachments_SAAJ_452723634;
002 
003 
004 import java.io.BufferedInputStream;
005 import java.io.ByteArrayInputStream;
006 import java.io.ByteArrayOutputStream;
007 import java.io.IOException;
008 import java.io.LineNumberReader;
009 import java.io.StringReader;
010 import java.util.Iterator;
011 
012 import javax.xml.soap.AttachmentPart;
013 import javax.xml.soap.MessageFactory;
014 import javax.xml.soap.MimeHeaders;
015 import javax.xml.soap.Name;
016 import javax.xml.soap.SOAPElement;
017 import javax.xml.soap.SOAPException;
018 import javax.xml.soap.SOAPFactory;
019 import javax.xml.soap.SOAPMessage;
020 
021 import org.w3c.dom.Node;
022 
023 import com.stc.codegen.alerter.Alerter;
024 import com.stc.codegen.logger.Logger;
025 import com.stc.codegen.util.CollaborationContext;
026 import com.stc.codegen.util.TypeConverter;
027 import com.stc.connector.otd.httpserveradapter.webservice.WebHeaderList;
028 import com.stc.connector.otd.httpserveradapter.webservice.WebServerApplication;
029 
030 
031 public class jcdSwAWithSAAJ13 {
032     public Logger logger;
033 
034     public Alerter alerter;
035 
036     public CollaborationContext collabContext;
037 
038     public TypeConverter typeConverter;
039 
040     public void processRequest(final WebServerApplication input)
041             throws Throwable {
042         MessageFactory mf_ = MessageFactory.newInstance();
043         SOAPMessage message_ = unmarshalSOAPMessage(input, mf_);
044         int helloIndexValue_ = 0;
045         int worldIndexValue_ = 0;
046         if (null != message_) {
047             helloIndexValue_ = extractIndex("helloIndex", message_);
048             worldIndexValue_ = extractIndex("worldIndex", message_);
049         }
050 
051         String greeting_ = buildGreeting(
052             helloIndexValue_, worldIndexValue_, message_);
053         SOAPMessage response_ = generateResponse(mf_, greeting_);
054         if (null != response_) {
055             sendResponse(response_, input);
056         }
057     }
058 
059     private SOAPMessage unmarshalSOAPMessage(
060             final WebServerApplication input, final MessageFactory factory) {
061         SOAPMessage result_ = null;
062         try {
063             BufferedInputStream bis_ = new BufferedInputStream(
064                 new ByteArrayInputStream(input.getRequest().getByteArray()));
065             MimeHeaders headers_ = extractHeaders(
066                 input.getRequest().getHeaderInfo());
067             result_ = factory.createMessage(headers_, bis_);
068         catch (Exception e_) {
069             error(e_.getMessage(), e_.getCause());
070         }
071 
072         return result_;
073     }
074 
075     private int extractIndex(
076             final String indexName, final SOAPMessage message) {
077         int result_ = Integer.MIN_VALUE;
078         SOAPElement element_ = extractElement(indexName, message);
079         if (null != element_) {
080             result_ = typeConverter.stringToInt(
081                 element_.getValue()"#", false, 0);
082         else {
083             result_ = 1;
084         }
085 
086         return result_;
087     }
088 
089     private String buildGreeting(
090             final int helloIndex, final int worldIndex,
091             final SOAPMessage message) {
092         String result_ = "";
093 
094         Iterator attachments_ = message.getAttachments();
095         int numberOfAttachments_ = 0;
096         String hello_ = "";
097         String world_ = "";
098         while (attachments_.hasNext()) {
099             numberOfAttachments_++;
100             AttachmentPart attachment_ = (AttachmentPartattachments_.next();
101             if (attachment_.getContentId().equalsIgnoreCase(
102                     "hello_in_multiple_languages")) {
103                 hello_ = extractWord(attachment_, helloIndex);
104             else if (attachment_.getContentId().equalsIgnoreCase(
105                     "world_in_multiple_languages")) {
106                 world_ = extractWord(attachment_, worldIndex);
107             }
108         }
109 
110         result_ = hello_ + " " + world_ + "!";
111 
112         return result_;
113     }
114 
115     /** Dito */
116     private MimeHeaders extractHeaders(final WebHeaderList headers) {
117         MimeHeaders result_ = new MimeHeaders();
118         int numberOfHeaders_ = headers.countWebHeaderList();
119         for (
120                 int headerIndex_ = 0;
121                 headerIndex_ < numberOfHeaders_;
122                 headerIndex_++) {
123             String headerName_ = headers.getWebHeaderList(
124                 headerIndex_).getName();
125             String[] headerValues_ = headers.getWebHeaderList(
126                 headerIndex_).getValues();
127             for (
128                     int headerValueIndex_ = 0;
129                     headerValueIndex_ < headerValues_.length;
130                     headerValueIndex_++) {
131                 result_.addHeader(
132                     headerName_, headerValues_[headerValueIndex_]);
133             }
134         }
135 
136         return result_;
137     }
138 
139     private SOAPElement extractElement(final String localName,
140             final SOAPMessage message) {
141         SOAPElement element_ = null;
142 
143         try {
144             Iterator elements_ = message.getSOAPBody().getChildElements();
145             while (elements_.hasNext()) {
146                 Node n_ = (Nodeelements_.next();
147                 if (n_.getLocalName().equalsIgnoreCase(localName)) {
148                     element_ = (SOAPElementn_;
149                     break;
150                 }
151             }
152         catch (Exception e_) {
153             error(e_.getMessage(), e_.getCause());
154         }
155 
156         return element_;
157     }
158 
159     private String extractWord(final AttachmentPart attachment,
160             final int index) {
161         String result_ = "Yebo";
162 
163         try {
164             LineNumberReader reader_ = new LineNumberReader(
165                 new StringReader((Stringattachment.getContent()));
166             int escapeHatch_ = 0;
167             while (reader_.getLineNumber() < index) {
168                 result_ = reader_.readLine();
169                 if (escapeHatch_++ > index) {
170                     break;
171                 }
172             }
173         catch (Exception e_) {
174             error(e_.getMessage(), e_.getCause());
175         }
176 
177         return result_;
178     }
179 
180     private SOAPMessage generateResponse(final MessageFactory factory,
181             final String greeting) {
182         SOAPMessage response_ = null;
183 
184         try {
185             response_ = factory.createMessage();
186             SOAPFactory factory_ = SOAPFactory.newInstance();
187             Name helloWorldName_ = factory_.createName(
188                 "helloWorld""dhpoc""http://www.discovery.co.za/poc");
189             response_.getSOAPBody().addBodyElement(helloWorldName_).setValue(
190                 greeting);
191         catch (SOAPException e_) {
192             error(e_.getMessage(), e_.getCause());
193         }
194 
195         return response_;
196     }
197 
198     private void sendResponse(final SOAPMessage response,
199             final WebServerApplication input) {
200         try {
201             byte[] responseAsBytes_ = convertResponseToBytes(response);
202             if (responseAsBytes_.length > 0) {
203                 input.getResponse().setByteArray(responseAsBytes_);
204                 input.getResponse().setContentType("text/xml");
205                 input.getResponse().setContentLength(
206                     input.getResponse().getByteArray().length);
207                 input.sendResponse();
208             }
209         catch (Exception e_) {
210             error(e_.getMessage(), e_.getCause());
211         }
212     }
213 
214     private byte[] convertResponseToBytes(final SOAPMessage message) {
215         ByteArrayOutputStream baos_ = new ByteArrayOutputStream();
216         try {
217             message.writeTo(baos_);
218         catch (SOAPException e_) {
219             error(e_.getMessage(), e_.getCause());
220         catch (IOException e_) {
221             error(e_.getMessage(), e_.getCause());
222         }
223 
224         return baos_.toByteArray();
225     }
226     private void error(final String message, final Throwable t) {
227         logger.error("::: ::: " + message + " ::: :::", t);
228     }
229 }



unmarshallSOAPMessage on line 59 shows how to reconstruct the incoming SOAP message from the WebApplication's byte array and HeaderList. The rest is fairly obvious. sendResponse on line 198 shows how to pump a newly created SOAP message back over the wire.

That covers SwA server functionality within Java CAPS. I will show the client side code in a next blog.

No comments: