# ServiceFactoryClient.jws Sample

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

## Sample Location

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

BEA_HOME/weblogic81/samples/workshop/SamplesApp/WebServices/controlFactory/

## Sample Source Code

`001 package controlFactory; 002 003 import java.util.HashMap; 004 import java.io.Serializable; 005 006 /** 007 * <p>Demonstrates use of a control factory.</p> 008 * 009 * <p>A control factory is used to dynamically create multiple 010 * instances of a Service control. When all instances of the 011 * Service control have returned results, a callback is sent 012 * to the client listing the result of each Service control.</p> 013 * @common:xmlns namespace="http://openuri.org/bea/samples/workshop/controlFactory" prefix="ns0" 014 * @common:target-namespace namespace="http://workshop.bea.com/ServiceFactoryClient" 015 */ 016 public class ServiceFactoryClient implements com.bea.jws.WebService 017 { 018 /** 019 * @common:control 020 */ 021 private controlFactory.SlowServiceControlFactory m_services; 022 023 int m_numServices; 024 int m_numServicesReturned; 025 HashMap m_serviceHash; 026 Result [] m_results; 027 028 /** 029 * A utility class used to collect and return results 030 */ 031 public static class Result implements Serializable 032 { 033 public String name; 034 public long time; 035 036 public Result(){}; 037 } 038 039 public Callback callback; 040 041 public interface Callback 042 { 043 /** 044 * Callback used to return results to the client. An array 045 * of Result objects is serialized into the outgoing XML 046 * message using an XQuery map. 047 * 048 * @jws:conversation phase="finish" 049 * @jws:parameter-xml schema-element="ns0:completeServices" xquery:: 050 * declare namespace ns0="http://workshop.bea.com/ServiceFactoryClient" 051 * declare namespace ns1="http://openuri.org/bea/samples/workshop/controlFactory" 052 * 053 * let $i := $input/ns0:result 054 * return 055 * <ns1:completeServices> 056 * <ns1:result> 057 * {for $r in $i/ns0:Result 058 * return 059 * <ns1:service> 060 * <ns1:name>{data($r/ns0:name)}</ns1:name> 061 * <ns1:time>{data($r/ns0:time)}</ns1:time> 062 * </ns1:service>} 063 * </ns1:result> 064 * </ns1:completeServices>:: 065 */ 066 public void allServicesComplete(Result [] result); 067 } 068 069 /** 070 * <p>Launch the number of instances of the service control that 071 * are specified by <b>numServices</b>.</p> 072 * 073 * @common:operation 074 * @jws:conversation phase="start" 075 */ 076 public void startServices(int numServices) 077 { 078 int i; 079 080 if(numServices > 0) 081 { 082 m_numServices = numServices; 083 m_numServicesReturned = 0; 084 m_serviceHash = new HashMap(); 085 m_results = new Result[numServices]; 086 087 for(i=0; i<numServices; i++) 088 { 089 String serviceName = "Service" + i; 090 091 // use the control factory's create method to create a control instance 092 controlFactory.SlowServiceControl service = m_services.create(); 093 094 // use the control like you would any other control 095 service.requestInfo(serviceName); 096 097 // stash the time each control is launched, indexed by instance name 098 m_serviceHash.put(serviceName, new Long((new java.util.Date().getTime()))); 099 } 100 } 101 } 102 103 104 105 /** 106 * <p>Callback handler for the control's infoReady callback.</p> 107 * 108 * <p>For a control factory, callback handlers take an extra argument that is 109 * the control instance, so that the handler code can tell which control is 110 * sending the callback.</p> 111 */ 112 private void m_services_infoReady(SlowServiceControl service, String name) 113 { 114 // compute how many seconds since this control was launched 115 long timeTaken = (new java.util.Date().getTime() - ((Long)m_serviceHash.get(name)).longValue()) / 1000; 116 117 // make a new Result object and populate it with control name and time taken 118 m_results[m_numServicesReturned] = new Result(); 119 m_results[m_numServicesReturned].name = name; 120 m_results[m_numServicesReturned].time = timeTaken; 121 122 // keep tack of how many services have returned 123 m_numServicesReturned++; 124 125 // when all services have returned, tell the client via the callback 126 if(m_numServicesReturned == m_numServices) 127 { 128 callback.allServicesComplete(m_results); 129 } 130 } 131 132 }`