159 lines
47 KiB
HTML
159 lines
47 KiB
HTML
<!doctype html><html lang=en class="js csstransforms3d"><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=generator content="Hugo 0.80.0"><meta name=description content="Strolch is a parameterized framework for use on servers and IoT"><meta name=author content="Strolch"><link rel=icon href=/favicon.ico type=image/ico><title>Reports - Strolch</title><link href=/css/nucleus.css?1660714134 rel=stylesheet><link href=/css/fontawesome-all.min.css?1660714134 rel=stylesheet><link href=/css/hybrid.css?1660714134 rel=stylesheet><link href=/css/featherlight.min.css?1660714134 rel=stylesheet><link href=/css/perfect-scrollbar.min.css?1660714134 rel=stylesheet><link href=/css/auto-complete.css?1660714134 rel=stylesheet><link href=/css/atom-one-dark-reasonable.css?1660714134 rel=stylesheet><link href=/css/theme.css?1660714134 rel=stylesheet><link href=/css/hugo-theme.css?1660714134 rel=stylesheet><link href=/css/theme-green.css?1660714134 rel=stylesheet><script src=/js/jquery-3.3.1.min.js?1660714134></script><style>:root #header+#content>#left>#rlblock_left{display:none!important}</style></head><body data-url=/documentation/reports/><nav id=sidebar><div id=header-wrapper><div id=header><a id=logo href=/><img src=/logo.png></a></div><div class=searchbox><label for=search-by><i class="fas fa-search"></i></label><input data-search-input id=search-by type=search placeholder=Search...>
|
|
<span data-search-clear><i class="fas fa-times"></i></span></div><script type=text/javascript src=/js/lunr.min.js?1660714134></script><script type=text/javascript src=/js/auto-complete.js?1660714134></script><script type=text/javascript>var baseurl="https:\/\/strolch.li\/";</script><script type=text/javascript src=/js/search.js?1660714134></script></div><section id=homelinks><ul><li><a class=padding href=/><i class="fas fa-home"></i>Home</a></li></ul></section><div class=highlightable><ul class=topics><li data-nav-id=/api/ title=API class=dd-item><a href=/api/>API</a></li><li data-nav-id=/documentation/ title=Documentation class="dd-item
|
|
parent"><a href=/documentation/>Documentation</a><ul><li data-nav-id=/documentation/architecture/ title=Architecture class=dd-item><a href=/documentation/architecture/>Architecture</a></li><li data-nav-id=/documentation/model/ title=Model class=dd-item><a href=/documentation/model/>Model</a></li><li data-nav-id=/documentation/do-and-donts/ title="Do and Don't" class=dd-item><a href=/documentation/do-and-donts/>Do and Don't</a></li><li data-nav-id=/documentation/runtime-configuration/ title="Runtime Configuration" class=dd-item><a href=/documentation/runtime-configuration/>Runtime Configuration</a></li><li data-nav-id=/documentation/realms/ title=Realms class=dd-item><a href=/documentation/realms/>Realms</a></li><li data-nav-id=/documentation/components/ title=Components class=dd-item><a href=/documentation/components/>Components</a></li><li data-nav-id=/documentation/services-and-commands/ title="Services and Commands" class=dd-item><a href=/documentation/services-and-commands/>Services and Commands</a></li><li data-nav-id=/documentation/searches/ title=Searches class=dd-item><a href=/documentation/searches/>Searches</a></li><li data-nav-id=/documentation/queries/ title=Queries class=dd-item><a href=/documentation/queries/>Queries</a></li><li data-nav-id=/documentation/transactions/ title=Transactions class=dd-item><a href=/documentation/transactions/>Transactions</a></li><li data-nav-id=/documentation/policies/ title=Policies class=dd-item><a href=/documentation/policies/>Policies</a></li><li data-nav-id=/documentation/observers/ title=Observers class=dd-item><a href=/documentation/observers/>Observers</a></li><li data-nav-id=/documentation/versioning/ title=Versioning class=dd-item><a href=/documentation/versioning/>Versioning</a></li><li data-nav-id=/documentation/reports/ title=Reports class="dd-item active"><a href=/documentation/reports/>Reports</a></li><li data-nav-id=/documentation/priviles/ title=Privileges class=dd-item><a href=/documentation/priviles/>Privileges</a></li></ul></li><li data-nav-id=/plc/ title=PLC class=dd-item><a href=/plc/>PLC</a><ul><li data-nav-id=/plc/architecture/ title=Architecture class=dd-item><a href=/plc/architecture/>Architecture</a></li><li data-nav-id=/plc/example-set-up/ title="Example Set-Up" class=dd-item><a href=/plc/example-set-up/>Example Set-Up</a></li></ul></li><li data-nav-id=/tutorial/ title=Tutorial class=dd-item><a href=/tutorial/>Tutorial</a><ul><li data-nav-id=/tutorial/configuration/ title=Configuration class=dd-item><a href=/tutorial/configuration/>Configuration</a></li><li data-nav-id=/tutorial/model/ title=Model class=dd-item><a href=/tutorial/model/>Model</a></li><li data-nav-id=/tutorial/crud-book/ title="CRUD Book" class=dd-item><a href=/tutorial/crud-book/>CRUD Book</a></li></ul></li><li data-nav-id=/download/ title=Download class=dd-item><a href=/download/>Download</a></li><li data-nav-id=/development/ title=Development class=dd-item><a href=/development/>Development</a><ul><li data-nav-id=/development/prerequisites/ title=Prerequisites class=dd-item><a href=/development/prerequisites/>Prerequisites</a></li><li data-nav-id=/development/building/ title="Building Strolch" class=dd-item><a href=/development/building/>Building Strolch</a></li><li data-nav-id=/development/maven-archetypes/ title="Maven Archetypes" class=dd-item><a href=/development/maven-archetypes/>Maven Archetypes</a></li><li data-nav-id=/development/web-app/ title="Web App" class=dd-item><a href=/development/web-app/>Web App</a></li><li data-nav-id=/development/main-class-app/ title="Main Class App" class=dd-item><a href=/development/main-class-app/>Main Class App</a></li><li data-nav-id=/development/converting-existing/ title="Converting Existing App" class=dd-item><a href=/development/converting-existing/>Converting Existing App</a></li></ul></li><li data-nav-id=/blog/ title=Blog class=dd-item><a href=/blog/>Blog</a><ul><li data-nav-id=/blog/post-00016/ title="Strolch PLC now also on Maven Central" class=dd-item><a href=/blog/post-00016/>Strolch PLC now also on Maven Central</a></li><li data-nav-id=/blog/post-00015/ title="Release of Strolch 1.6.100" class=dd-item><a href=/blog/post-00015/>Release of Strolch 1.6.100</a></li><li data-nav-id=/blog/post-00014/ title="Strolch Reports" class=dd-item><a href=/blog/post-00014/>Strolch Reports</a></li><li data-nav-id=/blog/post-00013/ title="Strolch Searches" class=dd-item><a href=/blog/post-00013/>Strolch Searches</a></li><li data-nav-id=/blog/post-00012/ title="Wow, the many changes!" class=dd-item><a href=/blog/post-00012/>Wow, the many changes!</a></li><li data-nav-id=/blog/post-00011/ title="Strolch now on Maven Central" class=dd-item><a href=/blog/post-00011/>Strolch now on Maven Central</a></li><li data-nav-id=/blog/post-00010/ title="Versioning of objects" class=dd-item><a href=/blog/post-00010/>Versioning of objects</a></li><li data-nav-id=/blog/post-00009/ title="Release 1.2.0" class=dd-item><a href=/blog/post-00009/>Release 1.2.0</a></li><li data-nav-id=/blog/post-00008/ title="Strolch Update" class=dd-item><a href=/blog/post-00008/>Strolch Update</a></li><li data-nav-id=/blog/post-00007/ title="Activities: Beginning of the planning engine" class=dd-item><a href=/blog/post-00007/>Activities: Beginning of the planning engine</a></li><li data-nav-id=/blog/post-00006/ title="Strolch Documentation" class=dd-item><a href=/blog/post-00006/>Strolch Documentation</a></li><li data-nav-id=/blog/post-00005/ title="Strolch Release 1.0.0" class=dd-item><a href=/blog/post-00005/>Strolch Release 1.0.0</a></li><li data-nav-id=/blog/post-00004/ title="DurationParameter and other minor changes: Release 1.0.0-RC4" class=dd-item><a href=/blog/post-00004/>DurationParameter and other minor changes: Release 1.0.0-RC4</a></li><li data-nav-id=/blog/post-00003/ title="DB Initialization: Release 1.0.0-RC3" class=dd-item><a href=/blog/post-00003/>DB Initialization: Release 1.0.0-RC3</a></li><li data-nav-id=/blog/post-00002/ title="Release 1.0.0-RC2" class=dd-item><a href=/blog/post-00002/>Release 1.0.0-RC2</a></li><li data-nav-id=/blog/post-00001/ title="Release 1.0.0-RC1" class=dd-item><a href=/blog/post-00001/>Release 1.0.0-RC1</a></li></ul></li></ul><section id=shortcuts><h3>More</h3><ul><li><a class=padding href=https://strolch.li/tags><i class="fas fa-tags"></i>Tags</a></li><li><a class=padding href=https://github.com/strolch-li target=_blank><i class="fab fa-github"></i>GitHub project</a></li></ul></section><section id=footer><p>Built with <a href=https://github.com/matcornic/hugo-theme-learn target=_blank><i class="fas fa-heart"></i></a>from <a href=https://getgrav.org target=_blank>Grav</a> and <a href=https://gohugo.io/ target=_blank>Hugo</a></p></section></div></nav><section id=body><div id=overlay></div><div class="padding highlightable"><div><div id=top-bar><div id=top-github-link><a class=github-link title="Edit this page" href=https://github.com/strolch-li/strolch-website/tree/develop/content/documentation/reports.md target=blank><i class="fas fa-code-branch"></i><span id=top-github-link-text>Edit this page</span></a></div><div id=breadcrumbs itemscope itemtype=http://data-vocabulary.org/Breadcrumb><span id=sidebar-toggle-span><a href=# id=sidebar-toggle data-sidebar-toggle><i class="fas fa-bars"></i></a></span><span id=toc-menu><i class="fas fa-list-alt"></i></span><span class=links><a href=/>Strolch Overview</a> > <a href=/documentation/>Documentation</a> > Reports</span></div><div class=progress><div class=wrapper><nav id=TableOfContents><ul><li><a href=#reports>Reports</a></li><li><a href=#genericreport>GenericReport</a><ul><li><a href=#parameters>Parameters</a></li><li><a href=#lookups>Lookups</a></li><li><a href=#ordering>Ordering</a></li><li><a href=#filtering>Filtering</a></li><li><a href=#joins>Joins</a></li><li><a href=#execution-of-reports>Execution of Reports</a></li><li><a href=#filter-criteria>Filter Criteria</a></li><li><a href=#date-range-filtering>Date Range Filtering</a></li></ul></li></ul></nav></div></div></div></div><div id=head-tags></div><div id=body-inner><h1>Reports</h1><h2 id=reports>Reports</h2><p>Since Strolch has a generic model, it was rather straight forward to create a
|
|
simple API for writing reports. In Strolch a report is defined by using its own
|
|
model, i.e. a Report is a <code>Resource</code> of type <code>Report</code>.</p><p>A report consists of the following parts:</p><ul><li>policy definition, thus allowing extensions</li><li>basic configuration like base object type, order direction, etc.</li><li>column definitions</li><li>joins</li><li>ordering definition</li><li>filters</li></ul><p>An example of a report is as follows:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-xml data-lang=xml>
|
|
<span style=color:#f92672><Resource</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"stockReport"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Stock Report"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Report"</span><span style=color:#f92672>></span>
|
|
|
|
<span style=color:#f92672><ParameterBag</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"parameters"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"parameters"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Parameters"</span><span style=color:#f92672>></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"objectType"</span> <span style=color:#a6e22e>Index=</span><span style=color:#e6db74>"20"</span> <span style=color:#a6e22e>Hidden=</span><span style=color:#e6db74>"false"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Object Type"</span>
|
|
<span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span> <span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Player"</span>
|
|
<span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"Player"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"descending"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Descending order"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Boolean"</span>
|
|
<span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"true"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672></ParameterBag></span>
|
|
|
|
<span style=color:#f92672><ParameterBag</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"ordering"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Ordering"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Ordering"</span><span style=color:#f92672>></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"name"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Name"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span>
|
|
<span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Player"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"$name"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672></ParameterBag></span>
|
|
|
|
<span style=color:#f92672><ParameterBag</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"noTeamFilter"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Filter"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Filter"</span><span style=color:#f92672>></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"policy"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Filter Policy"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span>
|
|
<span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"ReportFilterPolicy"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"key:Equals"</span>
|
|
<span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"!"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"fieldRef"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Field reference"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span>
|
|
<span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Slot"</span>
|
|
<span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"Bags/relations/team"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672></ParameterBag></span>
|
|
|
|
<span style=color:#f92672><ParameterBag</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"columns"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Display Columns"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Display"</span><span style=color:#f92672>></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"name"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Player"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span>
|
|
<span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Player"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"$name"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"birthDate"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Birth date"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span>
|
|
<span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Player"</span>
|
|
<span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"Bags/parameters/birthDate"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"team"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Team"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span>
|
|
<span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Team"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"$name"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672></ParameterBag></span>
|
|
|
|
<span style=color:#f92672><ParameterBag</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"joins"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Joins"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Joins"</span><span style=color:#f92672>></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"Team"</span> <span style=color:#a6e22e>Index=</span><span style=color:#e6db74>"10"</span> <span style=color:#a6e22e>Hidden=</span><span style=color:#e6db74>"false"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Team"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span>
|
|
<span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Team"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"Player"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672></ParameterBag></span>
|
|
|
|
<span style=color:#f92672><Policies></span>
|
|
<span style=color:#f92672><Policy</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"ReportPolicy"</span>
|
|
<span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"java:li.strolch.report.policy.GenericReport"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672></Policies></span>
|
|
|
|
<span style=color:#f92672></Resource></span>
|
|
</code></pre></div><p>This report</p><ul><li>shows all Resources of type player (parameter <code>objectType</code>) → marks the object
|
|
type to be show in the filter criteria (default), and that its sorting index
|
|
is at 20.</li><li>orders the report by player’s name (parameter bag <code>ordering</code>)</li><li>filters out all players with no team assigned (parameter bag <code>noTeamFilter</code>)</li><li>defines three columns: Player, Birth date, Team (paramger bag <code>columns</code>)</li><li>joins in the resource of type <code>Team</code></li><li>Uses the <code>GenericReport</code> class to generate the report</li></ul><h2 id=genericreport>GenericReport</h2><p>The default generic report implemented in Strolch has the following features and
|
|
options:</p><h3 id=parameters>Parameters</h3><p>The parameters bag can contain the following parameters:</p><ul><li><p><code>objectType</code> → the base type of object to get the input for the report. This
|
|
means that the <code>Interpretation</code> is set to one of:</p><ul><li><code>Resource-Ref</code></li><li><code>Order-Ref</code></li><li><code>Activity-Ref</code></li></ul><p>and that the <code>UOM</code> and <code>value</code> of the parameter is set to the type of element with
|
|
which to retrieve the elements from the strolch model.</p></li><li><p><code>descending</code> → boolean flag to define if sorting is in descending order</p></li><li><p><code>allowMissingColumns</code> → flag to define if no exception should be thrown if a
|
|
column is missing</p></li><li><p><code>dateRangeSel</code> → defines a lookup parameter to use as a date range selector.
|
|
This requires input when executing the report</p></li></ul><div class="notices warning"><p>Note: that the attributes Hidden and Index define the
|
|
visibility and sorting index as filter criteria respectively.</p></div><h3 id=lookups>Lookups</h3><p>Many of the features of the generic report rely on looking up a value on the
|
|
referenced element. The following shows the ways that a lookup can be performed:</p><ul><li><code>$id</code> → lookup the ID of the element</li><li><code>$name</code> → lookup the name of the element</li><li><code>$type</code> → lookup the type of the element</li><li><code>$date</code> → lookup the date of the element (only possible on <code>Order</code>
|
|
and <code>Activity</code> elements)</li><li><code>$state</code> → lookup the state of the element (only possible on <code>Order</code>
|
|
and <code>Activity</code> elements)</li><li><code>Bags/<bag_id>/<param_id></code> → a lookup on the selected element by bag ID and
|
|
parameter ID</li><li><code>$search:<parent_ref_id>:Bags/<bag_id>/<param_id></code> → searches for a parameter
|
|
with the given bag and parameter, and if it does not exist, looks for the
|
|
parent with the given parent_ref_id on the element. This allows a recursive
|
|
search up a tree of elements which all have the same parameter referencing a
|
|
parent. relations bag</li></ul><div class="notices warning"><p>Note: these definitions are set as the value of a
|
|
Parameter, and the Interpretation and UOM of the parameter is used to find the
|
|
element on which to perform the lookup. I.e. the following definition:</p></div><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-xml data-lang=xml><span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"name"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Player"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span> <span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Player"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"$name"</span><span style=color:#f92672>/></span>
|
|
</code></pre></div><p>defines that we want to lookup the name of the resource of type Player.</p><h3 id=ordering>Ordering</h3><p>Ordering, i.e sorting is done by adding the parameter bag with the id <code>ordering</code>
|
|
and each parameter defines a column to order by. The sequence of the ordering is
|
|
defined by the <code>index</code> value assigned to each parameter.</p><h3 id=filtering>Filtering</h3><p>Filtering use additional Strolch Policies which implement the operator function.
|
|
I.e. performing an equals, etc. The following <code>ReportFilterPolicy</code> are available
|
|
and should be added in your <code>StrolchPolicies.xml</code> file:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-xml data-lang=xml><span style=color:#f92672><StrolchPolicies></span>
|
|
...
|
|
<span style=color:#f92672><PolicyType</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"ReportFilterPolicy"</span> <span style=color:#a6e22e>Api=</span><span style=color:#e6db74>"li.strolch.report.policy.ReportFilterPolicy"</span><span style=color:#f92672>></span>
|
|
<span style=color:#f92672><Policy</span> <span style=color:#a6e22e>Key=</span><span style=color:#e6db74>"GreaterThan"</span> <span style=color:#a6e22e>Class=</span><span style=color:#e6db74>"li.strolch.report.policy.GreaterThanReportFilter"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Policy</span> <span style=color:#a6e22e>Key=</span><span style=color:#e6db74>"LessThan"</span> <span style=color:#a6e22e>Class=</span><span style=color:#e6db74>"li.strolch.report.policy.LessThanReportFilter"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Policy</span> <span style=color:#a6e22e>Key=</span><span style=color:#e6db74>"Equals"</span> <span style=color:#a6e22e>Class=</span><span style=color:#e6db74>"li.strolch.report.policy.EqualsReportFilter"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Policy</span> <span style=color:#a6e22e>Key=</span><span style=color:#e6db74>"Contains"</span> <span style=color:#a6e22e>Class=</span><span style=color:#e6db74>"li.strolch.report.policy.ContainsReportFilter"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Policy</span> <span style=color:#a6e22e>Key=</span><span style=color:#e6db74>"IsIn"</span> <span style=color:#a6e22e>Class=</span><span style=color:#e6db74>"li.strolch.report.policy.IsInReportFilter"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Policy</span> <span style=color:#a6e22e>Key=</span><span style=color:#e6db74>"ValueRef"</span> <span style=color:#a6e22e>Class=</span><span style=color:#e6db74>"li.strolch.report.policy.ValueRefReportFilter"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672></PolicyType></span>
|
|
...
|
|
<span style=color:#f92672></StrolchPolicies></span>
|
|
</code></pre></div><p>From this we can see that we can perform a <code>GreaterThan</code>, <code>LessThan</code> and <code>Equals</code>
|
|
filtering. These filters can also be negated by prefixing the filter value with
|
|
an exclamation mark (!).</p><p>A special case for the filter values are filters on dates. If you are filtering
|
|
on a date, then you can use the special operator <code>now()</code>. This filter will use the
|
|
current date and time and will add/subtract the ISO8601 period passed as an
|
|
argument to the operator.</p><p>The following shows examples of these filters:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-xml data-lang=xml><span style=color:#f92672><ParameterBag</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"minQtyFilter"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Filter"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Filter"</span><span style=color:#f92672>></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"policy"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Filter Policy"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span> <span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"ReportFilterPolicy"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"key:GreaterThan"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"10"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"fieldRef"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Field reference"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span> <span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Product"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"Bags/parameters/quantity"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672></ParameterBag></span>
|
|
|
|
<span style=color:#f92672><ParameterBag</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"notEmptyFilter"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Filter"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Filter"</span><span style=color:#f92672>></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"policy"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Filter Policy"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span> <span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"ReportFilterPolicy"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"key:Equals"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"!"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"fieldRef"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Field reference"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span> <span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Team"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"Bags/relations/team"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672></ParameterBag></span>
|
|
|
|
<span style=color:#f92672><ParameterBag</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"threeMonthsAgoFilter"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Filter"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Filter"</span><span style=color:#f92672>></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"policy"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Filter Policy"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span> <span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"ReportFilterPolicy"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"key:LessThan"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"now(-P3M)"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"fieldRef"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Field reference"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span> <span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"FromStock"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"$date"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672></ParameterBag></span>
|
|
</code></pre></div><div class="notices tip"><p>Note: One parameter defines which policy gets used and the <code>key:<name></code> value
|
|
references a policy defined in the <code>StrolchPolicies.xml</code> file. Further the lookup
|
|
is defined in the <code>fieldRef</code> parameter.</p></div><h3 id=joins>Joins</h3><p>To add columns from data which is not on the element denoted by the base object
|
|
type, we can join further elements. This is done by adding the parameter bag
|
|
<code>joins</code> and then each parameter references an element to join. The joining is done
|
|
as follows:</p><ul><li>The <code>Intepretation</code> and <code>UOM</code> define which object we want to join, i.e. resource
|
|
of type foo</li><li>The value of the parameter defines the type of element on which to find the
|
|
reference</li><li>The join ordering is not relevant, as the tree is traversed accordingly</li><li>At least one join must reference the base object type</li><li>The lookup of the join is done by finding a parameter with any ID, which has
|
|
the same <code>Interpretation</code> and <code>UOM</code> as the join definition</li><li>The attributes <code>Hidden</code> and <code>Index</code> define the visibility and sorting index as
|
|
filter criteria respectively.</li></ul><p>Thus the following:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-xml data-lang=xml><span style=color:#f92672><ParameterBag</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"joins"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Joins"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Joins"</span><span style=color:#f92672>></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"Team"</span> <span style=color:#a6e22e>Index=</span><span style=color:#e6db74>"10"</span> <span style=color:#a6e22e>Hidden=</span><span style=color:#e6db74>"false"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Team"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span> <span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Team"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"Player"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"Country"</span> <span style=color:#a6e22e>Index=</span><span style=color:#e6db74>"5"</span> <span style=color:#a6e22e>Hidden=</span><span style=color:#e6db74>"false"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Team"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span> <span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Country"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"Team"</span><span style=color:#f92672>/></span>
|
|
<span style=color:#f92672></ParameterBag></span>
|
|
</code></pre></div><p>Performs two joins: First we join a resource of type <code>Team</code> by finding the
|
|
relevant parameter on the <code>Player</code> resource, and then we lookup a resource of type
|
|
<code>Country</code> on the previously joined <code>Team</code> resource.</p><h3 id=execution-of-reports>Execution of Reports</h3><p>To execute a reports, we must instantiate the Report and can then directly
|
|
generate a JsonObject stream, which we can then pipe to a browser, file, etc.:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java>Stream<span style=color:#f92672><</span>JsonObject<span style=color:#f92672>></span> jsonObjectStream <span style=color:#f92672>=</span> <span style=color:#66d9ef>new</span> Report<span style=color:#f92672>(</span>tx<span style=color:#f92672>,</span> reportId<span style=color:#f92672>).</span><span style=color:#a6e22e>doReportAsJson</span><span style=color:#f92672>();</span>
|
|
</code></pre></div><p>If you prefer a CSV report:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=color:#66d9ef>try</span> <span style=color:#f92672>(</span>CSVPrinter csvP <span style=color:#f92672>=</span> <span style=color:#66d9ef>new</span> CSVPrinter<span style=color:#f92672>(</span><span style=color:#66d9ef>new</span> OutputStreamWriter<span style=color:#f92672>(</span>out<span style=color:#f92672>),</span>
|
|
CSVFormat<span style=color:#f92672>.</span><span style=color:#a6e22e>DEFAULT</span><span style=color:#f92672>.</span><span style=color:#a6e22e>withHeader</span><span style=color:#f92672>(</span>headers<span style=color:#f92672>).</span><span style=color:#a6e22e>withDelimiter</span><span style=color:#f92672>(</span><span style=color:#e6db74>';'</span><span style=color:#f92672>)))</span> <span style=color:#f92672>{</span>
|
|
|
|
<span style=color:#75715e>// do report without AsJson, and then iterating each row and sending to a CSV writer
|
|
</span><span style=color:#75715e></span> report<span style=color:#f92672>.</span><span style=color:#a6e22e>doReport</span><span style=color:#f92672>().</span><span style=color:#a6e22e>forEach</span><span style=color:#f92672>(</span>row <span style=color:#f92672>-></span> <span style=color:#f92672>{</span>
|
|
<span style=color:#66d9ef>try</span> <span style=color:#f92672>{</span>
|
|
csvP<span style=color:#f92672>.</span><span style=color:#a6e22e>printRecord</span><span style=color:#f92672>(</span>row<span style=color:#f92672>.</span><span style=color:#a6e22e>valueStream</span><span style=color:#f92672>().</span><span style=color:#a6e22e>collect</span><span style=color:#f92672>(</span>Collectors<span style=color:#f92672>.</span><span style=color:#a6e22e>toList</span><span style=color:#f92672>()));</span> <span style=color:#75715e>// add to CSV
|
|
</span><span style=color:#75715e></span> <span style=color:#f92672>}</span> <span style=color:#66d9ef>catch</span> <span style=color:#f92672>(</span>Exception e<span style=color:#f92672>)</span> <span style=color:#f92672>{</span>
|
|
logger<span style=color:#f92672>.</span><span style=color:#a6e22e>error</span><span style=color:#f92672>(</span><span style=color:#e6db74>"Could not write CSV row"</span><span style=color:#f92672>,</span> e<span style=color:#f92672>);</span>
|
|
<span style=color:#f92672>}</span>
|
|
<span style=color:#f92672>});</span>
|
|
<span style=color:#f92672>}</span>
|
|
</code></pre></div><h3 id=filter-criteria>Filter Criteria</h3><p>Predefining filters is a good start, but in some case you only want a portion of
|
|
the actual filtered data. For instance if you make a stock report, you might
|
|
only want one location. This information is dynamic and thus not stored on the
|
|
report definition.</p><p>To perform these dynamic filterings, one would call the <code>filter()</code>-method on the
|
|
report, passing the type of element to be filtered, and to which element IDs to
|
|
reduce the report data to. The following reduces the report to only return the
|
|
rows with the <code>product01</code> Product and <code>location02</code> Location elements:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=color:#66d9ef>new</span> Report<span style=color:#f92672>(</span>tx<span style=color:#f92672>,</span> <span style=color:#e6db74>"stockReport"</span><span style=color:#f92672>)</span>
|
|
<span style=color:#f92672>.</span><span style=color:#a6e22e>filter</span><span style=color:#f92672>(</span><span style=color:#e6db74>"Product"</span><span style=color:#f92672>,</span> <span style=color:#e6db74>"product01"</span><span style=color:#f92672>)</span>
|
|
<span style=color:#f92672>.</span><span style=color:#a6e22e>filter</span><span style=color:#f92672>(</span><span style=color:#e6db74>"Location"</span><span style=color:#f92672>,</span> <span style=color:#e6db74>"location02"</span><span style=color:#f92672>)</span>
|
|
<span style=color:#f92672>.</span><span style=color:#a6e22e>doReportAsJson</span><span style=color:#f92672>()</span>
|
|
</code></pre></div><p>It is possible to find the possible filter criteria dynamically using the
|
|
generateFilterCriteria() method.</p><h3 id=date-range-filtering>Date Range Filtering</h3><p>The last option to filter dynamically is using a date range selector. Define the
|
|
dateRangeSel lookup parameter, and then set the date range on the instantiated
|
|
report:</p><p>Model the report in XML:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-xml data-lang=xml><span style=color:#f92672><ParameterBag</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"parameters"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"parameters"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"Parameters"</span><span style=color:#f92672>></span>
|
|
...
|
|
<span style=color:#f92672><Parameter</span> <span style=color:#a6e22e>Id=</span><span style=color:#e6db74>"dateRangeSel"</span> <span style=color:#a6e22e>Name=</span><span style=color:#e6db74>"Date Range Selector"</span> <span style=color:#a6e22e>Type=</span><span style=color:#e6db74>"String"</span> <span style=color:#a6e22e>Interpretation=</span><span style=color:#e6db74>"Resource-Ref"</span> <span style=color:#a6e22e>Uom=</span><span style=color:#e6db74>"Product"</span> <span style=color:#a6e22e>Value=</span><span style=color:#e6db74>"Bags/parameters/expirationDate"</span><span style=color:#f92672>/></span>
|
|
...
|
|
<span style=color:#f92672></ParameterBag></span>
|
|
</code></pre></div><p>And now call the report in Java:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java>Date from <span style=color:#f92672>=</span> <span style=color:#66d9ef>new</span> Date<span style=color:#f92672>(</span>LocalDate<span style=color:#f92672>.</span><span style=color:#a6e22e>of</span><span style=color:#f92672>(</span>2016<span style=color:#f92672>,</span> 1<span style=color:#f92672>,</span> 1<span style=color:#f92672>).</span><span style=color:#a6e22e>toEpochDay</span><span style=color:#f92672>()</span> <span style=color:#f92672>*</span> 86400000<span style=color:#f92672>);</span>
|
|
Date to <span style=color:#f92672>=</span> <span style=color:#66d9ef>new</span> Date<span style=color:#f92672>(</span>LocalDate<span style=color:#f92672>.</span><span style=color:#a6e22e>of</span><span style=color:#f92672>(</span>2017<span style=color:#f92672>,</span> 1<span style=color:#f92672>,</span> 1<span style=color:#f92672>).</span><span style=color:#a6e22e>toEpochDay</span><span style=color:#f92672>()</span> <span style=color:#f92672>*</span> 86400000<span style=color:#f92672>);</span>
|
|
DateRange dateRange <span style=color:#f92672>=</span> <span style=color:#66d9ef>new</span> DateRange<span style=color:#f92672>().</span><span style=color:#a6e22e>from</span><span style=color:#f92672>(</span>from<span style=color:#f92672>,</span> <span style=color:#66d9ef>true</span><span style=color:#f92672>).</span><span style=color:#a6e22e>to</span><span style=color:#f92672>(</span>to<span style=color:#f92672>,</span> <span style=color:#66d9ef>false</span><span style=color:#f92672>);</span>
|
|
List<span style=color:#f92672><</span>JsonObject<span style=color:#f92672>></span> result <span style=color:#f92672>=</span> <span style=color:#66d9ef>new</span> Report<span style=color:#f92672>(</span>tx<span style=color:#f92672>,</span> <span style=color:#e6db74>"stockReport"</span><span style=color:#f92672>)</span> <span style=color:#75715e>//
|
|
</span><span style=color:#75715e></span> <span style=color:#f92672>.</span><span style=color:#a6e22e>filter</span><span style=color:#f92672>(</span><span style=color:#e6db74>"Product"</span><span style=color:#f92672>,</span> <span style=color:#e6db74>"product01"</span><span style=color:#f92672>)</span> <span style=color:#75715e>//
|
|
</span><span style=color:#75715e></span> <span style=color:#f92672>.</span><span style=color:#a6e22e>dateRange</span><span style=color:#f92672>(</span>dateRange<span style=color:#f92672>)</span> <span style=color:#75715e>//
|
|
</span><span style=color:#75715e></span> <span style=color:#f92672>.</span><span style=color:#a6e22e>doReportAsJson</span><span style=color:#f92672>()</span>
|
|
</code></pre></div><div class="notices tip"><p>Note: See the <a href=https://github.com/strolch-li/strolch/blob/develop/li.strolch.service/src/test/java/li/strolch/report/GenericReportTest.java target=_blank>GenericReportTest</a> for examples.</p></div><footer class=footline></footer></div></div><div id=navigation><a class="nav nav-prev" href=/documentation/versioning/ title=Versioning><i class="fa fa-chevron-left"></i></a><a class="nav nav-next" href=/documentation/priviles/ title=Privileges style=margin-right:0><i class="fa fa-chevron-right"></i></a></div></section><div style=left:-1000px;overflow:scroll;position:absolute;top:-1000px;border:none;box-sizing:content-box;height:200px;margin:0;padding:0;width:200px><div style=border:none;box-sizing:content-box;height:200px;margin:0;padding:0;width:200px></div></div><script src=/js/clipboard.min.js?1660714134></script><script src=/js/perfect-scrollbar.min.js?1660714134></script><script src=/js/perfect-scrollbar.jquery.min.js?1660714134></script><script src=/js/jquery.sticky.js?1660714134></script><script src=/js/featherlight.min.js?1660714134></script><script src=/js/highlight.pack.js?1660714134></script><script>hljs.initHighlightingOnLoad();</script><script src=/js/modernizr.custom-3.6.0.js?1660714134></script><script src=/js/learn.js?1660714134></script><script src=/js/hugo-learn.js?1660714134></script><script src=/mermaid/mermaid.js?1660714134></script><script>mermaid.initialize({startOnLoad:true});</script><script type=text/javascript>var _paq=window._paq=window._paq||[];_paq.push(["setDocumentTitle",document.domain+"/"+document.title]);_paq.push(["setCookieDomain","*.strolch.li"]);_paq.push(['trackPageView']);_paq.push(['enableLinkTracking']);(function(){var u="https://piwik.eitchnet.ch/";_paq.push(['setTrackerUrl',u+'matomo.php']);_paq.push(['setSiteId','2']);var d=document,g=d.createElement('script'),s=d.getElementsByTagName('script')[0];g.type='text/javascript';g.async=true;g.src=u+'matomo.js';s.parentNode.insertBefore(g,s);})();</script></body></html> |