You can use a top-down approach that starts from Web Services
Description Language (WSDL) or XML definition files to develop Service
Component Architecture (SCA) component implementations that use Service
Data Objects (SDO) 2.1.1 (JSR 235).
Before you begin
Install Feature Pack for SCA Version 1.0.1 and enable SDO.
Instructions on enabling the SDO feature are in the installation topics
for your operating system.
Consider installing a Rational® Application Developer product with
SCA Development Tools that you can use to assemble service-oriented
application components based on open SCA specifications. See the Rational
Application Developer documentation.
Access the default HelperContext
programmatically in a Java or
Java Platform, Enterprise Edition (Java EE) component implementation
type. Complete step 1 of Using SDO
2.1.1 in SCA applications.
- Describe the service interface in your WSDL and XSD definition
files.
The following example WSDL and XSD files describe
a service interface.
Example WSDL file, test.wsdl:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://test" xmlns:tns="http://test"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Test">
<wsdl:types>
<schema targetNamespace="http://test" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:p="http://person">
<import namespace="http://person" schemaLocation="person.xsd"/>
<element name="updateAccount">
<complexType>
<sequence>
<element name="person" type="p:Person"/>
<element name="code" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="updateAccountResponse">
<complexType>
<sequence>
<element name="response" type="p:Status"/>
</sequence>
</complexType>
</element>
</schema>
</wsdl:types>
<wsdl:message name="PersonRequestMessage">
<wsdl:part element="tns:updateAccount" name="parameters"/>
</wsdl:message>
<wsdl:message name="PersonResponseMessage">
<wsdl:part element="tns:updateAccountResponse" name="parameters"/>
</wsdl:message>
<wsdl:portType name="Test">
<wsdl:operation name="updateAccount">
<wsdl:input message="tns:PersonRequestMessage" name="ReqMsgName"/>
<wsdl:output message="tns:PersonResponseMessage" name="RespMsgName"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TestSoapBinding" type="tns:Test">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="updateAccount">
<wsdlsoap:operation soapAction="urn:updateAccount"/>
<wsdl:input name="ReqMsgName">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="RespMsgName">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TestService">
<wsdl:port binding="tns:TestSoapBinding" name="TestSoapPort">
<wsdlsoap:address location=""/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Example XSD file, person.xsd,
that test.wsdl imports:
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="http://person" xmlns="http://www.w3.org/2001/XMLSchema">
<complexType name="Person">
<sequence>
<element name="firstName" type="string"/>
<element name="lastName" type="string"/>
</sequence>
</complexType>
<complexType name="Status">
<sequence>
<element name="statusCode" type="int"/>
<element name="message" type="string"/>
</sequence>
</complexType>
</schema>
- Produce a corresponding Java interface.
If
you are using an IBM® Rational tool that supports
SCA, you do not need to complete this step. The tool generates the
code for you. Proceed to step 3.
If you are not using a Rational tool that supports
SCA, you can manually produce a Java interface from a WSDL file by
completing this step 2, which provides an example that modifies generated
code. There is not an automated tool to produce a Java interface from a command-line interface.
- Identify the WSDL and XSD files from which you want
to produce Java interfaces.
This example uses the test.wsdl and person.xsd files
in step 1.
- Run the wsimport command with the -s option
to save source files.
wsimport.bat -s . test.wsdl
- Among the generated Java files, identify the SEI.
The SEI is a Java interface, and not a class file, with a
class-level @WebService annotation, javax.jws.WebService.
In
this example, the Java interface is the test/Test.java file.
Running the wsimport command produces the following
output:
//
// Generated By:JAX-WS RI, IBM 2.1.1 in JDK 6 (JAXB RI, IBM JAXB 2.1.3 in JDK 1.6)
//
package test;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import person.Person;
import person.Status;
@WebService(name = "Test", targetNamespace = "http://test")
@XmlSeeAlso({
person.ObjectFactory.class,
test.ObjectFactory.class
})
public interface Test {
/**
*
* @param person
* @param code
* @return
* returns person.Status
*/
@WebMethod(action = "urn:updateAccount")
@WebResult(name = "response", targetNamespace = "")
@RequestWrapper(localName = "updateAccount", targetNamespace =
"http://test", className = "test.UpdateAccount")
@ResponseWrapper(localName = "updateAccountResponse", targetNamespace =
"http://test", className = "test.UpdateAccountResponse")
public Status updateAccount(
@WebParam(name = "person", targetNamespace = "")
Person person,
@WebParam(name = "code", targetNamespace = "")
String code);
}
- Modify the SEI.
- For all parameter and return values of generated (JAXB) types,
change the Java type to commonj.sdo.DataObject. All
complex schema types must map to commonj.sdo.DataObject Java
types. Also, remove all imports of these generated JAXB types.
- For each @RequestWrapper and @ResponseWrapper annotation, change
the value of the className element to commonj.sdo.DataObject.
Otherwise, leave the JAX-WS annotations because they are significant.
- Remove or comment out the @XmlSeeAlso block.
Completing these steps results in the following Java
interface:
//
// Generated By:JAX-WS RI, IBM 2.1.1 in JDK 6 (JAXB RI, IBM JAXB 2.1.3 in JDK 1.6)
//
package test;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import commonj.sdo.DataObject;
@WebService(name = "Test", targetNamespace = "http://test")
public interface Test {
/**
*
* @param person
* @param code
* @return
* returns person.Status
*/
@WebMethod(action = "urn:updateAccount")
@WebResult(name = "response", targetNamespace = "")
@RequestWrapper(localName = "updateAccount", targetNamespace =
"http://test", className = "commonj.sdo.DataObject")
@ResponseWrapper(localName = "updateAccountResponse", targetNamespace =
"http://test", className = "commonj.sdo.DataObject")
public DataObject updateAccount(
@WebParam(name = "person", targetNamespace = "")
DataObject person,
@WebParam(name = "code", targetNamespace = "")
String code);
}
The following example shows the resulting code with
JAX-WS annotations removed for readability only. Do not remove the
annotations before compiling to use the example code.
package test;
import commonj.sdo.DataObject;
public interface Test {
public DataObject updateAccount(DataObject person, String code);
}
- Write your SCA Java client or component implementation
using the dynamic SDO programming model.
The following
example code shows a service implementation in Java:
package test.impl;
import test.Test;
import org.osoa.sca.annotations.Service;
import commonj.sdo.DataObject;
import commonj.sdo.helper.DataFactory;
import commonj.sdo.helper.HelperContext;
import com.ibm.websphere.soa.sca.sdo.DefaultHelperContext;
@Service(Test.class)
public class TestImpl implements Test {
@DefaultHelperContext
protected HelperContext myDefaultHC;
public DataObject updateAccount(DataObject person, String code) {
String error_msg = null;
if (code.equals("ERROR_STRING_IN_FIELD1")) {
error_msg = “ERROR firstName: ” + person.getString(“firstName”0);
HelperContext defaultHC = ContextHelper.getCurrentHelperContext();
DataFactory dataFactory = myDefaultHCdefaultHC.getDataFactory();
DataObject returnDO = dataFactory.create("http://person","Status");
returnDO.setInt("statusCode", -1);
returnDO.setString("message", error_msg);
return returnDO;
} else {
// process(person);
...
}
}
}
The input person DataObject
is of type {http://person}Person. The returned output
DataObject is of type {http://person}Status. Both
the input and output are registered in the SCA application default
HelperContext that is accessed using the myDefaultHC object.
- In a composite definition, declare your component reference
or component service interface with an <interface.wsdl> element
that refers to the original portType value.
Example accountTest.composite file:
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://www.ibm.com/test/soa/sca/sdo/"
name="AccountTestComposite">
<component name="AccountTestComponent">
<implementation.java class="test.impl.TestImpl"/>
<service name="Test">
<interface.wsdl interface="http://test#wsdl.interface(Test)"/>
</service>
...
</component>
</composite>
- Package the composite and deploy the component with the
authored implementation along with the WSDL or XSD files into a single
contribution JAR file.
Suppose the example files
are packaged into a single file, MyAccountTestContribution.jar.
A listing of the JAR file contents from the command line is as follows:
$ jar tf MyAccountTestContribution.jar
wsdl/test.wsdl
wsdl/person.xsd
test/Test.class
test/impl/TestImpl.class
META-INF/accountTest.composite
META-INF/sca-contribution.xml
What to do next
Optionally, implement shared scopes. See the topic on
using SDO 2.1.1 in SCA applications.
Deploy your files that
use SDO in an SCA business-level application.