Orindasoft

The Orindabuild reference manual

Using the Web Service Classes

Using the Web Service Classes    

    Topics

  1. Purpose of generated web service classes.
  2. Description of generated web service classes.
  3. Altering Web Service Class Behaviour
  4. DAOFactoryServiceImpl class Methods
  5. Mapping Oracle data types to Web Services data types.
  6. Web Services with CLOBS, BLOBS and BFILES
  7. Supported Web Service configurations

Purpose of generated web service classes.

In step 4.4 of the OrindaBuild user interface you can create a class and matching interface that extend the DAO Factory class. These service classes provide stateless methods that can be used to call PL/SQL procedures or issue SQL statements as part of a web service implemented using a tool such as Apache Axis. The blue section of the diagram below shows where OrindaBuild generated Java source code fits in:
Web Services And Oracle

OrindaBuild will generate Java Wrapper classes for each procedure, function and SQL statement you select in the user interface. It then creates a Data Access Object class that hands out live copies of the generated classes. The Data Access Object class is extended to create a Web Service Implementation class. In addition to providing stateless calls to the wrapper classes it translates the Java data types used into the subset that work with serialization and uses special classes to hold the output of procedures that have work than one output parameter. Because this class contains several public methods that we wouldn't want to turn into a service we also create a Web Service Interface class that lists the methods we want access.

Description of generated web service classes.

The following classes are generated if you select the 'Create web services classes by extending DAO Factory class' option in step 4.4.

Class Name
Description
Core Web Services Classes
DAOFactoryServiceInterface.java
This is a Java interface that contains only those methods that we want to be part of our web service. It exists because DAOFactoryServiceImpl.java will often contain methods that are public but not intended for use in a web service. Rather than telling your version of Java2WSDL which public methods are intended for use by a web service it's a lot simpler to list the service methods in a Java interface and run  Java2WSDL against the interface.

