Function Library DSL

From OS.bee documentation
Jump to: navigation, search

Introduction

Function Library model defines the java functions for Os.bee. It could be used in other models. For example, in entity Person, the function getImagePickerMap from group ComboBox is used here.


Function Library DSL

The FunctionLibraryDSL defines the java functions for Os.bee and the functions will be used in other Os.bee models..

The main semantic elements of the FunctionLibraryDSL are:

  • package - The root element that contains all the other elements. A model can contain multiple packages.
  • import declarations - Used to import external models or other Java classes.
  • group - define the function group, including function, test and rate.
  • blip-group - define the function group for blip, including function, test and rate.
  • converter - define the function for converter.
  • statemachine - define the function for statemachine.
  • rating - define the rating, all value of the rating will be saved as enum.

Syntax

package definition

Syntax:

package <package name>  {
	 group <group name> {. . .}
	|blip-group <blipGroup name> {. . .}
	|converter <converter name> {. . .}
	|statemachine <statemachine name> {. . .}
	|rating <rating name> {. . .}
	. . .
}

Example:

package net.osbee.sample.foodmart.functionlibraries {
	group Lengths {. . .}
	. . .
	blip-group ProductMaintenance {. . .}
	. . .
	converter UomoGRAMMetricConverter {. . .}
	. . .
	statemachine CashRegister {. . .}
	. . .
	rating CountRating {. . .}
	. . .
}
  • For every group, blip-group, converter, statemachine or rating, a new .java files will be generated, <group/blip-group/converter/statmachine/rating name>.java. This .java files is generated in folder ./src-gen/<package name>/.
important definition

There are 3 important definitions of FunctionLibraryDSL which will be used in more than one place; they are FunctionLibraryFunction, FunctionLibraryTest and FunctionLibraryRate.

FunctionLibraryFunction

FunctionLibraryfunction defines the function for functionlibrary.

Syntax:

function <function name> ([<JvmType1> <parameter1> [, <JvmType2> <parameter2>]. . .]) returns <JvmType3>
{<block expression>}
  • One or more function parameter can be defined in () follow the function name. The parameter must be defined with its data type.
  • The data type of return value can be defined after keyword returns.
  • Inside {}, the function expression will be defined.

Example:

function getTaskId(Context context) returns Long {
	return Library.getTaskId(context);
}


FunctionLibraryTest

FunctionLibraryTest defines the test function for function library.

Syntax:

test <test name> ([<JvmType1> <parameter1> [, <JvmType2> <parameter2>]. . . ] )
{<block expression>}
  • One or more test parameter can be defined in () follow the test name. The parameter must be defined with its data type.
  • The return value of test function is only true or false.
  • Inside {}, the test function expression will be defined.


Example:

test isNearZero( double value ) {
	return Math.abs( value ) < Float.MIN_VALUE
}
test noProductsSelected( Object kcontext ) {
	return rateCountOfProductsSelected( kcontext ).equals( CountRating.NONE )
}


FunctionLibraryRate

FunctionLibraryRate define the rate function for function library.

Syntax:

rate <rate name> ([<JvmType1 > <parameter1 > [, <JvmType2> <parameter2>]. . . ])returns [Rating name]
{<block expression>}
  • One or more rate parameter can be defined in () follow the rate name. The parameter must be defined with its data type.
  • The return value of rate function can only be one of the redefined rating values.
  • Inside {}, the rate function expression will be defined.

Example:

rating CountRating {
	NONE
	ONE
	MANY
}

. . .

rate rateCountOfProductsSelected( Object kcontext ) returns CountRating {
switch( countOfProductsSelected( kcontext ) ) {
		case 0 : return CountRating.NONE case 1 : return CountRating.ONE
	}
	return CountRating.MANY
}
group

Keyword group is used to define the normal function group.

Syntax:

group <group name> {
	  FunctionLibraryFunction
	| FunctionLibraryTest
	| FunctionLibraryRate
	. . .
}
  • One or more FunctionLibraryFunction or FunctionLibraryTest or FunctionLibraryRate can be defined in the group.

Example:

group TaskToolbar {
	function getTaskId(Context context) returns Long {
		return Library.getTaskId(context);
	}
	function claimCanExecute(Context context) returns boolean {
		var userName = Library.getUserName(context);
		if( "Administrator".equals( userName ) ) {
			return false
		}
		return Library.isTask(context, Status.Created);
	}
	function startCanExecute(Context context) returns boolean {
		var userName = Library.getUserName(context);
		if( "Administrator".equals( userName ) ) {
			return false
		}
		return Library.isTask(context, Status.Ready);
	}
	function resumeCanExecute(Context context) returns boolean {
		var userName = Library.getUserName(context);
		if( "Administrator".equals( userName ) ) {
			return false
		}
		var suspended = Library.isTask(context, Status.Suspended);
		var progress = Library.isTask(context, Status.InProgress);
		return( suspended || progress )
	}
}
blip group

