This is a test message to test the length of the message box.
Login
ABAP XCO Generation und Info system
Erstellt von Software-Heroes

ABAP - XCO Generation und Info System

86

Wie kannst du mit ABAP Cloud Mitteln neue Objekte im System generieren und Informationen zu diesen erhalten? An einem Beispiel schauen wir uns das genauer an.

Werbung


Die XCO Klassen sind Hilfsklassen die verschiedene Funktionen des Alltags gebündelt unter einer öffentlichen API zur Verfügung stellen. Weitere Informationen und eine Übersicht über die XCO Bibliotheken findest du auf der Übersichtsseite.

 

Einleitung

Die XCO Bibliothek ist vor allem bekannt für die Fähigkeiten neue Objekte zu generieren und wird im RAP Generator und zur Generierung von Beispielen verwendet. Grundsätzlich kann dir das Framework auch viele Aufgaben durch Automatisierung abnehmen. Bei unseren IDE Actions verwenden wir die Klassen, um uns eine neue Klasse samt Interface, Factory und Injector zu generieren. Das spart einige Schritte bei der Anlage und automatisiert die Aufgabe etwas. Neben dem Generieren können wir aber auch zu bestehenden Objekten weiter Informationen erhalten. 

Daher schauen wir uns in diesem Artikel einmal das Lesen von Objekten an, sowie die einzelnen Schritte zur Erzeugung einer neuen Klasse im System.

 

Lesen

In diesem Kapitel wollen wir eine bestehende Klasse in verschiedenen Zuständen lesen und auswerten.

 

Vorbereitung

Bevor wir die XCO Klassen verwenden, benötigen wir eine Klasse, die wir zum Einlesen verwenden können. In der Klasse findest du eine Konstante und zwei Methoden. Eine Methode ist statisch und öffentlich, die andere Methode ist privat. Die private Methode enthält etwas Inhalt, den wir gleich lesen möchten.

CLASS zcl_bs_demo_xco_broken DEFINITION
  PUBLIC FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    CONSTANTS c_empty TYPE string VALUE ``.

    CLASS-METHODS static_access.

  PRIVATE SECTION.
    METHODS private_stuff.

ENDCLASS.


CLASS zcl_bs_demo_xco_broken IMPLEMENTATION.
  METHOD private_stuff.
    DATA(output) = `Hi from the method`.
  ENDMETHOD.


  METHOD static_access.
*    if method.
*    endif.
  ENDMETHOD.
ENDCLASS.

 

Informationen

Um nun an die Informationen der Klasse zu gelangen, erzeugen wir uns ein Klassenobjekt über die XCO Klasse XCO_CP_ABAP.

DATA(class) = xco_cp_abap=>class( 'ZCL_BS_DEMO_XCO_BROKEN' ).

 

Das Objekt bietet uns einige Methoden, um an verschiedene Informationen zu kommen, wie zum Beispiel den aktuellen Syntax Check, den API Status, ob die Klasse existiert und weitere Informationen.

 

Führen wir nun einen Syntax-Check auf dem Objekt aus. Dazu rufen wir die Methode CHECK_SYNTAX auf und erhalten ein Ergebnisobjekt zurück. Da wir in unserem Beispiel in einer XCO-Classrunner sind, können wir das Objekt direkt in der Konsole ausgeben.

DATA(syntax) = class->check_syntax( ).
out->write_news( syntax ).

 

Möchtest du an weitere Details der Syntax kommen, stehen dir im Objekt verschiedene Attribute zur Verfügung. Über MESSAGES können wir entsprechende Fehlermeldungen erhalten und über PASSED bekommen wir den aktuellen Status der Klasse.

 

Möchten wir im nächsten Schritt dann den Inhalt einer Methode lesen, müssen wir eine Reihe von Schritten durchführen. Zuerst einmal müssen wir über das Attribut IMPLEMENTATION auf die aktuelle Implementierung in der Klasse zugreifen, dann lassen wir uns die Methode zurückgeben und holen uns davon die Inhalte. Zum Abschluss lesen wir noch den Quellcode aus und lassen uns eine Tabelle mit dem aktuellen Inhalt zurückgeben. 

DATA(source) = class->implementation->method( 'PRIVATE_STUFF' )->content( )->get_source( ).
out->plain->write( source ).

 

Fehler

Nun verändern wir unsere Vorlageklasse ZCL_BS_DEMO_XCO_BROKEN und kommentieren in der Methode STATIC_ACCESS den Quellcode wieder ein. Im Anschluss speichern wir den Inhalt, damit eine aktuelle Version im Backend angelegt wird. Wir sollten nun einen entsprechenden Fehler in der Klasse haben und die Aktivierung funktioniert nicht mehr.

 

