Creating Custom Templates

It is possible to modify the look and feel of the default report. The report functionality uses a JasperReports template, an XML file with a .jrxml extension that can be edited in Jaspersoft Studio or in a text editor.

The main template file (<SQUORE_HOME>/configuration/models/Shared/Reports/templates/template.jrxml) includes most of the other files in the templates folder as sub-reports and allows the data sent from Squore to be turned into the final report document.

For any help with JasperReports, consult the forums at https://community.jaspersoft.com/.

Overall architecture

The template is split into the following sections:

  • Background

  • Title

  • PageHeader

  • ColumnHeader

  • Details (the body of the report where sub-reports are inserted)

  • ColumnFooter

  • PageFooter

  • LastPageFooter

  • Summary

Squore provides values for the following variables in the template automatically:

  • $P{report_data_source}: The full contents of the intermediate report file

  • $P{appName}: Squore

  • $P{application}: The name of the project

  • $P{artefactName}: The name of the artefact

  • $P{artefactType}: The type of the artefact

  • $P{author}: The name of the user generating the report

  • $P{companyName}: Vector

  • $P{companyUrl}: https://www.vector.com/

  • $P{logo}: The path to the logo to use in the header

  • $P{model}: The analysis model used

  • $P{poweredBy}: The path to the powered by Squore logo

  • $P{reportDate}: The date at which the report was generated

  • $P{restoreUrl}: The a URL to open the project’s dashboard in Squore

  • $P{supportUrl}: https://support.vector.com

  • $P{version}: The name of the version

  • $P{versionDate}: The analysis date

  • $P(userLanguage): The user interface language configured by the user.

For each chart from the dashboard that you include in a report, the following parameters are also available:

  • $P{chart_id}: a unique identifier for the chart based on the chart’s original ID

  • $P{chart_url_0} to $P{chart_url_x}: used to resolve the path to chart [0] to [X] (based on the chart’s position in Bundle.xml

  • $P{chart_name_0} to $P{chart_name_x}: used to resolve the name of chart [0] to [X] (based on the chart’s position in Bundle.xml

Up to 16 charts (and their comment threads) can be included without modifying the default template.

Sub-reports are activated based on the presence of an XML element in the data sent by Squore. The following lines checks for the presence of a highlights category in the exported data with the following dataSourceExpression to activate the highlights.jrxml sub-report:

<detail>
...
	<subreport>
		...
		<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JRXmlDataSource)$P{report_data_source}).subDataSource("//Highlights")]]></dataSourceExpression>
		<subreportExpression><![CDATA["/../../../Shared/Reports/templates/highlights.jasper"]]></subreportExpression>
	</subreport>
</detail>

Full sample

The following is a full sample of the data sent by Squore and fed into the report template.

This sample is provided to help you understand how the JasperReports template locates data to extract and format in the final report document.

Note that this data is only created in memory and not saved to disk when generating a report in Squore.

