ReportServer scripts can be developed directly from within ReportServer using the Terminal and the commands createTextFile and editTextFile. In order to take full advantage of the services offered by ReportServer to script designers it is, however, necessary to get a basic understanding of the ReportServer source code. For this we provide a javadoc documentation of the sources together with the complete source code of ReportServer Community Edition on sourceforge.
To run and develop scripts in ReportServer, login to your ReportServer and open up the terminal (CTRL+ALT+T). All scripts must be stored in the fileserver somewhere beneath the bin directory. Thus, to give us a temporary working directory we go to the bin directory by typing cd fileserver/bin create a new directory called tmp by typing mkdir tmp and go to our newly created directory (cd tmp). Next, we create our very first script by executing
A text editor opens in which we copy our first script:
return "Hello World"
which simply returns the string "Hello World" upon execution. Now, execute the script via
You should see the following output:
reportserver$ exec helloworld.groovy Hello World reportserver$
That is, when executing a script on the terminal, then the final return statement is printed on the console. If you want to print something during the execution of the script (note that all print statements are buffered until the script is successfully executed) you can use the tout object (for terminal output).
tout.println('Hello World') tout.println('Hello World2')
To edit the file in ReportServer directly call
ReportServer scripts can be used for a variety of tasks. You can use them to create data sources or interactive reports, they can be used as administration tools and scheduled to perform maintenance tasks. They can, however, also be used to extend ReportServer both on the client side and on the server side. In this guide we will mainly focus on the last part of ReportServer scripts. This, however, directly also provides a large insight into other applications of scripts.
Script developers should keep in mind that the source code contains both server and client side code. Although code can be shared between the server and the client this is usually not the case. As scripts are written in Groovy and interpreted and executed on the server this means that scripts can only use server side code. If you look through the projects you will find that the package structure is the following:
where rs denotes a ReportServer project and name the main package of that project. Projects that are not ReportServer specific such as for example the DwHookHandler will not have the "rs" prefix. After the name part you will usually find the following packages:
|client||Contains client side code.|
|service||Contains server side code|
Now that we have seen the basic source structure there are two important concepts for script designers. One is the concept of Services. Most of the functionality offered by ReportServer, such as, executing reports, managing users, scheduling and many more are exposed by Service interfaces. An example is the ReportExecutorService which exposes the functionality to execute reports. When writing scripts you will usually use services to access ReportServer functionality. Services are by convention adhering to the naming scheme: nameService. If you search for net.datenwerke.*.service.*Service in the sources (or javadoc) of ReportServer you will find a large number of available server side services. We have also included a special services documentation file which lists all available services together with a short description and links to the Javadoc documentation of the service.
The second important concept is that of Hooks. Hooks are extension points in ReportServer which allow you to enhance functionality or be informed on certain events (such as report x is about to be executed). As with Services Hooks are used both on the server and client side and for script writers only the server side Hooks can be used. Hooks can be recognized by interfaces or abstract classes that implement the Hook interface
An example of a Hook is the ReportExecutionNotificationHook which is notified throughout the various stages of report execution. To use a Hook the corresponding interface must be implemented and the implementing Hook must be registered with the HookHandlerService. Classes that instantiate a Hook are usually suffixed by Hooker (i.e., the one doing the hooking).
Entities are objects which are persisted in the database. Most objects, such as users, reports or TeamSpaces, that you will handle as a script designer are entities. You can recognize classes that represent entities by the @Entity annotation. When handling entities it is important to keep in mind that changes need to be persisted. To load and store entities the JPA EntityManager is used.
Entities can also be transported to the client. However, as they are inherently server based an entity is first transformed into a so called data transfer object (DTO) which is the representation on the client side. The conversion between entities and DTOs is handled by the DtoService.