Control Factories: Managing Collections of Controls

This topic describes control factories, which are collections of built-in or custom Java control instances.

What Is a Control Factory?

A control factory allows a single application to manage multiple instances of the same control.

For example, imagine a credit approval application that accepts batches of approval requests (one per applicant) and uses an external web service, via a Web Service control, to evaluate the requests. The application could use a control factory to create multiple instances of the Service control and dispatch requests to the Service control instances in parallel. If the control uses callbacks, a single parameterized callback handler in the calling application handles the callbacks received from all of the control instances.

You can only use control factories within a Java Web Service (JWS) or Java Process Definition (JPD) file. For more information on building Java Web Services with WebLogic Workshop, see Building Web Services. For more information on using JPD files, see Guide to Building Business Processes.

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; that is, 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.). Therefore, if you want WebLogic Workshop to automatically generate factory classes for a built-in or custom control, make sure that the name of that control does not end with the word "Factory".

A control factory instance can be included in a file just as a control instance can, with the same Javadoc annotation preceding the factory declaration that would precede a single control declaration.

For example, an ordinary Web Service control is declared as follows:

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

Meanwhile, a Web Service control factory is declared as follows:

   /**
    * @common: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 an application 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.someMethod();


   // 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. For example, if there is a CLASS file or JAVA file or JCX 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 @common: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 application 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

Using WebLogic Built-In Controls

Building Custom Java Controls