Skip Headers
Oracle® Application Development Framework Developer's Guide
10g Release 3 (10.1.3)
B25386-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

20.5 Implement the Data Control Class

The data control class must be able to access the data source based on the metadata that was saved during design time. This class is instantiated by the createDataControl method in the data control definition class (see Section 20.4.7, "Creating an Instance of the Data Control").

This class needs to:

Table 20-1 Data Control Interfaces

Interface When to Use

oracle.binding.DataControl

Implement this interface if you do not need to demarcate the start and end of a request and if you do not need transactional support.

oracle.binding.ManagedDataControl

Implement this interface if you need to demarcate the start and end of a request. This interface extends DataControl, which means that you have to implement the methods in DataControl as well.

oracle.binding.TransactionalDataControl

Implement this interface if you need transactional support. The interface requires you to implement the rollbackTransaction and commitTransaction methods, in addition to the methods in the DataControl interface. (TransactionalDataControl extends the DataControl interface.)


20.5.1 Location of JAR Files

The abstract class oracle.adf.model.AbstractImpl is located in the JDEV_HOME/bc4j/lib/adfm.jar file.

The data control interfaces are located in the JDEV_HOME/bc4j/lib/adfbinding.jar file.

20.5.2 Data Control Class Outline

The following class outline for a data control class shows the methods you have to implement:

Example 20-23 Outline for a Data Control Class

import oracle.adf.model.adapter.AbstractImpl;
import oracle.binding.DataControl;
import java.util.HashMap;

public class SampleDataControl extends AbstractImpl implements ManagedDataControl
{
   public boolean invokeOperation(java.util.Map map,
                                  oracle.binding.OperationBinding action)
   {
      // you need to implement this method.
      // see Section 20.5.4, "Implementing the invokeOperation Method".
   }

   public String getName()
   {
      // you need to implement this method.
      // see Section 20.5.5, "Implementing the getName Method".
   }

   public void release(int flags)
   {
      // you need to implement this method.
      // see Section 20.5.6, "Implementing the release Method".
   }

   public Object getDataProvider()
   {
      // you need to implement this method.
      // see Section 20.5.7, "Implementing the getDataProvider Method".
   }
}

20.5.3 Complete Source for the SampleDataControl Class

Example 20-24 shows the complete source for the SampleDataControl class.

Example 20-24 Complete Source for the SampleDataControl Class

package oracle.adfinternal.model.adapter.sample;

import java.io.InputStream;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.naming.Context;

import oracle.binding.ManagedDataControl;
import oracle.binding.OperationInfo;

import oracle.adf.model.adapter.AdapterException;
import oracle.adf.model.adapter.AbstractImpl;
import oracle.adf.model.adapter.dataformat.CSVHandler;

import oracle.adfinternal.model.adapter.url.SmartURL;

// Data control that represents a URL data source with CSV data format.
public class SampleDataControl extends AbstractImpl
   implements ManagedDataControl
{
   //URL to access the data source
   private String mCSVUrl = null;

   public SampleDataControl()
   {
   }

   public SampleDataControl(String csvUrl)
   {
      mCSVUrl = csvUrl;
   }

   public boolean invokeOperation(java.util.Map map,
                                  oracle.binding.OperationBinding action)
   {
      Context ctx = null;
      try
      {
         // We are interested of method action binding only. 
         if (action == null)
         {
            return false;
         }

         OperationInfo method = action.getOperationInfo();
         // No method defined, we are not interested.
         if (method == null)
         {
            return false;
         }

         // Execute only when the adapter execute is invoked
         if (METHOD_EXECUTE.equals(method.getOperationName()))
         {
            Object retVal = null;
            if (mCSVUrl != null)
            {
               SmartURL su = new SmartURL(mCSVUrl);
               InputStream isData = su.openStream();
               CSVHandler csvHandler = 
                                 new CSVHandler(isData,true,"UTF-8",",","\"");
               Map properties = new HashMap();
               retVal = csvHandler.getResult(properties);
            }

            Map rootDataRow = new java.util.HashMap(2);
            rootDataRow.put(SampleDCDef.RESULT_ACC_NAME, retVal);
            ArrayList aRes = new ArrayList(2);
            aRes.add(rootDataRow);

            processResult(aRes.iterator(), map, action);
            return true;
         } 
      }
      catch (AdapterException ae)
      {
         throw ae;
      }
      catch (Exception e)
      {
         throw new AdapterException(e);
      }
      return false;
   }

   /**
   * Perform request level initialization of the DataControl.
   * @param requestCtx a HashMap representing request context.
   */
   public void beginRequest(HashMap requestCtx)
   {
   }

   /**
   * perform request level cleanup of the DataControl.
   * @param requestCtx a HashMap representing request context.
   */
   public void endRequest(HashMap requestCtx)
   {
   }

   /**
   * return false as resetState was deferred to endRequest processing
   */
   public boolean resetState()
   {
      return false;
   }

   /**
   * returns the name of the data control.
   */
   public String getName()
   {
      return mName;
   }

   /**
   * releases all references to the objects in the data provider layer 
   */
   public void release(int flags)
   {
   }

   /**
   * Return the Business Service Object that this datacontrol is associated with.
   */
   public Object getDataProvider()
   {
      return null;
   }

}

