Oracle® Application Development Framework Developer's Guide
10g Release 3 (10.1.3) B25386-01 |
|
![]() Previous |
![]() Next |
This class needs to provide all the information that the framework needs to instantiate a data control during design time and runtime. This class is responsible for performing these operations:
creating a default constructor. See Section 20.4.4, "Creating a Default Constructor".
collecting metadata from the user about the data source. See Section 20.4.5, "Collecting Metadata from the User".
defining the structure of the output. The structure defines what the user sees when the user expands the data control in the Data Control Palette. The user can then drag elements from the data control entry in the Data Control Palette to a page to create a view component. See Section 20.4.6, "Defining the Structure of the Data Control".
creating an instance of the data control class using that metadata. The data control class is a class that you implement. See Section 20.4.7, "Creating an Instance of the Data Control".
enabling the framework to load the metadata from the DCX file. See Section 20.4.8, "Setting the Metadata for Runtime".
setting a name for your data control. See Section 20.4.9, "Setting the Name for the Data Control".
The data control definition class needs to extend the abstract class oracle.adf.model.adapter.AbstractDefinition
. This class is located in the JDEV_HOME/bc4j/lib/adfm.jar
file.
Example 20-9 is an outline showing the methods you have to implement when you create a data control definition class. The sample is taken from SampleDCDef
, which is the data control definition class for the simple CSV data control adapter.
Example 20-9 Outline for the Data Control Definition Class
import oracle.adf.model.adapter.AbstractDefinition; import org.w3c.dom.Node; import oracle.binding.meta.StructureDefinition; import oracle.binding.DataControl; import java.util.Map; public class SampleDCDef extends AbstractDefinition { // default constructor public SampleDCDef () { // you need a default constructor. // see Section 20.4.4, "Creating a Default Constructor". } public Node getMetadata() { // you need to implement this method. // see Section 20.4.5, "Collecting Metadata from the User". } public StructureDefinition getStructure() { // you need to implement this method. // see Section 20.4.6, "Defining the Structure of the Data Control". } public DataControl createDataControl() { // you need to implement this method. // see Section 20.4.7, "Creating an Instance of the Data Control". } public void loadFromMetadata(Node node, Map params) { // you need to implement this method. // see Section 20.4.8, "Setting the Metadata for Runtime". } public String getDCName() { // you need to implement this method. // see Section 20.4.9, "Setting the Name for the Data Control". } }
Example 20-10 shows the complete source for the SampleDCDef
class:
Example 20-10 Complete Source for the SampleDCDef Class
package oracle.adfinternal.model.adapter.sample; import java.io.InputStream; import java.util.Map; import oracle.binding.DataControl; import oracle.binding.meta.StructureDefinition; import oracle.adf.model.adapter.AbstractDefinition; import oracle.adf.model.adapter.AdapterDCService; import oracle.adf.model.adapter.AdapterException; import oracle.adf.model.adapter.dataformat.AccessorDef; import oracle.adf.model.adapter.dataformat.StructureDef; import oracle.adf.model.adapter.utils.NodeAttributeHelper; import oracle.adf.model.utils.SimpleStringBuffer; import oracle.adfinternal.model.adapter.sample.CSVHandler; import oracle.adfinternal.model.adapter.sample.SampleDataControl; import oracle.adfinternal.model.adapter.url.SmartURL; import oracle.xml.parser.v2.XMLDocument; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class SampleDCDef extends AbstractDefinition { // Name of the root accessor for a definition public static final String RESULT_ACC_NAME = "Result"; // Namespace for the metadata definition. public static final String SAMPLEDC_NS = "http://xmlns.oracle.com/adfm/adapter/sampledc"; // Definition tag as the root public static final String DEFINITION = "Definition"; // Attribute to contain the source URL public static final String SOURCE_LOC = "SourceLocation"; // Name of the data control private String mName = "SampleDC"; // the structure definition private StructureDef mStructDef = null; // URL for this definition. private String mCSVUrl = null; public SampleDCDef() { } public SampleDCDef(String csvURL,String dcName) { mCSVUrl = csvURL; mName = dcName; } public Node getMetadata() { XMLDocument xDoc = new XMLDocument(); Element metadata = xDoc.createElementNS(SAMPLEDC_NS, DEFINITION); metadata.setAttribute(SOURCE_LOC, mCSVUrl.toString()); return metadata; } public StructureDefinition getStructure() { if (mStructDef == null) { // create an empty StructureDefinition mStructDef = new StructureDef(getName()); SmartURL su = new SmartURL(mCSVUrl.toString()); InputStream isData = su.openStream(); CSVHandler csvHandler = new CSVHandler(isData, true, "UTF-8", ",", "\""); // Name of the accessor or the method structure to hold the attributes String opName = new SimpleStringBuffer(50).append(getDCName()) .append("_") .append(RESULT_ACC_NAME) .toString(); StructureDef def = (StructureDef)csvHandler.getStructure(opName, null); // Create the accessor definition AccessorDef accDef = new AccessorDef(RESULT_ACC_NAME, mStructDef, def, true); def.setParentType(StructureDef.TYPE_ACCESSOR); accDef.setBindPath(new SimpleStringBuffer(50) .append(mStructDef.getFullName()) .append(".") .append(AdapterDCService.DC_ROOT_ACC_NAME) .toString()); mStructDef.addAccessor(accDef); } return mStructDef; } public void loadFromMetadata(Node node, Map params) { try { // Get the information from the definition NodeList listChld = node.getChildNodes(); int cnt = listChld.getLength(); Node chld; for (int i = 0; i < cnt; i++) { chld = listChld.item(i); // System.out.println("Tag: " + chld.getNodeName()); if (DEFINITION.equalsIgnoreCase(chld.getNodeName())) { // Load the required attributes NodeAttributeHelper attribs = new NodeAttributeHelper(chld.getAttributes()); mCSVUrl = attribs.getValue(SOURCE_LOC); } } } catch (AdapterException ae) { throw ae; } catch (Exception e) { throw new AdapterException(e); } } public DataControl createDataControl() { SampleDataControl dcDataControl = new SampleDataControl(mCSVUrl); return dcDataControl; } public String getDCName() { return mName; } public String getAdapterType() { return "oracle.adfm.adapter.SampleDataControl"; } }
You need to create a default constructor for the data control definition class. The simple CSV adapter has an empty default constructor:
The default constructor is used only during runtime. It is not used during design time.
Metadata in a data control adapter provides information on the data source. The data control definition class uses the metadata to create a data control. Examples of metadata for the full-featured CSV data control adapter include the URL to the CSV file, the field separator character, and the quote character. For the simple CSV adapter, the metadata consists of only the location of the CSV file.
A data control adapter can collect metadata in different ways. Examples:
The CSV data control adapter that comes with JDeveloper uses a wizard to collect metadata from the user.
The web service data control adapter also uses a wizard to collect metadata. Alternatively, users can drag a web service connection node and drop it on the Data Control Palette. The web service adapter extracts metadata from the node instead of launching the wizard.
When the user drags and drops a node onto the Data Control Palette, the adapter framework looks for an adapter that can handle the type of node that was dropped by searching the registered data control adapters. Data control adapters declare which node types they support. The nodes are JDeveloper nodes that represent specific source types. When the framework finds an adapter that supports the type of node that was dropped, it invokes the data control adapter, which then extracts the required information from the node.
The simple CSV adapter extracts metadata from a node when the user right-clicks a node and selects "Create Data Control" from the context menu.
Regardless of how a data control adapter retrieves the metadata, you must implement the getMetadata
method in your data control definition class. The framework calls the method to get the metadata.
This method returns the metadata in the form of a Node
object. The getMetadata
method has the following signature:
In the simple CSV adapter, the getMetadata
method retrieves the metadata from the mCSVUrl
class variable and inserts the value in an Element
object.
Example 20-13 getMetadata Method
public Node getMetadata() { XMLDocument xDoc = new XMLDocument(); Element metadata = xDoc.createElementNS(SAMPLEDC_NS, DEFINITION); metadata.setAttribute(SOURCE_LOC, mCSVUrl.toString()); return metadata; }
The framework extracts the information from getMetadata
's return value (the Node
object) and writes the information to the DataControls.dcx
file. For example, after the user has created a CSV data control, the file looks like the following:
Example 20-14 DataControls.dcx File
<?xml version="1.0" encoding="UTF-8" ?> <DataControlConfigs xmlns="http://xmlns.oracle.com/adfm/configuration" version="10.1.3.36.45" Package="view" id="DataControls"> <AdapterDataControl id="testdata" FactoryClass="oracle.adf.model.adapter.DataControlFactoryImpl" ImplDef="oracle.adfinternal.model.adapter.sample.SampleDCDef" SupportsTransactions="false" SupportsSortCollection="false" SupportsResetState="false" SupportsRangesize="false" SupportsFindMode="false" SupportsUpdates="false" Definition="testdata" BeanClass="testdata" xmlns="http://xmlns.oracle.com/adfm/datacontrol"> <Source> <Definition SourceLocation="/C:/Application1/ViewController/public_html/testdata.csv"/> </Source> </AdapterDataControl> </DataControlConfigs>
The value of the id
attribute of the AdapterDataControl
tag ("testdata
") is extracted from the name of the CSV file. The other attributes in the AdapterDataControl
tag contain information about the simple CSV adapter itself. In the Definition
element, the framework writes the metadata provided by the node; the SourceLocation
attribute specifies the location of the CSV file.
Structure in a data control definition describes the items that appear when the user expands the data control in the Data Control Palette. Items that can appear include methods, accessors, and attributes of the underlying service that are available to the user to invoke or display. The user can drag these items onto a view page.
In your data control definition class, you need to implement the getStructure
method. The framework calls this method when the user expands the data control in the Data Control Palette.
The getStructure
method has the following signature:
StructureDefinition
is an interface. You can find more information about this interface in the online help in JDeveloper, under Reference > Oracle ADF Model API Reference.
Example 20-16 getStructure Method
public StructureDefinition getStructure() { if (mStructDef == null) { // create an empty StructureDefinition mStructDef = new StructureDef(getName()); SmartURL su = new SmartURL(mCSVUrl.toString()); InputStream isData = su.openStream(); CSVHandler csvHandler = new CSVHandler(isData, true, "UTF-8", ",", "\""); // Name of the accessor or the method structure to hold the attributes String opName = new SimpleStringBuffer(50).append(getDCName()) .append("_") .append(RESULT_ACC_NAME) .toString(); StructureDef def = (StructureDef)csvHandler.getStructure(opName, null); // Create the accessor definition AccessorDef accDef = new AccessorDef(RESULT_ACC_NAME, mStructDef, def, true); def.setParentType(StructureDef.TYPE_ACCESSOR); accDef.setBindPath(new SimpleStringBuffer(50) .append(mStructDef.getFullName()) .append(".") .append(AdapterDCService.DC_ROOT_ACC_NAME) .toString()); mStructDef.addAccessor(accDef); } return mStructDef; }
The framework calls the createDataControl
method in the data control definition class to create a data control instance. The createDataControl
method has the following signature:
The DataControl
object returned by the method is an instance of the data control class that you create. Section 20.5, "Implement the Data Control Class" describes this class.
In the data control definition for the simple CSV adapter, the createDataControl
method looks like the following:
Example 20-18 createDataControl Method
public DataControl createDataControl() { SampleDataControl dcDataControl = new SampleDataControl(mCSVUrl); return dcDataControl; }
The SampleDataControl
class is described in more detail in Section 20.5, "Implement the Data Control Class".
When the user runs the view page that references your data control, the framework reads the metadata from the DCX file and invokes the loadFromMetadata
method in the data control definition class to load the data control with the metadata saved during design time.
Recall that the framework wrote the metadata to the DCX file in the getMetadata
method. See Section 20.4.5, "Collecting Metadata from the User".
The loadFromMetadata
method has the following signature:
Example 20-19 loadFromMetadata Signature
public void loadFromMetadata(org.w3c.dom.Node node, java.util.Map params);
The node
parameter contains the metadata. In the simple CSV adapter, the method looks like the following:
Example 20-20 loadFromMetadata Method
public void loadFromMetadata(Node node, Map params) { try { // Get the information from the definition NodeList listChld = node.getChildNodes(); int cnt = listChld.getLength(); Node chld; for (int i = 0; i < cnt; i++) { chld = listChld.item(i); // System.out.println("Tag: " + chld.getNodeName()); if (DEFINITION.equalsIgnoreCase(chld.getNodeName())) { // Load the required attributes NodeAttributeHelper attribs = new NodeAttributeHelper(chld.getAttributes()); mCSVUrl = attribs.getValue(SOURCE_LOC); } } } catch (AdapterException ae) { throw ae; } catch (Exception e) { throw new AdapterException(e); } }
You need to implement the getDCName
method to return a string that is used to identify the data control instance in the Data Control Palette. getDCName
has the following signature:
In the simple CSV adapter, the method just returns the value of the mName
class variable, which was set by the SampleDCDef(String csvURL, String dcName)
constructor. This constructor was called in the SampleDCAdapter
class. mName
is the name of the CSV file without the .csv
extension.
Note that each data control instance must have a unique name within an application. For example, if you have two CSV data controls in an application, you can name them "CSV1" and "CSV2". For the CSV data control adapter that is shipped with JDeveloper, the user can enter the name in the wizard. For the simple CSV adapter, the name is the name of the CSV file without the .csv
extension.