<?xml version="1.0" encoding="UTF-8"?>
<ReportModelResources appName="Squore"
                      application="Earth"
                      artefactName="Earth"
                      artefactType="Application"
                      author="demo"
                      companyName="Vector"
                      companyUrl="http://www.vector.com/"
                      logo="/path/to/header.image"
                      model="software_analytics"
                      poweredBy="/path/to/poweredBy.image"
                      reportDate="2018.02.27 17:55:54 CET"
                      restoreUrl="${artefacturl}?tabName=default"
                      supportUrl="https://support.vector.com/"
                      version="V6"
                      versionDate="2017.09.05 01:00:00 CEST"
                      userLanguage="en">
	<Charts>
		<Chart id="INDICATOR"
		       name="Key Performance Indicator"
		       path="/path/to/chart.image"/>
			   <Annotations>
					<Annotation status="OPEN">
						<Message creationTime="2019.04.26 18:08:08 CEST" poster="demo"><![CDATA[My super message!]]></Message>
					</Annotation>
			   </Annotations>
         <Description>
             <![CDATA[KPI description with HTML <ul><li>Point 1</li><li>Point 2</li></ul>]]>
         </Description>
		<Chart ... />
	</Charts>
	<Tables>
		<Table id="COMPLEXITY_DENSITY"
		       name="Complexity">
			<Line data="10,8 %"
			      evolution="/path/to/trend.image"
			      image="/path/to/level.image"
			      isIcon="true|false"
			      isOnlyText="true|false"
			      name="Ratio of complex modules"/>
			<Line ... />
		</Table>
		<Table ... >
		...
		</Table>
	</Tables>
	<Measures>
		<Measure evolution="↑"
		         id="VG"
		         name="Cyclomatic Complexity"
		         refValue="335"
		         value="453"/>
		<Measure ... />
	</Measures>
	<Indicators>
		<Indicator evolution="/path/to/trendImage.svg"
		           icon="/path/to/icon.svg"
		           id="CPXT"
		           level="Level B"
		           name="Complexity Distribution"
		           refIcon="$/path/to/levelImage.svg"
		           refLevel="Level A">
			<Measure evolution="↑"
				 id="CPXT"
				 name="Complexity Distribution"
				 refValue="0.01"
				 value="0.0.3"/>
		</Indicator>
		<Indicator ... />
	</Indicators>
	<Infos>
		<Info id="LANGUAGE"
		      name="Language"
		      refValue="Multiple"
		      value="Multiple"/>
		<Info ... />
	</Infos>
	<Data>
		<Findings id="VIOLATIONS"
		          total="247"
		          totalDelta="104"
		          type="Findings"
		          url="${artefacturl}?tabName=findings">
			<FindingsDefinition CHARACTERISTIC="Maintainability"
			                    SCALE_NATURE="Non Conformity"
			                    SCALE_REMEDIATION="High"
			                    SCALE_SEVERITY="Critical"
			                    <!-- scales and characteristics according to your analysis model -->
			                    delta="+1"
			                    desc="Functions shall not called themselves either directly or indirectly (see [MISRA-C:2004]: RULE 16.2)."
			                    justif="My relaxation comment"
			                    measureId="R_NORECURSION"
			                    mnemo="NORECURSION"
			                    name="Recursion are not allowed"
			                    occ="1"
			                    toolName="Squore Analyzer"/>
			<FindingsDefinition ... />
		</Findings>
		<Findings ... >
		...
		</Findings>
		<FindingOccurrences id="FINDINGS"
		                    relaxationState="RELAXED">
			<Artefact name="main(int,char*[])"
			          path="apps/master.c"
			          type="C Function"
			          url="${artefacturl}?tabName=FINDINGS">
				<Finding count="1"
				         id="2064416"
				         line="Ligne: 95"
				         new="true"
				         tool="Squore Analyzer">
					<Rule externalId="R_COMPOUND"
					      mnemonic="COMPOUND"
					      name="Missing compound statement"/>
					<Relaxation date="2018-01-31T10:08:04"
					            status="Derogation (Imported)"
					            user="demo">keeping some conciseness by avoiding using compound {}</Relaxation>
				</Finding>
				<Finding ... >
				...
				</Finding>
			</Artefact>
		</FindingOccurrences>
		<DefectReports id="AIS">
			<DefectReportsDefinition SCALE_AI_TYPE="Non Regression"
			                         SCALE_PRIORITY="High"
			                         <!-- scales according to your analysis model -->
			                         artefactName="hi_scores_disp(int)"
			                         artefactPath="apps/score.c"
			                         desc="The object hi_scores_disp(int) has a higher number of 'Blocker' or 'Critical' rules violated since the previous version."
			                         id="${actionitemid}"
			                         measureId="${actionitemid}"
			                         name="More 'Blocker' or 'Critical' rules violated"
			                         scope="C Function"
			                         since="V6"
			                         status="Open"
			                         url="${artefacturl}?tabName=action-items">
				<Reason desc="Code Status reveals that development is in progress (=1).{}#10;"/>
				<Reason ... />
			</DefectReportsDefinition>
			<DefectReportsDefinition ... />
		</DefectReports>
		<Highlights col0="New Code Stability Index"
		            col1="Line Count"
		            filterId="TOP_10_MOST_CHANGED_ARTEFACTS"
		            id="MOST_CHANGED"
		            nbColumns="2"
		            title="Top 10 most changed artefacts">
			<TopArtefact artefactName="print_instructions_fr()"
			             artefactPath="core/write.c"
			             col0="12,5 %"
			             col1="72"
			             rating="/path/to/level.image"
			             url="${artefacturl}?tabName=highlights"/>
			<TopArtefact ... />
		</Highlights>
		<Artefacts id="RELAXED_ARTEFACT"
                   relaxationState="RELAXED">
			<Artefact name="machine.c"
                      path="apps"
                      relaxationComment="Why I relaxed this..."
                      relaxationDate="2018.02.28 16:11:29 CET"
                      relaxationUser="demo"
                      type="C File"/>
			<Artefact ... />
		</Artefacts>
	</Data>
	<SubData>
		<SubArtefacts id="COMPLEX_MODULES">
			<SubArtefact name="machine_plays()"
			             path="apps/machine.c"
			             type="C Function"
			             url="${artefacturl}">
				<!-- Each SubArtefact contains Charts, Tables Measures, Indicators and Infos sections similar to the ones at ReportModelResources level -->
				<Charts>
					<Chart ... />
				</Charts>
				<Tables>
					<Table ... />
				</Tables>
				<Measures>
					<Measure ... />
				</Measures>
				<Indicators>
					<Indicator ... />
				</Indicators>
				<Infos>
					<Info ... />
				</Infos>
			</SubArtefact>
		</SubArtefacts>
	</SubData>
</ReportModelResources>

${artefacturl} is a direct link to open the specified Explorer tab in Squore for the artefact mentioned in the report.