Führen wir nun die Klasse noch einmal aus und versuchen die beiden Schritte von oben, dann sollten wir nun über CHECK_SYNTAX die entsprechende Fehlermeldung aus der Klasse erhalten. Die zweite Methode zum Lesen des Inhalts funktioniert weiterhin. Somit haben wir einen einfachen Weg die Syntax der Klasse zu validieren und im Fehlerfall eine detaillierte Meldung zu erzeugen.

 

Erstellen

In diesem Kapitel ersten wir eine neue Klasse, wollen dabei ein Interface implementieren, verschiedene Methoden anlegen und einen lokalen Typen erzeugen.

 

Operation

Im ersten Schritt benötigen wir eine Operation, um mit der eigentlichen Anlage zu beginnen. Dazu gehen wir über die Klasse XCO_CP_GENERATION und lassen uns über das entsprechende Environment und einen Transportauftrag eine Operation anlegen. Neben PU gibt es auch noch PATCH, falls wir etwas aktualisieren wollen.

DATA(operation) = xco_cp_generation=>environment->dev_system( transport_request )->create_put_operation( ).

 

Spezifikation

Über die Operation erzeugen wir uns eine Spezifikation, also einen Bauplan für ein spezifisches Objekt. Daher sagen wir auf der Operation, dass wir etwas für eine Klasse machen wollen und zwar ein neues Objekt hinzufügen. Der Klasse geben wir einen Namen, weisen ein Paket zu und lassen uns die neue Spezifikation zurückgeben, um damit weiterzuarbeiten.

DATA(specification) = operation->for-clas->add_object( 'ZCL_BS_DEMO_XCO_GENERATED'
  )->set_package( 'ZBS_DEMO_XCO'
  )->create_form_specification( ).

 

Über die Spezifikation können wir dann direkt die Beschreibung am Objekt setzen.

specification->set_short_description( `Generated by ZCL_BS_DEMO_XCO_REPOSITORY` ).

 

Interface

Um ein Interface hinzuzufügen, gehen wir über die Definition und nutzen dazu die Methode ADD_INTERFACE, um unseren Classrunner bekannt zu geben. Um nun die Methode zu implementieren, müssen wir über die Implementierung und fügen eine neue Methode ein. Da wir die Methode aus dem Interface implementieren wollen, geben wir den Namen des Interfaces mit der entsprechenden Methode an. Im Anschluss können wir direkt den neuen Quellcode mitgeben, der in der Methode stehen soll.

