Advanced Customization > Info*Engine User’s Guide > Custom Webjects > Creating an External Custom Webject
  
Creating an External Custom Webject
You can create Info*Engine external custom webjects by coding a public class within a unique Java package. The class name must be unique and should follow the standard Java naming rules.
The Info*Engine webject name is derived from the class name by separating each word in the name with a hyphen. For example, if the class name is “averageColumn” then the webject name is “Average-Column.”
Webject names are not case sensitive.
You must code the class so the custom webjects in the class:
Are implemented as static methods.
Take a com.infoengine.object.factory.Task object as their only argument.
Return a com.infoengine.object.factory.Task object.
Throw IEException on error.
For example, the signature for the method that implements the Average-Column custom webject is the following:
import com.infoengine.object.factory.Task;
public static Task averageColumn ( Task task ) throws IEException {
    :
    :
    Task response = new Task();
            response.addVdb ( group_out );
            return response;
    :
    :
}
You can put the code for multiple custom webjects in the same class. For example, if you have private methods that are used by multiple custom webject methods, the private methods and the custom webject methods can be in one class in a package.
When compiling the NumericColumnWebjects.java file, you must add the ieWeb.jar and servlet.jar files to the classpath. To make your compiled class files automatically available to Info*Engine through the JSP engine, you can put the files in the WEB-INF/classes directory where Info*Engine is installed. If this directory does not exist you can create it.
External Custom Webject Examples
The following sections include:
Source code for the NumericColumnWebjects class.
An example JSP page that uses the external custom webjects.
You can find the source code and JSP page in the prog_examples/customwebjects directory where Info*Engine is installed.
NumericColumnWebjects Class
The following example package contains the NumericColumnWebjects class. This class contains the following methods:
getColumnElements — A private method used by the public methods to get the elements in a column.
averageColumn — Averages the elements in a numeric column of data.
totalColumn — Computes a total using the elements in a numeric column of data.
package examples.customwebjects;

import com.infoengine.util.IEException;
import com.infoengine.exception.fatal.IEInternalServiceException;
import com.infoengine.procunit.webject.GroupWebjectException;
import com.infoengine.object.factory.*;

import java.util.Enumeration;
import java.util.Vector;

/**
* NumericColumnWebjects
*
* supplies implementation for two simple webjects:<br>
* <li><b>totalColumn</b> - return the numeric total of a column
* <li><b>averageColumn</b> - return the numeric average of a column
* The implementation is simple minded using a 'double' to calculate
* totals and averages.  No formating of the results is performed.
* <br>
* Example:<br>
* <ie:webject name="Query-Objects" type="OBJ">
*   <ie:param name="INSTANCE" data="jdbcAdapter"/>
*   <ie:param name="CLASS" data="EMP"/>
*   <ie:param name="WHERE" data="()"/>
*   <ie:param name="GROUP_OUT" data="employees"/>
* </ie:webject>
*
* <ie:webject name="Total-Column" type="EXT" use="examples.custom
webjects.NumericColumnWebjects">
*   <ie:param name="COLUMN" data="SAL"/>
*   <ie:param name="GROUP_IN" data="employees"/>
*   <ie:param name="GROUP_OUT" data="total_salary"/>
* </ie:webject>
*
* <ie:webject name="Average-Column" type="EXT" use="examples.custom
webjects.NumericColumnWebjects">
*   <ie:param name="COLUMN" data="SAL"/>
*   <ie:param name="GROUP_IN" data="employees"/>
*   <ie:param name="GROUP_OUT" data="average_salary"/>
* </ie:webject>
**/

public class NumericColumnWebjects
{

/**
     * return a list of column elements
     *
     * @return Vector
     * @exception IEException if required values aren't found within
the webject
     **/

