Skip Headers

Oracle® Database JPublisher User's Guide
10g Release 1 (10.1)

Part Number B10983-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Feedback

Go to previous page
Previous
Go to next page
Next
View PDF

A Generated Code Examples

This appendix contains generated code examples that do not fit conveniently into the corresponding sections earlier in the manual:

Generated Code: User Subclass for Java-to-Java Transformations

This section contains generated code for the example in "JPublisher-Generated Subclasses for Java-to-Java Type Transformations". This example uses style files and holder classes in generating a user subclass that supports PL/SQL output arguments and uses Java types supported by Web services.

To review, this example shows the JPublisher-generated interface, base class, and user subclass to publish the following PL/SQL package foo_pack, consisting of the stored function foo, using Java types suitable for Web services:

create or replace package foo_pack as 
   function foo(a IN OUT sys.xmltype, b integer) return CLOB; 
end; 
/

Assume that you translate the foo_pack package as follows:

% jpub -u scott/tiger -s foo_pack:FooPack -style=webservices10

Note the following:

The wrapper method foo() in the user subclass FooPackUser uses the following type transformation functionality and a call to the corresponding _foo() method of the generated base class, which is where the JDBC calls occur to invoke the wrapped stored function foo:

foo (SourceHolder, Integer)
{
     SourceHolder -> Source 
          Source -> SimpleXMLType 
               _foo (SimpleXMLType[], Integer); 
          SimpleXMLType -> Source 
     Source -> SourceHolder
}

Interface Code

This is code for the Java interface that JPublisher generates in FooPack.java.

import java.sql.SQLException;
import sqlj.runtime.ref.DefaultContext;
import sqlj.runtime.ConnectionContext;
import java.sql.Connection;
// Ensure that the java.io.* package etc. is imported.
import java.io.*;

public interface FooPack extends java.rmi.Remote {
   public java.lang.String foo(SourceHolder _xa_inout_x, Integer b) 
                                              throws java.rmi.RemoteException;
}

Base Class Code

This is code for the base class that JPublisher generates in FooPackBase.java. The _foo() method is called by the foo() method of the user subclass and uses JDBC to invoke the foo stored function of the foo_pack PL/SQL package that JPublisher is publishing.

Comments indicate corresponding SQLJ code, which JPublisher translates automatically during generation of the class.

import java.sql.SQLException;
import sqlj.runtime.ref.DefaultContext;
import sqlj.runtime.ConnectionContext;
import java.sql.Connection;
// Ensure that the java.io.* package etc. is imported.
import java.io.*;

public class FooPackBase
{

  /* connection management */
  protected DefaultContext __tx = null;
  protected Connection __onn = null;
  public void _setConnectionContext(DefaultContext ctx) throws SQLException
  { release(); __tx = ctx; 
    ctx.setStmtCacheSize(0);
    ctx.setDefaultStmtCacheSize(0);
    if (ctx.getConnection() instanceof oracle.jdbc.OracleConnection)
    {
       try 
       {
          java.lang.reflect.Method m =
             ctx.getConnection().getClass().getMethod("setExplicitCachingEnabled",
             new Class[]{Boolean.TYPE});
          m.invoke(ctx.getConnection(), new Object[]{Boolean.FALSE});
       }
       catch(Exception e) { /* do nothing for pre-9.2 JDBC drivers*/ }
    }}
public DefaultContext _getConnectionContext() throws SQLException
{ if (__tx==null)
  { __tx = (__onn==null) ? DefaultContext.getDefaultContext() : 
                               new DefaultContext(__onn); }
  return __tx;
};
public Connection _getConnection() throws SQLException
{ return (__onn==null) ? ((__tx==null) ? null : __tx.getConnection()) : __onn; }
public void release() throws SQLException
{ if (__tx!=null && __onn!=null) __tx.close(ConnectionContext.KEEP_CONNECTION);
  __onn = null; __tx = null;
}

/* constructors */
public FooPackBase() throws SQLException
{ __tx = DefaultContext.getDefaultContext();
}
public FooPackBase(DefaultContext c) throws SQLException
{ __tx = c; }
public FooPackBase(Connection c) throws SQLException
{__onn = c; __tx = new DefaultContext(c);  }

/* *** _foo() USES JDBC TO INVOKE WRAPPED foo STORED PROCEDURE *** */

public oracle.sql.CLOB _foo (
  oracle.sql.SimpleXMLType a[],
  Integer b)
  throws SQLException
{
  oracle.sql.CLOB __jPt_result;
 
  //  ************************************************************
  //  #sql [_getConnectionContext()] __jPt_result = { VALUES(SCOTT.FOO_PACK.FOO(
  //        :a[0],
  //        :b))  };
  //  ************************************************************
 
{
  // declare temps
  oracle.jdbc.OracleCallableStatement __sJT_st = null;
  sqlj.runtime.ref.DefaultContext __sJT_cc = _getConnectionContext(); 
  if (__sJT_cc==null) sqlj.runtime.error.RuntimeRefErrors.raise_NULL_CONN_CTX();
  sqlj.runtime.ExecutionContext.OracleContext __sJT_ec =
              ((__sJT_cc.getExecutionContext()==null) ?
              sqlj.runtime.ExecutionContext.raiseNullExecCtx() :
              __sJT_cc.getExecutionContext().getOracleContext());
  try {
   String theSqlTS = "BEGIN :1 := SCOTT.FOO_PACK.FOO
              (\n       :2 ,\n       :3 )  \n; END;";
   __sJT_st = __sJT_ec.prepareOracleCall(__sJT_cc,"0FooPackBase",theSqlTS);
   if (__sJT_ec.isNew())
   {
      __sJT_st.registerOutParameter(1, Oracle.jdbc.OracleTypes.CLOB);
      __sJT_st.registerOutParameter(2,2007,"SYS.XMLTYPE");
   }
   // set IN parameters
   if (a[0]==null) __sJT_st.setNull(2,2007,"SYS.XMLTYPE"); 
   else __sJT_st.setORAData(2,a[0]);
   if (b == null) __sJT_st.setNull(3, Oracle.jdbc.OracleTypes.INTEGER); 
   else __sJT_st.setInt(3,b.intValue());
 // execute statement
   __sJT_ec.oracleExecuteUpdate();
   // retrieve OUT parameters
   __jPt_result =  (oracle.sql.CLOB) __sJT_st.getCLOB(1);
   a[0] = (oracle.sql.SimpleXMLType)__sJT_st.getORAData
                                (2, Oracle.sql.SimpleXMLType.getORADataFactory());
  } finally { __sJT_ec.oracleClose(); }
}

 //  ************************************************************

    return __jPt_result;
  }
}

User Subclass Code

This is code for the user subclass that JPublisher generates in FooPackUser.java. The foo() method calls the _foo() method of the base class. Java-to-Java transformations are handled in try blocks as indicated in code comments.

This class extends the class FooPackBase and implements the interface FooPack.

import java.sql.SQLException;
import sqlj.runtime.ref.DefaultContext;
import sqlj.runtime.ConnectionContext;
import java.sql.Connection;
// Ensure that the java.io.* package etc. is imported.
import java.io.*;

public class FooPackUser extends FooPackBase implements FooPack, java.rmi.Remote
{