'DAOFactoryServiceInterface' is a default name. The actual name can be set in step 4.4. An example of this file is available here.
DAOFactoryServiceImpl.java This class extends DAOFactory.java by adding 'service' methods for each PL/SQL procedure and SQL statement selected by the user. It also translates the data types used by DAOFactory.java to ones that are compaible with the serialization protocols used by web services. 'DAOFactoryServiceImpl' is a default name. The actual name is set in step 4.4. An example of this file is available here
DAOFactoryServiceException.java
This is a special Exception that is used when errors are encountered by the service method. An example of this class can be found here.
Classes used to represent Cursors when the fields in the cursor aren't known at compile time.
WsdlRowSet.java
This class represents the result of a Query. It consists of a list of column names and one WsdlRow for each row returned. This class has no methods other than a constructor. An example can be found here.
WsdlRow.java This class represents a single row returned by a query. It consists of an array of WsdlElement. This class has no methods other than a constructor. An example can be found here.
WsdlElement.java This class represents a column in a row returned by a query. This class has no methods other than a constructor. An example can be found here.
Classes used when more than one value is returned by a procedure.
plsql/*Return.java
If a service method returns more than one parameter they will be stored together in a class in the plsql subdirectory whose name ends in 'Return.java'. This class has no methods other than a constructor. An example of a Return class for the example procedure 'getLists' can be found here.
Classes used to represent records.
plsql/*Attrs.java
These classes represent records that are used as parameters for PL/SQL procedures and functions.


Altering Web Service Class Behaviour

In step 4.4 of the OrindaBuild user interface you can define a number of options that alter the generated web service code:

Option
Description
Number type used by service
All numbers used by the service classes will be of the same data type. The available types are:
Always release database connection after call
If selected the DAOFactory classes's 'relaseConnection' method will be called at the end of each service method call
Add pre call code stubs
If selected an additional method called 'doPreServiceEvent' is added to the class to assist users who want to customize generated code.
Add post call code stubs
If selected an additional method called 'doPostServiceEvent' is added to the class to assist users who want to customize generated code.
Uploaded BFILE naming is abstract
Creating new BFILE's represents a challange when working in a web services environment. See the section on BFILES for information on how OrindaBuild can do this.

DAOFactoryServiceImpl class Methods

The table below lists the methods you can expect to find in a DAOFactoryServiceImpl class and explains what they are for. Methods that are part of the base DAOFactory class are here.

 Method Name
Purpose
Comment
Constructors
DAOFactoryServiceImpl()
Default Constructor - calls parent classes null parameter constructor.

The default constructor calls the parent classes null parameter constructor.
Event  Methods  - Allow the user to alter the behaviour of generated code.
doPreServiceEvent()
Execute additional user defined code.
Optional. By extending DAOFactoryServiceImpl and overiding these methods uses can add custom behaviour to generated code.
doPostServiceEvent() Execute additional user defined code.
setAlwaysReleaseResourcesFlag() Controls whether database resources are released at the end of each call. Default value is controlled by user interface
Conversion and File IO Methods
createBFILEarrayFromByteArray()
Turn an array of byte[] into an array of oracle.sql.BFILE
This method used createNewBfilePointer(). See the section on BFILES for further information.
createBLOBarrayFromByteArray()
Turn an array of byte[] into an array of oracle.sql.BLOB These methods rely on the temporary LOB functionality introduced in Oracle V9.0.1.
createCLOBarrayFromByteArray()
Turn an array of byte[] into an array of oracle.sql.CLOB
createByteArrayFromBFILEArray()
Unloads an oracle.sql.BFILE into a byte[].
These methods unload oracle LOB objects into byte arrays suitable for serialization.
createByteArrayFromBLOBArray()
Unloads an oracle.sql.BLOB into a byte[].
createByteArrayFromCLOBArray()
Unloads an oracle.sql.CLOB into a byte[].
createBigDecimalArrayFromIndexByTable()
Turns an 'index by' table into an array of numbers
These methods are used by generated code for working with INDEX BY Tables.
createStringArrayFromIndexByTable()
Turns an 'index by' table into an array of Strings
createIndexByTableFromBigDecimalArray()
Turns an array of numbers into an 'index by' table.
createIndexByTableFromStringArray()
Turns an array of Strings into an 'index by' table.
loadByteArrayIntoFile()
Returns a java.io.File that contains an array of byte[].
These are generic IO methods that are needed because serialziation prefers byte[] to java.io.File.
loadFileIntoByteArray()
Returns a byte array that respresents the contents of a java.io.File.
createWSDLRowset()
Turns a com.orindasoft.pub.ReadOnlyRowSet into a WSDLRowSet.
com.orindasoft.pub.ReadOnlyRowSet is unsuitable for serialization.
BFILE Creation Methods - Exist when the web services code is trying to call procedures or functions that insert BFILES. See below.
setOracleDirectoryDbName()
Sets the Oracle Directory name to be used when creating BFILES. The value entered should be the same as the column DIRECTORY_NAME in  the ALL_DIRECTORIES data dictionary view.
Generated code that inserts BFILES will throw an exception if these methods have not been called prior to the execution of the procedure. Both DB Name and OS Name must refer to the same OS directory.
setOracleDirectoryOsName()
Sets the Oracle Directory name to be used when creating BFILES. The value entered should be the same as the column DIRECTORY_PATH in  the ALL_DIRECTORIES data dictionary view.

createNewBfilePointer()
Creates an oracle.sql.BFILE object.
Involves a database access.
createNewBfileName()
Return an array of Strings that collectivly represent a BFILE.

[abstract] getArbitraryGeneratedBfileName()
Creates a unique name for an uploaded BFILE.
Can be abstract. See below.
prepareBfileSequenceQry()
Creates a query used for creating unique BFILE names.
Will not exist if getArbitraryGeneratedBfileName() is abstract.

Mapping Oracle data types to Web Services data types.

Java classes used for Web Services must use a subset of the available Java data types. The table below shows how OrindaBuild maps Oracle's data types to the appropriate Java data types.


Domain    Oracle or PL/SQL Data Type Web Services Data Type
Comment
Numeric BINARY_INTEGER All numbers used by the service classes will be of the same data type. The available types are:
The data type is chosen in Step 4.4 of the user interface.l
DEC
DECIMAL
DOUBLE PRECISION
FLOAT
INT
INTEGER
NATURAL
NATURALN
NUMBER
NUMERIC
PLS_INTEGER
POSITIVE
POSITIVEN
REAL
SIGNTYPE
SMALLINT
Text CHAR
String 

CHARACTER
LONG
STRING
VARCHAR
VARCHAR2
Binary LONG RAW
byte[]


RAW
ROWID
String

UROWID
String
Not supported in JDBC as of 9.2.0
Large Objects BFILE
byte[] 
Retrieval works from Oracle 8.1.7 onwards.
Creation of BLOBS and CLOBS works from Oracle 9.0.1 onwards. Note that the size of BLOBS, CLOBS and BFILES can easily exceed that which can be comfortably handled by a web server and that attention must be paid to JVM memory parameters.
BLOB
CLOB
Boolean BOOLEAN
boolean 

Date DATE
java.util.date 
All
TIMESTAMP
String 
 This value is a String representation of an oracle.sql.TIMESTAMP data type. The format used is:
yyyy-mm-dd hh:mm:ss.fffffffff
  An oracle.sql.TIMESTAMP representing 9:26AM and 50.12346 seconds on the 31st Jan, 1997  would be stored as
1997-1-31 9:26:50.123456000 
TIMESTAMP WITH LOCAL TIME ZONE
byte[11] 
 'String' is not a safe way to represent this object as the 'toString()' method does not return a value that can be used to construct an identical copy. We therefore turn it into a byte array, which is how Oracle represents it internally. The byte representation can be used to reconstruct the value by passing it to the constructor of
oracle.sql.TIMESTAMPTZ. Oracle's documentation states that the byte array is structured as follows:

The internal data for this object is stored as a 11 byte array in the super class' storage area. The bytes are arranged as follows:
Byte  Represents
0
Century (119 for 1990)
1
Decade (190 for 1990)
2
Month
3
Day
4
Hour
5
Minute
6
Seconds
7
Nanoseconds (Most Significant bit)
8
Nanoseconds
9
Nanoseconds
10
Nanoseconds (Least Significant Bit)

Static methods are used for conversions.

TIMESTAMP WITH TIME ZONE
byte[13] 
 'String' is not a safe way to represent this object as the 'toString()' method does not return a value that can be used to construct an identical copy. We therefore turn it into a byte array, which is how Oracle represents it internally. The byte representation can be used to reconstruct the value by passing it to the constructor of oracle.sql.TIMESTAMPLTZ. Oracle's documentation states that the byte array is structured as follows:

The internal data for this object is stored as a eleven byte array. The bytes are arranged as follows:
Byte  Represents
0
Century (119 for 1990)
1
Decade (190 for 1990)
2
Month
3
Day
4
Hour
5
Minute
6
Seconds
7
Nanoseconds (Most Significant bit)
8
Nanoseconds
9
Nanoseconds
10
Nanoseconds (Least Significant Bit)
11,12
Region id or Timezone Hour/Minute

The timezone information is stored as an offset in the RegionID format or in the HOUR/MINUTE format

100 is added to the century and decade fields so that negative values will be positive and positive values will be higher than negative values. 1 is added to the month, hour, minute, second fields for the java objects since they start of from 0.
INTERVAL YEAR MONTH
String
An interval of two years and three months would be stored as:
2-3 
INTERVAL DAY SECOND
String
An interval of two days, three hours and 2.99 seconds would be stored as:
2 3:0:2.99
Records %ROWTYPE A custom Java class is created for each one.

PL/SQL Package Records
Oracle TYPE Objects
CURSORS Either a WSDLRowSet or a custom class is created.
Whether a WSDLRowSet or a dedicated class is created depends on how much information OrindaBuild has about the contents of the Cursor. Cursors which are defined in packages are more likely to have dedicated classes created to represent the

Web Services with CLOBS, BLOBS and BFILES.

Oracle's LOB data types are unsuitable for serialization because they are pointers to objects inside Oracle databases. OrindaBuild gets round this by generating source code that uses byte[] instead.

Retrieval of  LOBS and BFILES using a Web Service.

Generated code will create service methods that return byte arrays (byte[]) when the underlying PL/SQL procedure or SQL query returns a BLOB, CLOB or BFILE. If you are returning LOBS that are bigger than a few kilobytes in size you will need to make sure that the Java Virtual Machine the service is running on has been allocated a large amount of memory.

Creation of CLOBS and BLOBS using a Web Service.

OrindaBuild uses Oracle's createTemporary() method when inserting LOBs using a service. 'createTemporary()' was introduced in V9.0.1 of Oracle. This means that OrindaBuild requires that you are using at least Oracle V9.0.1 if you wish to insert BLOBS and CLOBS using a Web Service.

Creation of BFILEs using a Web Service.

Using a web service to create BFILEs requires that the Java Virtual Machine that is hosting the service has access to the same filesystem as the Oracle database and also that it has the ability to create files in the directories that database is using for storing BFILES. In order to create a BFILE you need to create the BFILE pointer object inside the database and then create a matching file in the location it refers to. This implies that you are on the same physical machine as the Oracle database server.


Supported Web Service configurations

OrindaBuild web service code has been tested against the configurations below. OrindaBuild should work with the final version of Axis 1.2. Currently it fails with Axis 1.2.1 due to the blocker bugs AXIS-1985 and AXIS-1986

Java Virtual Machine
Web Server
Web Service Toolkit
Sun JDK 1.4.2
Apache Tomcat/4.1.31 Apache Axis 1.1
Sun JDK 1.5.0 Apache Tomcat/4.1.31 Apache Axis 1.2.1 (see AXIS-1985 and AXIS-1986)
Sun JDK 1.5.0 Apache Tomcat/5.0.28 Apache Axis 1.1
Sun JDK 1.5.0 Apache Tomcat/5.0.28 Apache Axis 1.2.1 (see AXIS-1985 and AXIS-1986)
Sun JDK 1.5.0 Apache Tomcat/5.5.4 Apache Axis 1.1
Sun JDK 1.5.0 Apache Tomcat/5.5.4 Apache Axis 1.2.1 (see AXIS-1985 and AXIS-1986)