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; |
|
} |
} |
|
|