  /* constructors */
  public FooPackUser() throws SQLException  { super(); }
  public FooPackUser(DefaultContext c) throws SQLException { super(c); }
  public FooPackUser(Connection c) throws SQLException { super(c); }
  /* superclass methods */
  public java.lang.String foo(SourceHolder _xa_inout_x, Integer b) 
                                                   throws java.rmi.RemoteException
  { 
    oracle.sql.CLOB __jRt_0 = null;
    java.lang.String __jRt_1 = null;

/* *** FOLLOWING try BLOCK CONVERTS SourceHolder TO Source *** */

    try {
       javax.xml.transform.Source[] a_inout;
       // allocate an array for holding the OUT value
       a_inout = new javax.xml.transform.Source[1];
       if (_xa_inout_x!=null) a_inout[0] = _xa_inout_x.value;
       oracle.sql.SimpleXMLType[] xa_inoutx;
       xa_inoutx = new oracle.sql.SimpleXMLType[1];

/* *** FOLLOWING try BLOCK TRANSFORMS Source TO SimpleXMLType *** */

    try 
    {
      javax.xml.transform.Transformer trans =
           javax.xml.transform.TransformerFactory.newInstance().newTransformer();
      xa_inoutx[0] = null;
      if (a_inout[0]!=null)
      {
        java.io.ByteArrayOutputStream buf = new java.io.ByteArrayOutputStream();
        javax.xml.transform.stream.StreamResult streamr = 
                                new javax.xml.transform.stream.StreamResult(buf);
        trans.transform(a_inout[0], streamr);
        xa_inoutx[0] = new oracle.sql.SimpleXMLType(_getConnection());
        xa_inoutx[0] = xa_inoutx[0].createxml(buf.toString()); 
      }
    }
    catch (java.lang.Throwable t)
    {
      throw OC4JWsDebugPrint(t);
    }

/* *** CALL _foo() FROM BASE CLASS (SUPER CLASS) *** */

    __jRt_0 = super._foo(xa_inoutx, b);

/* *** FOLLOWING try BLOCK TRANSFORMS SimpleXMLType TO Source *** */

    try 
    {
      javax.xml.parsers.DocumentBuilder db = 
      javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder();
      a_inout[0] = null;
      if (xa_inoutx[0]!=null) 
      {
        org.w3c.dom.Document _tmpDocument_ = db.parse
       (new java.io.ByteArrayInputStream(xa_inoutx[0].getstringval().getBytes()));
        a_inout[0]= new javax.xml.transform.dom.DOMSource(_tmpDocument_);
      }
    }
    catch (java.lang.Throwable t)
    {
      throw OC4JWsDebugPrint(t);
    }

/* *** FOLLOWING CODE CONVERTS Source TO SourceHolder *** */

      // convert OUT value to a holder
      if (a_inout!=null) _xa_inout_x.value = a_inout[0];
    if (__jRt_0==null)
    {
       __jRt_1=null;
    }
    else
    {
       __jRt_1=readerToString(__jRt_0.getCharacterStream());
    }

    }  
    catch (Exception except) {
        try {
           Class sutil = Class.forName("com.evermind.util.SystemUtils");
           java.lang.reflect.Method getProp = sutil.getMethod("getSystemBoolean",
                                       new Class[]{String.class, Boolean.TYPE}); 
           if (((Boolean)getProp.invoke(null, new Object[]{"ws.debug",
                       Boolean.FALSE})).booleanValue()) except.printStackTrace();
        }  catch (Throwable except2) {}
        throw new java.rmi.RemoteException(except.getMessage(), except); 
    }
    return __jRt_1;
  }
 private java.lang.String readerToString(java.io.Reader r)
                                                 throws java.sql.SQLException
{
        CharArrayWriter caw = new CharArrayWriter();
        
        try
          {
                //Read from reader and write to writer
                boolean done = false;
         
                while (!done)
                {
                        char[] buf = new char[4096];
                        int len = r.read(buf, 0, 4096);
                        if(len == -1)
                        {
                        done = true;
                        }
                        else
                        {
                                caw.write(buf,0,len);
                        }
                }
           }
         catch(Throwable t)
         {
           throw OC4JWsDebugPrint(t);
         }  
        return caw.toString();
 }
    private void populateClob(oracle.sql.CLOB clb, java.lang.String data)
                                                        throws Exception
    {
        java.io.Writer writer = clb.getCharacterOutputStream();
        writer.write(data.toCharArray());
        writer.flush();
        writer.close();
    }
    private boolean OC4JWsDebug() 
    {
      boolean debug = false;
      try {
        // Server-side Debug Info for "java -Dws.debug=true -jar oc4j.jar" 
        Class sutil = Class.forName("com.evermind.util.SystemUtils");
        java.lang.reflect.Method getProp = sutil.getMethod("getSystemBoolean", 
                                      new Class[]{String.class, Boolean.TYPE});
        if (((Boolean)getProp.invoke(null, new Object[]{"ws.debug", 
                                   Boolean.FALSE})).booleanValue()) 
        {
          debug = true;
        }
      }  catch (Throwable except2) {}
      return debug;
    }
    private java.sql.SQLException OC4JWsDebugPrint(Throwable t) 
    {
      java.sql.SQLException t0 =  new java.sql.SQLException(t.getMessage());
      if (!OC4JWsDebug()) return t0;
      t.printStackTrace();
      try 
      {
        java.lang.reflect.Method getST =
                       Exception.class.getMethod("getStackTrace", new Class[]{});
        java.lang.reflect.Method setST =
                       Exception.class.getMethod("setStackTrace", new Class[]{});
        setST.invoke(t0, new Object[]{getST.invoke(t, new Object[]{})});
      }
      catch (Throwable th){}
      return t0;
    }
}

Generated Code: SQL Statement

This section contains a generated code example for a specified SQL statement, relating to the discussion in "Declaration of SQL Statements to Translate (-sqlstatement)".

The example is for the following sample settings of the -sqlstatement option:

-sqlstatement.class=MySqlStatements
-sqlstatement.getEmp="select ename from emp
                      where ename=:{myname VARCHAR}"
-sqlstatement.return=both

Note the following for this example:

(For UPDATE, INSERT, or DELETE statements, code is generated both with and without batching for array binds.)

Here is the translated SQLJ code that JPublisher would produce:

public class MySqlStatements_getEmpRow 
{ 
 
  /* connection management */ 
 
  /* constructors */ 
  public MySqlStatements_getEmpRow() 
  { } 
 
  public String getEname() throws java.sql.SQLException 
  { return ename; } 
 
  public void setEname(String ename) throws java.sql.SQLException 
  { this.ename = ename; } 
 
  private String ename; 
} 
 
/*@lineinfo:filename=MySqlStatements*/
/*@lineinfo:user-code*/
/*@lineinfo:1^1*/
import java.sql.SQLException; 
import sqlj.runtime.ref.DefaultContext; 
import sqlj.runtime.ConnectionContext; 
import java.sql.Connection; 
import oracle.sql.*; 

public class MySqlStatements 
{ 