specification->definition->add_interface( 'IF_OO_ADT_CLASSRUN' ).
specification->implementation->add_method( 'IF_OO_ADT_CLASSRUN~MAIN' )->set_source(
    VALUE #( ( `    say_hello( name = 'Bernd' out = out ).` ) ) ).

 

Typ

Nun möchten wir gern einen neuen Typen in der Klasse definieren, dieser soll PRIVATE sein und ein einfacher Typ ohne Datenelement. Da Typen in der DEFINITION angelegt werden, gehen wir dann über die spezifische SECTION und ergänzen einen neuen Typ mit ADD_TYPE. Der neue Typ soll unter "NAME" zur Verfügung stehen und erhält dann über FOR unseren neuen Typen. Über TYPE und SOURCE können wir dann einen Character mit der Länge 60 definieren.

specification->definition->section-private->add_type( `name` )->for( xco_cp_abap=>type-source->for( 'c LENGTH 60' ) ).

 

Methode

Definieren wir nun eine neue Methode wie wir es bereits oben mit dem Interface getan haben. In diesem Abschnitt erzeugen wir die private Methode SAY_HELLO. Dieses Mal weisen wir das Objekt einer Variable zu, da wir mehrere Schritte durchführen müssen. Als nächstes fügen wir der Methode einen Importing Parameter namens NAME hinzu, geben der Methode einen DEFAULT Wert und setzen den Typen auf unseren zuvor definierten Typen. Weiterhin ergänzen wir einen zusätzlichen Importing Parameter, um das OUT Objekt aus der MAIN Methode an unsere Methode zu geben. Zum Abschluss fügen wir die neue Methode hinzu und setzen direkt auch den Quellcode.

DATA(method) = specification->definition->section-private->add_method( 'SAY_HELLO' ).

method->add_importing_parameter( 'NAME' )->set_default_value( `'Herbert'` )->set_type(
    xco_cp_abap=>type-source->for( 'name' ) ).
method->add_importing_parameter( 'OUT' )->set_type( xco_cp_abap=>interface( 'IF_OO_ADT_CLASSRUN_OUT' ) ).

specification->implementation->add_method( 'SAY_HELLO' )->set_source(
    VALUE #( ( `    out->write( |Hello { name }| ).` ) ) ).

 

Aktivierung

Nachdem unsere Klassendefinition nun abgeschlossen ist, müssen wir nur noch die Anlage ausführen. Dazu verwenden wir in der Operation die EXECUTE Methode, dann werden alle definierten Objekte angelegt. Als Default werden die Objekte zum Abschluss auch aktiviert. Möchtest du die Objekte nicht aktivieren, sondern nur im System inaktiv anlegen, dann kannst du die Option SKIP_ACTIVACTION übergeben.

* DATA(result) = operation->execute( VALUE #( ( xco_cp_generation=>put_operation_option->skip_activation ) ) ).
DATA(result) = operation->execute( ).

 

Ergebnis

Als Ergebnis erhalten wir im System eine neue Klasse, so wie wir sie auch definiert haben. Für die Formatierung solltest du noch einem den Pretty Printer oder am besten den ABAP Cleaner verwenden, dann musst du dich nicht mit der manuellen Formatierung des Objekts auseinandersetzen.

CLASS zcl_bs_demo_xco_generated DEFINITION
  PUBLIC FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

  PRIVATE SECTION.
    TYPES name TYPE c LENGTH 60.

    METHODS say_hello
      IMPORTING !name TYPE name DEFAULT 'Herbert'
                !out  TYPE REF TO if_oo_adt_classrun_out.
ENDCLASS.


CLASS zcl_bs_demo_xco_generated IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    say_hello( name = 'Bernd'
               out  = out ).
  ENDMETHOD.


  METHOD say_hello.
    out->write( |Hello { name }| ).
  ENDMETHOD.
ENDCLASS.

 

Die Klasse lässt sich auch direkt ausführen und wir erhalten eine Ausgabe in die Konsole.

 

Einschränkungen

In unserem Beispiel verwenden wir die ABAP Cloud API für die Cloud Platform (CP), diese hat einige Einschränkungen bei der Nutzung. So hast du nur Zugriff auf ABAP Cloud Objekte, also kundeneigene Objekte oder Objekte, die mit einem C1-Contract freigegeben wurden. Verwendest du eine API aus dem Bereich Classic ABAP, dann kannst du auch andere Objekte damit einlesen. Möchtest du mehr über die Unterschiede der verschiedenen APIs erfahren, dann schau bei unserem Quick Guide für XCO auf YouTube vorbei.

 

Komplettes Beispiel

Alle Klassen in diesem Artikel findest du als Commit bei uns im Repository auf GitHub. Damit solltest du die verschiedenen Schritte bei dir im System nachstellen können. Die generierte Klasse befindet sich ebenfalls im Repository, wenn du die Code-Generierung ausführst, solltest du die alte Klasse zuvor löschen.

 

Fazit

Mit der XCO Bibliothek kannst du nicht nur Objekte generieren, sondern auch Informationen zu bestehenden Objekten holen und diese gegebenenfalls anpassen. Der heutige Artikel war nur ein kleiner Einblick in das Thema Klassen und Interfaces, theoretisch gibt es für jedes ABAP Cloud Objekt die passende API.


Enthaltene Themen:
Modernes ABAPXCOGenerationInfo
Kommentare (0)



Und weiter ...

Bist du zufrieden mit dem Inhalt des Artikels? Wir posten jeden Freitag neuen Content im Bereich ABAP und unregelmäßig in allen anderen Bereichen. Schaue bei unseren Tools und Apps vorbei, diese stellen wir kostenlos zur Verfügung.


ABAP - XCO Nachricht und Sprache

Kategorie - ABAP

Was kannst du zusätzlich mit Nachrichten und den Sprachobjekten der XCO Bibliothek in ABAP Cloud machen? Lass uns der Frage im Detail nachgehen.

01.07.2025

ABAP - XCO Callstack und Tenant

Kategorie - ABAP

Wie kommst du mit den XCO Klassen an den ABAP Call Stack und bekommst weitere Informationen zum aktuellen Tenant? In diesem Artikel schauen wir einmal ins Detail.

06.06.2025

ABAP - XCO Class Runner

Kategorie - ABAP

Wie sieht es mit der Ausführung von ABAP Klassen im Bereich von XCO aus? Schauen wir uns dazu den Class Runner genauer an.

04.02.2025

ABAP - XCO UUID

Kategorie - ABAP

Wie generierst du mit den XCO Klassen eindeutige IDs in ABAP? In diesem Artikel erfährst du, wie schnell und einfach das möglich ist.

28.01.2025

ABAP - XCO Systemfelder

Kategorie - ABAP

Gibt es für SY bzw. SYST auch eine Alternative in der XCO Bibliothek in ABAP Cloud? Einen Blick ist sie auf jeden Fall wert.

24.01.2025