Calculadora en RAP (side effects)
Desarrollo de calculadora basica en ABAP Restful Application Programming model, ambiente Cloud.
Objetivo
Mostrar el uso de Side Effects con el modelo RestFul Application programming model en Eclipse utilizando ABAP Development Tools.
Prerequisitos
- Una cuenta trial SAP Cloud BTP.
- Instalar Eclipse y Abap Development Tools.
- Una cuenta ABAP Environment Cloud tial.
Pasos
- Crear la persistencia de datos.
- Generar los objetos del repositorio ABAP.
- Ajustar el behaviour Definition.
- Implementar el determination en la clase.
- Ajustar el behavior definition del projection.
- Ajustar el metadata extension.
- Visualizar Aplicación (Preview).
1.- Crear la persistencia de datos.
Crear la siguiente tabla en eclipse.
@EndUserText.label : 'Pocket Calculator'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zrap_calculator {
key client : abap.clnt not null;
key calc_uuid : sysuuid_x16 not null;
operand_a : abap.int4;
operand_b : abap.int4;
operator : abap.char(1);
calc_result : abap.fltp;
created_at : abp_creation_tstmpl;
created_by : abp_creation_user;
last_changed_by : abp_lastchange_user;
last_changed_at : abp_lastchange_tstmpl;
local_last_changed_at : abp_locinst_lastchange_tstmpl;
}
Grabar (Ctrl+S) y Activar (CTRL+F3).
2.- Generar los objetos de repositorio ABAP
Seleccionar la tabla creada.
En el menú de contexto seleccionar Generate ABAP Repository Objects…
Esto creará todos los objetos que necesitamos para la aplicación.
3.- Ajustar el behavior definition.
Ajustar el campo de resultado a solo lectura.
Agregar los side effects en el campo de resultado.
Agregar la determinación del cálculo al modificar los operandos.
managed implementation in class ZBP_R_RAP_CALCULATOR unique;
strict ( 2 );
with draft;
define behavior for ZR_RAP_CALCULATOR alias Calculator
persistent table ZRAP_CALCULATOR
draft table ZRAP_CALCULATO_D
etag master LocalLastChangedAt
lock master total etag LastChangedAt
authorization master( global )
{
field ( readonly )
CalcUuid,
CreatedAt,
CreatedBy,
LastChangedBy,
LastChangedAt,
LocalLastChangedAt;
field ( numbering : managed )
CalcUuid;
field ( readonly ) CalcResult;
create;
update;
delete;
// side effects
side effects
{
field OperandA affects field CalcResult;
field OperandB affects field CalcResult;
field Operator affects field CalcResult;
}
// internal action recalcResult;
determination CalculateCalcResult on modify { field OperandA, OperandB, Operator; }
draft action Activate optimized;
draft action Discard;
draft action Edit;
draft action Resume;
draft determine action Prepare;
mapping for ZRAP_CALCULATOR
{
CalcUuid = calc_uuid;
OperandA = operand_a;
OperandB = operand_b;
Operator = operator;
CalcResult = calc_result;
CreatedAt = created_at;
CreatedBy = created_by;
LastChangedBy = last_changed_by;
LastChangedAt = last_changed_at;
LocalLastChangedAt = local_last_changed_at;
}
}
Grabar (Ctrl+S) y Activar (CTRL+F3).
4.- Implementar el determination en la clase.
Al grabar nos aparecerá que aún debemos implementar la clase para el determination. Click en el foco amarillo y seleccionar la creación del método.
Ajustar la clase para codificar el método del cálculo utilizando el Entity Manipulation Language (EML).
CLASS lhc_calculator DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS:
get_global_authorizations FOR GLOBAL AUTHORIZATION
IMPORTING
REQUEST requested_authorizations FOR Calculator
RESULT result,
CalculateCalcResult FOR DETERMINE ON MODIFY
IMPORTING keys FOR Calculator~CalculateCalcResult.
ENDCLASS.
CLASS lhc_calculator IMPLEMENTATION.
METHOD get_global_authorizations.
ENDMETHOD.
**************************************************************************
* Internal instance-bound action calculateTotalPrice
**************************************************************************
METHOD CalculateCalcResult.
" Read all relevant operand instances.
READ ENTITIES OF zr_rap_calculator IN LOCAL MODE
ENTITY Calculator
FIELDS ( OperandA OperandB Operator )
WITH CORRESPONDING #( keys )
RESULT DATA(Calculations).
LOOP AT Calculations ASSIGNING FIELD-SYMBOL(<Calculator>).
IF <Calculator>-Operator = '+'.
<Calculator>-CalcResult = <Calculator>-OperandA + <Calculator>-OperandB.
ELSEIF <Calculator>-Operator = '-'.
<Calculator>-CalcResult = <Calculator>-OperandA - <Calculator>-OperandB.
ELSEIF <Calculator>-Operator = '*'.
<Calculator>-CalcResult = <Calculator>-OperandA * <Calculator>-OperandB.
ELSEIF <Calculator>-Operator = '/'.
<Calculator>-CalcResult = <Calculator>-OperandA / <Calculator>-OperandB.
ELSE.
<Calculator>-CalcResult = 0.
ENDIF.
ENDLOOP.
" write back the modified the result
MODIFY ENTITIES OF zr_rap_calculator IN LOCAL MODE
ENTITY Calculator
UPDATE FIELDS ( CalcResult )
WITH CORRESPONDING #( Calculations ).
ENDMETHOD.
ENDCLASS.
Grabar (Ctrl+S) y Activar (CTRL+F3).
5.- Ajustar el behavior definition del Projection.
Agregar la línea del uso de los Side Effects.
projection;
strict ( 2 );
use side effects;
use draft;
define behavior for ZC_RAP_CALCULATOR alias Calculator
use etag
{
use create;
use update;
use delete;
use action Edit;
use action Activate;
use action Discard;
use action Resume;
use action Prepare;
}
Grabar (Ctrl+S) y Activar (CTRL+F3).
6.- Ajustar el metadata extension.
Ajustar el código en el metadata extension del data definition.
@Metadata.layer: #CORE
@UI.headerInfo.title.type: #STANDARD
@UI.headerInfo.title.value: 'CalcUuid'
@UI.headerInfo.description.type: #STANDARD
@UI.headerInfo.description.value: 'CalcUuid'
annotate view ZC_RAP_CALCULATOR with
{
@EndUserText.label: 'Calc Uuid'
@UI.facet: [ {
label: 'General Information',
id: 'GeneralInfo',
purpose: #STANDARD,
position: 10 ,
type: #IDENTIFICATION_REFERENCE
} ]
@UI.identification: [ {
position: 10 ,
label: 'UUID'
} ]
@UI.lineItem: [ {
position: 10 ,
label: 'UUID'
} ]
@UI.selectionField: [ {
position: 10
} ]
@UI.hidden: true
CalcUuid;
@EndUserText.label: 'Operand A'
@UI.identification: [ {
position: 20
} ]
@UI.lineItem: [ {
position: 20
} ]
@UI.selectionField: [ {
position: 20
} ]
OperandA;
@EndUserText.label: 'Operand B'
@UI.identification: [ {
position: 30
} ]
@UI.lineItem: [ {
position: 30
} ]
@UI.selectionField: [ {
position: 30
} ]
OperandB;
@EndUserText.label: 'Operator'
@UI.identification: [ {
position: 40
} ]
@UI.lineItem: [ {
position: 40
} ]
@UI.selectionField: [ {
position: 40
} ]
Operator;
@EndUserText.label: 'Calc Result'
@UI.identification: [ {
position: 50
} ]
@UI.lineItem: [ {
position: 50
} ]
@UI.selectionField: [ {
position: 50
} ]
CalcResult;
@UI.identification: [ {
position: 60 ,
label: 'Created On'
} ]
@UI.lineItem: [ {
position: 60 ,
label: 'Created On'
} ]
@UI.selectionField: [ {
position: 60
} ]
@UI.hidden: true
CreatedAt;
@UI.identification: [ {
position: 70 ,
label: 'Created By'
} ]
@UI.lineItem: [ {
position: 70 ,
label: 'Created By'
} ]
@UI.selectionField: [ {
position: 70
} ]
@UI.hidden: true
CreatedBy;
@UI.identification: [ {
position: 80 ,
label: 'Changed By'
} ]
@UI.lineItem: [ {
position: 80 ,
label: 'Changed By'
} ]
@UI.selectionField: [ {
position: 80
} ]
@UI.hidden: true
LastChangedBy;
@UI.identification: [ {
position: 90 ,
label: 'Changed On'
} ]
@UI.lineItem: [ {
position: 90 ,
label: 'Changed On'
} ]
@UI.selectionField: [ {
position: 90
} ]
@UI.hidden: true
LastChangedAt;
@UI.identification: [ {
position: 100 ,
label: 'Changed On'
} ]
@UI.lineItem: [ {
position: 100 ,
label: 'Changed On'
} ]
@UI.selectionField: [ {
position: 100
} ]
@UI.hidden: true
LocalLastChangedAt;
}
Grabar (Ctrl+S) y Activar (CTRL+F3).
7.- Visualizar la aplicación.
Seleccionar el Service Binding de la aplicación.
Presionar el botón Publish.
Presionar la entidad Calculator.
Presionar el botón Preview.
Presionar el botón Create.
Capturar operadores para visualizar el resultado al dar <ENTER>.
Esto sin necesidad de haber salvado para ver el resultado.
Fin.