  /* connection management */ 
  protected DefaultContext __tx = null; 
  protected Connection __onn = null; 
  public void setConnectionContext(DefaultContext ctx) throws SQLException 
  { release(); __tx = ctx; } 
  public DefaultContext getConnectionContext() throws SQLException 
  { if (__tx==null) 
    { __tx = (__onn==null) ? DefaultContext.getDefaultContext() : 
                             new DefaultContext(__onn); } 
    return __tx; 
  }; 
  public Connection getConnection() throws SQLException 
  { return (__onn==null) ? ((__tx==null) ? null : __tx.getConnection()) : __onn; } 
  public void release() throws SQLException 
  { if (__tx!=null && __onn!=null) __tx.close(ConnectionContext.KEEP_CONNECTION); 
    __onn = null; __tx = null; 
  } 
 
  /* constructors */ 
  public MySqlStatements() throws SQLException 
  { __tx = DefaultContext.getDefaultContext(); } 
  public MySqlStatements(DefaultContext c) throws SQLException 
  { __tx = c; } 
  public MySqlStatements(Connection c) throws SQLException 
  {__onn = c; __tx = new DefaultContext(c); } 
/*@lineinfo:generated-code*/
/*@lineinfo:36^1*/ 

//  ************************************************************ 
//  SQLJ iterator declaration: 
//  ************************************************************ 

public static class getEmpIterator 
    extends sqlj.runtime.ref.ResultSetIterImpl 
    implements sqlj.runtime.NamedIterator 
{ 
  public getEmpIterator(sqlj.runtime.profile.RTResultSet resultSet) 
    throws java.sql.SQLException 
  { 
    super(resultSet); 
    enameNdx = findColumn("ename"); 
    m_rs = (oracle.jdbc.OracleResultSet) resultSet.getJDBCResultSet(); 
  } 
  private oracle.jdbc.OracleResultSet m_rs; 
  public String ename() 
    throws java.sql.SQLException 
  { 
    return m_rs.getString(enameNdx); 
  } 
  private int enameNdx; 
} 
 
//  ************************************************************ 
 
/*@lineinfo:user-code*/
/*@lineinfo:36^56*/ 
 
  public MySqlStatements_getEmpRow[] getEmpBeans (String myname) 
         throws SQLException 
  { 
    getEmpIterator iter; 
    /*@lineinfo:generated-code*/
    /*@lineinfo:43^5*/ 
//  ************************************************************ 
//  #sql [getConnectionContext()] 
//                     iter = { select ename from emp where ename=:myname }; 
//  ************************************************************ 
{ 
  // declare temps 
  oracle.jdbc.OraclePreparedStatement __sJT_st = null; 
  sqlj.runtime.ref.DefaultContext __sJT_cc = getConnectionContext(); 
  if (__sJT_c c==null) sqlj.runtime.error.RuntimeRefErrors.raise_NULL_CONN_CTX(); 
  sqlj.runtime.ExecutionContext.OracleContext __sJT_ec = 
        ((__sJT_cc.getExecutionContext()==null) ? 
        sqlj.runtime.ExecutionContext.raiseNullExecCtx() : 
        __sJT_cc.getExecutionContext().getOracleContext()); 
  try { 
   String theSqlTS = "select ename from emp where ename= :1"; 
   __sJT_st = __sJT_ec.prepareOracleStatement
                    (__sJT_cc,"0MySqlStatements",theSqlTS); 
   // set IN parameters 
   __sJT_st.setString(1,myname); 
   // execute query 
   iter = new MySqlStatements.getEmpIterator
             (new sqlj.runtime.ref.OraRTResultSet 
             (__sJT_ec.oracleExecuteQuery(),__sJT_st,"0MySqlStatements",null)); 
  } finally { __sJT_ec.oracleCloseQuery(); } 
} 

//  ************************************************************ 
 
/*@lineinfo:user-code*/
/*@lineinfo:43^84*/ 
    java.util.Vector v = new java.util.Vector(); 
    while (iter.next()) 
    { 
       MySqlStatements_getEmpRow r = new MySqlStatements_getEmpRow(); 
       r.setEname(iter.ename()); 
       v.addElement(r); 
    } 
    MySqlStatements_getEmpRow[] __jPt_result = 
          new MySqlStatements_getEmpRow[v.size()]; 
    for (int i = 0; i < v.size(); i++) 
       __jPt_result[i] = (MySqlStatements_getEmpRow) v.elementAt(i); 
    return __jPt_result; 
  } 
 
  public java.sql.ResultSet getEmp (String myname) 
          throws SQLException 
  { 
    sqlj.runtime.ResultSetIterator iter; 
    /*@lineinfo:generated-code*/
    /*@lineinfo:62^5*/ 
 
//  ************************************************************ 
//  #sql [getConnectionContext()] iter = 
//                     { select ename from emp where ename=:myname }; 
//  ************************************************************ 
 
{ 
  // declare temps 
  oracle.jdbc.OraclePreparedStatement __sJT_st = null; 
  sqlj.runtime.ref.DefaultContext __sJT_cc = getConnectionContext(); 
  if (__sJT_c c==null) sqlj.runtime.error.RuntimeRefErrors.raise_NULL_CONN_CTX(); 
  sqlj.runtime.ExecutionContext.OracleContext __sJT_ec = 
              ((__sJT_cc.getExecutionContext()==null) ?
              sqlj.runtime.ExecutionContext.raiseNullExecCtx() :
              __sJT_cc.getExecutionContext().getOracleContext()); 
  try { 
   String theSqlTS = "select ename from emp where ename= :1"; 
   __sJT_st = __sJT_ec.prepareOracleStatement
                 (__sJT_cc,"1MySqlStatements",theSqlTS); 
   // set IN parameters 
   __sJT_st.setString(1,myname); 
   // execute query 
   iter = new sqlj.runtime.ref.ResultSetIterImpl
         (new sqlj.runtime.ref.OraRTResultSet
         (__sJT_ec.oracleExecuteQuery(),__sJT_st,"1MySqlStatements",null)); 
  } finally { __sJT_ec.oracleCloseQuery(); } 
} 
 
//  ************************************************************ 
 
/*@lineinfo:user-code*/
/*@lineinfo:62^84*/ 
    java.sql.ResultSet __jPt_result = iter.getResultSet(); 
    return __jPt_result; 
  } 
}
/*@lineinfo:generated-code*/ 

Generated Code: Java and PL/SQL Wrappers for Web Services

This section contains code examples for JAX-RPC client proxies and the associated Java and PL/SQL wrappers, generated according to the WSDL document indicated by the -proxywsdl setting. The code in this example is for use with an EJB Web service, and also uses a table function. The following are included:

For this example, assume that a JAX-RPC Web service, called HelloServiceEJB, is deployed to the following endpoint:

http://localhost:8888/javacallout/javacallout

The WSDL document for this Web service is at the following location:

http://localhost:8888/javacallout/javacallout?WSDL

The Web service provides an operation called getProperty that takes a Java string specifying the name of a system property, and returns the value of that property. For example, getProperty("os.name") may return "SunOS".Based on the WSDL description of the Web service, JPublisher can direct the generation of a Web service client proxy, and generate Java and PL/SQL wrappers for the client proxy. Here is the command to perform these functions:

% jpub -user=scott/tiger -sysuser=sys/change_on_install
       -url=jdbc:oracle:thin:@localhost:1521:orcl
       -proxywsdl=http://localhost:8888/javacallout/javacallout?WSDL
       -endpoint=http://localhost:8888/javacallout/javacallout
       -proxyopts=jaxrpc,tabfun -package=javacallout -dir=genproxy

