Beginning soapUI Scripting: Javadocs 1

I've written quite a few posts now on scripting in soapUI; hopefully they've provided enough useful information to get you started on your own projects.  However, you may come to a point where you're trying to do something for which you can't find a good example, or you've found an example but need some help understanding it.  Or perhaps you're just curious to see what else might be possible with a script you've already written.  In this post, I want to begin a series looking at javadoc documentation to help you explore the capabilities of Java and Groovy libraries on your own.

The javadoc format is standardized, generated directly from a resource's code and specially formatted comments and annotation within the code (Javadoc is the name of the tool used to do this).  Although it may be a little non-intuitive at first, its ubiquity across the Java world makes even a basic understanding extremely useful: if you can read javadoc documentation, you can learn more not just about soapUI but many of the other APIs we've discussed in previous posts: POI, Groovy, and, of course, the base Java library itself.

Let's take a look at the HSSFWorkbook class of the Apache POI API, which I think provides a fairly straightforward example-- for those of you unfamiliar with it, this API allows you to work with Microsoft document formats within Java; the HSSFWorkbook class corresponds to an Excel xls workbook.  Launch the documentation page via this link (I recommend opening the link in a new window or tab so you can read this post and see the example side by side): http://poi.apache.org/apidocs/index.html.  Near the top of the page or the top of the main frame on the right (depending on your current view), you'll see links/buttons for "Frames" or "No Frames" that you can use to switch between two available views; this post is written from the perspective of the "Frames" view.

The top left frame lists the packages of the POI API, the organizational units into which its resources are divided.  You can select an individual package to view its classes or "All Classes" to view all of the API's classes together.  Scroll through the packages in the upper left frame and select the org.apache.poi.hssf.usermodel package, then take a look at the lower left frame, which should now be populated with the package's contents.  In this case, they're divided into three different categories: interfaces (I'll explain more about these a little later), classes, and enums.  These aren't the only categories you may encounter-- another common category is exceptions, for example. For the sake of this post and to keep things simple, I'm going to think in terms of two primary groups: classes and interfaces (enums and exceptions are both special types of classes).  Note that interfaces and classes are distinguished from each other by the way they're displayed; interfaces are always displayed in italics.

Find the HSSFWorkbook class in the lower left frame and click on it-- the main frame on the right will update and display information specific to the class.

Just above the name of the class at the top of the frame is its enclosing package.  In the context of scripting, one reason this is important is for import statements.  Recall from my post about using the XmlHolder class in soapUI that an import statement was necessary in order to create an instance of the class:

import com.eviware.soapui.support.XmlHolder

def myHolder = new XmlHolder(messageExchange.getResponseContentAsXml())

The fully qualified name of the class (including its package) is needed for the import statement.

The fully qualified name is also displayed in the class's hierarchical structure, displayed just below the name-- a description of the classes from which it inherits properties and methods and the interfaces implemented by the class.  I'll try to explain these concepts briefly here, but I strongly recommend checking out the more detailed explanation here in Oracle's Java Tutorials.

One benefit of Java's object-oriented approach is the idea of inheritance-- when creating a new class you don't have to start from scratch; you can designate another class as its base class and the new class starts with some (or all) of its base class's methods and properties.  You can then override some of those inherited members (create a new implementation of a method, for example) or add new ones to make the new class more specialized and add additional functionality.  In fact, there are some classes called abstract classes that are designed specifically to be used as base classes.  You can't actually create an instance of an abstract class; you'll never work with an abstract class directly in code.  However, "concrete" classes (which can be instantiated) can inherit from it.

Interfaces are similar to abstract classes in some ways.  In simplified terms, interfaces primarily define a set of methods-- but they don't provide any actual implementation of those methods.  The methods in an interface have names and signatures-- describing what types of data the methods take as arguments and what types are returned-- but they don't have any code for the methods.  Where does the actual code come from?  A class can implement an interface; if it does, it is required to "fill in" the implementation of each of the methods defined for the interface.  Importantly, a class can inherit from only one class (although that class may itself inherit from another, which may inherit from another, etc.), but it can implement multiple interfaces.

Returning to our example of the HSSFWorkbook class, its javadoc page shows us that it's a sub-class of (i.e., it inherits from) the POIDocument class and it implements the Workbook interface.

Just below the hierarchy information is the class's declaration-- this is actually how the class is declared in its underlying Java code:

public final class HSSFWorkbook
extends POIDocument
implements Workbook

I'll discuss the meaning of some of the keywords like public and final in the next post.  This declaration also tells us some of the same information we saw in the hierarchy information: the extends keyword indicates the class's base class (POIDocument), and the implements keyword indicates interfaces implemented by the class (Workbook).

Just below this information is a description of the class (the description is a single line here, but this may be much longer and more detailed in some cases) followed by the meat of the javadoc entry: descriptions of its members, its properties and methods.  These are described in brief summary form at the top of the page, then in more detail farther down on the page.

Fields are the member variables of a class-- variables associated with the class itself (as opposed to variables that are declared within methods or code blocks-- a variable used as a counter in a for loop would not be a member variable, for example).  For fields that are not inherited, the summary section shows them in a table with modifying keywords and type (the data type/class of the field) on the left and a name and description on the right.  Inherited fields are simply listed with the class or interface from which they're inherited, linked to their detailed descriptions in those classes and interfaces.

Below the field descriptions are the class's constructors.  Constructors are special methods used to create new instances of a class when used in conjunction with the new keyword:

//An import statement is required to use the constructor
import org.apache.poi.hssf.usermodel.HSSFWorkbook

def myXLSWorkbook = new HSSFWorkbook()

Note constructors have the same name as the class.  Also note that with the HSSFWorkbook there are multiple constructors, demonstrating the concept of overloading-- its possible for a class to have multiple methods (this is not limited to constructors) with the same name as long as each method takes different sets of argument types.  For example, you can see that one constructor takes no arguments, while another takes an InputStream as an argument, and yet another takes an InputStream and a boolean (true or false) as its arguments.  This is permissible because the data types of the arguments are unique for each constructor; the interpreter or compiler can tell which particular constructor you're trying to call based on the types of the arguments passed into the constructor.

Below the constructors are the remaining methods of the class.  These are displayed in a table with modifying keywords and type (the data type returned by the method) on the left and the method name and parameter types (the data types the method takes) on the right.  As with fields, methods that are inherited from other classes or interfaces are listed separately, linked to their detailed descriptions in the corresponding class or interface.

That completes a quick overview of a typical javadoc page.  In the next post, I'll look at some of those keyword modifiers and what they mean in the context of scripting.