RODL sample (Delphi)

Overview

This example demonstrates several things that could be useful for advanced developers:

  • Creating a RODL library on the fly using the object model.
  • Parsing a RODL file and getting access to the RODL library object model.
  • Generating Interface, Invoker and Implementation code using the same facility the Service Builder uses internally.

Getting started

  • Compile the project.
  • Run the application.
  • Use the Generate button to generate a RODL library on the fly (it is done automatically on application startup). Alternatively, use the Load button to load any other library from disk.
  • Having a library generated or loaded, select the converter from the Converter drop-down list.
  • Click the Convert button to see the conversion result.
  • You can save code using the Save button

Examine the code

  • Examine how the new RODL library is generated on the fly:
procedure TRODLMainForm.GenerateButtonClick(Sender: TObject);
var
  struct: TRODLStruct;
  stelem: TRODLTypedEntity;
  arr: TRODLArray;
  svc: TRODLService;
  enum: TRODLEnum;
  eval: TRODLEnumValue;
  intf: TRODLServiceInterface;
  op: TRODLOperation;
  par: TRODLOperationParam;

begin
  // The library root object
  fLibrary := TRODLLibrary.Create;

  fLibrary.Info.Name := 'TestLibrary';
  fLibrary.Info.UID := NewGuid;
  fLibrary.Info.Attributes.Values['Test'] := 'a library attribute';

  // Defining a service
  svc := TRODLService.Create;
  svc.Info.Name := 'Gadget';
  svc.Default.Info.UID := NewGuid;
  svc.Default.Info.Documentation := 'Default interface for Gadget';
  svc.Default.Info.Attributes.Values['TestName1'] := 'TestValue1';

  intf := svc.Default;

  // Defining an operation (method)
  op := intf.Add;
  op.Info.Name := 'Sum';
  op.Info.UID := NewGuid;
  op.Info.Documentation := 'Sum message';
  op.Info.Attributes.Values['TestAttr1'] := 'TestAttrValue2';

  // Operation parameter
  par := op.Add;
  par.Name := 'A';
  par.DataType := 'integer';
  par.Flag := fIn;

  // And the result
  par := op.AddResult;
  par.DataType := 'integer';

  // ...
  
  // Adding the service to the library
  fLibrary.Add(svc);

  // ...
  
  // Creating a structure (complex type)    
  struct := TRODLStruct.Create;
  struct.Attributes.Values['TestAttr1'] := 'TestAttrValue2';
  
  struct.Name := 'TAddress';
  struct.UID := NewGuid;
  struct.Documentation := 'An address';

  stelem := struct.Add;
  stelem.Name := 'Street1';
  stelem.DataType := 'AnsiString';

  // ...
  
  fLibrary.Add(struct);

  // ...
  
  // Creating an enum
  enum := TRODLEnum.Create;
  enum.Name := 'TColor';
  enum.UID := NewGuid;
  enum.Documentation := 'This is TColor';
  enum.Attributes.Values['TestAttr1'] := 'TestAttrValue2';

  eval := enum.Add;
  eval.Name := 'clRed';

  eval := enum.Add;
  eval.Name := 'clBlue';

  fLibrary.Add(enum);

  // ...
  
  // Creating an array
  arr := TRODLArray.Create;
  arr.Name := 'TIntegerArray';
  arr.Documentation := 'Thisis an integer array';
  arr.UID := NewGuid;
  arr.ElementType := 'integer';
  arr.Attributes.Values['TestAttr1'] := 'TestAttrValue2';

  fLibrary.Add(arr);

  // ...
end;
  • Examine how it loads a RODL library from a file:
procedure TRODLMainForm.LoadButtonClick(Sender: TObject);
var
  fs: TFileStream;
begin
  // ...
  fs := TFileStream.Create(OpenDialog.FileName, fmOpenRead);
  with TXMLToRODL.Create do try
    fLibrary := Read(fs);
  finally
    Free;
    fs.Free;
  end;
  FillLibrary;
  // ...
end;
  • Examine how it converts the RODL library to the desired code:
procedure TRODLMainForm.ConvertButtonClick(Sender: TObject);
var
  conv:TRODLConverter;
  cg4: TROCodegen4;
  res: TROCodegen4Files;
  mode: codegen4_mode;
  li: TListItem;
  i: Integer;
begin
  lvFiles.Items.Clear;
  if Integer(cbWriters.Items.Objects[cbWriters.ItemIndex]) = 1 then begin
    conv := TRODLToWSDL.Create(fLibrary, '');
    try
      li := lvFiles.Items.Add;
      li.Caption := fLibrary.Name + '.wsdl';
      li.Data := PChar(conv.Buffer.Text);
      li.Checked := True;
    finally
      conv.Free;
    end;
  end
  else begin
    cg4 := TROCodegen4.Create;
    res := cg4.Generate(fLibrary, Codegen4_Lang(ROGetEnumValue(TypeInfo(Codegen4_Lang),cbLang.Text,'cg4l_')),cg4m_all);
    for i := 0 to Length(res)-1 do begin
      li := lvFiles.Items.Add;
      li.Caption := res[i].FileName;
      li.Data := PChar(res[i].Content);
      li.Checked := True;
    end;
  end;
  if lvFiles.Items.Count > 0 then lvFiles.Items[0].Selected := True;
end;

Concepts Covered