WSDLEditorWSDLWizardExtensionHowTo

How to provide customized steps for binding components in the wsdl wizard.

The following section describes how a Binding Component can plug in its own wizard configuration panels. These binding wizard panel(s) can be integrated from the existing WSDL Wizard to provide concrete configurations of binding-specific parameters.

Brief summary of how the plugin works from the WSDL Wizard

From the WSDL Wizard's first panel, the user can select the type of WSDL to create:

____
[[{ImageSrc=WSDLType_WSDLEditorWSDLWizardExtensionHowTo.PNG} | {Image src=WSDLType_WSDLEditorWSDLWizardExtensionHowTo.PNG'}]]
':'Abstract WSDL Document - generates a wsdl without the binding-specific definitions
':'Concrete WSDL Document - generates a wsdl with the binding-specific definitions

Selecting the Concrete WSDL Document will prompt the user to select the Binding and its associated Type:

____
[[{ImageSrc=BindingSelected_WSDLEditorWSDLWizardExtensionHowTo.PNG} | {Image src=BindingSelected_WSDLEditorWSDLWizardExtensionHowTo.PNG'}]]

Selecting a Binding invokes that Binding Component to provide its implementation as a pluggable module with its wizard binding panel(s). As part of this pluggable contract, the BC needs to provide their own wizard iterator which defines the steps and corresponding wizard panels for that particular BC.

If the Binding selected has a WSDLWizardExtensionIterator implementation, this iterator class would be instantiated and its setTemplateName method will be called. The BC plugin should initialize the steps and the corresponding wizard panel per each step in this method. The Steps text on the left side of the wizard will be updated based on the steps provided by the BC plugin as well as the available selected Type or templates.

____
[[{ImageSrc=BindingSteps_WSDLEditorWSDLWizardExtensionHowTo.PNG} | {Image src=BindingSteps_WSDLEditorWSDLWizardExtensionHowTo.PNG'}]]

When Next is clicked on, WSDLWizardExtensionIterator.nextPanel is called first and is followed by a call to WSDLWizardExtensionIterator.current. You can provide logic here in case you want to skip to a particular wizard panel that you have.

When Finish is clicked on, WSDLWizardExtensionIterator.commit is called, where you can persist all the values into the wsdl model provided.

If it does not make sense to provide template files, don't provide wsdlTemplate element. You are free to create your own port type definition and message structure in your panels. Currently there is no way to reuse the default abstract configuration page, if you need to have access to it, let me know, I can update the api for you.


New interfaces to be implemented by BC wsdl extension:

1. WSDLWizardExtensionIterator

____
Provides the iterator, which contains the various panels needed for the BC wizard.

2. WSDLWizardDescriptionPanel

____
Provides for definition of each panel that will be shown in the wizard page.
____
This will be one per panel that you want to add.


Updated interfaces to be implemented by BC wsdl extension:

TemplateProvider api has been updated to return the iterator implementation and provide the template wsdls. It requires 2 new methods to be implemented by the participating BC

1. getWSDLWizardExtensionIterator(WSDLWizardContext context)

____
Return the iterator instance here.

2. getTemplateInputStream(String relativePath)

____
Return the input stream of the template wsdl file here.

The following steps describes how a Binding Component can plug in its binding wizard panels. The snippet of code used was taken from the File BC implementation and is available in the soa-dev branch under the wsdlextension.file module.

Step 1
Define the various templates specific to the binding component's direction mode. For File BC, there are 4 specific templates:
____
a. InboundOneWay.wsdl
____
b. OutboundOneWay.wsdl
____
c. InboundRequestResponse.wsdl
____
d. SyncRead.wsdl
Step 2
Modify the BC's existing template provider template.xml to include the templates defined above along with the default template. Previously, this document called for removing the default template but to allow support from CASA, the default template needs to be put back. The above templates will be used by the WSDL Wizard and the default one will be used from CASA.
____
Here is a sample implementation from the File Binding component:
    <template name="defaultSkeleton" skeleton="true">
        <wsdlElement name="Binding">
            <extensionElement name="binding"/>
        </wsdlElement>
        <wsdlElement name="BindingOperation">
            <extensionElement name="operation">
                <extensionAttr name="verb" defaultValue="poll"/>
            </extensionElement>
        </wsdlElement>
        <wsdlElement name="BindingOperationInput">
            <extensionElement name="message">
                <extensionAttr name="use" defaultValue="literal" />
                <extensionAttr name="fileName" defaultValue="test.xml" />
                <extensionAttr name="pollingInterval" defaultValue="1000" />
            </extensionElement>
        </wsdlElement>
        <wsdlElement name="BindingOperationOutput">
            <extensionElement name="message" >
                <extensionAttr name="use" defaultValue="literal" />
                <extensionAttr name="fileName" defaultValue="output.xml" />
            </extensionElement>
        </wsdlElement>
        <wsdlElement name="ServicePort">
            <extensionElement name="address" >
                <extensionAttr name="fileDirectory"  defaultValue="C:\Temp"/>
                <extensionAttr name="lockName"  defaultValue="filebc.lck"/>
                <extensionAttr name="workArea"  defaultValue="filebc-in-processing"/>
                <extensionAttr name="seqName"  defaultValue="filebc.seq"/>
            </extensionElement>
        </wsdlElement>
    </template>
    <template name="Inbound One Way" default="true">
        <wsdlTemplate file="wsdltemplates/InboundOneWay.wsdl"/>
        <wsdlElement name="Binding">
            <extensionElement name="binding"/>
        </wsdlElement>
        <wsdlElement name="BindingOperation">
            <extensionElement name="operation"/>
        </wsdlElement>
        <wsdlElement name="BindingOperationInput">
            <extensionElement name="message"/>
        </wsdlElement>
        <wsdlElement name="BindingOperationOutput">
            <extensionElement name="message"/>
        </wsdlElement>
        <wsdlElement name="ServicePort">
            <extensionElement name="address"/>
        </wsdlElement>
    </template>
    <template name="Inbound Request Response">
        <wsdlTemplate file="wsdltemplates/InboundRequestResponse.wsdl"/>
        <wsdlElement name="Binding">
            <extensionElement name="binding"/>
        </wsdlElement>
        <wsdlElement name="BindingOperation">
            <extensionElement name="operation"/>
        </wsdlElement>
        <wsdlElement name="BindingOperationInput">
            <extensionElement name="message"/>
        </wsdlElement>
        <wsdlElement name="BindingOperationOutput">
            <extensionElement name="message"/>
        </wsdlElement>
        <wsdlElement name="ServicePort">
            <extensionElement name="address"/>
        </wsdlElement>
    </template>
    <template name="Outbound One Way">
        <wsdlTemplate file="wsdltemplates/OutboundOneWay.wsdl"/>
        <wsdlElement name="Binding">
            <extensionElement name="binding"/>
        </wsdlElement>
        <wsdlElement name="BindingOperation">
            <extensionElement name="operation"/>
        </wsdlElement>
        <wsdlElement name="BindingOperationInput">
            <extensionElement name="message"/>
        </wsdlElement>
        <wsdlElement name="BindingOperationOutput">
            <extensionElement name="message"/>
        </wsdlElement>
        <wsdlElement name="ServicePort">
            <extensionElement name="address"/>
        </wsdlElement>
    </template>
    <template name="Solicited Read">
        <wsdlTemplate file="wsdltemplates/SyncRead.wsdl"/>
        <wsdlElement name="Binding">
            <extensionElement name="binding"/>
        </wsdlElement>
        <wsdlElement name="BindingOperation">
            <extensionElement name="operation"/>
        </wsdlElement>
        <wsdlElement name="BindingOperationInput">
            <extensionElement name="message"/>
        </wsdlElement>
        <wsdlElement name="BindingOperationOutput">
            <extensionElement name="message"/>
        </wsdlElement>
        <wsdlElement name="ServicePort">
            <extensionElement name="address"/>
        </wsdlElement>
    </template>

}}

Step 3
Modify the BC's existing ExtensibilityElementTemplateProvider to implement 2 new interface:
':'getTemplateFileInputStream - should provide the input stream to the new template.xml.
':'getWSDLWizardExtensionIterator should provide the class that handles the wizard iterator that contains the BC wizard panels
____
Here is a sample implementation from the File Binding component:
    @Override
    public InputStream getTemplateFileInputStream(String filePath) {
        return FileTemplateProvider.class.getResourceAsStream("/org/netbeans/modules/wsdlextensions/file/template/" + filePath);
    }
    
    @override
    public WSDLWizardExtensionIterator getWSDLWizardExtensionIterator(WSDLWizardContext context) {
        return new FileWSDLWizardExtensionIterator(context);
    }
Step 4
Create a wizard iterator that will contain the BC wizard panels. This wizard iterator should extend the org.netbeans.modules.xml.wsdl.bindingsupport.spi.WSDLWizardExtensionIterator. Two important methods to implement are:
':'setTemplateName - allows the BC to setup the wizard panel(s) that will be used by the wizard framework.
':'commit - allows the BC to invoke the appropriate commit code for the wizard panel(s)
____
Here is a sample snippet of code from the File Binding component:
    public void setTemplateName(String templateName) {
        this.templateName = templateName;
        currentStepIndex = -1;
   
        if (templateName.equals(NbBundle.getMessage(
                FileWSDLWizardExtensionIterator.class, 
                "TEMPLATE_name_InboundOneWay"))) {
            panels = new WSDLWizardDescriptorPanel[]{
                        new InboundMessageStepWizardPanel(context)
                    };
        } else if (templateName.equals(NbBundle.getMessage(
                FileWSDLWizardExtensionIterator.class, 
                "TEMPLATE_name_OutboundOneWay"))) {
            panels = new WSDLWizardDescriptorPanel[]{
                        new OutboundMessageInStepWizardPanel(context)
                    };
        } else if (templateName.equals(NbBundle.getMessage(
                FileWSDLWizardExtensionIterator.class, 
                "TEMPLATE_name_InboundRequestResponse"))) {
            panels = new WSDLWizardDescriptorPanel[]{
                        new InboundMessageStepWizardPanel(context),
                        new OutboundMessageStepWizardPanel(context)
                    };
        } else if (templateName.equals(NbBundle.getMessage(
                FileWSDLWizardExtensionIterator.class, 
                "TEMPLATE_name_SyncRead"))) {
            panels = new WSDLWizardDescriptorPanel[]{
                        new SolicitedReadStepWizardPanel(context)
                    };
        }
        
        steps = new String[Panels.length];
        int i = 0;
        for (WSDLWizardDescriptorPanel panel : panels) {
            steps[I++] = panel.getName();
        }
        
    }

    public boolean commit() {
        for (WSDLWizardDescriptorPanel panel : panels) {
            if (panel instanceof InboundMessageStepWizardPanel) {                                
                status = ((InboundMessageStepWizardPanel)panel).commit();                        
            } else if (panel instanceof OutboundMessageStepWizardPanel) {
                status = ((OutboundMessageStepWizardPanel)panel).commit();
            } else if (panel instanceof SolicitedReadStepWizardPanel) {
                status = ((SolicitedReadStepWizardPanel)panel).commit();
            }
        }
        ....
   }


Step 5
Create a wizard panel that extends WSDLWizardDescriptorPanel for each of the BC panels. The getComponent implementation will return the actual visual component.
____
Here is a sample snippet of code from the File Binding component for the Inbound One Way panel:
    // Get the visual component for the panel. In this template, the component
    // is kept separate. 
    public Component getComponent() {
        if (mPanel == null) {
            mPanel = new InboundMessagePanel(mQName, mComponent);
        }
                
        return mPanel;
    }


The Binding Component developer is responsible for creating the visual components corresponding to its configuration parameters as well as the retrieval and persistence of these same parameters given the wsdl model. The above setTemplateName() implementation should define the panels corresponding to the visual components to be populated with the model. The commit() implementation should persist the values from the visual components back to the wsdl model.

There should be validation per parameter (if applicable) to ensure validity of the value from the user. For example, if a parameter is of an integer value, visual components should not allow the persistence of non-numeric values. There is however the isValid() implementation that should use the existing binding component's validator code. This is called from the WSDLEditor wizard once the 'Finish' button is clicked on.

The same visual component from the binding wizard panel(s) from Step 5 above can also be used and be pluggable from CASA

Additional Framework support

There's been a few enhancements made to the framework that allows for the Binding Components to add additional usability features.

1. Since each BC predefines the name of the port in their templates, these port names can look the same when multiple ports are used from CASA. So to distinguish each one, you can prepend the name of the wsdl to your port in your template by prepending the string #SERVICE_NAME to the port name. Example below taken from the InboundOneWay.wsdl template for FileBC

    <service name="FileInboundService">
        <port name="#SERVICE_NAME_InboundPort" binding="tns:FileInboundBinding">
            <file:address fileDirectory="c:/temp"/>
        </port>
    </service>

2. You can provide tooltips to your templates by providing in your resource bundle the following format: TEMPLATE_description_<name of your template file>=<your tooltip>

____
Example below taken from the template\Bundle.properties.
    #Description name
    TEMPLATE_description_InboundOneWay=<html>Choose this type for scenarios in which the\
     File BC polls for message(s)<br>from a file directory and invokes a JBI service \
    with the message(s)</html>

3. If you want to post an error to the user based on their input, you can fire an event to the component returned by getComponent implementation. The constants used for reporting the various levels are:


package org.netbeans.modules.xml.wsdl.bindingsupport.spi;

public interface ExtensibilityElementConfigurationEditorComponent {
    public static final String PROPERTY_ERROR_EVT = "PROPERTY_ERROR_EVT";
    public static final String PROPERTY_WARNING_EVT = "PROPERTY_WARNING_EVT";
    public static final String PROPERTY_CLEAR_MESSAGES_EVT = "PROPERTY_CLEAR_MESSAGES_EVT";
    public static final String PROPERTY_NORMAL_MESSAGE_EVT = "PROPERTY_NORMAL_MESSAGE_EVT";
}

Sample usage:

            if (!isValidPatternSpecified()) {
                firePropertyChange(
                        ExtensibilityElementConfigurationEditorComponent.
                        PROPERTY_ERROR_EVT, null, NbBundle.getMessage(
                        FileBindingConfigurationPanel.class,
                        "FileBindingConfigurationPanel.UnsupportedFileNamePattern"));
            }


Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo