program interfaces

A program source code implements the ProgramCode SDK interface.

public class <CLASSNAME> <EXTEND=> {
  public Framework OberonMain(Vector vArgs,Framework framework) throws OberonException {
    .... PROGRAM CODE ....
  }
}


The <CLASSNAME> tag is automatically replaced with the program name during the compilation while the <EXTEND=..> tag can be used to extend another program [class] with this class.
Inside the program class you can declare public or private methods / parameters and define the source code for the Main method named OberonMain. This method is automatically executed and receives as input a Vector of arguments depending on the program purpose or type. See the following table for details:

program type input arguments output
object method

vArgs[0] = object parameters (Hashtable)

   METHOD = method name
   OBJECTID = object ID
   HOLDER = object holder
   DESCRIPTION = object description
   CLASS = object class name
   NAME = object name
   REVISION = object revision
   LIFECYCLE = object lifecycle
   STAGE = object current stage
   OBJECTSPACE = object objectspace
   OBJECT = the ObjectObj instance

vArgs[1+] = method input arguments
framework.setResult( ..... );    








trigger program vArgs[0] = trigger parameters (Hashtable)

   EVENT = the event name

vArgs[1+] = trigger input arguments

Trigger event names and arguments are listed in the SDK Event class and Arg class respectively.
NOTHING

Trigger fails if program raises a OberonException


field
compute ranges
vArgs[0] = Field object (SDK object)
vArgs[1+] = input arguments