Keyword blip-group is used to define the blip function group.

Syntax:

blip-group <blipGroup name> {
	  FunctionLibraryFunction
	| FunctionLibraryTest
	| FunctionLibraryRate
	. . .
}
  • One or more FunctionLibraryFunction or FunctionLibraryTest or FunctionLibraryRate can be defined in the blip group.

Example:

blip-group MultipleEndEventsEverythinNeedsToBeDone {
	function NecessaryTask1_Enter( Object kcontext ) returns void {
		System.err.println( appendProcessProtocol( kcontext, "Necessary Task 1 - enter" ) )
	}

	function NecessaryTask1_Exit( Object kcontext ) returns void {
		System.err.println( appendProcessProtocol( kcontext, "Necessary Task 1 - EXIT" ) )
	}

	function NecessaryTask2_Enter( Object kcontext ) returns void {
		System.err.println( appendProcessProtocol( kcontext, "Necessary Task 2 - enter" ) )
	}

	function NecessaryTask2_Exit( Object kcontext ) returns void {
		System.err.println( appendProcessProtocol( kcontext, "Necessary Task 2 - EXIT" ) )
	}

	function NecessaryTask3_Enter( Object kcontext ) returns void {
		System.err.println( appendProcessProtocol( kcontext, "Necessary Task 3 - enter" ) )
	}

	function NecessaryTask3_Exit( Object kcontext ) returns void {
		System.err.println( appendProcessProtocol( kcontext, "Necessary Task 3 - EXIT" ) )
	}
}
converter

Keyword converter is used to define the converter for different units, e.g. cm -> m, g -> kg….

Syntax:

converter <converter name> {
	model-datatype <DataType1>  
	presentation-datatype <DataType2> 
	to-model {<block expression1>}
	to-presentation {<block expression2>}
}
  • Data type for model and data type for presentation must be defined.
  • The converter function defined in the block expression. The function for model should be defined after keyword to-model in the {} ; and the function for presentation should be defined after keyword to-presentation in the {}.


Example:

converter UomoKMMetricConverter {
	model-datatype Double presentation-datatype BaseAmount
	to-model {
		var localUnitFormat = LocalUnitFormatImpl.getInstance( presentationLocale );
		var baseUnit = localUnitFormat.format( MetricLengthUnit.KM ) var suffix =( presentationParams.get( 1 ) as String ) if( suffix == null ) {
			uffix = baseUnit
		}
		if( localUnitFormat.format( MetricLengthUnit.M ).equals( suffix ) ) 
{
			var amount = MetricLengthUnit.amount( presentationValue, MetricLengthUnit.M ) return amount.to( MetricLengthUnit.KM ).value.doubleValue
		}
		else if( localUnitFormat.format( MetricLengthUnit.CM ).equals( suffix ) ) {
			var amount = MetricLengthUnit.amount( presentationValue, MetricLengthUnit.CM ) return amount.to( MetricLengthUnit.KM ).value.doubleValue
		}
		else {
			return presentationValue
		}
	}

	to-presentation {
		var amount = MetricLengthUnit.amount( modelValue, MetricLengthUnit.KM ) if( modelValue < 1d && modelValue > 0.001d ) {
			amount = amount.to( MetricLengthUnit.M )
		}
		else if( modelValue < 0.001d ) {
			amount = amount.to( MetricLengthUnit.CM )
		}
		return amount as BaseAmount
	}
}
statemachine

Keyword statemachine is used to define the function for statemachine.

Syntax:

statemachine <statemachine name> {	
	  operation <operation name> ([<JvmType11> <parameter11> [, <JvmType12> <parameter12>]. . . ] ){<block expression1>}
	| guard <guard name> ([<JvmType21> <parameter21> [, <JvmType22> <parameter22>]. . . ] ){<block expression2>}
	| FunctionLibraryFunction
	. . .
}
  • Keyword operation defines the operation function for the statemachine, e.g. loading, check the exist state…
  • Keyword guard defines the guard function for the statemachine, e.g. check the validation, check the exist state…
  • FunctionLibraryFunction can be defined here. This kind of function can also be called in other functions of this statemachine, e.g. operation functions and guard functions…


Example:

statemachine CashRegister {
	guard passwordExists( IStateMachine stateMachine ) {
		return stateMachine.userPassword != null
	}
	guard checkPassword( IStateMachine stateMachine )  {
		return stateMachine.userPassword.equals( stateMachine.get("passwordEntry") )
	}
	operation loadPLU( IStateMachine stateMachine, Object [] params ) {
		for (var plu = (params.get(0) as Double).intValue; plu <= (params.get(1) as Double).intValue; plu++) {
			if(stateMachine.find("MproductDto", "plu", plu.toString)) {
				stateMachine.caption("plu"+plu, stateMachine.get("MproductDtoPluLabel") as String)
			}
		}
		return true
	}
	operation loadPaymentMethods(IStateMachine stateMachine, Object [] params) {
		stateMachine.putStorage("methods", "start", (params.get(0) as Double).intValue)
		stateMachine.putStorage("methods", "end", (params.get(1) as Double).intValue)
		for (var methodId = (params.get(0) as Double).intValue; methodId <= (params.get(1) as Double).intValue; methodId++) {
			if(stateMachine.find("CashPaymentMethodDto", "num", methodId.toString)) {
				stateMachine.image("method" + methodId,	stateMachine.get("CashPaymentMethodDtoImageName") as String)
				stateMachine.putStorage("onMethod" + methodId, "dto", stateMachine.get("CashPaymentMethodDto"))
				stateMachine.putStorage("method" + methodId, "limit", stateMachine.get("CashPaymentMethodDtoLowerLimit") as Double)
				stateMachine.putStorage("method" + methodId, "paymentTerminal", stateMachine.get("CashPaymentMethodDtoPaymentTerminal") as Boolean)
			}
		}
		return true
	}
	guard hasCashRegister(IStateMachine stateMachine) {
		if(stateMachine.get("CashRegisterDto") == null) {
			stateMachine.find("CashRegisterDto", "ip", stateMachine.IPAddress)
		}
		if(stateMachine.get("CashRegisterDto") == null) {
			return false
		}
		return true
	}
	function newSlip(IStateMachine stateMachine) returns void {
		stateMachine.set("CashSlipDto", new CashSlipDto)
		stateMachine.set("CashSlipDtoNow", stateMachine.now)
		stateMachine.set("CashSlipDtoCurrentDay", stateMachine.get("CashRegisterDtoCurrentDay") as String)
		stateMachine.set("CashSlipDtoCashier", stateMachine.userName)
		stateMachine.addTo("CashRegisterDto", "Slips", stateMachine.get("CashSlipDto") as IDto)
		stateMachine.update("CashRegisterDto")
	}			
	guard hasCurrentSlip(IStateMachine stateMachine) {
		if(stateMachine.get("CashSlipDto") == null) {
			var query = new Query(new LAnd(new LCompare.Equal("currentDay", stateMachine.get("CashRegisterDtoCurrentDay") as String), new LCompare.Equal("payed", false)))
			stateMachine.find("CashSlipDto", query)
		}
		if(stateMachine.get("CashSlipDto") == null) {
			newSlip(stateMachine)
		}
		computeTotal(stateMachine)
		return true
	}
		
	. . .

	function addGiven(IStateMachine stateMachine, Object [] params) returns String {
		var givenStr = params.get(0) as String
		var given = Double.parseDouble(givenStr)
		var addend = params.get(1) as Double
		given = given + addend
		return given.toString
	}	
	guard isPayed(IStateMachine stateMachine) {
		var total = stateMachine.get("paymentTotal") as Double
		var payed = stateMachine.get("paymentPayed") as Double
		if(total-payed <= 0.0001) {
			return true
		}
		return false
	}
	guard mustOpenDrawer(IStateMachine stateMachine) {
		var slip = stateMachine.get("CashSlipDto") as CashSlipDto
		for(pay:slip.payments) {
			if(pay.methodOfPayment.openDrawer) {
				return true
			}
		}
		return false
	}
}
rating

Keyword rating is used to define the rating enum for function library.

Syntax:

rating <rating name> { 
	<item name>
	. . . 
}
  • Rating name must be defined.
  • One or more item can be defined in the same rating.

Example:

rating CountRating {
	NONE
	ONE
	MANY
}

Copyright Notice

All rights are reserved by Compex Systemhaus GmbH. In particular, duplications, translations, microfilming, saving and processing in electronic systems are protected by copyright. Use of this manual is only authorized with the permission of Compex Systemhaus GmbH. Infringements of the law shall be punished in accordance with civil and penal laws. We have taken utmost care in putting together texts and images. Nevertheless, the possibility of errors cannot be completely ruled out. The Figures and information in this manual are only given as approximations unless expressly indicated as binding. Amendments to the manual due to amendments to the standard software remain reserved. Please note that the latest amendments to the manual can be accessed through our helpdesk at any time. The contractually agreed regulations of the licensing and maintenance of the standard software shall apply with regard to liability for any errors in the documentation. Guarantees, particularly guarantees of quality or durability can only be assumed for the manual insofar as its quality or durability are expressly stipulated as guaranteed. If you would like to make a suggestion, the Compex Team would be very pleased to hear from you.

(c) 2018 Compex Systemhaus GmbH