The -proxyopts setting directs the generation of the JAX-RPC client proxy and wrappers, and the use of a table function to wrap the Web service operation. The -url setting indicates the database, and the -user setting indicates the schema, where JPublisher loads the generated Java and PL/SQL wrappers. The -sysuser setting specifies the SYS account that has the privileges to grant permissions to execute the wrapper script.

See "WSDL Document for Java and PL/SQL Wrapper Generation (-proxywsdl)" and "Web Services Endpoint (-endpoint)" for information about those options. The -endpoint setting is used in the Java wrapper class that JPublisher generates, shown in "Java Wrapper Class and PL/SQL Wrapper". See "Code Generation for Table Functions" for general information about table functions.

For more Java and PL/SQL wrapper examples, also see "Generated Code: Java and PL/SQL Wrappers for General Use".

WSDL Document

This section contains the WSDL document for the Web service. HelloServiceInf in the <message> element is the name of the service bean and determines the name of the interface that is generated and that is implemented by the generated JAX-RPC client proxy stub class. The HelloServiceInf interface has the following signature:

public interface HelloServiceInf extends java.rmi.Remote {
  public String getProperty(String prop) throws java.rmi.RemoteException;
}

The method getProperty() corresponds to the getProperty operation specified in the WSDL document. It returns the value of a specified system property (prop). For example, specify the property "os.version" to return the operating system version.

<?xml version="1.0" encoding="UTF-8"?>
 
<definitions name="HelloServiceEJB"
             targetNamespace="http://oracle.j2ee.ws/javacallout/Hello"
             xmlns:tns="http://oracle.j2ee.ws/javacallout/Hello"
             xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  <types/>
  <message name="HelloServiceInf_getProperty">
    <part name="String_1" type="xsd:string"/>
  </message>
  <message name="HelloServiceInf_getPropertyResponse">
    <part name="result" type="xsd:string"/>
  </message>
  <portType name="HelloServiceInf">
    <operation name="getProperty" parameterOrder="String_1">
      <input message="tns:HelloServiceInf_getProperty"/>
      <output message="tns:HelloServiceInf_getPropertyResponse"/>
    </operation>
  </portType>
  <binding name="HelloServiceInfBinding" type="tns:HelloServiceInf">
    <operation name="getProperty">
      <input>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                   use="encoded"
                   namespace="http://oracle.j2ee.ws/javacallout/Hello"/>
      </input>
      <output>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                   use="encoded"
                   namespace="http://oracle.j2ee.ws/javacallout/Hello"/>
      </output>
      <soap:operation soapAction=""/>
    </operation>
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
  </binding>
  <service name="HelloServiceEJB">
    <port name="HelloServiceInfPort" binding="tns:HelloServiceInfBinding">
      <soap:address location="/javacallout"/>
    </port>
  </service>
</definitions>

JAX-RPC Client Proxy Classes and Interfaces

This section shows the JAX-RPC client proxy stub class, the interface that it implements, a factory class to produce instances of the stub class, and the interface that the factory class implements. These classes and interfaces are all generated by the Oracle Database Web services assembler tool, which is invoked by JPublisher. The stub class is for invoking the Web service, through Java and PL/SQL wrappers that JPublisher produces.


Interface for JAX-RPC Client Proxy Stub Class

Here is code for the interface, HelloServiceInf, implemented by the JAX-RPC client proxy stub class, HelloServiceInf_Stub, which is shown immediately following.

// !DO NOT EDIT THIS FILE!
// This source file is generated by Oracle tools
// Contents may be subject to change
// For reporting problems, use the following
// Version = [failed to localize] wscompile.version(Oracle WebServices, 10i, J1)

package javacallout;

public interface HelloServiceInf extends java.rmi.Remote {
    public java.lang.String getProperty(java.lang.String string_1) 
                                        throws java.rmi.RemoteException;}

JAX-RPC Client Proxy Stub Class

Here is code for the JAX-RPC client proxy stub class, HelloServiceInf_Stub. It implements the interface HelloServiceInf, shown immediately preceding.

// !DO NOT EDIT THIS FILE!
// This source file is generated by Oracle tools
// Contents may be subject to change
// For reporting problems, use the following
// Version = [failed to localize] wscompile.version(Oracle WebServices, 10i, J1)
 
package javacallout;
 
import oracle.j2ee.ws.server.MessageContextProperties;
import oracle.j2ee.ws.common.streaming.*;
import oracle.j2ee.ws.common.encoding.*;
import oracle.j2ee.ws.common.encoding.soap.SOAPConstants;
import oracle.j2ee.ws.common.encoding.soap.SOAP12Constants;
import oracle.j2ee.ws.common.encoding.literal.*;
import oracle.j2ee.ws.common.soap.streaming.*;
import oracle.j2ee.ws.common.soap.message.*;
import oracle.j2ee.ws.common.soap.SOAPVersion;
import oracle.j2ee.ws.common.soap.SOAPEncodingConstants;
import oracle.j2ee.ws.common.wsdl.document.schema.SchemaConstants;
import javax.xml.namespace.QName;
import java.rmi.RemoteException;
import java.util.Iterator;
import java.lang.reflect.*;
import oracle.j2ee.ws.client.SenderException;
import oracle.j2ee.ws.client.*;
import oracle.j2ee.ws.client.http.*;
import javax.xml.rpc.handler.*;
import javax.xml.rpc.JAXRPCException;
import javax.xml.rpc.soap.SOAPFaultException;
 
