/* * @(#)BookClient.java * * Copyright 2002 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms * */ package com.sun.eportal.bookordering; import javax.xml.messaging.*; import javax.xml.soap.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.stream.*; import javax.xml.transform.dom.*; import org.w3c.dom.*; import java.util.Vector; import java.io.*; import java.util.*; import javax.xml.messaging.*; import javax.xml.soap.*; /** * BookClient.java is a class which will contact all the book providers * It gets the vector of endpoints from BookLister and then it sends * synchronous messages to each of the endpoint.In our case it sends * synchronous messages to the bookProviders Aerns and Cables and Funbooks * * @author Bhakti Mehta and Ramesh Mandava * */ public class BookClient { SOAPMessage message; Vector returnVector = new Vector(); String file=""; String orgName=""; /* * This message takes the vector of endpoints for book providers * It calls the getAvailableBooks method for each endpoint * */ public Vector getAllAvailableBooks(Vector jaxmEndPointVector) { returnVector = new Vector(); for (int i = 0; i < jaxmEndPointVector.size();i++){ Vector temp= new Vector(); temp =getAvailableBooks((String)jaxmEndPointVector.elementAt(i)); returnVector.addAll(temp); System.out.println("return Vector size() "+ returnVector.size()); } return returnVector; } public void setMessage(SOAPMessage msg){ message=msg; } /* * This method constructs the SOAP message which is to * sent synchronously to the book providers * This message contains the searchCriteria and searchValue */ public void constructMessage(String queryType, String queryValue){ try { MessageFactory mf = MessageFactory.newInstance(); SOAPMessage msg = mf.createMessage(); SOAPPart sp = msg.getSOAPPart() ; SOAPEnvelope envelope = sp.getEnvelope(); SOAPHeader hdr = envelope.getHeader(); SOAPBody bdy = envelope.getBody(); SOAPBodyElement sbe = bdy.addBodyElement (envelope.createName("GetBookDetails", "bp", "http://www.bookprovider.com")); sbe.addChildElement( envelope.createName("searchCriteria", "bp", "http://www.bookprovider.com" )).addTextNode(queryType); sbe.addChildElement( envelope.createName("searchValue", "bp", "http://www.bookprovider.com" )).addTextNode(queryValue); message=msg; } catch ( Exception e ) { e.printStackTrace(); } } /* * This method sends the query to each of the endpoint * Since it sends a synchronous message * it gets back the reply from each endpoint * The reply message contains the attachments which contain * book information and discount information */ public Vector getAvailableBooks (String endPoint){ try { Vector retVector = new Vector(); URLEndpoint urlEndpoint = new URLEndpoint(endPoint); System.out.println("Sent message is logged in \"query.msg\""); FileOutputStream sentFile = new FileOutputStream("query.msg"); message.writeTo(sentFile); sentFile.close(); SOAPConnection conn; SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance(); conn = scf.createConnection(); SOAPMessage reply = conn.call(message, urlEndpoint); AttachmentPart ap =null; if (reply!=null) { System.out.println("reply is not null"); FileOutputStream replyFile = new FileOutputStream ("attachmentResponse.msg"); reply.writeTo(replyFile); replyFile.close(); SOAPEnvelope envelope = reply.getSOAPPart().getEnvelope(); SOAPHeader header = envelope.getHeader(); orgName = extract( envelope, header, "organization"); System.out.println("Message from Organization ->" + orgName ); /* * The reply should contain two attachments * One whose content type is text/xml which contains the * book information * Second attachment whose content type is text/html * which contains the promotion information */ int attachmentCount = reply.countAttachments(); System.out.println("Attachments count" + attachmentCount); Iterator attachmentIterator = reply.getAttachments(); while ( attachmentIterator.hasNext() ) { System.out.println("Working on Attachment:" ); ap = (AttachmentPart)attachmentIterator.next(); System.out.println("ContentType is" + ap.getContentType()); if ( ap.getContentType().equals("text/html") ) { String is = (String)ap.getContent(); FileOutputStream fos = new FileOutputStream ( "../webapps/ROOT/" +getFileName(endPoint)+ ".html"); fos.write(is.getBytes()); System.out.println("Attachment is saved "+ getFileName(endPoint)+".html"); fos.flush(); fos.close(); } else { /* * This is the attachment whose content type is * text/xml */ javax.xml.transform.stream.StreamSource bookSource = (StreamSource)ap.getContent (); if (bookSource!= null) { System.out.println("bookSource not null"); TransformerFactory tfactory = TransformerFactory .newInstance(); Transformer transformer = tfactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.METHOD, "xml"); /* * This will transform the received attachment * to an xml file */ file = getFileName(endPoint); String fileName = "../webapps/ROOT/"+file+".xml"; FileOutputStream fos = new FileOutputStream (fileName) ; transformer.transform(bookSource, new StreamResult(fos)); fos.close(); retVector = generateDataBeans(fileName, endPoint); System.out.println("v.size"+retVector.size()); System.out.println("Reply log in queryResponse.msg"); } else { // In This case the attachment containing book info // is null System.out.println("s is null"); return null; } } //end else text/xml }//while }else { System.out.println("reply is null"); return null; } return retVector; }catch (Exception e) { e.printStackTrace(); return null; } } /* * This method takes in the endpoint and process the endpoint * to generate a fileName * This file name will be used to extract the attachments * and to differentiate between the attachments which * are sent by different endpoints */ public String getFileName(String endpoint){ StringTokenizer s = new StringTokenizer(endpoint,"/:"); String sub=""; String fileName="Rec"; try { while (s.hasMoreTokens()){ sub=s.nextToken(); fileName=fileName+"_"+sub; System.out.println(sub); } System.out.println(fileName); return fileName; }catch (Exception e){ e.printStackTrace(); return null; } } /* * This method generates a vector of books which will be displayed to the * user. * The vector is generated after parsing the information * which the book provider sends as an xml attachment */ public Vector generateDataBeans(String fos , String endPoint) { Vector dataBeans = new Vector(); try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(fos); NodeList nl = doc.getElementsByTagName("book"); if (nl.getLength()==0){ System.out.println("no nodes"); return dataBeans; }else { for (int i = 0;i0 }catch (Exception e ) { e.printStackTrace(); return null; } }//generateDataBean /* Extract the value of the first child element under element * with this localname */ private String extract(SOAPEnvelope envelope, SOAPElement element, String localname) throws SOAPException { Iterator it = element.getChildElements( envelope.createName(localname, "bp", "http://www.bookprovider.com")); if( it.hasNext()) { SOAPElement e = (SOAPElement) it.next(); return e.getValue(); } System.err.println("Could not extract " + localname + " from message"); return null; } }