    private static Vector getColumnElements ( Task task ) throws IE
Exception {
        Webject w = task.getWebject();
        String grp_out = null;
        String column = null;
        String grp_in = null;
        Group group_in = null;

        // get the column name to retrieve
        Param param = w.getParam ( "COLUMN" );
        if ( param == null )
           throw new GroupWebjectException ( "NumericColumnWebjects:
no COLUMN" );

        column = param.getData();

        // if GROUP_IN not supplied take the default group off the VDB
        param = w.getParam ( "GROUP_IN" );
        if ( param == null )
            group_in = task.getGroupIn();
        else
            group_in = task.getVdb ( param.getData() );
        if ( group_in == null )
            throw new GroupWebjectException
                      ( "NumericColumnWebjects: no GROUP_IN" );

        // build the Vector of column contents

        int element_count = group_in.getElementCount();
        Vector elements = new Vector ();
        for ( int i = 0; i < element_count; i++ ) {
            Element e = group_in.getElementAt ( i );

               Vector ev = e.getValues ( column, true );

               if ( ev == null ) continue;

               for ( int j = 0; j < ev.size (); ++j )
                   elements.addElement ( ev.elementAt ( j ) );
        }
        if ( !(elements.size() > 0) )
            throw new GroupWebjectException
                      ( "NumericColumnWebjects: no COLUMN \"" + column
\"" );

        return elements;
    }
/**
     * given a input group, column name, and group out name
     * generate the numeric average of the column's contents
     * return the value in a group.
     *
     * @return Task - response
     * @exception IEException - if required parameters are
missing or column
     *                          is not numeric.
     **/

    public static Task averageColumn ( Task task ) throws IE
Exception {
        try {
            String grp_out = null;
            String column = null;
            Webject w = task.getWebject();
            // get the name of the group to create
            Param param = w.getParam ( "GROUP_OUT" );
            if ( param == null )
                throw new GroupWebjectException
                         ( "NumericColumnWebjects: no GROUP_OUT" );
            grp_out = param.getData();
            // get the name of the column to average
            param = w.getParam ( "COLUMN" );
            if ( param == null )
                throw new GroupWebjectException
                          ( "NumericColumnWebjects: no COLUMN" );

            column = param.getData();

            Vector elements = getColumnElements ( task );

            // total the values
            Object val;
            Double dval;
            double average = 0;
            for ( Enumeration en = elements.elements();
                en.hasMoreElements (); ) {
                val = en.nextElement();
                dval = new Double ( val.toString() );
                average += dval.doubleValue();
            }
            // calculate the average
            average = average / elements.size();

            Element elem = new Element ();
            Att att = new Att ( column + " average" );
            att.addValue ( "" + average );
            elem.addAtt ( att );
            Group group_out = new Group ( grp_out );
            group_out.setElement ( elem );

            Task response = new Task();
            response.addVdb ( group_out );

            return response;
        } catch ( Exception exc ) {
            exc.printStackTrace ( System.err );
            if ( exc instanceof IEException )
                throw (IEException)exc;
            throw new IEInternalServiceException ( exc );
        }
    }
/**
     * given a input group, column name, and group out name
     * generate the numeric total of the column's contents
     * return the value in a group.
     *
     * @return Task - response
     * @exception IEException - if required parameters are
missing or column
     *                          is not numeric.
     **/

    public static Task totalColumn ( Task task ) throws IE
Exception {
        try {
            String grp_out = null;
            String column = null;

            Webject w = task.getWebject();

            // get the name of the group to create
            Param param = w.getParam ( "GROUP_OUT" );
            if ( param == null )
                throw new GroupWebjectException
                          ( "NumericColumnWebjects: no GROUP_OUT" );

            grp_out = param.getData();

            // get the name of the column to total
            param = w.getParam ( "COLUMN" );
            if ( param == null )
                throw new GroupWebjectException
                          ( "NumericColumnWebjects: no COLUMN" );

            column = param.getData();

            Vector elements = getColumnElements ( task );

            // calculate the total
            Object val;
            Double dval;
            double total = 0;
            for ( Enumeration en = elements.elements();
                en.hasMoreElements (); ) {
                val = en.nextElement();
                dval = new Double ( val.toString() );
                total += dval.doubleValue();
            }

            // build GROUP_OUT and response
            Element elem = new Element ();
            Att att = new Att ( column + " total" );
            att.addValue ( "" + total );
            elem.addAtt ( att );
            Group group_out = new Group ( grp_out );
            group_out.setElement ( elem );

            Task response = new Task();
            response.addVdb ( group_out );

            return response;
        } catch ( Exception exc ) {
            exc.printStackTrace ( System.err );
            if ( exc instanceof IEException )
                throw (IEException)exc;
            throw new IEInternalServiceException ( exc );
        }
    }
}
You can execute the averageColumn and totalColumn methods using the Average-Column and Total-Column external webjects.
Example Average-Column and Total-Column External Webjects
The following NumericColumnWebjects.jsp executes a Query-Objects webject that creates the “employees” group, which is then used by the Average-Column and Total-Column external webjects:
<%@page language="java" session="false" errorPage="IEError.jsp"%>

<%@ taglib uri="http://www.ptc.com/infoengine/taglib/core" prefix="ie" %>

<!-- Creates the employees group to be used by Average-Column and
Total-Column extended webjects -->

<ie:webject name="Query-Objects" type="obj">
  <ie:param name="INSTANCE"   data="jdbcAdapter"/>
  <ie:param name="CLASS"   data="EMP"/>
  <ie:param name="WHERE"   data="()"/>
  <ie:param name="GROUP_OUT"   data="employees"/>
</ie:webject>

<!-- This custom webject computes the total of the SAL column -->

<ie:webject name="Total-Column" type="EXT"
                               use="example.customwebjects.NumericColumnWebjects"/>
  <ie:param name="COLUMN"   data="SAL"/>
  <ie:param name="GROUP_IN"   data="employees"/>
  <ie:param name="GROUP_OUT"   data="total_salary"/>
</ie:webject>

<!-- This custom webject computes the average of the SAL column -->

<ie:webject name="Average-Column" type="EXT" use="examples.custom
webjects.NumericColumnWebjects">
  <ie:param name="COLUMN"   data="SAL"/>
  <ie:param name="GROUP_IN"   data="employees"/>
  <ie:param name="GROUP_OUT"   data="average_salary"/>
</ie:webject>

<ie:webject name="Display-Table" type="DSP">
  <ie:param name="GROUP_IN"   data="total_salary"/>
</ie:webject>

<ie:webject name="Display-Table" type="DSP">
  <ie:param name="GROUP_IN" data="average_salary"/>
</ie:webject>