public class HelloServiceInf_Stub
    extends oracle.j2ee.ws.client.StubBase
    implements javacallout.HelloServiceInf {
    
    /*
     *  public constructor
     */
    public HelloServiceInf_Stub(HandlerChain handlerChain) {
        super(handlerChain);
        _setProperty(ENDPOINT_ADDRESS_PROPERTY,
                     "http://localhost:8888/javacallout/javacallout");
    }
    
    /*
     *  implementation of getProperty
     */
    public java.lang.String getProperty(java.lang.String string_1)
        throws java.rmi.RemoteException {
        
        try {
            
            StreamingSenderState _state = _start(_handlerChain);
            
            InternalSOAPMessage _request = _state.getRequest();
            _request.setOperationCode(getProperty_OPCODE);
            javacallout.HelloServiceInf_getProperty_RequestStruct
                 _myHelloServiceInf_getProperty_RequestStruct =
                 new javacallout.HelloServiceInf_getProperty_RequestStruct();
            
            _myHelloServiceInf_getProperty_RequestStruct.setString_1(string_1);
            
            SOAPBlockInfo _bodyBlock = 
                 new SOAPBlockInfo(ns1_getProperty_getProperty_QNAME);
            _bodyBlock.setValue(_myHelloServiceInf_getProperty_RequestStruct);
            _bodyBlock.setSerializer
                 (myHelloServiceInf_getProperty_RequestStruct_SOAPSerializer);
            _request.setBody(_bodyBlock);
            
            _state.getMessageContext().setProperty("http.soap.action", "");
            
            _send((String) _getProperty(ENDPOINT_ADDRESS_PROPERTY), _state);
            
            javacallout.HelloServiceInf_getProperty_ResponseStruct
                 _myHelloServiceInf_getProperty_ResponseStruct = null;
            Object _responseObj = _state.getResponse().getBody().getValue();
            if (_responseObj instanceof SOAPDeserializationState) {
                _myHelloServiceInf_getProperty_ResponseStruct =
                    (javacallout.HelloServiceInf_getProperty_ResponseStruct)
                         ((SOAPDeserializationState)_responseObj).getInstance();
            } else {
                _myHelloServiceInf_getProperty_ResponseStruct =
            (javacallout.HelloServiceInf_getProperty_ResponseStruct)_responseObj;
            }
            
            return _myHelloServiceInf_getProperty_ResponseStruct.getResult();
        } catch (RemoteException e) {
            // let this one through unchanged
            throw e;
        } catch (JAXRPCException e) {
            throw new RemoteException(e.getMessage(), e);
        } catch (Exception e) {
            if (e instanceof RuntimeException) {
                throw (RuntimeException)e;
            } else {
                throw new RemoteException(e.getMessage(), e);
            }
        }
    }
    
    /*
     *  this method deserializes the request/response structure in the body
     */
    protected void _readFirstBodyElement(XMLReader bodyReader,
              SOAPDeserializationContext deserializationContext, 
              StreamingSenderState  state) throws Exception {
        int opcode = state.getRequest().getOperationCode();
        switch (opcode) {
            case getProperty_OPCODE:
                _deserialize_getProperty(bodyReader, deserializationContext,
                                         state);
                break;
            default:
                throw new SenderException("sender.response.unrecognizedOperation",
                                           Integer.toString(opcode));
        }
    }
    
    /*
     * This method deserializes the body of the getProperty operation.
     */
    private void _deserialize_getProperty(XMLReader bodyReader,
            SOAPDeserializationContext deserializationContext, 
            StreamingSenderState state) throws Exception {
        Object myHelloServiceInf_getProperty_ResponseStructObj =
          myHelloServiceInf_getProperty_ResponseStruct_SOAPSerializer.deserialize
               (ns1_getProperty_getPropertyResponse_QNAME,
                bodyReader, deserializationContext);
        
        SOAPBlockInfo bodyBlock = 
             new SOAPBlockInfo(ns1_getProperty_getPropertyResponse_QNAME);
        bodyBlock.setValue(myHelloServiceInf_getProperty_ResponseStructObj);
        state.getResponse().setBody(bodyBlock);
    }
    
    public String _getEncodingStyle() {
        return SOAPNamespaceConstants.ENCODING;
    }
    
    public void _setEncodingStyle(String encodingStyle) {
        throw new UnsupportedOperationException("cannot set encoding style");
    }
    
    /*
     * This method returns an array containing (prefix, nsURI) pairs.
     */
    protected String[] _getNamespaceDeclarations() {
        return myNamespace_declarations;
    }
    
    /*
     * This method returns an array containing the names of the headers 
     * we understand.
     */
    public QName[] _getUnderstoodHeaders() {
        return understoodHeaderNames;
    }
    
    public void _initialize(InternalTypeMappingRegistry registry) 
        throws Exception {
        super._initialize(registry);
        myHelloServiceInf_getProperty_RequestStruct_SOAPSerializer =
            (CombinedSerializer)registry.getSerializer
            (SOAPConstants.NS_SOAP_ENCODING,
            javacallout.HelloServiceInf_getProperty_RequestStruct.class,
            ns1_getProperty_TYPE_QNAME);
        myHelloServiceInf_getProperty_ResponseStruct_SOAPSerializer =
            (CombinedSerializer)registry.getSerializer
            (SOAPConstants.NS_SOAP_ENCODING,
            javacallout.HelloServiceInf_getProperty_ResponseStruct.class,
            ns1_getPropertyResponse_TYPE_QNAME);
    }
    
    private static final QName _portName = 
      new QName("http://oracle.j2ee.ws/javacallout/Hello", "HelloServiceInfPort");
    private static final int getProperty_OPCODE = 0;
    private static final QName ns1_getProperty_getProperty_QNAME = 
      new QName("http://oracle.j2ee.ws/javacallout/Hello", "getProperty");
    private static final QName ns1_getProperty_TYPE_QNAME = 
      new QName("http://oracle.j2ee.ws/javacallout/Hello", "getProperty");
    private CombinedSerializer
            myHelloServiceInf_getProperty_RequestStruct_SOAPSerializer;
    private static final QName ns1_getProperty_getPropertyResponse_QNAME = 
      new QName("http://oracle.j2ee.ws/javacallout/Hello", "getPropertyResponse");
    private static final QName ns1_getPropertyResponse_TYPE_QNAME = 
      new QName("http://oracle.j2ee.ws/javacallout/Hello", "getPropertyResponse");
    private CombinedSerializer
            myHelloServiceInf_getProperty_ResponseStruct_SOAPSerializer;
    private static final String[] myNamespace_declarations =
                                        new String[] {
                                        "ns0",
                                        "http://oracle.j2ee.ws/javacallout/Hello"
                                        };
    
    private static final QName[] understoodHeaderNames = new QName[] {  };}

Interface for JAX-RPC Client Proxy Factory Class

Here is the code for the interface, HelloServiceEJB, implemented by the client proxy factory class, HelloServiceEJB_Impl, which is shown immediately following.

// !DO NOT EDIT THIS FILE!
// This source file is generated by Oracle tools
// Contents may be subject to change
// For reporting problems, use the following
// Version = [failed to localize] wscompile.version(Oracle WebServices, 10i, J1)
 
package javacallout;
 
import javax.xml.rpc.*;
 
public interface HelloServiceEJB extends javax.xml.rpc.Service {
    public javacallout.HelloServiceInf getHelloServiceInfPort();}

JAX-RPC Client Proxy Factory Class

Here is code for the client proxy factory class, HelloServiceEJB_Impl, used to create instances of the client proxy stub class, HelloServiceInf_Stub, which is shown earlier in this section. The HelloServiceEJB_Impl class implements the HelloServiceEJB interface, shown immediately preceding.

// !DO NOT EDIT THIS FILE!
// This source file is generated by Oracle tools
// Contents may be subject to change
// For reporting problems, use the following
// Version = null
 
package javacallout;
 
import oracle.j2ee.ws.common.encoding.*;
import oracle.j2ee.ws.client.ServiceExceptionImpl;
import oracle.j2ee.ws.common.util.exception.*;
import oracle.j2ee.ws.common.soap.SOAPVersion;
import oracle.j2ee.ws.client.HandlerChainImpl;
import javax.xml.rpc.*;
import javax.xml.rpc.encoding.*;
import javax.xml.rpc.handler.HandlerChain;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.namespace.QName;
 
public class HelloServiceEJB_Impl extends oracle.j2ee.ws.client.BasicService implements HelloServiceEJB {
    private static final QName serviceName = 
      new QName("http://oracle.j2ee.ws/javacallout/Hello", "HelloServiceEJB");
    private static final QName ns1_HelloServiceInfPort_QNAME = 
      new QName("http://oracle.j2ee.ws/javacallout/Hello", "HelloServiceInfPort");
    private static final Class helloServiceInf_PortClass =
                               javacallout.HelloServiceInf.class;
    
    public HelloServiceEJB_Impl() {
        super(serviceName, new QName[] {
                        ns1_HelloServiceInfPort_QNAME
                    },
            new javacallout.HelloServiceEJB_SerializerRegistry().getRegistry());
        
    }
    
