CreditReport.jws Sample

This topic inludes the source code for the CreditReport.jws Sample.

Sample Location

This sample is located in the following directory in your WebLogic Workshop installation:

BEA_HOME/weblogic81/samples/workshop/SamplesApp/WebServices/creditReport/

Sample Source Code


001 package creditReport; 
002 
003 /**
004  <p>Credit reporting service.  This service simulates constructing
005  * a credit report from multiple secondary sources of information.
006  * It uses two external services, one representing a bank and the
007  * other representing the Internal Revenue Service (IRS).</p>
008  
009  <p>The @jws:conversation-lifetime max-idle-time tag controls how
010  * long a conversational instance of this service will survive without
011  * seeing activity.</p>
012  *
013  <p>Conversations represent resources: they shouldn't be left around.</p>
014  * @common:target-namespace namespace="http://workshop.bea.com/CreditReport"
015  * @jws:conversation-lifetime max-age="1 hour" max-idle-time="30 minutes"
016  * @common:xmlns namespace="http://openuri.org/bea/samples/workshop/creditReport" prefix="ns0"
017  */
018 
019 
020 public class CreditReport implements com.bea.jws.WebService
021 
022     /**
023      * @common:control
024      */
025     private creditReport.IRSControl irsControl;
026 
027     /**
028      * @common:control
029      */
030     private creditReport.BankControl bankControl;
031 
032     /*
033      * <p>ReportResult is an inner class used to represent a complete
034      * credit report.  It is used to return report responses to
035      * the client.</p>
036      
037      * <p>Inner classes that are used outside the parent class
038      * MUST be declared "public static" and they MUST have
039      * a public no-argument constructor.</p>
040      */
041     public static class ReportResult implements java.io.Serializable
042     {
043         public String bank;
044         public String tax;
045     
046         public ReportResult() {}
047     }
048 
049     
050 
051     
052   
053     /**
054      <p>Here we declare some persistent storage used
055      * to store intermediate results.<p>
056      *
057      <p>All member variables of the Java class become
058      * persistent in the presence of a @common:conversation
059      * start tag on one or more methods.</p>
060      */
061     public String taxReport = null;
062     public String bankReport = null;
063 
064     public Callback callback;
065 
066     /**
067      <p>A Service can have an inner interface called
068      * Callback if it wants to have automatic (and WSDL)
069      * support for sending asynchronous messages back to
070      * the client.</p>
071      *
072      <p>The methods in the callback interface are published in
073      * the .wsdl file for this service.</p>
074      
075      <p>Note that callbacks are asynchronous messages to the
076      * client.  It may not be possible for these messages
077      * to pass through firewalls.</p>
078      */
079     public interface Callback
080     {
081         /**
082          <p>We call this method whenever we get some new data, to
083          * tell our client what kind of new data we have. We
084          * don't transmit the complete data, just a status
085          * message.</p>
086          *
087          <p>We've declared this as a buffered method so that
088          * it's queued when we send it.  That way we don't sit
089          * around waiting for the client to process it.  Only
090          * methods that return 'void' may be buffered.</p>
091          
092          * @jws:conversation phase="continue"
093          * @common:message-buffer enable="true"
094          */
095         void onProgressNotify(String progressMsg);
096 
097         /**
098          <p>We call this method to deliver the final credit
099          * report once we're completely done (both external
100          * services have completed).</p>
101          *
102          <p>We define the format of the message this
103          * callback contains by using a custom XQuery map.
104          * An XQuery map is like an XML map, except that it
105          * uses XQuery expressions to retrieve values that should
106          * be inserted into the message. </p>
107          
108          * @jws:conversation phase="finish"
109          *
110          *  @common:message-buffer enable="true"
111          * @jws:parameter-xml schema-element="ns0:creditReport" xquery::
112          * declare namespace ns0="http://workshop.bea.com/CreditReport"
113          * declare namespace ns1="http://openuri.org/bea/samples/workshop/creditReport"
114 
115          <ns1:creditReport>
116          *     <ns1:bankReport>{data($input//ns0:bank)}</ns1:bankReport>
117          *     <ns1:taxReport>{data($input//ns0:tax)}</ns1:taxReport>
118          </ns1:creditReport>
119          * ::
120          */
121         void onReportDone(ReportResult resultMsg);
122     }
123   
124     /**
125      <p>Request a credit report from our service.</p>
126      *
127      <p>Since it may take some time for us to complete
128      * the report (we have to wait until both of our
129      * requests to external services complete), this
130      * methods has no return value.  We will return the
131      * result to the client at a later time via the
132      * onReportDone() callback, above.</p>
133      
134      <p>We start a conversation so that per-client
135      * information will be persisted and correlated.
136      * There may be several clients using this service
137      * simultaneously.  Conversations keep track of
138      * data and message traffic on a per-client basis
139      * automatically.</p>
140      
141      <p>We add the @common:message-buffer tag so the client
142      * doesn't syncrhonously wait for a return from
143      * this request.</p>
144      *
145      * @common:operation
146      * @jws:conversation phase="start"
147      * @common:message-buffer enable="true"
148      */
149     public void requestReport(String ssn)
150     {
151         // Request information from the bank
152         bankControl.startCustomerAnalysis(ssn);
153         
154         // Request information from the IRS
155         irsControl.requestTaxReport(ssn);
156         
157         /*
158          * Both of the external services will return
159          * their responses to us via callbacks that
160          * we will recieve via the handlers
161          * bank_onDeliverAnalysis and irs_onDeliverTaxReport,
162          * below.  So we're done initiating the request.
163          */
164         return;
165     }
166 
167     /**
168      <p>Request the current status of the request.</p>
169      *
170      <p>For our impatient customers, we can give them
171      * partial results whenever they ask for them.</p>
172      *
173      <p>Since this only makes sense after a request
174      * is initiated (ie., a conversation is started),
175      * this is a continue method that runs
176      * in the context of an existing conversation.</p>
177      *
178      <p>The current result is delivered as an XML
179      * message with its format controlled by
180      * an XQuery map.</p>
181      *
182      * @common:operation
183      * @jws:conversation phase="continue"
184      * @jws:return-xml schema-element="ns0:creditReportReturn" xquery::
185      * declare namespace ns0="http://workshop.bea.com/CreditReport"
186      * declare namespace ns1="http://openuri.org/bea/samples/workshop/creditReport"
187 
188      <ns1:creditReportReturn>
189      *     <ns1:bankReport>{data($input//ns0:bank)}</ns1:bankReport>
190      *     <ns1:taxReport>{data($input//ns0:tax)}</ns1:taxReport>
191      </ns1:creditReportReturn>
192      * ::
193      */
194     public ReportResult getCurrentStatus()
195     {
196         /*
197          * Call an internal helper method to construct
198          * an intermediate result.
199          */
200         return assembleResult();
201     }
202   
203     /**
204      <p>Cancel the credit report request.</p>
205      *
206      <p>This is marked as a finish method so that the
207      * conversation is automatically ended when we
208      * finish processing this message.</p>
209      *
210      <p>We've declared this as a buffered method so the
211      * client doesn't sit around waiting for a return.</p>
212      *
213      * @common:operation
214      * @jws:conversation phase="finish"
215      * @common:message-buffer enable="true"
216      */
217     public void cancelReport()
218     {
219         /*
220          * If we haven't heard form the bank, cancel
221          * the request to the bank.
222          */
223         if (bankReport == null
224         {
225             bankControl.cancelAnalysis();
226         }
227 
228         /*
229          * If we haven't heard form the IRS, cancel
230          * the request to the IRS.
231          */
232         if (taxReport == null)
233         {
234             irsControl.cancelReport();
235         }
236     }
237 
238     /**
239      <p>Handler for the onDeliverAnalysis callback of the Bank.jws
240      * web service.</p>
241      
242      <p>The name of the handler is always the variable name of the
243      * service control ('bank' in this case), followed by an
244      * underscore and the name of the callback.</p>
245      */
246     public void bankControl_onDeliverAnalysis(String analysisResult)
247     {
248         /*
249          * Store the bank result in persistent storage.
250          */
251         bankReport = analysisResult;
252         
253         /*
254          * Notify the client that we have recieved results
255          * from the bank.
256          */
257         callback.onProgressNotify("Bank Report Received");
258         
259         /*
260          * Check to see if all results have been received.
261          * If so, checkIfDone will send the completed
262          * results.
263          */
264         checkIfDone();
265     }
266 
267     /**
268      <p>Handler for the onDeliverTaxReport callback of the IRS.jws
269      * web service.</p>
270      
271      <p>The name of the handler is always the variable name of the
272      * service control ('irs' in this case), followed by an
273      * underscore and the name of the callback.</p>
274      */
275     public void irsControl_onDeliverTaxReport(String report)
276     {
277         /*
278          * Store the IRS result in persistent storage.
279          */
280         taxReport = report;
281         
282         /*
283          * Notify the client that we have recieved results
284          * from the IRS.
285          */
286         callback.onProgressNotify("Tax Report Received");
287         
288         /*
289          * Check to see if all results have been received.
290          * If so, checkIfDone will send the completed
291          * results.
292          */
293         checkIfDone();
294     }
295 
296     /**
297      * A private helper that builds our simple credit report,
298      * using the current (possibly incomplete) results.
299      */
300     private ReportResult assembleResult()
301     {
302         ReportResult result = new ReportResult();
303   
304         /*
305          * Java includes the ?: construct as a shorthand way of
306          * coding if-then-else.  The statement takes the form:
307          
308          * value = condition ? value-if-true : value-if-false
309          
310          * If condition evaluates to true, the value-if-true
311          * expression is evaluated and the result is assigned
312          * to value.  If condition evaluates to false, the
313          * value-if-false expression is evaluated and the
314          * result is assigned to value.
315          */
316         result.bank = (bankReport == null"Not Received" : bankReport;
317         result.tax = (taxReport == null"Not Received" : taxReport;
318   
319         return result;
320     }
321 
322     /**
323      * A private helper that may call "callback.onReportDone" if
324      * we're actually done.
325      */
326     private void checkIfDone()
327     {
328         /*
329          * If all results are back from external services...
330          */
331         if (bankReport != null && taxReport != null)
332         {
333             /*
334              * ... call the client with the completed results.
335              */
336             callback.onReportDone(assembleResult());
337         }
338         return;
339     
340