20.5.4 Implementing the invokeOperation Method

You must implement the invokeOperation method in your data control class. The framework invokes this method when the user runs the view page.

This method is declared in the DataControl interface. The method has the following signature:

Example 20-25 invokeOperation Signature

public boolean invokeOperation(java.util.Map bindingContext,
                               oracle.binding.OperationBinding action);

The bindingContext parameter contains the return values fetched from the data source. The keys for retrieving the values are generated by the framework. Typically you do not need to process the values unless you need to filter or transform them.

The action parameter specifies the method that generated the values. The method could be a method supported by the underlying service, as in the case of a web service. The framework calls the data control even for some built-in actions if the data control wants to override the default behavior. You can check this parameter to determine if you need to process the action or not. For data controls that represent data sources that do not expose methods, the framework creates an action AbstractImpl.METHOD_EXECUTE to the execute the query for a data control.

The method should return false if it does not handle an action.

In the simple CSV adapter, the invokeOperation method checks that the method is METHOD_EXECUTE before fetching the data. It invokes the CSVHandler class, which invokes the CSVParser class, to get the data from the CSV file.

Example 20-26 invokeOperation Method

   public boolean invokeOperation(java.util.Map map,
                                  oracle.binding.OperationBinding action)
   {
      Context ctx = null;
      try
      {
         // We are interested in method action binding only.
         if (action == null)
         {
            return false;
         }

         OperationInfo method = action.getOperationInfo();
         // No method defined, we are not interested.
         if (method == null)
         {
            return false;
         }

         // Execute only when the adapter execute is invoked
         if (METHOD_EXECUTE.equals(method.getOperationName()))
         {
            Object retVal = null;
            if (mCSVUrl != null)
            {
               SmartURL su = new SmartURL(mCSVUrl);
               InputStream isData = su.openStream();
               CSVHandler csvHandler =
                                 new CSVHandler(isData, true, "UTF-8", ",", "\"");
               Map properties = new HashMap();
               retVal = csvHandler.getResult(properties);
            }

            Map rootDataRow = new java.util.HashMap(2);
            rootDataRow.put(SampleDCDef.RESULT_ACC_NAME, retVal);
            ArrayList aRes = new ArrayList(2);
            aRes.add(rootDataRow);

            processResult(aRes.iterator(), map, action);
            return true;
         } 
      }
      catch (AdapterException ae)
      {
         throw ae;
      }
      catch (Exception e)
      {
         throw new AdapterException(e);
      }
      return false;
   }

Note that invokeOperation calls the processResult method after fetching the data. See the next section for details.

20.5.4.1 About Calling processResult

invokeOperation should call processResult to provide updated values to the framework. The method puts the result into the binding context for the framework to pick up. The method has the following syntax:

Example 20-27 processResult Syntax

public void processResult(Object result,
                          Map bindingContext,
                          oracle.binding.OperationBinding action)

In the result parameter, specify the updated values.

In the bindingContext parameter, specify the binding context. This is typically the same binding context passed into the invokeOperation method.

In the action parameter, specify the operation. This is typically the same action value passed into the invokeOperation method.

20.5.4.2 Return Value for invokeOperation

Return true from invokeOperation if you handled the action in the method. Return false if the action should be handled by the framework.

20.5.5 Implementing the getName Method

Implement the getName method to return the name of the data control as used in a binding context.

This method is declared in the DataControl interface. It has the following signature:

Example 20-28 getName Signature

public String getName();

In the simple CSV adapter, the method simply returns mName, which is a variable defined in the AbstractImpl class.

Example 20-29 getName Method

public String getName()
{
   return mName;
}

20.5.6 Implementing the release Method

The framework calls the release method to release all references to the objects in the data provide layer.

This method is declared in the DataControl interface. It has the following signature:

Example 20-30 release Signature

public void release(int flags);

The flags parameter indicate which references should be released:

  • REL_ALL_REFS: The data control should release all references to the view and model objects.

  • REL_DATA_REFS: The data control should release references to data provider objects.

  • REL_VIEW_REFS: The data control should release all references to view or UI layer objects.

In the simple CSV data control adapter, the release method is empty. However, if your data control uses a connection, it should close and release the connection in this method.

20.5.7 Implementing the getDataProvider Method

This method returns the business service object associated with this data control.

This method is declared in the DataControl interface. It has the following signature:

Example 20-31 getDataProvider Signature

public Object getDataProvider();

In the simple CSV data control adapter, this method just returns null.