use framework.getEnv( fieldName ) to read form input values
[ basic field names start with '_' ]
framework.setResult("range1|translation1\n
range2|translation2\n.....");


form
compute item field ranges
[range program]
vArgs[0] = item field name (String)
vArgs[1+] = filter parameter values

use framework.getEnv( fieldName ) to read form input values
[ basic field names start with '_' ]
framework.setResult("range1|translation1\n
range2|translation2\n.....");
form
check input values
[check program]
No arguments

use framework.getEnv( fieldName ) to read form input values
[ basic field names start with '_' ]
framework.setResult(<Alert Message>);

leave <Alert Message> empty ("")
if check results positive
form
post commit actions
[action program]
No arguments

use framework.getEnv( fieldName ) to read form commit values
[ basic field names start with '_' ]
NOTHING
item (form)
visible/editable... [check access]
vArgs[0] = Item object (SDK object)
vArgs[1+] = input arguments

use framework.getEnv( fieldName ) to read form commit values
[ basic field names start with '_' ]

framework.getEnv(Arg.EVENT)
framework.getEnv(Arg.ACCESS)
NOTHING

if program raises a OberonException blocks the visible, editable, required, disabled access


column (view)
seeable/modifiable [check access]
vArgs[0] = Column object (SDK object)
vArgs[1+] = input arguments

framework.getEnv(Arg.EVENT)
framework.getEnv(Arg.ACCESS)
NOTHING

if program raises a OberonException blocks the seeable or modifiable access
command
access check
vArgs[0] = Command object (SDK)
vArgs[1+] = input arguments

framework.getEnv("id"')
NOTHING

if program raises a OberonException blocks the command access
autonumber increment vArgs[0]=autonumber parameters (Hashtable)

   METHOD = program name
   AUTONUMBER = the AutoNumber SDK object
   NAME = autonumber name
   DESCRIPTION = autonumber description
   CLASS = autonumber related class name
   LIFECYCLE = autonumber related lifecycle
   OBJECTSPACE = autonumber objectspace
   VALUE = autonumber current value
   FORMAT = autonumber format

vArgs[1] = increment value (Integer)
NOTHING

Modify and update the
autonumber nextvalue  
process-step
completion / decision trigger
vArgs[0]=process-step parameters (Hashtable)

  EVENT = the event name
  CHOICES = user choices for decision steps

vArgs[1] = process SDK object
vArgs[2] = step SDK object
vArgs[3] = process-step SDK object

NOTHING

or returns valid transitions for final decision

framework.setResult("Transition1, Transition2,....");

transition (process)
check/action trigger
vArgs[0]=process-step parameters (Hashtable)

  EVENT = the event name
  TRANSITION = transition name
  NEXT-STEP = transition step-fork

vArgs[1] = process SDK object
vArgs[2] = step SDK object
vArgs[3] = process-step SDK object

NOTHING

if program raises a OberonException blocks the transition and as result interrupts the branch



Program templates

Programs are very important to extend the platform functionalities and developers often deal with program code generation. A set of program templates are included inside the OBEROn resource/models folder to accelerate this process; these models are java source files (with .java extension) and implement the program interface for the different purposes.


When you add a new program in the Context Design admin client, the creation form proposes the list of program types by reading this folder. So, when you select a specific type, the file content is loaded into the Source tab and you have only to write the core part of the program. You can define your custom models and save them inside the same folder, the name of your template files will appear in the type list, togheter with the default models.







object method

Method programs are associated to administrative class objects and can be executed for a object instance of this class by the OOQL command:

object execute ObjectIdName method  ProgramName [ input ProgramArg {ProgramArg} ];

or by the execute (String methodName,Vector args, Framework framework) method of ObjectObj class

import com.oberon.ooql.sdk.*;
import java.util.*;

public class <CLASSNAME> <EXTEND=> {
  public Framework OberonMain(Vector vArgs,Framework framework) throws OberonException {
    // Get the object parameters
Hashtable
hObjectParams = (Hashtable) vArgs.elementAt(0);
ObjectObj oObject = (ObjectObj) hObjectParams.get(Arg.OBJECT);

// Read the field name as input parameter
String sInputParam1 = (String) vArgs.elementAt(1);

// Read the object field value
String sFieldValue = oObject.getFieldValue(sInputParam1);

framework.setResult( "Field value for " + sInputParam1 + " is : " + sFieldValue) );

return framework;
  }
}


trigger program

Trigger programs run when a object or link event occours (see the trigger events and sequences)

import com.oberon.ooql.sdk.*;
import java.util.*;

public class <CLASSNAME> <EXTEND=LibraryProgram> {
  public Framework OberonMain(Vector vArgs,Framework framework) throws OberonException {
    // Get the trigger parameters
Hashtable
hTriggerParams = (Hashtable) vArgs.elementAt(0);
String sTriggerEvent = (String) hTriggerParams.get(Arg.EVENT);
String sObjectID = (String) hTriggerParams.get(Arg.OBJECTID);
String sObjectName = (String) hTriggerParams.get(Arg.NAME);
// Read the input parameters
String sInputParam1 = (String) vArgs.elementAt(1);
String sInputParam2 = (String) vArgs.elementAt(2);

// Open the object
ObjectObj oObject = ObjectObj.open( sObjectID, true , framework );
// Read a object field value
String sFieldValue = oObject.getFieldValue(sInputParam1);

...... do something .........

if ( ... fail condition... ) { throw new OberonException(".... error message ...." ); }

return framework;
  }
}


field - compute ranges

The field - range programs are associated to administrative field objects; their purpose is to compute a list of ranges for the field values. They run automatically when a field-show OOQL command try to extract ranges using the "range[program]" get option:

field show  FieldName get { ... range[program] ... } [ input ProgramArg {ProgramArg} ] ;

or by the computeProgramRanges (Vector filterArgs, Framework framework) method of Field class

import com.oberon.ooql.sdk.*;
import com.oberon.ooql.sdk.Dictionary;
import java.util.*;

public class <CLASSNAME> <EXTEND=> {
  public Framework OberonMain(Vector vArgs,Framework framework) throws OberonException {
    Field oField = (Field) vArgs.elementAt(0);
// A single program can be used to compute ranges for several fields
if ( field.getName().equals("BookType") ) {
      String sAdultType = framework.getEnv("AdultType");
// Extract sub-key translations for a given key - from a dictionary section
Vector vRanges = Dictionary.getTranslations( "BookSection", "BookType_"+sAdultType , framework);
framework.setResult( JLClient.vectorToString(vRanges,"\n") );
    } else if ( field.getName().equals("BookAuthor") ) {
      Vector vRanges = Dictionary.getTranslations( "AuthorSection", "BookAuthor" , framework);
// Add the select all option (*) if the form is a search form
if ( framework.getEnv("search")!=null ) { vRanges.insertElementAt("*",0); }
framework.setResult( JLClient.vectorToString(vRanges,"\n") );
    }
return framework;
  }
}


form - range program

The form - range programs are associated to administrative form objects; their purpose is to compute a list of ranges for the form item-field values. They run automatically when a form-show OOQL command try to extract item ranges using the "range[Fieldname]" get option:

form show  FormName get { ... range[FieldName] ... } [ input ProgramArg {ProgramArg} ] ;

or by the computeProgramRanges(String fieldName,Vector filterArgs, Framework framework) method of the Form class

These programs are usually used when the item field ranges depend on the form where they are employed or when the item represents a basic or a action field. In these cases is not possible to use the field range program.

import com.oberon.ooql.sdk.*;
import com.oberon.ooql.sdk.Class;
import com.oberon.ooql.sdk.Dictionary;
import java.util.*;

public class <CLASSNAME> <EXTEND=> {
  public Framework OberonMain(Vector vArgs,Framework framework) throws OberonException {
    String sFieldName = (String) vArgs.elementAt(0);

if ( sFieldName.equals("_class") ) {
      // Read a form hidden field value
String
sAbstractClass = framework.getEnv("rootClass");
// Open the root abstract class and get its direct sub-classes
Class
oAbstractClass = Class.open(sAbstractClass, framework, null);
Vector vRanges = oAbstractClass.getOwnSubClasses(framework);
for (int i=0;i<vRanges.size();i++) {
        // Apply the translation to each sub-class name
String
sRange = (String) vRanges.elementAt(i);
vRanges.setElementAt( sRange+"|"+ Dictionary.getKey( "Classes" , sRange, framework) ,i);
      }
framework.setResult( JLClient.vectorToString(vRanges,"\n") );
    } else if ( sFieldName.equals("_currentstage") ) {
      // Read the name of selected class by user on the form
String
sClass = framework.getEnv("_class");
if (sClass != null && sClass.length()>0) {
        // Use OOQL command to read the stage names for the lifecycles associated to the class
String
sStages=JLClient.performOOQL("class show '"+sClass+ "' get { lifecycle.stage } token { '' '' '' '\n' } ;" , framework);
Vector vRanges = JLClient.StringTokensToVector(sStages ,"\n" );
// Add the select all option (*) if the form is a search form
if ( framework.getEnv("search")!=null ) { vRanges.insertElementAt("*",0); }
framework.setResult( JLClient.vectorToString(vRanges,"\n") );
      }
    }
return framework;
  }
}


form - check program

The form - check programs are associated to administrative form objects; their purpose is to check the form-item input values before committing it. They can be directly executed with the form OOQL command :

form
check  FormName [ input ProgramArg {ProgramArg} ] ;

or by the check (Framework framework,Vector filterArgs) method of the Form class

The input form item values can be passed to the program as input args (Vector elements) or setting the framework variables:
(OOQL) framework env set varName = value;
(java) framework.setEnv (String varName, String value)
They can be also executed with a AJAX call to the com.oberon.ooql.rmi.JRFormValidateServlet posting the item values into the http xml request.

import com.oberon.ooql.sdk.*;
import com.oberon.ooql.sdk.Dictionary;
import java.util.*;

public class <CLASSNAME> <EXTEND=> {
  public Framework OberonMain(Vector vArgs,Framework framework) throws OberonException {
    // Read the form input values
String
sBookTitle = framework.getEnv("BookTitle");
String sBookDescription = framework.getEnv("_description");

if ( sBookTitle != null && sBookDescription != null && sBookTitle.equals(sBookDescription) ) {
      // Return a translated message if check fails
framework.setResult( Dictionary.getKey( "Messages" , "MSG_TitleDescription", framework)) );
    } else { framework.setResult(""); }
    return framework;
  }
}


form - action program

The form - action programs are associated to administrative form objects; their purpose is to perform additional actions after the form is committed. They can be directly executed with the form OOQL command :

form
action  FormName [ input ProgramArg {ProgramArg} ] ;

or by the action (Framework framework,Vector filterArgs) method of the Form class

The input form item values can be passed to the program as input args (Vector elements) or setting the framework variables:
(OOQL) framework env set varName = value;
(java) framework.setEnv (String varName, String value)
import com.oberon.ooql.sdk.*;
import com.oberon.ooql.sdk.Dictionary;
import java.util.*;

public class <CLASSNAME> <EXTEND=> {
  public Framework OberonMain(Vector vArgs,Framework framework) throws OberonException {
    // Read the form input values
String sSendMailUser = framework.getEnv("sendMaiUser");
String sObjectID = framework.getEnv("id");

try {
      // Open the user and check if it exists (raise Exception otherwhise)
User
oUser = User.open(sSendMailUser, framework, null);
// Prepare the mail
Mail mail = new Mail();
mail.addToUser(sSendMailUser);
mail.addCcUser(framework.getUserName()); // send a copy to the framework user
mail.setSubject(".... mail subject...." );
mail.setBody(".... mail body...." );
mail.addAttachObj(sObjectID); // attach current object
mail.send(framework);
    } catch (Exception e) { System.out.println(e.getMessage()); }
return
framework;
  }
}


item - access

The form-item show and edit check programs are associated to items of administrative form objects; they control the form-item user access and in particular determine if a item must be showed and/or if it is editable. They run automatically for each form-item when a form-show OOQL command try to extract the item list using the "item.visible" , "item.editable" , "item.required" or/ and "item.disabled" get options:

form
show  FormName get { ... item.visible ... item.editable ... item.required .... item.disabled .. } ;

or by the getAccessItems (int accessType, Vector filterArgs, Framework framework) method of the Form class [ accessType is one of Item.ITEMACCESS_VISIBLE, Item.ITEMACCESS_EDITABLE, Item.ITEMACCESS_REQUIRED, ITEMACCESS_DISABLED ]

They also run automatically for a specific form-item when a form-show OOQL command try to get the item properties using the "item.access" get options:

form show  FormName get { ... item[ItemName].access[<access_type>] ... };

where <access_type> is one of visible , editable , required , disabled

or by the hasAccess (int accessType, Vector filterArgs, Framework framework) method of the Item class
[ accessType is one of Item.ITEMACCESS_VISIBLE, Item.ITEMACCESS_EDITABLE, Item.ITEMACCESS_REQUIRED, ITEMACCESS_DISABLED ]

import com.oberon.ooql.sdk.*;
import java.util.*;

public class <CLASSNAME> <EXTEND=> {
  public Framework OberonMain(Vector vArgs,Framework framework) throws OberonException {
   
Item
oFormItem = (Item) vArgs.elementAt(0);
String
sItemFormat = oFormItem.getFormat();
// Read the current stage as a form filter param
String sCurrentStage = (String) vArgs.elementAt(1);

// Read the access type
// visible [Item.ITEMACCESS_VISIBLE] / editable [Item.ITEMACCESS_EDITABLE]
// required [Item.ITEMACCESS_REQUIRED] / disabled [Item.ITEMACCESS_DISABLED])

String sAccessType = framework.getEnv(Arg.ACCESS);

/* Inside the item format you can add extra options with the list of the available stages

if current stage is not present into the list you can raise a Exception to hide or disable the item */
if ( sItemFormat.indexOf("{"+sCurrentStage+"}")<0 ) { throw new OberonException(""); }
    return framework;
  }
}


column - access

The view-column show and edit check programs are associated to columns of administrative view objects; they control the view-column user access and in particular determine if a column must be showed and/or if it is editable. They run automatically for each view-column when a view-show OOQL command try to extract the "column.seeable" or/ and "column.modifiable" get options:

view
show  ViewName get { ... column.seeable ... column.modifiable... } ;

or by the getAccessColumns (int accessType, Vector filterArgs, Framework framework) method of the View class [ accessType is one of Column.COLUMNACCESS_SEEABLE, Column.COLUMNACCESS_MODIFIABLE ]

They also run automatically for a specific view-column when a view-show OOQL command try to get the column properties using the "column.access" get options:

view show  ViewName get { ... column[ColumnName].access[<access_type>] ... };

where <access_type> is one ofseeable ,modifiable

or by the hasAccess (int accessType, Vector filterArgs, Framework framework) method of the Column class
[ accessType is one of Column.COLUMNACCESS_SEEABLE, Column.COLUMNACCESS_MODIFIABLE ]

import com.oberon.ooql.sdk.*;
import java.util.*;

public class <CLASSNAME> <EXTEND=> {
  public Framework OberonMain(Vector vArgs,Framework framework) throws OberonException {
   
Column
oViewCol = (Column) vArgs.elementAt(0);

// Read the access type
// seeable [Column.COLUMNACCESS_SEEABLE] / modifiable [Column.COLUMNACCESS_MODIFIABLE]

String sAccessType = framework.getEnv(Arg.ACCESS);

if ( ... check something ..... ) { throw new OberonException(""); }
    return framework;
  }
}


command - access check

The command access check programs are associated to command administrative objects; they control the command user access in addition to the basic user / team / assignment access rights checks. In particular they determine if a command must be showed on a navigation menu. They run automatically when a command-show OOQL command try to extract the user access using the get option:

command
show  CommandName get { ... access ... } [ input ProgramArg {ProgramArg} ] ;

or by the hasAccess (Vector filterArgs, Framework framework) method of the Command class

They also run automatically when a menu-show OOQL command or the lifecycle-show OOQL command try to get the command properties using the "owncommand.access" or "command.access" or "ownchild.access" get options:

menu show MenuName get { ... owncommand[CommandName].access ... ownchild.access ... };

lifecycle show
MenuName get { ... command.access ... stage[StageName].command.access ... };

In this cases the additional parameters should be passed inside the framework environment setting the framework variables:
(OOQL) framework env set varName = value;
(java) framework.setEnv (String varName, String value)
import com.oberon.ooql.sdk.*;
import java.util.*;

public class <CLASSNAME> <EXTEND=> {
  public Framework OberonMain(Vector vArgs,Framework framework) throws OberonException {
    Command oCommandItem = (Command) vArgs.elementAt(0);
String
sObjectID = framework.getEnv("id");

// Open the object
ObjectObj oObject = ObjectObj.open( sObjectID, true , framework );

...... do something .........

if ( ... fail condition... ) { throw new OberonException(); }
    return framework;
  }
}


autonumber increment

AutoNumber increment programs are associated to administrative autonumber objects; their purpose is to compute the autonumber next value in a custom way. They can be executed for a autonumber instance by the OOQL command:

autonumber increaseAutoNumberName [value Increment_Value] ;

or by the increment (int increment,Framework framework) method of AutoNumber class

import com.oberon.ooql.sdk.*;
import java.util.*;

public class <CLASSNAME> <EXTEND=> {
  public Framework OberonMain(Vector vArgs,Framework framework) throws OberonException {
    // Get the autonumber parameters
Hashtable
hParams = (Hashtable) vArgs.elementAt(0);
AutoNumber oAutoName = (AutoNumber) hParams.get(Arg.AUTONUMBER);
String sNextValue = (String) hParams.get(Arg.VALUE);

// Read the increment value
Integer iIncrement= (Integer) vArgs.elementAt(1);

// Increase the next value and update the AutoNumber
int iNextValue = Integer.parseInt(sNextValue)+iIncrement.intValue();
oAutoName.setNextValue(""+iNextValue);
oAutoName.write(framework);

return framework;
  }
}


© 2008-2015 MS Enterprise Solutions | Website Templates by IceTemplates.com
Please Read: Privacy Policy and Terms of Use