    public java.rmi.Remote getPort(QName portName, Class serviceDefInterface)
                                  throws javax.xml.rpc.ServiceException {
        try {
            if (portName.equals(ns1_HelloServiceInfPort_QNAME) &&
                serviceDefInterface.equals(helloServiceInf_PortClass)) {
                return getHelloServiceInfPort();
            }
        } catch (Exception e) {
            throw new ServiceExceptionImpl(new LocalizableExceptionAdapter(e));
        }
        return super.getPort(portName, serviceDefInterface);
    }
    
    public java.rmi.Remote getPort(Class serviceDefInterface) 
                                   throws javax.xml.rpc.ServiceException {
        try {
            if (serviceDefInterface.equals(helloServiceInf_PortClass)) {
                return getHelloServiceInfPort();
            }
        } catch (Exception e) {
            throw new ServiceExceptionImpl(new LocalizableExceptionAdapter(e));
        }
        return super.getPort(serviceDefInterface);
    }
    
    public javacallout.HelloServiceInf getHelloServiceInfPort() {
        String[] roles = new String[] {};
        HandlerChainImpl handlerChain = 
           new HandlerChainImpl
           (getHandlerRegistry().getHandlerChain(ns1_HelloServiceInfPort_QNAME));
        handlerChain.setRoles(roles);
        javacallout.HelloServiceInf_Stub stub = 
             new javacallout.HelloServiceInf_Stub(handlerChain);
        try {
            stub._initialize(super.internalTypeRegistry);
        } catch (JAXRPCException e) {
            throw e;
        } catch (Exception e) {
            throw new JAXRPCException(e.getMessage(), e);
        }
        return stub;
    }}

Java Wrapper Class and PL/SQL Wrapper

This section shows code for the Java wrapper class and PL/SQL wrapper that JPublisher generates. These are used to call the proxy client stub class from PL/SQL.


Wrapper Class

Here is the class, HelloServiceEJBJPub, that JPublisher generates as a Java wrapper for the proxy client stub class. The Java wrapper is required to publish instance methods of the stub class as static methods, to allow accessibility from PL/SQL. The Web service endpoint in the code, "http://localhost:8888/javacallout/javacallout", is according to the -endpoint setting in the JPublisher command line.

The corresponding PL/SQL wrapper is shown immediately following.

package javacallout;
import javax.xml.rpc.Stub;
 
public class HelloServiceEJBJPub{
 
   public static void release()
   {
      m_service = null;
      m_port0 = null;
   }
 
   private static void init()
   {
      m_service = new javacallout.HelloServiceEJB_Impl();
      m_port0 = (javacallout.HelloServiceInf)(m_service.getHelloServiceInfPort());
      ((Stub)m_port0)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY,
                     "http://localhost:8888/javacallout/javacallout");
   }
 
   private static javacallout.HelloServiceEJB_Impl m_service;
   private static javacallout.HelloServiceInf m_port0 = null;
 
   public static java.lang.String getProperty(java.lang.String p0)
   throws java.rmi.RemoteException
   {
     try
     {
     if (m_port0==null) init();
      java.lang.String o;
      o = m_port0.getProperty(p0);
      return o;
     }
     catch (Exception e)
     {
         throw new java.rmi.RemoteException(e.getMessage());
     }
   }
}

PL/SQL Wrapper

Here is the PL/SQL wrapper script, plsql_wrapper.sql, that creates the PL/SQL wrapper package, JPUB_PLSQL_WRAPPER. This package is created for invoking the Web service from PL/SQL. Note that it includes the definition of a table function—data from the Web service is returned through a database table, rather than through a normal function return.

An intermediate Java wrapper class, shown immediately preceding, is required to publish instance methods of the JAX-RPC client proxy stub class as static methods, which is required for accessibility from PL/SQL.

-- SQL types assisting the procedures that invoke web services
CREATE OR REPLACE TYPE GRAPH_getProperty AS OBJECT(p0 VARCHAR2(32767), 
                                                   res VARCHAR2(32767));/
 
SHOW ERRORS
CREATE OR REPLACE TYPE GRAPH_TAB_getProperty AS TABLE OF GRAPH_getProperty;/
 
SHOW ERRORS
 
-- PL/SQL procedures that invoke webserviecs
CREATE OR REPLACE PACKAGE JPUB_PLSQL_WRAPPER AS
   FUNCTION getProperty(p0 VARCHAR2) RETURN VARCHAR2;
   FUNCTION TO_TABLE_getProperty(cur SYS_REFCURSOR) 
            RETURN GRAPH_TAB_getProperty PIPELINED;
 
END JPUB_PLSQL_WRAPPER;/
 
SHOW ERRORS
 
CREATE OR REPLACE PACKAGE BODY JPUB_PLSQL_WRAPPER IS
   FUNCTION getProperty(p0 VARCHAR2) RETURN VARCHAR2
   as language java
   name 'javacallout.HelloServiceEJBJPub.getProperty(java.lang.String) 
         return java.lang.String';
FUNCTION TO_TABLE_getProperty(cur SYS_REFCURSOR) RETURN GRAPH_TAB_getProperty
  PIPELINED IS
  p0 VARCHAR2(32767);
  res VARCHAR2(32767);
BEGIN
  LOOP
    FETCH cur INTO p0;
    EXIT WHEN cur%NOTFOUND;
    res:=getProperty(p0);
    PIPE ROW(GRAPH_getProperty(p0,res));
  END LOOP;
  CLOSE cur;
  RETURN;
END TO_TABLE_getProperty;
 
END JPUB_PLSQL_WRAPPER;
/ 
SHOW ERRORS
 
EXIT;

Because a -user setting is specified in the JPublisher command line to publish this Web service, JPublisher will load the generated Java code and PL/SQL wrapper into the database. Once everything is loaded, you can use the PL/SQL wrapper to invoke the Web service. The PL/SQL wrapper consists of two functions: getProperty and TO_TABLE_getProperty.

The getProperty function directly wraps the getProperty() method in the generated client proxy class. For example, the following SQL*Plus command uses getProperty to determine the operating system where the Web service is running ("SunOS"):

SQL> select JPUB_PLSQL_WRAPPER.getProperty('os.name') from dual;
JPUB_PLSQL_WRAPPER.GETPROPERTY('OS.NAME')
-----------------------------------------
SunOS

TO_TABLE_getProperty is a table function based on the getProperty function. It takes a REF CURSOR as input and returns a table. The schema of the table returned is defined by GRAPH_getProperty.

In this example, TO_TABLE_getProperty is called with a REF CURSOR obtained from a one-column table of VARCHAR2 data, where each data item is the name of a system property (such as "os.version"). Then TO_TABLE_getProperty returns a table in which each row contains an item from the input REF CURSOR, and the result of a getProperty call taking that item as input. Following is a sample usage of TO_TABLE_getProperty.

SQL> -- Test Table Function
SQL> create table props (name varchar2(50));
Table created.

SQL> insert into props values('os.version');
1 row created.

SQL> insert into props values('java.version');
1 row created.
SQL> insert into props values('file.separator');
1 row created.

SQL> insert into props values('file.encoding.pkg');
1 row created.

SQL> insert into props values('java.vm.info');
1 row created.

SQL> SELECT * FROM
TABLE(JPUB_PLSQL_WRAPPER.TO_TABLE_getProperty(CURSOR(SELECT * FROM props)));
P0                      RES
------------------------------
os.version              5.8
java.version            1.4.1_03
file.separator          /
file.encoding.pkg       sun.io
java.vm.info            mixed mode

