Control Factories: Managing Collections of Controls

This topic describes control factories, which are a way to dynamically manage a collection of instances of a control from a web service.

You should first understand WebLogic Workshop controls before reading this topic. To learn about WebLogic Workshop controls, see Controls: Using Resources from a Web Service.

# What Is a Control Factory?

A control factory allows a single web service to manage an n-way relationship with a control. For example, a web service can disassemble the line items of an incoming purchase order and conduct a concurrent conversation with a separate Service control for each of multiple vendors.

# Automatically Generated Factory Classes

For any control interface called MyControl, WebLogic Server generates a control factory interface called MyControlFactory that has the following very simple shape:

    interface MyControlFactory
    {
        MyControl create();
    }

The implicit factory class is located in the same package as the control class. E.g., if the full classname of the control interface is com.myco.mypackage.MyControl then the full classname of the factory is com.myco.mypackage.MyControlFactory. An automatic factory class is not generated if there is a name conflict (i.e., if there is already an explicit user class called MyControlFactory.)

A control factory instance can be put into a JWS file just like a control instance, with the same Javadoc preceding the factory declaration that would precede a single control declaration.

For example, an ordinary Service control would be declared as follows:

       /**
        * @jws:control
        */
       MyServiceControl oneService;

While a Service control factory would be declared as follows:

       /**
        * @jws:control
        */
       MyServiceControlFactory manyServices;

Note again that the set of annotations allowed and required on a factory are exactly the same as the set of annotations on the corresponding control. The factory behaves as if those annotations were on every instance created by the factory.

Once a web service includes a control factory declaration, a new instance of a single control can be created as follows:

       // creates one control
       MyServiceControl c = manyServices.create();

       // then you can just use the control, store it, or whatever.
       c.someMethot();

       // For example, let's associate a name with the service...
       serviceMap.put("First Service", c);

Factory classes are automatically generated on-demand, as follows. When resolving a class named FooFactory:

1. First the class is resolved normally, i.e., if there is a CLASS file or JAVA file or CTRL file that contains a definition for FooFactory, then the explicitly defined class is used.

2. If there is no explicit class FooFactory, then, since the classname ends in "Factory", we remove the suffix and look for an explicit class called Foo (in the same package).

3. If Foo is found but does not implement the Control interface (i.e., is not annotated with @jws:control), it's considered an error (as if Foo were never found).

4. However, if Foo is found and implements the Control interface, then the interface FooFactory is automatically created; the interface contains only the single create() method that returns the Foo class.

All instances of the control are destroyed when the web service instance that created them is destroyed.

# Parameterized Callback Handlers

Since there may be multiple controls that were created with a single control factory, and they all have the same instance name, a mechanism is provided to enable you to tell which instance of the control is sending a callback.

For example, for the oneService example above, an event handler still has the following form:

        void oneService_onSomeCallback(String arg)
        {
            System.out.println("arg is " + arg);
        }

For callback handlers that are receiving callbacks from factory-created control instances, the callback handler must take an extra first parameter that is in addition to the ordinary parameters of the callback. The first parameter is typed as the control interface, and the control instance is passed to the event handler.

The manyServices factory callback handler looks like this:

       void manyServices_onSomeCallback(MyServiceControl c, String arg)
       {
           // let's retrieve the remembered name associated with the control
           String serviceName = (String)serviceMap.get(c);

           // and print it out
           System.out.println("Event received from " + serviceName);
       }

Related Topics

Controls: Using Resources from a Web Service

ServiceFactoryClient.jws Sample