Technical Articles
CL_DEMO_OUTPUT invigorated
Some time ago, we introduced CL_DEMO_OUTPUT for simple examples and demonstrations.
CL_DEMO_OUTPUT, Part 1 of 2 – Usage | SAP Blogs
The functionality up to now was already nice and useful, but somehow it was not complete.
Writing a simple piece of code such as
DATA:
BEGIN OF super,
col1 TYPE i VALUE 1,
BEGIN OF sub,
col2 TYPE i VALUE 2,
col3 TYPE i VALUE 3,
END OF sub,
END OF super.
cl_demo_output=>display( super ).
results in
Duh!
We are happy to announce that from ABAP release 7.56, SP01 on, this output will look as follows:
In fact, you can output (nearly?) everything now:
CLASS demo_class DEFINITION.
PUBLIC SECTION.
TYPES:
BEGIN OF spfli_line,
carrid TYPE spfli-carrid,
connid TYPE spfli-connid,
cityfrom TYPE spfli-cityfrom,
cityto TYPE spfli-cityto,
END OF spfli_line,
spfli_tab TYPE HASHED TABLE OF spfli_line
WITH UNIQUE KEY carrid connid,
BEGIN OF struct,
carrname TYPE scarr-carrname,
spfli TYPE REF TO spfli_tab,
END OF struct.
DATA result TYPE SORTED TABLE OF struct WITH UNIQUE KEY carrname.
METHODS constructor.
ENDCLASS.
CLASS demo_class IMPLEMENTATION.
METHOD constructor.
SELECT s~carrname, p~carrid, p~connid, p~cityfrom, p~cityto
FROM scarr AS s
INNER JOIN spfli AS p
ON s~carrid = p~carrid
ORDER BY s~carrname
INTO TABLE @DATA(itab).
LOOP AT itab ASSIGNING FIELD-SYMBOL(<fs>) GROUP BY <fs>-carrname.
INSERT VALUE #( carrname = <fs>-carrname ) INTO TABLE result
ASSIGNING FIELD-SYMBOL(<line>).
<line>-spfli = NEW #(
FOR <wa> IN GROUP <fs> ( CORRESPONDING #( <wa> ) ) ).
ENDLOOP.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(oref) = NEW demo_class( ).
cl_demo_output=>display( oref ).
gives
Note, that simply the name of the reference variable oref is passed to the display method.
This has been achieved by introducing some recursions in CL_DEMO_OUTPUT_STREAM. That means that the intermediate XML coming from CL_DEMO_OUTPUT_STREAM supports nested stuff now and that the conversion capabilities of CL_DEMO_OUTPUT_HTML were enhanced accordingly.
And just for fun, we can also write self-explaining demos now:
DATA(o) = cl_demo_output=>new(
)->write_doc( cl_demo_output_helper=>get_infobox_html(
`This output is produced by program ` && sy-repid )
)->next_section( 'ABAP CDS View Entity'
)->write_doc( cl_demo_output_helper=>get_ddls_source_code_html(
source = 'DEMO_CDS_SPFLI_ENTITY' )
)->next_section( `ABAP SQL SELECT`
)->write_doc(
`The following code snippet demonstrates a ` &&
`<code>SELECT</code> statement accessing ` &&
`the CDS view entity without ` &&
`<code>ORDER BY</code> clause:`
)->begin_code( `select1` ).
SELECT *
FROM demo_cds_spfli_entity
INTO TABLE @DATA(itab). "#EC CI_NOWHERE
o->end_code( `select1`
)->write_doc( `The result in <code>itab</code> is:`
)->write( itab
)->write_doc( `Adding`
)->write_doc(
cl_demo_output_helper=>get_abap_source_code_html(
code = `ORDER BY cityfrom, cityto` )
)->write_doc( `as follows`
)->begin_code( `select2` ).
SELECT *
FROM demo_cds_spfli_entity
ORDER BY cityfrom, cityto
INTO TABLE @itab. "#EC CI_NOWHERE
o->end_code( `select2`
)->write_doc( `gives:`
)->write( itab
)->display( ).
gives
As before, you can retrieve the HTML file with method GET instead of DISPLAY in order to become independent from SAP GUI.
Caveats
- You have to wait for 7.56, SP01
- The new complex outputs are not fully supported by the text mode (but who wants to reprogram a browser in CL_DEMO_OUTPUT_TEXT?)
- ADT console supports only text but not HTML mode
- It is for demonstration purposes only …
Update
With releases 2308/2023
- CL_DEMO_OUTPUT_TEXT also supports all data types
- The ABAP console of ADT calls CL_DEMO_OUTPUT_TEXT
https://blogs.sap.com/2023/10/24/abap-console-reloaded/
Thanks for an update, Horst! This is great news. Too many times I've run into "data type not yet supported" and was wondering when that "yet" might be coming. I guess we're there now. 🙂
Thanks for sharing!
Wow. This looks cool.
Amazing,
though still for demonstration purposes only…
Hi Horst,
Cl_DEMO_OUTPUT is only for developer testing since we cannot move these classes to production systems, Could you please the let me know the possibilities where I could use this except testing?
Thanks & Regards
It is only for testing and demonstration purposes.
It's great to see that the good old cl_demo_output is still being developed. It makes me happy. 🙂
I won't ask about planned downport, because I think I know the answer 🙂
Nice blog, I got some issues earlier while using Cl_DEMO_OUTPUT (data type not yet supported)
https://answers.sap.com/questions/12655529/using-cldemooutput-to-display-internal-table.html
Thanks for sharing it is very helpful.
It is really amazing!
But, is it possible SAP release this tool, stop spelling it as "demo"? This is so usefull.
Personnaly I used it in productive program.
There are good reasons for keeping it as "Demo". First of all, it was developed for demo programs only (for a never finished follow-up of the ABAP Objects Book, later for the ABAP Keyword Documentation). If iit s useful for you in your demos, that's fine, but productive usage is at your own risk. For example, CL_DEMO_OUTPUT and CL_DEMO_OUTPT_STREAM are not suitable for large amounts of data. If we would publish it for productive usage, shortly we would be swamped with demands for improvement,
Furthermore, keeping it as "Demo" allows incompatible improvements. The change discussed under https://blogs.sap.com/2016/05/10/cldemooutput-part-1-of-2-usage/#comment-387632 was in fact incompatible and we received a customer incident regarding this change just recently! Of course we reacted by improving the respective behavior (method GET delivers HTML in background processing again, only DISPLAY switches to text mode), but we are not forced to backport that.
All in all, the classes might serve as patterns for your own (productive) classes but then it is your own responsibility. Please be aware, that it is not "SAP" that is shirking responsibility here. The classes are just the product of ABAP documentation writers playing around for their own purposes.
It is the problem of the tool coming realy usefull. But I understand the reasons you exposed.
As you set-it as FINAL class, we could not use inheritance to encapsulate in specific class.
Is it allowed to create a public version on GitHub of this tool ? if we want to propose a new version.
Removing the FINAL would cause the same compatibility problems. We couldn't change or even remove components of the class any more. In fact, that problem already occurred internally.
Since we promote it as a demo, you can copy it to your own (GIT) repositories.
Hi Horst,
I was running in CX_SY_REGEX_TOO_COMPLEX in method FORMAT_NESTED when using the output for some large data objects.
As it is generally not the best choice to operate on an XML document on string level, I wrote an XSLT transformation which basically does the same as your implementation with regexes that you designed in the methods CONVERT and its fan-out.
For this, I transformed the document at the beginning of CONVERT( ) not with transformation ID but with transformation ZDEMO_OUT_HTML. Afterwards, all the <ab:...> elements of the source had already been converted to html in my test cases, and the data were displayed correctly.
Maybe you would like to simplify your code by switching to this XSLT transformation. If so, you can find the XSLT transformation ZDEMO_OUT_HTML in my pastebin.
Cheers,
Rüdiger
Hi Rüdiger,
Thanks for sharing.
We will definitely look into that. This is very important, since ADT classrun will call CL_DEMO_OUTPUT in an upcoming release and we shouldn't have any exceptions there.
Another way to get rid of the exception could be switching from POSIX to PERL regular expressions but you are absolutely right, transformations rule.
Kind regards
Horst
Hi Horst,
in our system (SAP_BASIS 756.0001), I already have a version with PCREs, but I still got the CX_SY_REGEX_TOO_COMPLEX - and it crashed precisely at the place where PCRE where used (in method FORMAT_NESTED). So this doesn't solve the problem.
Yes, XSLT are designed for transforming XML, so they are the better choice at this place. Also, with XSLT you don't have to bother about the recursivity, ("I have to start with the <ab:nested> which don't have <ab:nested> in their content, and then working out from there in a loop..."), it's basically already built-in in the XSLT processing model. Of course, also XSLT have a size limit for the input, but it I presume it is much higher (at least it worked for my examples which didn't work with the PCREs).
Cheers
Rüdiger
Yes, this part was done already with PCRE.
And you won't believe it but we already have an XSLT call foreseen in a sandbox in the CCIMP of CL_DEMO_OUTPUT_HTML since some weeks. "Only" the transformation was missing but you helped us with that now.
We will call it and run all our some hundred demos and compare the results.
To keep you informed ...
While your XSLT seems to perform nicely for XML-streams consisting of purely ABAP-data (nodes <ab:object>), it does not take into account formatted textual data mixed in between. See above example for "self-explaining demos" or try methods as BEGIN_SECTION, WRITE_XML, WRITE_JSON, LINE. Only the ABAP data are formatted correctly.
We must either adjust the XSLT to fulfill also these requirements (we have one, that produces JSON already) or we have to split the XML stream into textual and data (<ab:object>) snippets and process them sequentially, where your transformation deals with the ABAP data. We have introduced such a sequential processing of snippets for an invigorated text output in the ADT console just recently.
Best,
Horst
Thanks for your informations, Horst. Indeed, the XSLT transformation only fixes the ABAP data part, and the modified method doesn't work correctly now for mixed sections in the output object. I am looking forward to your final solution.
But, as the incoming data are completely encoded in an XML document, it should be possible to extend that XSLT transformation by further template rules in order match all the possible nodes in the output document.
Best regards,
Rüdiger