This example creates a one-column table of VARCHAR2, populates it with system property names, and uses TO_TABLE_getProperty to find out the values of those system properties. For example, you see that the operating system is Sun Microsystems Solaris 5.8.

See "Code Generation for Table Functions" for general information about table functions.

Additional PL/SQL Utility Scripts

This section illustrates PL/SQL utility scripts that JPublisher generates, in addition to the wrapper script, plsql_wrapper.sql, already shown. There are scripts to grant permission for execution of the PL/SQL wrapper, revoke permission, and drop the PL/SQL package from the database schema.

See "Superuser for Permissions to Run Client Proxies (-sysuser)" for information about the option to specify a superuser name and password for running these scripts.


Script to Grant Permission for PL/SQL Wrapper

Here is the script to grant permission to execute JPUB_PLSQL_WRAPPER.

-- Run this script as SYSDBA to grant permissions for SCOTT to run the PL/SQL
-- wrapper procedures.
BEGIN
dbms_java.grant_permission('SCOTT', 'SYS:java.lang.RuntimePermission',
                           'accessClassInPackage.sun.util.calendar', '' );
dbms_java.grant_permission('SCOTT', 'SYS:java.lang.RuntimePermission',
                           'getClassLoader', '' );
dbms_java.grant_permission('SCOTT', 'SYS:java.net.SocketPermission', '*',
                           'connect,resolve' );
END;/
 
EXIT

Script to Revoke Permission for PL/SQL Wrapper

Here is the script to revoke permission to execute JPUB_PLSQL_WRAPPER.

-- Run this script as SYSDBA to revoke the permissions granted to SCOTT.
BEGIN
dbms_java.revoke_permission('SCOTT', 'SYS:java.lang.RuntimePermission',
                            'accessClassInPackage.sun.util.calendar', '' );
dbms_java.revoke_permission('SCOTT', 'SYS:java.lang.RuntimePermission',
                            'getClassLoader', '' );
dbms_java.revoke_permission('SCOTT', 'SYS:java.net.SocketPermission', '*',
                            'connect,resolve' );
END;/
 
EXIT

Script to Drop the PL/SQL Package

Here is the script to drop JPUB_PLSQL_WRAPPER from the database schema:

-- Drop the PL/SQL procedures that invoke Web services.
 
DROP PACKAGE JPUB_PLSQL_WRAPPER;
EXIT

Generated Code: Java and PL/SQL Wrappers for General Use

This section has code examples for Java and PL/SQL wrappers generated for server-side Java classes, according to -proxyclasses and -proxyopts settings. See "Options to Facilitate Web Services Call-Outs" for information about these and related options.

Assume that the Java and PL/SQL wrappers in these examples are for general use, not necessarily associated with Web services.

The following sections show the classes to be wrapped, the wrapper classes and PL/SQL wrappers produced for static methods, and the wrapper classes and PL/SQL wrappers produced for instance methods in the handle scenario.

Also see "Generated Code: Java and PL/SQL Wrappers for Web Services".

Classes to Be Wrapped

This section shows classes for which Java and PL/SQL wrappers, shown in subsequent sections, will be generated. Assume that the following classes, named X and Y, are installed in the server:

public class X
 {
   public void add(int arg) { tot = tot + arg; }
   public void add(Y arg)   { tot = tot + arg.getTotal(); }
   public int getTot() { return tot; }
   public Y cloneTot()
   { Y y=new Y(); y.setTotal(getTot()); return y; }
 
   public static int add(int i, int j) { return i+j; }
   public static Y add(Y i, Y j)   
   { Y y = new Y(); 
     y.setTotal(i.getTotal()+j.getTotal()); 
     return y; 
   }
   private int tot;
 }
 
 
 public class Y
 {
   public void setTotal(int total)  { this.total = total; }
   public int getTotal() { return total; }
   private int total;
 }

Java and PL/SQL Wrappers for Static Methods

Assume that class X from the preceding section is processed by JPublisher with the following settings:

% jpub -proxyclasses=X -proxyopts=static

With these settings, JPublisher generates Java (as necessary) and PL/SQL wrappers for static methods only. This always includes a PL/SQL wrapper, and in this example also includes a wrapper class, XJPub, for the class X. A wrapper class is necessary, even when there are no instance methods to wrap, because class X uses the Java type Y for an argument in a method calling sequence. A wrapper class is required whenever types other than Java primitive types are used in method calls. In this case, the wrapper class has a wrapper method for the following:

add(Y arg) {...}

Note that because Y is a JavaBean type, it is mapped to the weakly typed oracle.sql.STRUCT class. See "Code Generation for Method Parameters".


Wrapper Class

Here is the wrapper class:

import java.util.Hashtable;
 import java.sql.StructDescriptor;
 import java.sql.Connection;
 import java.sql.DriverManager;
 import oracle.sql.STRUCT;
 import java.math.BigDecimal;

 public class XJPub
 {
   public static STRUCT add( STRUCT arg0, STRUCT arg1)
   throws java.sql.SQLException
   { 
      Y _p1 = new Y();
      BigDecimal _p0 = (BigDecimal) arg0.getAttributes()[0];
      _p1.setTotal(_p0.intValue());
 
      Y _p3 = new Y();
      BigDecimal _p4 = (BigDecimal) arg2.getAttributes()[0];
      _p3.setTotal(_p4.intValue());
      Y _p5 = X.add(_p0, _p4);
 
      Connection conn = _getConnection();
      StructDescriptor structdesc = 
                             StructDescriptor.createDescriptor("YSQL", conn);
      STRUCT _r = new STRUCT(structdesc, conn, new Object[]{_p5.getTotal()});
      return _r;
   }
   Connection _getConnection() throws java.sql.SQLException
   {
       return DriverManager.getConnection("jdbc:default:connection:");
   }
 }

PL/SQL Wrapper

Following is the PL/SQL wrapper. The type YSQL is created to enable the PL/SQL code to access Y instances.

CREATE OR REPLACE TYPE YSQL AS OBJECT(total number);
 /
 CREATE OR REPLACE PACKAGE JPUB_PLSQL_WRAPPER AS
   FUNCTION add(arg0 NUMBER, arg1 NUMBER) RETURN NUMBER;
   FUNCTION add(arg0 Y, arg1 Y) RETURN Y;
 END JPUB_PLSQL_WRAPPER;
 /
 CREATE OR REPLACE PACKAGE BODY JPUB_PLSQL_WRAPPER AS
   FUNCTION add(arg0 NUMBER, arg1 NUMBER) RETURN NUMBER AS LANGUAGE JAVA
   NAME 'X.add(int,int) return int';
   FUNCTION add(arg0 YSQL, arg1 YSQL) RETURN NUMBER AS LANGUAGE JAVA
   NAME 'XJPub.add(oracle.sql.STRUCT, Oracle.sql.STRUCT) return oracle.sql.STRUCT';
 END JPUB_PLSQL_WRAPPER;
 /

Java and PL/SQL Wrappers for Instance Methods Using the Handle Mechanism

Assume that classes X and Y from "Classes to Be Wrapped" are processed by JPublisher with the following settings:

% jpub -proxyclasses=X,Y -proxyopts=multiple

