blob: 70d97fad9a4717697a4f4cd3a89418aefda0adfa [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2017 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*
*
* This copyright notice shows up in the generated Java code
*
*/
package org.eclipse.osbp.xtext.statemachine.jvmmodel
import com.google.inject.Inject
import com.vaadin.data.Container.Filter
import com.vaadin.ui.Audio
import com.vaadin.ui.Video
import java.util.ArrayList
import java.util.Date
import java.util.Iterator
import java.util.regex.Pattern
import java.util.stream.Collectors
import org.eclipse.emf.common.util.EList
import org.eclipse.emf.ecore.EObject
import org.eclipse.osbp.abstractstatemachine.AbstractDataProvider
import org.eclipse.osbp.abstractstatemachine.AbstractEventSource
import org.eclipse.osbp.abstractstatemachine.AbstractPeripheralService
import org.eclipse.osbp.abstractstatemachine.AbstractStateMachine
import org.eclipse.osbp.dsl.common.datatypes.IDto
import org.eclipse.osbp.dsl.common.xtext.extensions.AnnotationExtension
import org.eclipse.osbp.dsl.dto.xtext.extensions.DtoModelExtensions
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute
import org.eclipse.osbp.dsl.semantic.common.types.LDataType
import org.eclipse.osbp.dsl.semantic.common.types.LDateType
import org.eclipse.osbp.dsl.semantic.common.types.LEnum
import org.eclipse.osbp.dsl.semantic.common.types.LFeature
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType
import org.eclipse.osbp.dsl.semantic.dto.LDto
import org.eclipse.osbp.dsl.semantic.dto.LDtoAttribute
import org.eclipse.osbp.dsl.semantic.dto.LDtoInheritedAttribute
import org.eclipse.osbp.dsl.semantic.dto.LDtoInheritedReference
import org.eclipse.osbp.dsl.semantic.dto.LDtoReference
import org.eclipse.osbp.dsl.semantic.entity.LBeanAttribute
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute
import org.eclipse.osbp.dsl.semantic.entity.LEntityReference
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableEvent
import org.eclipse.osbp.ecview.core.^extension.model.^extension.YSuggestTextFieldEvents
import org.eclipse.osbp.ui.api.functionlibrary.IFunctionLibraryService
import org.eclipse.osbp.ui.api.message.MessageEvent
import org.eclipse.osbp.ui.api.statemachine.IBeeper
import org.eclipse.osbp.ui.api.statemachine.IStateMachine
import org.eclipse.osbp.xtext.statemachine.FSM
import org.eclipse.osbp.xtext.statemachine.FSMAbstractFilter
import org.eclipse.osbp.xtext.statemachine.FSMAction
import org.eclipse.osbp.xtext.statemachine.FSMActionButtonCaption
import org.eclipse.osbp.xtext.statemachine.FSMActionButtonImage
import org.eclipse.osbp.xtext.statemachine.FSMActionConditionalTransition
import org.eclipse.osbp.xtext.statemachine.FSMActionDTOClear
import org.eclipse.osbp.xtext.statemachine.FSMActionDTOFind
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldClear
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldConcatenation
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldFilterToggle
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldGet
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldKeystroke
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldRemove
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldSet
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldSource
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldSourceBoolean
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldSourceDtoAttribute
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldSourceEvaluate
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldSourceEvent
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldSourceInteger
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldSourceNumber
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldSourceString
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldSourceTranslate
import org.eclipse.osbp.xtext.statemachine.FSMActionItemInvisible
import org.eclipse.osbp.xtext.statemachine.FSMActionItemVisible
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralBeeper
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralBlinkRate
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralClear
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralCreateWindow
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralCursorType
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralDestroyWindow
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralDeviceBrightness
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralDisplayText
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralInterCharacterWait
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralLineDisplayText
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralLineDisplayTextAt
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralMarqueeFormat
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralMarqueeRepeatWait
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralMarqueeType
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralMarqueeUnitWait
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralOpenDrawer
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPTAcknowledge
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPTAuthorization
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPTClose
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPTOpen
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPTRegistration
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPTResponse
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPTReversal
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPlayer
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPrintBarcode
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPrintBitmap
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPrintCut
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPrintNormal
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPrintRegisterBitmap
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPrintReport
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralScroll
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralSignatureCapture
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralSignatureClear
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralSignatureClose
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralSignatureIdle
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralSignatureLabel
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralSignatureOpen
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralSound
import org.eclipse.osbp.xtext.statemachine.FSMActionScheduler
import org.eclipse.osbp.xtext.statemachine.FSMAndFilter
import org.eclipse.osbp.xtext.statemachine.FSMBetweenFilter
import org.eclipse.osbp.xtext.statemachine.FSMCompareFilter
import org.eclipse.osbp.xtext.statemachine.FSMControlButton
import org.eclipse.osbp.xtext.statemachine.FSMControlButtonAttributeEvent
import org.eclipse.osbp.xtext.statemachine.FSMControlButtonAttributeEventEvent
import org.eclipse.osbp.xtext.statemachine.FSMControlButtonAttributeEventIdentity
import org.eclipse.osbp.xtext.statemachine.FSMControlButtonAttributeEventKeyboard
import org.eclipse.osbp.xtext.statemachine.FSMControlDTO
import org.eclipse.osbp.xtext.statemachine.FSMControlDTOAttribute
import org.eclipse.osbp.xtext.statemachine.FSMControlField
import org.eclipse.osbp.xtext.statemachine.FSMControlFieldAttribute
import org.eclipse.osbp.xtext.statemachine.FSMControlPeripheral
import org.eclipse.osbp.xtext.statemachine.FSMControlScheduler
import org.eclipse.osbp.xtext.statemachine.FSMDotExpression
import org.eclipse.osbp.xtext.statemachine.FSMFilterProperty
import org.eclipse.osbp.xtext.statemachine.FSMFunction
import org.eclipse.osbp.xtext.statemachine.FSMGuard
import org.eclipse.osbp.xtext.statemachine.FSMInternalType
import org.eclipse.osbp.xtext.statemachine.FSMIsNullFilter
import org.eclipse.osbp.xtext.statemachine.FSMLikeFilter
import org.eclipse.osbp.xtext.statemachine.FSMModel
import org.eclipse.osbp.xtext.statemachine.FSMNotFilter
import org.eclipse.osbp.xtext.statemachine.FSMOperation
import org.eclipse.osbp.xtext.statemachine.FSMOperationParameter
import org.eclipse.osbp.xtext.statemachine.FSMOrFilter
import org.eclipse.osbp.xtext.statemachine.FSMPackage
import org.eclipse.osbp.xtext.statemachine.FSMPeripheralDevice
import org.eclipse.osbp.xtext.statemachine.FSMPeripheralDeviceCashDrawer
import org.eclipse.osbp.xtext.statemachine.FSMPeripheralDeviceLineDisplay
import org.eclipse.osbp.xtext.statemachine.FSMPeripheralDevicePOSPrinter
import org.eclipse.osbp.xtext.statemachine.FSMState
import org.eclipse.osbp.xtext.statemachine.FSMStorage
import org.eclipse.osbp.xtext.statemachine.FSMStorageRetrieve
import org.eclipse.osbp.xtext.statemachine.FSMStringFilter
import org.eclipse.osbp.xtext.statemachine.FSMTrigger
import org.eclipse.osbp.xtext.statemachine.StatemachineDSLFactory
import org.eclipse.osbp.xtext.statemachine.StatemachineEnums
import org.eclipse.xtext.common.types.JvmDeclaredType
import org.eclipse.xtext.common.types.JvmField
import org.eclipse.xtext.common.types.JvmGenericType
import org.eclipse.xtext.common.types.JvmOperation
import org.eclipse.xtext.common.types.JvmTypeReference
import org.eclipse.xtext.common.types.JvmVisibility
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.osgi.service.component.annotations.Component
import org.osgi.service.component.annotations.Reference
import org.osgi.service.component.annotations.ReferenceCardinality
import org.osgi.service.component.annotations.ReferencePolicy
import org.slf4j.Logger
import org.eclipse.osbp.dsl.semantic.entity.LBean
import org.eclipse.osbp.xtext.statemachine.services.StatemachineDSLGrammarAccess.FSMControlElements
import org.eclipse.osbp.xtext.statemachine.FSMEvent
/**
* <p>
* FSM
* This inferrer infers models of extension statemachine and generates code for a enum based statemachine
* </p>
*
* @author Joerg Riegel
*/
class StatemachineDSLJvmModelInferrer extends AbstractModelInferrer {
@Inject extension JvmTypesBuilder
@Inject extension StatemachineDSLModelGenerator
@Inject extension IQualifiedNameProvider
@Inject extension AnnotationExtension
@Inject extension DtoModelExtensions
val binderPostfix = "ServiceBinder"
def dispatch void infer(FSMPackage statemachinePkg, IJvmDeclaredTypeAcceptor acceptor,
boolean isPreIndexingPhase) {
statemachinePkg.generatePckgName(acceptor)
// the service binder class
val bindercls = statemachinePkg.toClass(statemachinePkg.name.toString.concat(binderPostfix))
bindercls.simpleName = bindercls.simpleName.toFirstUpper
acceptor.accept(bindercls, [
annotations += _annotationTypesBuilder.annotationRef(SuppressWarnings, "serial")
annotations += _annotationTypesBuilder.annotationRef(typeof(Component))
packageName = statemachinePkg.fullyQualifiedName.toString
documentation = statemachinePkg.documentation
it.toBinderFields(statemachinePkg)
it.toBinderOperations(statemachinePkg, bindercls.simpleName)
])
for (statemachine : statemachinePkg.statemachines) {
val clsName = statemachine.className.toFirstUpper
val cls = statemachinePkg.toClass(clsName);
cls.superTypes.add(_typeReferenceBuilder.typeRef(AbstractStateMachine))
cls.simpleName = cls.simpleName.toFirstUpper
cls.fileHeader = (statemachinePkg.eContainer as FSMModel).documentation
val pkgName = statemachinePkg.fullyQualifiedName.toString + "." + clsName.toLowerCase
acceptor.accept(
cls,
[
it.toConstructor(statemachine)
it.toFields(statemachine)
it.toOperations(statemachine)
packageName = pkgName
]
)
// create event emitter to be bound to components' events (focus, blur etc)
val eventCls = statemachinePkg.toClass("EventEmitter");
eventCls.simpleName = eventCls.simpleName.toFirstUpper
eventCls.superTypes.add(_typeReferenceBuilder.typeRef(AbstractEventSource))
acceptor.accept(
eventCls,
[
// events
it.generateEventEmitters(statemachine)
packageName = pkgName
]
)
// collect display associated dtos
val associatedDtos = <FSMControlDTOAttribute>newArrayList
statemachine.controls.stream.filter[it instanceof FSMControlPeripheral].forEach[p|(p as FSMControlPeripheral).displays.forEach[associatedDtos.add(it.output)]]
for (control : statemachine.controls) {
val controlClsName = control.name.toString.toFirstUpper
val controlCls = statemachinePkg.toClass(controlClsName);
controlCls.simpleName = controlCls.simpleName.toFirstUpper
switch control {
FSMControlScheduler: {
controlCls.superTypes.add(_typeReferenceBuilder.typeRef(AbstractEventSource))
acceptor.accept(
controlCls,
[
// schedulers
it.generateSchedulers(control)
packageName = pkgName
]
)
}
FSMControlButton: {
controlCls.superTypes.add(_typeReferenceBuilder.typeRef(AbstractEventSource))
acceptor.accept(
controlCls,
[
// buttons
it.generateButtons(control)
packageName = pkgName
]
)
}
FSMControlField: {
controlCls.superTypes.add(_typeReferenceBuilder.typeRef(AbstractEventSource))
acceptor.accept(
controlCls,
[
// fields
it.generateFields(control)
packageName = pkgName
]
)
}
FSMControlDTO: {
controlCls.superTypes.add(_typeReferenceBuilder.typeRef(AbstractDataProvider))
acceptor.accept(
controlCls,
[
// dto
it.generateDTOs(control, associatedDtos)
packageName = pkgName
]
)
}
FSMControlPeripheral: {
controlCls.superTypes.add(_typeReferenceBuilder.typeRef(AbstractPeripheralService))
acceptor.accept(
controlCls,
[
it.generatePeripheral(control)
packageName = pkgName
]
)
}
}
}
}
}
def void generateEventEmitters(JvmGenericType eventCls, FSM statemachine) {
for (event : statemachine.events) {
var JvmField field = event.toField(event.name, _typeReferenceBuilder.typeRef(Number))
field.visibility = JvmVisibility::PRIVATE
eventCls.members += field
var JvmOperation operation = event.toMethod('''get«event.name.toFirstUpper»Event''', _typeReferenceBuilder.typeRef(Number)) [
body = [append('''return «event.name»;''')]
]
operation.visibility = JvmVisibility::PUBLIC
eventCls.members += operation
operation = event.toMethod('''set«event.name.toFirstUpper»Event''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility.PUBLIC
parameters += event.toParameter(event.name, _typeReferenceBuilder.typeRef(Number));
body = [
append(
'''
statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "«event.name»"));
this.«event.name» = «event.name»;''')
]
]
operation.visibility = JvmVisibility::PUBLIC
eventCls.members += operation
}
}
def generatePeripheral(JvmGenericType controlCls, FSMControlPeripheral peripheral) {
var JvmOperation init = peripheral.toMethod("initDevices", _typeReferenceBuilder.typeRef(boolean)) [
annotations += _annotationTypesBuilder.annotationRef(Override)
visibility = JvmVisibility.PUBLIC
parameters += peripheral.toParameter("beeper", _typeReferenceBuilder.typeRef(IBeeper));
parameters += peripheral.toParameter("audio", _typeReferenceBuilder.typeRef(Audio));
parameters += peripheral.toParameter("video", _typeReferenceBuilder.typeRef(Video));
body = [append(peripheral.initDevices)]
]
controlCls.members += init
var JvmOperation release = peripheral.toMethod("releaseDevices", _typeReferenceBuilder.typeRef(Void::TYPE)) [
annotations += _annotationTypesBuilder.annotationRef(Override)
visibility = JvmVisibility.PUBLIC
body = [append(peripheral.releaseDevices)]
]
controlCls.members += release
}
def String initDevices(FSMControlPeripheral peripheral) {
val StringBuilder b = new StringBuilder
b.append("this.beeper = beeper;\nthis.audio=audio;\nthis.video=video;\n")
b.append("BaseControl device = null;\nSimpleEntry entry = null;\nHttpPut put;\n")
b.append(
'''
if(isRemote) {
''')
peripheral.posPrinters.forEach[b.append(initRemoteDevice(it))]
peripheral.cashDrawers.forEach[b.append(initRemoteDevice(it))]
peripheral.lineDisplays.forEach[b.append(initRemoteDevice(it))]
b.append(
'''
} else if(props != null) {
''')
peripheral.posPrinters.forEach[b.append(initDevice(it))]
peripheral.cashDrawers.forEach[b.append(initDevice(it))]
peripheral.lineDisplays.forEach[b.append(initDevice(it))]
b.append(
'''
}
''')
b.append(
'''
if(getPTIP() != null && getPTIP().length() > 0 && POSServiceBinder.getPosService() != null) {
if(!POSServiceBinder.getPosService().openZVTChannel(getPTIP(), getPTPort())) {
LOGGER.error("could not open ZVT socket");
}
}
initDone = true;
return true;''')
return b.toString
}
def String releaseDevices(FSMControlPeripheral peripheral) {
val StringBuilder b = new StringBuilder
b.append(
'''
HttpPut put;
if(isRemote) {
super.releaseDevices();
put = new HttpPut(String.format("http://%s:%d/devices/release", remoteHost, remotePort));
put.addHeader("Accept", "application/json");
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
CloseableHttpResponse response = httpClient.execute(put);
LOGGER.info(EntityUtils.toString(response.getEntity()));
} catch (IOException e) {
LOGGER.error("{}", e);
} finally {
put.releaseConnection();
}
} else if(isInitDone()) {
''')
peripheral.posPrinters.forEach[b.append(releaseDevice(it))]
peripheral.cashDrawers.forEach[b.append(releaseDevice(it))]
peripheral.lineDisplays.forEach[b.append(releaseDevice(it))]
b.append(
'''
}
if(getPTIP() != null && getPTIP().length() > 0 && POSServiceBinder.getPosService() != null) {
POSServiceBinder.getPosService().closeZVTChannel();
}
windowsCreated = 0;
''')
return b.toString
}
def initRemoteDevice(FSMPeripheralDevice device)
'''
put = new HttpPut(String.format("http://%s:%d/devices/claim?deviceName=%s", remoteHost, remotePort, "«device.name»"));
put.addHeader("Accept", "application/json");
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
CloseableHttpResponse response = httpClient.execute(put);
LOGGER.info(EntityUtils.toString(response.getEntity()));
} catch (IOException e) {
LOGGER.error("{}", e);
} finally {
put.releaseConnection();
}
'''
def initDevice(FSMPeripheralDevice device)
'''
entry = (SimpleEntry) props.getJposEntry("«device.name»");
if(entry == null) {
LOGGER.error("«device.name» is not configured");
} else {
try {
device = (BaseControl) Class.forName("jpos." + entry.getProp("deviceCategory").getValueAsString()).getConstructor().newInstance();
device.open("«device.name»");
device.claim(1000);
device.setDeviceEnabled(true);
«IF device instanceof FSMPeripheralDeviceCashDrawer»
((CashDrawer) device).addStatusUpdateListener(this);«ENDIF»
«IF device instanceof FSMPeripheralDevicePOSPrinter»
((POSPrinter) device).addStatusUpdateListener(this);
((POSPrinter) device).addErrorListener(this);
((POSPrinter) device).addOutputCompleteListener(this);
// Even if using any printer, 0.01mm unit makes it possible to print neatly.
((POSPrinter) device).setMapMode(POSPrinterConst.PTR_MM_METRIC);
// Output by the high quality mode
((POSPrinter) device).setRecLetterQuality(true);
// 2mm spaces
((POSPrinter) device).printNormal(POSPrinterConst.PTR_S_RECEIPT, "\u001b|200uF");«ENDIF»
devices.put("«device.name»", device);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException | ClassNotFoundException | JposException ex) {
LOGGER.error("device init error: {}", ex);
if(ex instanceof JposException && ((JposException)ex).getOrigException()!=null) {
LOGGER.error(((JposException)ex).getOrigException().getMessage());
}
LOGGER.error("check path for dll access:"+ System.getProperty("java.library.path"));
}
}
'''
def releaseDevice(FSMPeripheralDevice device)
'''
if(devices.containsKey("«device.name»")) {
try {
«IF device instanceof FSMPeripheralDeviceLineDisplay»
try {
if(windowsCreated > 0) {
((LineDisplay) devices.get("«device.name»")).destroyWindow();
}
} catch (JposException e) {}
((LineDisplay) devices.get("«device.name»")).clearText();
«ENDIF»
devices.get("«device.name»").setDeviceEnabled(false);
«IF device instanceof FSMPeripheralDeviceCashDrawer»
((CashDrawer) devices.get("«device.name»")).removeStatusUpdateListener(this);«ENDIF»
«IF device instanceof FSMPeripheralDevicePOSPrinter»
((POSPrinter) devices.get("«device.name»")).removeStatusUpdateListener(this);«ENDIF»
devices.get("«device.name»").release();
devices.get("«device.name»").close();
} catch (JposException e) {
LOGGER.error("Error releasing «device.name»");
}
}
'''
def generateSchedulers(JvmGenericType controlCls, FSMControlScheduler control) {
control.schedulers.forEach [
var JvmField field = control.toField(it.name + "Scheduler", _typeReferenceBuilder.typeRef(int))
field.visibility = JvmVisibility::PRIVATE
controlCls.members += field
]
// methods
control.schedulers.forEach [
var JvmOperation operation = control.toGetter(it.name + "Scheduler", _typeReferenceBuilder.typeRef(int))
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
val scheduler = it
operation = control.toMethod('''set«it.name.toFirstUpper»Scheduler''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility.PUBLIC
parameters += control.toParameter("delay", _typeReferenceBuilder.typeRef(int));
body = [
append(
'''
Timer timer = new Timer(delay, action -> {
statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "«scheduler.event.name»"));
});
timer.setRepeats(false);
timer.start();''')
]
]
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
]
// init
var JvmOperation init = control.toMethod("init", _typeReferenceBuilder.typeRef(Void::TYPE)) [
annotations += _annotationTypesBuilder.annotationRef(Override)
visibility = JvmVisibility.PUBLIC
body = []
]
controlCls.members += init
}
def generateButtons(JvmGenericType controlCls, FSMControlButton control) {
var JvmField pad = control.toField(control.name.toFirstLower + "Enabled",
_typeReferenceBuilder.typeRef(Boolean))
pad.visibility = JvmVisibility::PRIVATE
controlCls.members += pad
if(control.hasRange) {
for(var i=control.start;i<=control.end;i++) {
control.buildButtonField(controlCls, control.rangedName+i, "", _typeReferenceBuilder.typeRef(Number))
control.buildButtonField(controlCls, control.rangedName+i, "Caption", _typeReferenceBuilder.typeRef(String))
control.buildButtonField(controlCls, control.rangedName+i, "Enabled", _typeReferenceBuilder.typeRef(Boolean))
control.buildButtonField(controlCls, control.rangedName+i, "Image", _typeReferenceBuilder.typeRef(Object))
control.buildButtonField(controlCls, control.rangedName+i, "Styles", _typeReferenceBuilder.typeRef(String))
}
for(var i=control.start;i<=control.end;i++) {
var eventId = StatemachineDSLFactory.eINSTANCE.createFSMControlButtonAttributeEventIdentity
eventId.identity = i
// bean
control.buildButtonMethods(controlCls, control.rangedName+i, "", _typeReferenceBuilder.typeRef(Number), eventId)
// caption
control.buildButtonMethods(controlCls, control.rangedName+i, "Caption", _typeReferenceBuilder.typeRef(String), eventId)
// enabled
control.buildButtonMethods(controlCls, control.rangedName+i, "Enabled", _typeReferenceBuilder.typeRef(Boolean), eventId)
// image
control.buildButtonMethods(controlCls, control.rangedName+i, "Image", _typeReferenceBuilder.typeRef(Object), eventId)
// styles
control.buildButtonMethods(controlCls, control.rangedName+i, "Styles", _typeReferenceBuilder.typeRef(String), eventId)
}
} else {
control.buttons.forEach [
control.buildButtonField(controlCls, it.name, "", _typeReferenceBuilder.typeRef(Number))
control.buildButtonField(controlCls, it.name, "Caption", _typeReferenceBuilder.typeRef(String))
control.buildButtonField(controlCls, it.name, "Enabled", _typeReferenceBuilder.typeRef(Boolean))
control.buildButtonField(controlCls, it.name, "Image", _typeReferenceBuilder.typeRef(Object))
control.buildButtonField(controlCls, it.name, "Styles", _typeReferenceBuilder.typeRef(String))
]
// methods
control.buttons.forEach [
// bean
control.buildButtonMethods(controlCls, it.name, "", _typeReferenceBuilder.typeRef(Number), it.event)
// caption
control.buildButtonMethods(controlCls, it.name, "Caption", _typeReferenceBuilder.typeRef(String), it.event)
// enabled
control.buildButtonMethods(controlCls, it.name, "Enabled", _typeReferenceBuilder.typeRef(Boolean), it.event)
// image
control.buildButtonMethods(controlCls, it.name, "Image", _typeReferenceBuilder.typeRef(Object), it.event)
// styles
control.buildButtonMethods(controlCls, it.name, "Styles", _typeReferenceBuilder.typeRef(String), it.event)
]
}
// keypad enabled
var JvmOperation getEnabled = control.toGetter(control.name.toFirstLower + "Enabled",
_typeReferenceBuilder.typeRef(Boolean))
getEnabled.visibility = JvmVisibility::PUBLIC
controlCls.members += getEnabled
var JvmOperation setEnabled = control.toMethod(
'''set«control.name.toFirstUpper»Enabled''', _typeReferenceBuilder.typeRef(Void::TYPE)) [
parameters += control.toParameter(control.name.toFirstLower + "Enabled",
_typeReferenceBuilder.typeRef(Boolean));
visibility = JvmVisibility.PUBLIC
body = [
append(
'''
«FOR button : control.buttons»
set«button.name.toFirstUpper»Enabled(«control.name.toFirstLower»Enabled);
«ENDFOR»
pcs.firePropertyChange("«control.name.toFirstLower»Enabled", this.«control.name.toFirstLower»Enabled, this.«control.name.toFirstLower»Enabled = «control.name.toFirstLower»Enabled);
'''
)
]
]
setEnabled.visibility = JvmVisibility::PUBLIC
controlCls.members += setEnabled
// init
var _hasImages = false
for (button : control.buttons) {
if(button.hasImage) _hasImages = true
}
val hasImages = _hasImages
var JvmOperation init = control.toMethod("init", _typeReferenceBuilder.typeRef(Void::TYPE)) [
annotations += _annotationTypesBuilder.annotationRef(Override)
visibility = JvmVisibility.PUBLIC
// suppress label if image is set and load resource
body = [
append(
'''
super.init();
set«control.name.toFirstUpper»Enabled(false);
«IF hasImages»
«FOR button : control.buttons»
«IF button.hasImage»set«button.name.toFirstUpper»Caption(null);
«ENDIF»
«ENDFOR»
if(statemachine != null) {
«FOR button : control.buttons»
«IF button.hasImage && button.image.length>0» set«button.name.toFirstUpper»Image(statemachine.getThemeResourceService().getThemeResource("«button.
image»", ThemeResourceType.ICON));
«ENDIF»
«ENDFOR»
}
«ENDIF»
''')
]
]
controlCls.members += init
}
def generateFields(JvmGenericType controlCls, FSMControlField control) {
control.fields.forEach [
var JvmField field = control.toField(it.name, _typeReferenceBuilder.typeRef(it.decodeType))
field.visibility = JvmVisibility::PRIVATE
controlCls.members += field
// extra suggest text event field
if (it.attributeType.attributeType == FSMInternalType.SUGGESTTEXT) {
field = control.toField(it.name + "Event", _typeReferenceBuilder.typeRef(YSuggestTextFieldEvents))
field.visibility = JvmVisibility::PRIVATE
controlCls.members += field
}
field = control.toField(it.name + "Enabled", _typeReferenceBuilder.typeRef(Boolean))
field.visibility = JvmVisibility::PRIVATE
controlCls.members += field
]
control.layouts.forEach [
var JvmField layout = control.toField(it.name + "Enabled", _typeReferenceBuilder.typeRef(Boolean))
layout.visibility = JvmVisibility::PRIVATE
controlCls.members += layout
]
// methods
control.fields.forEach [
var JvmOperation operation = control.toGetter(it.name, _typeReferenceBuilder.typeRef(it.decodeType))
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
val field = it
// setter
operation = control.toMethod('''set«it.name.toFirstUpper»''', _typeReferenceBuilder.typeRef(Void::TYPE)) [
parameters += control.toParameter(field.name, _typeReferenceBuilder.typeRef(field.decodeType))
visibility = JvmVisibility.PUBLIC
body = [
append(
'''
«field.decodeSetter»''')
]
]
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
// enabled
operation = control.toGetter(it.name + "Enabled", _typeReferenceBuilder.typeRef(Boolean))
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
operation = control.toMethod('''set«it.name.toFirstUpper»Enabled''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
parameters += control.toParameter(field.name + "Enabled", _typeReferenceBuilder.typeRef(Boolean));
visibility = JvmVisibility.PUBLIC
body = [
append(
'''
pcs.firePropertyChange("«field.name»Enabled", this.«field.name»Enabled, this.«field.name»Enabled = «field.
name»Enabled);''')
]
]
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
// extra methods for suggestText field
if (it.attributeType.attributeType == FSMInternalType.SUGGESTTEXT) {
operation = control.toGetter(it.name + "Event", _typeReferenceBuilder.typeRef(YSuggestTextFieldEvents))
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
val eventfield = it
// setter
operation = control.toMethod('''set«it.name.toFirstUpper»Event''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
parameters += control.toParameter(eventfield.name + "Event",
_typeReferenceBuilder.typeRef(YSuggestTextFieldEvents))
visibility = JvmVisibility.PUBLIC
body = [
append(
'''
pcs.firePropertyChange("«field.name»Event", this.«field.name»Event, this.«field.name»Event = «field.name»Event);
if(«eventfield.name»Event == YSuggestTextFieldEvents.SELECTED && statemachine != null) {
statemachine.processEvent(statemachine, new MessageEvent(MessageEvent.EventType.TRIGGER, "on«field.name.toFirstUpper»Selection"));
}''')
]
]
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
}
]
control.layouts.forEach [
// enabled
var JvmOperation operation = control.toGetter(it.name + "Enabled", _typeReferenceBuilder.typeRef(Boolean))
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
val layout = it
operation = control.toMethod('''set«it.name.toFirstUpper»Enabled''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
parameters += control.toParameter(layout.name + "Enabled", _typeReferenceBuilder.typeRef(Boolean));
visibility = JvmVisibility.PUBLIC
body = [
append(
'''
pcs.firePropertyChange("«layout.name»Enabled", this.«layout.name»Enabled, this.«layout.name»Enabled = «layout.
name»Enabled);''')
]
]
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
]
// init
var JvmOperation init = control.toMethod("init", _typeReferenceBuilder.typeRef(Void::TYPE)) [
annotations += _annotationTypesBuilder.annotationRef(Override)
visibility = JvmVisibility.PUBLIC
body = [
append(
'''
super.init();
«FOR field : control.fields»
pcs.firePropertyChange("«field.name»Enabled", this.«field.name»Enabled, this.«field.name»Enabled = false);
«ENDFOR»
«FOR layout : control.layouts»
pcs.firePropertyChange("«layout.name»Enabled", this.«layout.name»Enabled, this.«layout.name»Enabled = false);
«ENDFOR»
''')
]
]
controlCls.members += init
}
def generateDTOs(JvmGenericType controlCls, FSMControlDTO control, ArrayList<FSMControlDTOAttribute> associatedDtos) {
control.dtos.forEach [
control.buildDTOField(controlCls, it.name, _typeReferenceBuilder.typeRef(it.attributeType.attributeType.fullyQualifiedName.toString))
]
// filters
control.filters.forEach [
val name = it.name.toFirstLower
val filterExpression = it.filter.source.buildFilter
var JvmField field = control.toField(it.name,
_typeReferenceBuilder.typeRef(Filter))
field.visibility = JvmVisibility::PRIVATE
controlCls.members += field
field = control.toField(it.name + "Enabled", _typeReferenceBuilder.typeRef(Boolean))
field.visibility = JvmVisibility::PRIVATE
controlCls.members += field
controlCls.members += control.toMethod('''get«it.name.toFirstUpper»''', _typeReferenceBuilder.typeRef(Filter)) [
visibility = JvmVisibility::PUBLIC
body = [append('''return this.«name»;''')]
]
controlCls.members += control.toMethod('''set«it.name.toFirstUpper»''', _typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility::PUBLIC
parameters += control.toParameter("create", _typeReferenceBuilder.typeRef(Boolean))
visibility = JvmVisibility.PUBLIC
body = [
append(
'''
if(create) {
pcs.firePropertyChange("«name»", this.«name», this.«name» = «filterExpression»);
} else {
pcs.firePropertyChange("«name»", this.«name», this.«name» = null);
}'''
)]
]
// enabled
var JvmOperation operation = control.toGetter(it.name + "Enabled", _typeReferenceBuilder.typeRef(Boolean))
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
val filter = it
operation = control.toMethod('''set«it.name.toFirstUpper»Enabled''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
parameters += control.toParameter(filter.name + "Enabled", _typeReferenceBuilder.typeRef(Boolean));
visibility = JvmVisibility.PUBLIC
body = [
append(
'''
pcs.firePropertyChange("«filter.name»Enabled", this.«filter.name»Enabled, this.«filter.name»Enabled = «filter.name»Enabled);
set«filter.name.toFirstUpper»(«filter.name»Enabled);''')
]
]
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
]
control.dtos.forEach [
control.buildDTOMethods(controlCls, it, _typeReferenceBuilder.typeRef(IDto), control.dtos, associatedDtos)
]
// init
var JvmOperation init = control.toMethod("init", _typeReferenceBuilder.typeRef(Void::TYPE)) [
annotations += _annotationTypesBuilder.annotationRef(Override)
visibility = JvmVisibility.PUBLIC
body = [
append('''
«FOR dto:associatedDtos»
«dto.name»=new «dto.attributeType.attributeType.name»();
«ENDFOR»
''')
]
]
controlCls.members += init
}
def buildDTOField(EObject control, JvmDeclaredType controlCls, String dtoName, JvmTypeReference type) {
var JvmField field = control.toField(dtoName, type)
field.visibility = JvmVisibility::PRIVATE
controlCls.members += field
}
def buildDTOMethods(EObject control, JvmDeclaredType controlCls, FSMControlDTOAttribute dto, JvmTypeReference type, EList<FSMControlDTOAttribute> dtos, ArrayList<FSMControlDTOAttribute> associatedDtos) {
// dto getter
var JvmOperation operation = control.toMethod('''get«dto.name.toFirstUpper»''',
type) [
visibility = JvmVisibility::PUBLIC
body = [
append(
'''
return «dto.name»;''')
]
]
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
// dto id getter
if (dto.attributeType.attributeType.primaryKeyAttribute !== null) {
operation = control.
toMethod('''get«dto.name.toFirstUpper»«dto.attributeType.attributeType.idAttributeName.toFirstUpper»''',
_typeReferenceBuilder.typeRef(dto.attributeType.attributeType.idAttributeType.name)) [
visibility = JvmVisibility::PUBLIC
body = [
append(
'''
return «dto.name».get«dto.attributeType.attributeType.idAttributeName.toFirstUpper»();''')
]
]
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
}
// attribute/ref getter/setter
for (f : dto.attributeType.attributeType.features) {
if (f instanceof LDtoAttribute) {
control.buildDTOAttribute(controlCls, dto, f, null, associatedDtos)
}
if (f instanceof LDtoInheritedAttribute) {
control.buildDTOAttribute(controlCls, dto, f.inheritedFeature, f, associatedDtos)
}
if (f instanceof LDtoReference) {
val LDto targetDto = f.type
if (f.toMany) {
if (dtos !== null && dtos.exists[it.attributeType.attributeType.name == targetDto.name]) {
operation = control.
toMethod('''addTo«dto.name.toFirstUpper»«f.name.toFirstUpper»''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility::PUBLIC
parameters +=
control.toParameter(f.name,
type)
body = [
append('''«dto.name».addTo«f.name.toFirstUpper»((«f.type.name.toString»)«f.name»);''')
]
]
controlCls.members += operation
operation = control.
toMethod('''removeFrom«dto.name.toFirstUpper»«f.name.toFirstUpper»''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility::PUBLIC
parameters +=
control.toParameter(f.name,
type)
body = [
append('''«dto.name».removeFrom«f.name.toFirstUpper»((«f.type.name.toString»)«f.name»);''')
]
]
controlCls.members += operation
}
} else {
operation = control.toMethod('''set«dto.name.toFirstUpper»«f.name.toFirstUpper»''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility::PUBLIC
parameters += control.toParameter(f.name, type)
body = [
append(
'''
if(«dto.name»!=null) {
«dto.name».set«f.name.toFirstUpper»((«f.type.name.toString»)«f.name»);«dto.notifySlaveReference(f, associatedDtos)»
}''')
]
]
controlCls.members += operation
operation = control.toMethod('''get«dto.name.toFirstUpper»«f.name.toFirstUpper»''', type) [
visibility = JvmVisibility::PUBLIC
parameters += control.toParameter(f.name, type)
body = [
append('''return «dto.name».get«f.name.toFirstUpper»();''')
]
]
controlCls.members += operation
}
}
if (f instanceof LDtoInheritedReference) {
val LDto targetDto = f.type
if (f.inheritedFeature.toMany) {
if (dtos !== null && dtos.exists[it.attributeType.attributeType.name == targetDto.name]) {
operation = control.
toMethod('''addTo«dto.name.toFirstUpper»«f.inheritedFeature.name.toFirstUpper»''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility::PUBLIC
parameters +=
control.toParameter(f.inheritedFeature.name,
type)
body = [
append('''«dto.name».addTo«f.inheritedFeature.name.toFirstUpper»((«f.type.name.toString»)«f.inheritedFeature.name»);''')
]
]
controlCls.members += operation
operation = control.
toMethod('''removeFrom«dto.name.toFirstUpper»«f.inheritedFeature.name.toFirstUpper»''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility::PUBLIC
parameters +=
control.toParameter(f.inheritedFeature.name,
type)
body = [
append('''«dto.name».removeFrom«f.inheritedFeature.name.toFirstUpper»((«f.type.name.toString»)«f.inheritedFeature.name»);''')
]
]
controlCls.members += operation
}
} else if (dtos !== null && dtos.exists[it.attributeType.attributeType.name == targetDto.name]) {
controlCls.members += operation
operation = control.
toMethod('''set«dto.name.toFirstUpper»«f.inheritedFeature.name.toFirstUpper»''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility::PUBLIC
parameters +=
control.toParameter(f.inheritedFeature.name,
type)
body = [
append('''«dto.name».set«f.inheritedFeature.name.toFirstUpper»((«f.type.name.toString»)«f.inheritedFeature.name»);''')
]
]
controlCls.members += operation
}
}
}
// dto setter
/**
* the following lambda expressions searches for references in the associated dto
* of the display that match with the dto the display is attached to
* */
operation = control.toMethod('''set«dto.name.toFirstUpper»''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
parameters += control.toParameter(dto.name, type)
visibility = JvmVisibility.PUBLIC
body = [
append(
'''
pcs.firePropertyChange("«dto.name.toFirstLower»", this.«dto.name», this.«dto.name» = («dto.attributeType.attributeType.name»)«dto.name»);
«IF dto.hasEvent»
if(statemachine != null) {
statemachine.processEvent(statemachine, new MessageEvent(MessageEvent.EventType.TRIGGER, "«dto.event.name»"));
}«ENDIF»
«IF dto.isAttached && dto.display !== null»
«FOR match:dto.display.output.attributeType.attributeType.allFeatures.stream.filter[it instanceof LDtoReference && (it as LDtoReference).type.equals(dto.attributeType.attributeType)].collect(Collectors.toList)»
set«dto.display.output.name.toFirstUpper»«match.name.toFirstUpper»(«dto.name»);«ENDFOR»
«FOR match:dto.display.output.attributeType.attributeType.allFeatures.stream.filter[it instanceof LDtoInheritedReference && (it as LDtoInheritedReference).type.equals(dto.attributeType.attributeType)].collect(Collectors.toList)»
set«dto.display.output.name.toFirstUpper»«match.name.toFirstUpper»(«dto.name»);«ENDFOR»«ENDIF»''')
]
]
// associatedDtos do not need to interact with jpa
if(!associatedDtos.contains(dto)) {
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
operation = control.toMethod('''update«dto.name.toFirstUpper»''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility::PUBLIC
parameters += control.toParameter(dto.name, type)
body = [
append(
'''
((IDTOService<«dto.attributeType.attributeType.name»>)dtoServices.get("«dto.name»")).update((«dto.attributeType.attributeType.name»)«dto.name»);
«dto.attributeType.attributeType.name» dto = ((IDTOService<«dto.attributeType.attributeType.name»>)dtoServices.get("«dto.name»")).reload((«dto.attributeType.attributeType.name»)«dto.name»);
set«dto.name.toFirstUpper»(dto);''')
]
]
controlCls.members += operation
operation = control.toMethod('''reload«dto.name.toFirstUpper»''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility::PUBLIC
parameters += control.toParameter(dto.name, type)
body = [
append(
'''
«dto.attributeType.attributeType.name» dto = ((IDTOService<«dto.attributeType.attributeType.name»>)dtoServices.get("«dto.name»")).reload((«dto.attributeType.attributeType.name»)«dto.name»);
set«dto.name.toFirstUpper»(dto);''')
]
]
controlCls.members += operation
operation = control.toMethod('''delete«dto.name.toFirstUpper»''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility::PUBLIC
parameters += control.toParameter(dto.name, type)
body = [
append('''((IDTOService<«dto.attributeType.attributeType.name»>)dtoServices.get("«dto.name»")).delete((«dto.attributeType.attributeType.name»)«dto.name»);''')
]
]
controlCls.members += operation
}
}
def notifySlaveReference(FSMControlDTOAttribute dto, LDtoReference f, ArrayList<FSMControlDTOAttribute> associatedDtos) '''
«IF associatedDtos.contains(dto)»
if(statemachine != null) {
Map<String, Object> data = new HashMap<>();
data.put("«dto.attributeType.attributeType.fullyQualifiedName»/«f.name»", «f.name»);
statemachine.sendSlaveData(data);
}«ENDIF»
'''
def notifySlaveAttribute(FSMControlDTOAttribute dto, LAttribute f, ArrayList<FSMControlDTOAttribute> associatedDtos) '''
«IF associatedDtos.contains(dto)»
if(statemachine != null) {
Map<String, Object> data = new HashMap<>();
data.put("«dto.attributeType.attributeType.fullyQualifiedName»/«f.name»", «f.name»);
statemachine.sendSlaveData(data);
}«ENDIF»
'''
def buildDTOAttribute(EObject control, JvmDeclaredType controlCls, FSMControlDTOAttribute dto, LAttribute f, LDtoInheritedAttribute prop, ArrayList<FSMControlDTOAttribute> associatedDtos) {
var isTimestamp = false
var typeRef = f.type.toTypeReference
var LScalarType st = null
switch f.type {
LDataType: {
val LDataType _dt = f.type as LDataType
st = _dt
if (_dt.isDate && _dt.dateType == LDateType.TIMESTAMP) {
isTimestamp = true
}
}
LEnum: {
st = f.type as LEnum
if(prop !== null) {
typeRef = prop.toDtoTypeReference
}
}
LBean: {
st = f.type as LBean
if(prop !== null) {
typeRef = prop.toDtoTypeReference
}
}
}
if (isTimestamp) {
typeRef = _typeReferenceBuilder.typeRef("org.joda.time.DateTime")
}
val _isTimestamp = isTimestamp
val _st = st
var JvmOperation operation = control.
toMethod('''get«dto.name.toFirstUpper»«f.name.toFirstUpper»''',
typeRef) [
visibility = JvmVisibility::PUBLIC
body = [
append(
'''
if(«dto.name»!=null) {
return «IF _isTimestamp»new DateTime(«ENDIF»«dto.name».get«f.name.toFirstUpper»()«IF _isTimestamp»)«ENDIF»;
} else {
return «_st.toNullReturnValue»;
}''')
]
]
val _typeRef = typeRef
controlCls.members += operation
operation = control.
toMethod('''set«dto.name.toFirstUpper»«f.name.toFirstUpper»''',
_typeReferenceBuilder.typeRef(Void::TYPE)) [
visibility = JvmVisibility::PUBLIC
parameters += control.toParameter(f.name, _typeRef)
body = [
append(
'''
if(«dto.name»!=null) {
«dto.name».set«f.name.toFirstUpper»(«f.name»«IF _isTimestamp».toDate()«ENDIF»);«dto.notifySlaveAttribute(f, associatedDtos)»
}''')
]
]
controlCls.members += operation
}
def JvmTypeReference decodeFilterProperty(FSMFilterProperty property, ArrayList<String> parts) {
parts.clear
return decodePath(property.path as FSMDotExpression, parts)
}
protected def JvmTypeReference decodePath(FSMDotExpression path, ArrayList<String> parts) {
var JvmTypeReference type = null
val head = path.ref
switch(head) {
FSMDotExpression: {
var tmpType = head.decodePath(parts)
if(type === null) {
type = tmpType
}
}
}
var tmpType = path.tail.decodeTail(parts)
if(type === null) {
type = tmpType
}
return type
}
protected def JvmTypeReference decodeTail(LFeature tail, ArrayList<String> parts) {
var JvmTypeReference type = null
var EObject ref = null
switch (tail) {
LDtoReference: {
parts.add(tail.name)
}
LDtoAttribute: {
parts.add(tail.name)
type = tail.datatype.jvmTypeReference
}
LDtoInheritedReference: {
ref = (tail as LDtoInheritedReference).inheritedFeature
if(ref instanceof LEntityReference) {
parts.add(ref.name)
}
}
LDtoInheritedAttribute: {
ref = (tail as LDtoInheritedAttribute).inheritedFeature
switch(ref) {
LBeanAttribute: {
parts.add(ref.name)
type = ref.datatype.jvmTypeReference
}
LEntityAttribute: {
parts.add(ref.name)
type = ref.datatype.jvmTypeReference
}
}
}
default:
parts.add("unknown")
}
return type
}
def String buildFilter(FSMAbstractFilter filter) {
var JvmTypeReference type
var parts = <String>newArrayList
switch(filter) {
FSMAndFilter:{
return '''new And(«filter.first.source.buildFilter»«FOR f:filter.more»,«f.source.buildFilter»«ENDFOR»)'''
}
FSMOrFilter:{
return '''new Or(«filter.first.source.buildFilter»«FOR f:filter.more»,«f.source.buildFilter»«ENDFOR»)'''
}
FSMBetweenFilter:{
type = decodeFilterProperty(filter.propertyId, parts)
val property = parts.stream.collect(Collectors.joining(".", "\"", "\""))
val start = decodeActionFieldSource(filter.start, type)
val end = decodeActionFieldSource(filter.end, type)
return '''new Between(«property»,«start»,«end»)'''
}
FSMCompareFilter:{
type = decodeFilterProperty(filter.propertyId, parts)
val property = parts.stream.collect(Collectors.joining(".", "\"", "\""))
val operand = decodeActionFieldSource(filter.operand, type)
val oper = filter.operation.literal.toFirstUpper
return '''new «oper»(«property»,«operand»)'''
}
FSMIsNullFilter:{
type = decodeFilterProperty(filter.propertyId, parts)
val property = parts.stream.collect(Collectors.joining(".", "\"", "\""))
return '''new IsNull(«property»)'''
}
FSMLikeFilter:{
type = decodeFilterProperty(filter.propertyId, parts)
val property = parts.stream.collect(Collectors.joining(".", "\"", "\""))
val value = decodeActionFieldSource(filter.value, type)
return '''new Like(«property»,«value»,«filter.ignoreCase.booleanValue.toString»)'''
}
FSMNotFilter:{
return '''new Not(«filter.filter.source.buildFilter»)'''
}
FSMStringFilter:{
type = decodeFilterProperty(filter.propertyId, parts)
val property = parts.stream.collect(Collectors.joining(".", "\"", "\""))
return '''new SimpleStringFilter(«property»,"«filter.filterString»",«filter.ignoreCase.booleanValue.toString»,«filter.onlyMatchPrefix.booleanValue.toString»)'''
}
}
return "null"
}
def decodeSetter(FSMControlFieldAttribute field) {
switch field.attributeType.attributeType {
case BOOLEAN: {
return '''pcs.firePropertyChange("«field.name»", this.«field.name», this.«field.name» = «field.name»);
'''
}
case INTEGER: {
return '''pcs.firePropertyChange("«field.name»", this.«field.name», this.«field.name» = «field.name»);
'''
}
case LONG: {
return '''pcs.firePropertyChange("«field.name»", this.«field.name», this.«field.name» = «field.name»);
'''
}
case DOUBLE: {
return '''pcs.firePropertyChange("«field.name»", this.«field.name», this.«field.name» = «field.name»);
'''
}
case STRING: {
return '''pcs.firePropertyChange("«field.name»", this.«field.name», this.«field.name» = «field.name»);
'''
}
case DATE: {
return '''pcs.firePropertyChange("«field.name»", this.«field.name», this.«field.name» = «field.name»);
'''
}
case SUGGESTTEXT: {
return '''
pcs.firePropertyChange("«field.name»", this.«field.name», this.«field.name» = «field.name»);
if(«field.name» == null || «field.name».isEmpty()) {
set«field.name.toFirstUpper»Event(YSuggestTextFieldEvents.CLEAR);
} else {
set«field.name.toFirstUpper»Event(YSuggestTextFieldEvents.OPEN_POPUP);
}'''
}
case EMBEDDABLEEVENT: {
return '''pcs.firePropertyChange("«field.name»", this.«field.name», this.«field.name» = «field.name»);
'''
}
}
}
def decodeType(FSMControlFieldAttribute field) {
switch field.attributeType.attributeType {
case BOOLEAN: {
return Boolean;
}
case INTEGER: {
return Integer;
}
case LONG: {
return Long;
}
case DOUBLE: {
return Double;
}
case STRING: {
return String;
}
case DATE: {
return Date;
}
case SUGGESTTEXT: {
return String;
}
case EMBEDDABLEEVENT: {
return YEmbeddableEvent;
}
}
}
def void buildButtonField(EObject control, JvmDeclaredType controlCls, String buttonName, String postFix, JvmTypeReference type) {
var JvmField field = control.toField(buttonName + postFix, type)
field.visibility = JvmVisibility::PRIVATE
controlCls.members += field
}
def void buildButtonMethods(EObject control, JvmDeclaredType controlCls, String buttonName, String postFix, JvmTypeReference type, FSMControlButtonAttributeEvent event) {
var JvmOperation operation = control.toGetter(buttonName + postFix, type)
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
operation = control.toMethod('''set«buttonName.toFirstUpper»«postFix»''', _typeReferenceBuilder.typeRef(Void::TYPE)) [
parameters += control.toParameter(buttonName + postFix, type);
visibility = JvmVisibility.PUBLIC
body = [
if(postFix.empty) {
append(
'''
«IF event instanceof FSMControlButtonAttributeEventKeyboard»
statemachine.processEvent(statemachine, new MessageEvent(EventType.KEYBOARD, "«(event as FSMControlButtonAttributeEventKeyboard).
keystroke»"));
«ELSEIF event instanceof FSMControlButtonAttributeEventIdentity»
statemachine.processEvent(statemachine, new MessageEvent(EventType.ID, "«(event as FSMControlButtonAttributeEventIdentity).identity»"));
«ELSEIF event instanceof FSMControlButtonAttributeEventEvent»
statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "«(event as FSMControlButtonAttributeEventEvent).event.name»"));
«ENDIF»
this.«buttonName» = «buttonName»;''')
} else {
append(
'''
pcs.firePropertyChange("«buttonName»«postFix»", this.«buttonName»«postFix», this.«buttonName»«postFix» = «buttonName»«postFix»);''')
}
]
]
operation.visibility = JvmVisibility::PUBLIC
controlCls.members += operation
}
def void toConstructor(JvmDeclaredType type, FSM statemachine) {
type.members += statemachine.toConstructor(
[
body = [
append(
'''
super();
state = States.«statemachine.initialState.name»;'''
)
]
])
}
def void toFields(JvmGenericType type, FSM statemachine) {
var JvmField field = null
// create logger
field = statemachine.toField("log", _typeReferenceBuilder.typeRef(Logger)) [
setInitializer([append('''org.slf4j.LoggerFactory.getLogger("statemachine")''')])
]
field.static = true
field.visibility = JvmVisibility::PRIVATE
type.members += field
field = statemachine.toField("state", _typeReferenceBuilder.typeRef("States"))
field.visibility = JvmVisibility::PRIVATE
type.members += field
}
def void toOperations(JvmGenericType type, FSM statemachine) {
type.members += statemachine.toMethod("start", _typeReferenceBuilder.typeRef(Void::TYPE), [
annotations += _annotationTypesBuilder.annotationRef(Override)
body = [
append(
'''
super.start();
schedule(this, 100, new MessageEvent(EventType.TRIGGER, "«statemachine.initialEvent.name»"));''')
]
])
type.members += statemachine.toInterface("State") [
members += statemachine.toMethod("process", _typeReferenceBuilder.typeRef("States"), [
abstract = true
parameters += statemachine.toParameter("statemachine", _typeReferenceBuilder.typeRef(IStateMachine))
parameters += statemachine.toParameter("event", _typeReferenceBuilder.typeRef(MessageEvent))
])
]
type.members += statemachine.toMethod("doProcessEvent", _typeReferenceBuilder.typeRef(Void::TYPE), [
annotations += _annotationTypesBuilder.annotationRef(Override)
parameters += statemachine.toParameter("statemachine", _typeReferenceBuilder.typeRef(IStateMachine))
parameters += statemachine.toParameter("event", _typeReferenceBuilder.typeRef(MessageEvent))
body = [append('''state = state.process(statemachine, event);''')]
])
type.members += statemachine.toEnumerationType("States") [
superTypes += _typeReferenceBuilder.typeRef("State")
statemachine.states.forEach [ state |
documentation = state.documentation
members += state.toEnumerationLiteral(state.name, [
initializer = [
append(
'''
@Override
public States process(final IStateMachine statemachine, final MessageEvent event) {
statemachine.dispatchMessages(event);
«IF state.functionalKeyEvent !== null»
if(event.getType()==EventType.FUNCTIONALKEYBOARD && "«state.functionalKeyCode.getName()»".equals(event.getId())) {
event.setType(EventType.TRIGGER);
event.setId("«state.functionalKeyEvent.name»");
}
«ENDIF»
switch (event.getType()) {
«IF state.keystroke !== null» case KEYBOARD:
statemachine.append("«state.keystroke.name»", event.getId());«IF state.hasKeyOperation»
«state.keyOperation.decodeOperation(0)»
«ENDIF»
break;
«ENDIF»
««« «IF state.functionalKeyEvent !== null» case FUNCTIONALKEYBOARD:
««« if("«state.functionalKeyCode.getName()»".equals(event.getId())) {
««« statemachine.schedule(statemachine, 100, new MessageEvent(EventType.TRIGGER, "«state.functionalKeyEvent.name»"));
««« }
««« break;
««« «ENDIF»
«IF state.identity !== null» case ID:
«state.identity.decodeOperation(true, 0)»
break;
«ENDIF»
«IF state.triggers.size > 0» case TRIGGER:
«state.createTriggerEvents»
«ENDIF»
default:
break;
}
return this;
}''')
]
])
]
]
}
def String className(FSM statemachine) {
var String clsName = statemachine.name.toString.toFirstUpper
var parts = clsName.split(Pattern.quote("."))
var len = parts.length
if (len > 1) {
return parts.get(len - 1).toFirstUpper
}
return clsName
}
def createTriggerEvents(FSMState state) '''
switch (event.getId()) {
«FOR trig : state.triggers»«FOR t:trig.triggers» case "«t.name»":
«ENDFOR»
«trig.doGuards(2)»
«ENDFOR»
«identation(1)»}
«identation(1)»break;
'''
def doGuards(FSMTrigger trigger, int level) {
return '''
«trigger.recurseGuards(trigger.guards.iterator, level)»«IF trigger.guards.size == 0 && !trigger.hasTransition || trigger.guards.size > 0»
«identation(level)»break;«ENDIF»'''
}
def String recurseGuards(FSMTrigger trigger, Iterator<FSMGuard> guards, int level) {
var body = ""
if (guards.hasNext) {
var guard = guards.next
body = '''
«guard.decodeGuard(level)»
«trigger.recurseGuards(guards, level+1)»
«identation(level)»}
«guard.decodeGuardOnFail(level)»
'''
} else {
body = '''
«identation(level)»statemachine.blockQueueTaking(true);
«trigger.generateActions(level)»
'''
if(trigger.hasTransition){
body = '''
«body»
/* --- entry actions begin --- */
«trigger.generateEntryActions(level)»
/* --- entry actions end --- */
«identation(level)»statemachine.blockQueueTaking(false);
«IF trigger.hasTransition»«identation(level)»return «trigger.transition.getName()»;
«ENDIF»'''
} else {
body = '''
«body»
«identation(level)»statemachine.blockQueueTaking(false);'''
}
}
return body
}
def identation(int level) {
var body = ''''''
for (var i = 0; i < level; i++) {
body = '''«body» '''
}
return body
}
def decodeGuard(FSMGuard guard, int level) '''
«identation(level)»if((boolean)«call(guard as EObject, guard.group.fullyQualifiedName.toString, guard.guard.name, StatemachineEnums.Functions.GUARD, null, null, false)») {'''
def decodeGuardOnFail(FSMGuard guard, int level) '''
«IF guard.hasOnFail»
«identation(level)»else {
«identation(level)»Notification.show(statemachine.getTranslation("«guard.onFailCaption»"), statemachine.getTranslation("«guard.onFailDescription»"), Type.«guard.onFailType.getName()»);
«identation(level)»}«ENDIF»'''
def generateActions(FSMTrigger trigger, int level) '''
«FOR action : trigger.actions»«action.switchAction(level)»
«ENDFOR»
'''
def generateEntryActions(FSMTrigger trigger, int level) '''
«FOR action : trigger.transition.conditions»
«action.switchAction(level)»
«ENDFOR»
'''
def String switchAction(FSMAction action, int level) {
switch action {
FSMActionPeripheralBlinkRate: {
return '''«identation(level)»statemachine.set("blinkRate", "«action.device.name»", «action.blinkRate»);
'''
}
FSMActionPeripheralClear: {
return '''«identation(level)»statemachine.set("clearDisplay", "«action.device.name»", "");
'''
}
FSMActionPeripheralCreateWindow: {
return '''«identation(level)»statemachine.set("createWindow", "«action.device.name»", "«action.viewportRow»|«action.viewportColumn»|«action.viewportHeight»|«action.viewportWidth»|«action.windowHeight»|«action.windowWidth»");'''
}
FSMActionPeripheralCursorType: {
return '''«identation(level)»statemachine.set("cursorType", "«action.device.name»", LineDisplayConst.«action.cursorType.getName()»);'''
}
FSMActionPeripheralDestroyWindow: {
return '''«identation(level)»statemachine.set("destroyWindow", "«action.device.name»", "");'''
}
FSMActionPeripheralDeviceBrightness: {
return '''«identation(level)»statemachine.set("deviceBrightness", "«action.device.name»", «action.brightness»);'''
}
FSMActionPeripheralLineDisplayText: {
if (action.hasType) {
return '''«identation(level)»statemachine.set("displayLine", "«action.device.name»", «action.text.concatenation(_typeReferenceBuilder.typeRef(String))»+"|"+LineDisplayConst.«action.textType.getName()»);'''
} else {
return '''«identation(level)»statemachine.set("displayLine", "«action.device.name»", «action.text.concatenation(_typeReferenceBuilder.typeRef(String))»);'''
}
}
FSMActionPeripheralLineDisplayTextAt: {
if (action.hasType) {
return '''«identation(level)»statemachine.set("displayTextAt", "«action.device.name»", "«action.row»|«action.column»|"+«action.text.concatenation(_typeReferenceBuilder.typeRef(String))»+"|"+LineDisplayConst.«action.textType.getName()»);'''
} else {
return '''«identation(level)»statemachine.set("displayTextAt", "«action.device.name»", "«action.row»|«action.column»|"+«action.text.concatenation(_typeReferenceBuilder.typeRef(String))»);'''
}
}
FSMActionPeripheralInterCharacterWait: {
return '''«identation(level)»statemachine.set("interCharacterWait", "«action.device.name»", «action.getWait()»);'''
}
FSMActionPeripheralMarqueeFormat: {
return '''«identation(level)»statemachine.set("marqueeFormat", "«action.device.name»", LineDisplayConst.«action.format.getName()»);'''
}
FSMActionPeripheralMarqueeRepeatWait: {
return '''«identation(level)»statemachine.set("marqueeRepeatWait", "«action.device.name»", «action.getWait()»);'''
}
FSMActionPeripheralMarqueeType: {
return '''«identation(level)»statemachine.set("marqueeType", "«action.device.name»", LineDisplayConst.«action.marqueeType.getName()»);'''
}
FSMActionPeripheralMarqueeUnitWait: {
return '''«identation(level)»statemachine.set("marqueeUnitWait", "«action.device.name»", «action.getWait()»);'''
}
FSMActionPeripheralScroll: {
return '''«identation(level)»statemachine.set("scroll", "«action.device.name»", ""+LineDisplayConst.«action.direction.getName()»+"|«action.units»");'''
}
FSMActionPeripheralOpenDrawer: {
return '''«identation(level)»statemachine.set("openDrawer", "«action.device.name»", 0);'''
}
FSMActionPeripheralPrintBarcode: {
return '''«identation(level)»statemachine.set("printBarcode", "«action.device.name»", "«action.data»|"+POSPrinterConst.«action.barcodeType.
getName()»);'''
}
FSMActionPeripheralPrintBitmap: {
return '''«identation(level)»statemachine.set("printBitmap", "«action.device.name»", «action.bitmapId»);'''
}
FSMActionPeripheralDisplayText: {
return '''«identation(level)»statemachine.set("«action.device.output.name»«action.attribute.name.toFirstUpper»", «action.text.concatenation(_typeReferenceBuilder.typeRef(String))»);'''
}
FSMActionPeripheralPrintCut: {
return '''«identation(level)»statemachine.set("printCut", "«action.device.name»",«action.text.concatenation(_typeReferenceBuilder.typeRef(String))»);'''
}
FSMActionPeripheralPrintNormal: {
return '''«identation(level)»statemachine.set("printNormal", "«action.device.name»", «action.text.concatenation(_typeReferenceBuilder.typeRef(String))»);'''
}
FSMActionPeripheralPrintRegisterBitmap: {
return '''«identation(level)»statemachine.set("printerBitmap", "«action.bitmapId»", "«action.name»");'''
}
FSMActionPeripheralPTOpen: {
return '''«identation(level)»statemachine.set("paymentTerminalOpen", «action.host.concatenation(_typeReferenceBuilder.typeRef(String))»+"|"+«action.port.concatenation(_typeReferenceBuilder.typeRef(int))»);'''
}
FSMActionPeripheralPTClose: {
return '''«identation(level)»statemachine.set("paymentTerminalClose", "");'''
}
FSMActionPeripheralPTAcknowledge: {
return '''«identation(level)»statemachine.set("paymentTerminalAcknowledge", "");'''
}
FSMActionPeripheralPTReversal: {
return '''«identation(level)»statemachine.set("paymentTerminalReversal", «action.password.concatenation(_typeReferenceBuilder.typeRef(String))»+"|"+«action.receipt.concatenation(_typeReferenceBuilder.typeRef(String))»);'''
}
FSMActionPeripheralPTRegistration: {
return '''«identation(level)»statemachine.set("paymentTerminalRegistration", «action.password.concatenation(_typeReferenceBuilder.typeRef(String))»+"|«action.configuration»");'''
}
FSMActionPeripheralPTAuthorization: {
return '''«identation(level)»statemachine.set("paymentTerminalAuthorization", «action.amount.concatenation(_typeReferenceBuilder.typeRef(Double))»);'''
}
FSMActionPeripheralSignatureOpen: {
return '''«identation(level)»statemachine.set("signatureOpen", "");'''
}
FSMActionPeripheralSignatureClose: {
return '''«identation(level)»statemachine.set("signatureClose", "");'''
}
FSMActionPeripheralSignatureClear: {
return '''«identation(level)»statemachine.set("signatureClear", "");'''
}
FSMActionPeripheralSignatureCapture: {
return '''«identation(level)»statemachine.set("signatureCapture", "");'''
}
FSMActionPeripheralSignatureIdle: {
return '''«identation(level)»statemachine.set("signatureIdle", "");'''
}
FSMActionPeripheralSignatureLabel: {
return '''«identation(level)»statemachine.set("signatureLabel", statemachine.getTranslation("«action.okLabel»")+"|"+statemachine.getTranslation("«action.clearLabel»")+"|"+statemachine.getTranslation("«action.cancelLabel»"));'''
}
FSMActionPeripheralPrintReport: {
return '''«identation(level)»statemachine.set("printReport", "«action.report.fullyQualifiedName»«IF action.hasFilter»|«action.key.key»«ENDIF»", «action.printService.concatenation(_typeReferenceBuilder.typeRef(String))»);'''
}
FSMActionPeripheralBeeper: {
return '''«identation(level)»statemachine.set("beeper", "«action.duration.toString»|«action.frequency»");'''
}
FSMActionPeripheralPlayer: {
return '''«identation(level)»statemachine.set("player", "«action.tune»");'''
}
FSMActionPeripheralSound: {
return '''«identation(level)»statemachine.set("sound", "«action.name»");'''
}
FSMActionFieldSet: {
return '''«identation(level)»statemachine.set("«action.attribute.name»", «action.source.concatenation(_typeReferenceBuilder.typeRef(action.attribute.attributeType.attributeType.literal))»);'''
}
FSMActionFieldRemove: {
return '''«identation(level)»statemachine.remove("«action.attribute.name»", -1);'''
}
FSMActionFieldClear: {
return '''«identation(level)»statemachine.clear("«action.attribute.name»");'''
}
FSMActionFieldKeystroke: {
return '''«identation(level)»statemachine.append("«action.attribute.name»", event.getId());'''
}
FSMActionItemVisible: {
return '''«identation(level)»statemachine.enable("«action.attribute.name»", true);'''
}
FSMActionItemInvisible: {
return '''«identation(level)»statemachine.enable("«action.attribute.name»", false);'''
}
FSMActionButtonCaption: {
return '''«identation(level)»statemachine.caption("«action.attribute.name»", "«action.caption»");'''
}
FSMActionButtonImage: {
return '''«identation(level)»statemachine.image("«action.attribute.name»", "«action.image»");'''
}
FSMActionDTOFind: {
return '''«identation(level)»statemachine.find("«action.dto.attributeType.attributeType.name»", "«action.attribute.inheritedFeature.name»", «action.search.concatenation»);'''
}
FSMActionDTOClear: {
return '''«identation(level)»statemachine.set("«action.dto.name»", null);'''
}
FSMActionFieldFilterToggle: {
return '''«identation(level)»statemachine.toggle("«action.filter.name»");'''
}
FSMStorage: {
return '''«identation(level)»statemachine.putStorage("«action.key»","«action.attribute»", «action.content.concatenation»);'''
}
FSMActionScheduler: {
return '''«identation(level)»statemachine.set("«action.scheduler.name»Scheduler", «action.scheduler.delay»);'''
}
FSMOperation: {
return '''«action.decodeOperation(level)»'''
}
FSMActionConditionalTransition: {
return '''
«action.guard.decodeGuard(level)»
«FOR act : action.actions»
«act.switchAction(level+1)»
«ENDFOR»
«IF action.transition.conditions.length > 0»
/* --- entry actions begin --- */
«FOR condition : action.transition.conditions»
«condition.switchAction(level)»
«ENDFOR»
/* --- entry actions end --- */
«ENDIF»
«identation(level+1)»statemachine.blockQueueTaking(false);
«identation(level+1)»return «action.transition.name»;
«identation(level)»}'''
}
}
}
def concatenation(FSMActionFieldConcatenation concatenation) {
return concatenation(concatenation, null)
}
def concatenation(FSMActionFieldConcatenation concatenation,
JvmTypeReference cast) '''«concatenation.first.decodeActionFieldSource(cast)»«FOR element : concatenation.more»+«element.
decodeActionFieldSource(cast)»«ENDFOR»'''
def decodeActionFieldSource(FSMActionFieldSource action, JvmTypeReference cast) {
switch action {
FSMActionFieldSourceString: {
return '''"«action.text»"'''
}
FSMActionFieldSourceNumber: {
return '''«action.value»'''
}
FSMActionFieldSourceInteger: {
return '''«action.value»'''
}
FSMActionFieldSourceBoolean: {
return '''«action.value»'''
}
FSMActionFieldSourceEvaluate: {
return '''statemachine.«action.evaluationtype.literal»()'''
}
FSMActionFieldSourceEvent: {
return '''event.getId()'''
}
FSMActionFieldSourceTranslate: {
return '''statemachine.getTranslation("«action.text»")'''
}
FSMActionFieldGet: {
var attrType = action.attribute.attributeType.attributeType.literal
if(attrType.equals("SuggestText")) {
attrType = "String";
}
var castPre = ""
var castPost = ""
var getter = '''statemachine.get("«action.attribute.name»")'''
if(cast !== null && !cast.simpleName.equals(attrType)) {
if(attrType.equals("String") || attrType.equals("SuggestText")) {
castPre = '''«cast.simpleName».parse«cast.simpleName»((String)'''
castPost = '''.toString())'''
} else {
castPre = '''(«attrType»)'''
}
}
return castPre+getter+castPost
}
FSMOperation: {
return '''«IF cast !== null»(«cast.simpleName»)«ENDIF»«action.decodeOperation(0)»'''
}
FSMFunction: {
return '''«IF cast !== null»(«cast.simpleName»)«ENDIF»«action.decodeFunction(0)»'''
}
FSMStorageRetrieve: {
return '''«IF cast !== null»(«cast.simpleName»)«ENDIF»statemachine.getStorage("«action.key»", "«action.attribute»")'''
}
FSMActionFieldSourceDtoAttribute: {
var typeName = action.attribute.inheritedFeature.type.name
return '''statemachine.get("«action.dto.name»«action.attribute.inheritedFeature.name.toFirstUpper»")«IF cast !== null && !typeName.equals("String") && cast.simpleName.equals("String")».toString()«ENDIF»'''
}
FSMActionPeripheralPTResponse: {
return '''statemachine.get("PaymentTerminalResponse")'''
}
}
}
def decodeOperation(FSMOperation operation, int level) {
return decodeOperation(operation, false, level)
}
def String decodeOperation(FSMOperation operation, boolean isIdentity, int level) '''
«identation(level)»if(!((boolean)«call(operation as EObject, operation.group.fullyQualifiedName.toString, operation.operation.name, StatemachineEnums.Functions.OPERATION, operation.first, operation.more, isIdentity)»)) {
«identation(level)» Notification.show("Operation failed", "«operation.group.fullyQualifiedName.toString».«operation.operation.name»", Type.ERROR_MESSAGE);
«identation(level)» statemachine.blockQueueTaking(false);
«identation(level)» return this;
«identation(level)»}'''
def String decodeFunction(FSMFunction function, int level) '''
«identation(level)»«call(function as EObject, function.group.fullyQualifiedName.toString, function.function.name, StatemachineEnums.Functions.FUNCTION, function.first, function.more, false)»'''
def call(EObject parent, String className, String name, StatemachineEnums.Functions function,
FSMOperationParameter first, FSMOperationParameter[] more, boolean isIdentity) {
// find some parents
var FSM statemachine = null
var eObj = parent
while (!(eObj instanceof FSMPackage)) {
if (eObj instanceof FSM) {
statemachine = eObj as FSM
}
eObj = eObj.eContainer
}
if (eObj instanceof FSMPackage) {
switch function {
case GUARD:
return '''«eObj.name + "." + eObj.fullyQualifiedName.lastSegment.toFirstUpper»«binderPostfix».getFunctionLibraryService().guard(statemachine, "«className»", "«name»")'''
case OPERATION:
return '''«eObj.name + "." + eObj.fullyQualifiedName.lastSegment.toFirstUpper»«binderPostfix».getFunctionLibraryService().operation(statemachine, "«className»", «name.processParameters(first, more, isIdentity)»)'''
case FUNCTION:
return '''«eObj.name + "." + eObj.fullyQualifiedName.lastSegment.toFirstUpper»«binderPostfix».getFunctionLibraryService().function(statemachine, "«className»", «name.processParameters(first, more, isIdentity)»)'''
}
} else {
return '''/* error: parents not found */'''
}
}
def processParameters(String name, FSMOperationParameter first, FSMOperationParameter[] more,
boolean isIdentity) {
if (first === null) {
return '''"«name»"«IF isIdentity», event.getId()«ENDIF»'''
}
var body = '''"«name»", «IF isIdentity»event.getId(), «ENDIF»«first.source.concatenation»'''
if (more !== null) {
for (para : more) {
body = '''«body», «para.source.concatenation»'''
}
}
return body
}
def void toBinderFields(JvmDeclaredType type, FSMPackage datamart) {
var JvmField field = null
// create logger
field = datamart.toField("log", _typeReferenceBuilder.typeRef(Logger)) [
setInitializer([append('''org.slf4j.LoggerFactory.getLogger("servicebinder")''')])
]
field.static = true
field.visibility = JvmVisibility::PRIVATE
type.members += field
field = datamart.toField("functionLibraryService", _typeReferenceBuilder.typeRef(IFunctionLibraryService))
field.static = true
field.visibility = JvmVisibility::PRIVATE
type.members += field
}
def void toBinderOperations(JvmDeclaredType type, FSMPackage datamart, String binderClassName) {
type.members +=
datamart.toMethod("getFunctionLibraryService", _typeReferenceBuilder.typeRef(IFunctionLibraryService), [
visibility = JvmVisibility.PUBLIC
static = true
body = [append('''return functionLibraryService;''')]
])
type.members += datamart.toMethod("bindFunctionLibraryService", _typeReferenceBuilder.typeRef(Void::TYPE), [
var annotationRef = _annotationTypesBuilder.annotationRef(typeof(Reference))
annotationRef.addAnnAttr(datamart, "cardinality", ReferenceCardinality.MANDATORY)
annotationRef.addAnnAttr(datamart, "policy", ReferencePolicy.STATIC)
annotations += annotationRef
visibility = JvmVisibility.PUBLIC
synchronized = true
parameters +=
datamart.toParameter("functionLibraryService",
_typeReferenceBuilder.typeRef(IFunctionLibraryService))
body = [
append(
'''
«binderClassName».functionLibraryService = functionLibraryService;
log.debug("FSM FunctionLibraryServiceService bound");''')
]
])
type.members +=
datamart.toMethod("unbindFunctionLibraryService", _typeReferenceBuilder.typeRef(Void::TYPE), [
visibility = JvmVisibility.PUBLIC
synchronized = true
parameters +=
datamart.toParameter("functionLibraryService",
_typeReferenceBuilder.typeRef(IFunctionLibraryService))
body = [
append(
'''
«binderClassName».functionLibraryService = null;
log.debug("FSM FunctionLibraryServiceService unbound");''')
]
])
}
}