Given these settings, JPublisher generates wrappers for instance methods, including Java wrapper classes and a PL/SQL wrapper. In this example, JPublisher generates the wrapper classes XJPub and YJPub for X and Y, respectively. Because of the multiple setting, JPublisher uses the handle mechanism to expose instance methods as static methods to allow access from PL/SQL (which supports only static methods). See "Mechanisms Used in Exposing Java to PL/SQL" and "Wrapper Class Generation with Handles" for related information.


Wrapper Class XJPub

Here is the class XJPub:

import java.util.Hashtable;
 
 public class XJPub
 {
   public static void add(long handleX, int arg)
   { XJPub._getX(handleX).add(arg); }
 
   public static void add(long handleX, long handleY)
   { XJPub._getX(handleX).add(YJPub._getY(handleY)); }
 
   public static int getTot(long handleX)
   { return XJPub._getX(handleX).getTot(); }
 
   public static long cloneTot(long handleX)
   { return YJPub._setY(XJPub._getX(handleX).cloneTot()); }
 
   // Generic Code
   //
   // This code is generated similarly for all classes.
   //
 
   private static long m_seq;  // instance count
   private static long m_base; // base represents null instance
   private static Hashtable m_objs = new Hashtable();
   private static Hashtable m_tags = new Hashtable();
   static { m_base = XJPub.class.hashCode();
            m_base = (m_base>0l) ? -m_base : m_base;
            /* m_base = m_base && 0xFFFFFFFF00000000l */ ;
            m_seq = m_base;
          }
 
   public static X _getX(long handleX)
   {
     if (handleX<=m_base || handleX>m_seq) return null;
     return (X)m_objs.get(new Long(handleX));
   }
 
   public static long _setX(X x)
   {
     if (x==null)
     {
       return m_base;
     }
     Long l = (Long)m_tags.get(x);
 
     if (l != null)
     {
       return l.longValue();
     }
     else
     {
       return newX();
     }
   }
 
   public static long newX()
   { m_seq++;
     Long l = new Long(m_seq);
     X x = new X();
     m_objs.put(l,x);
     m_tags.put(x,l);
     return m_seq;
   }
 
   public static void releaseX(long handleX)
   { if (handleX<=m_base || handleX>m_seq)
     { /* wrong type - should we issue an error? */
       return;
     }
     Long l = new Long(handleX);
     m_objs.remove(l);
     Object x = m_objs.get(l);
     if (x!=null) m_tags.remove(x);
   }
 
   public static void releaseAllX()
   { m_objs.clear(); m_tags.clear(); m_seq=m_base; }
 }

Wrapper Class YJPub

Here is the class YJPub:

import java.util.Hashtable;
 
 public class YJPub
 {
   public static void setTotal(long handleY, int total)
   { YJPub._getY(handleY).setTotal(total); }
 
   public static int getTotal(long handleY)
   { return YJPub._getY(handleY).getTotal(); }
 
   // Generic Code
   //
   // This code is generated similarly for all classes.
   //
 
   private static long m_seq;  // instance count
   private static long m_base; // base represents null instance
   private static Hashtable m_objs = new Hashtable();
   private static Hashtable m_tags = new Hashtable();
   static { m_base = YJPub.class.hashCode();
            m_base = (m_base>0l) ? -m_base : m_base;
            /* m_base = m_base && 0yFFFFFFFF00000000l */ ;
            m_seq = m_base;
          }
 
   public static Y _getY(long handleY)
   {
     if (handleY<=m_base || handleY>m_seq) return null;
     return (Y)m_objs.get(new Long(handleY));
   }
 
   public static long _setY(Y y)
   {
     if (y==null)
     {
       return m_base;
     }
 
     Long l = (Long)m_tags.get(y);
 
     if (l != null)
     {
       return l.longValue();
     }
     else
     {
       return newY();
     }
   }
 
   public static long newY()
   { m_seq++;
     Long l = new Long(m_seq);
     Y y = new Y();
     m_objs.put(l,y);
     m_tags.put(y,l);
     return m_seq;
   }
 
   public static void releaseY(long handleY)
   { if (handleY<=m_base || handleY>m_seq)
     { /* wrong type - should we issue an error? */
       return;
     }
     Long l = new Long(handleY);
     m_objs.remove(l);
     Object y = m_objs.get(l);
     if (y!=null) m_tags.remove(y);
   }
 
   public static void releaseAllY()
   { m_objs.clear(); m_tags.clear(); m_seq=m_base; }
 }

PL/SQL Wrapper

Here is the PL/SQL wrapper:

CREATE OR REPLACE PACKAGE JPUB_PLSQL_WRAPPER AS
    FUNCTION NEW_X() RETURN NUMBER;
    PROCEDURE ADD(handle_X NUMBER, arg0 NUMBER);
    PROCEDURE ADD2(handle_X NUMBER, handle_Y NUMBER);
    FUNCTION  GET_TOT(handle_X NUMBER) RETURN NUMBER;
    FUNCTION  CLONE_TOT(handle_X NUMBER) RETURN NUMBER;
 
    FUNCTION  NEW_Y() RETURN NUMBER;
    PROCEDURE SET_TOTAL(handle_Y NUMBER, arg0 NUMBER);
    FUNCTION  GET_TOTAL(handle_Y NUMBER) RETURN NUMBER;
 END JPUB_PLSQL_WRAPPER;
 /
 CREATE OR REPLACE PACKAGE BODY JPUB_PLSQL_WRAPPER AS
   FUNCTION NEW_X() RETURN NUMBER AS LANGUAGE JAVA
    NAME 'XJPub.newX() return long';
 
   PROCEDURE RELEASE_X(handle_X NUMBER) AS LANGUAGE JAVA
    NAME 'XJPub.releaseX(long)';
 
   PROCEDURE RELEASE_ALL_X() AS LANGUAGE JAVA
    NAME 'XJPub.releaseAllX()';
 
   PROCEDURE ADD(handle_X NUMBER, arg0 NUMBER) AS LANGUAGE JAVA
    NAME 'XJPub.add(long,int)';
 
   PROCEDURE ADD2(handle_X NUMBER, handle_Y NUMBER) AS LANGUAGE JAVA
    NAME 'XJPub.add(long,long)';
 
   FUNCTION GET_TOT(handle_X NUMBER) RETURN NUMBER AS LANGUAGE JAVA
    NAME 'XJPub.getTot(long) return int';
 
   FUNCTION CLONE_TOT(handle_X NUMBER) RETURN NUMBER AS LANGUAGE JAVA
    NAME 'XJPub.cloneTot(long) return long';
 
   FUNCTION NEW_Y() RETURN NUMBER AS LANGUAGE JAVA
    NAME 'YJPub.newY() return long';
 
   PROCEDURE RELEASE_Y(handle_Y NUMBER) AS LANGUAGE JAVA
    NAME 'YJPub.releaseY(long)';
 
   PROCEDURE RELEASE_ALL_Y() AS LANGUAGE JAVA
    NAME 'YJPub.releaseAllY()';
 
   PROCEDURE SET_TOTAL(handle_Y NUMBER, arg0 NUMBER) AS LANGUAGE JAVA
    NAME 'YJPub.setTotal(long,int)';
 
   FUNCTION GET_TOTAL(handle_Y NUMBER, arg0 NUMBER) RETURN NUMBER AS LANGUAGE JAVA
    NAME 'YJPub.getTotal(long) return int';
 
 END JPUB_PLSQL_WRAPPER;