blob: 5f97ece0788e89d25e52964caa14152676b1e120 [file] [log] [blame]
<%--
Copyright (c) 2019 Ed Merks and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v2.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v20.html
--%>
<%@jet
package="org.eclipse.oomph.p2.internal.core"
class="RepositoryIndex"
imports=
"
java.security.cert.Certificate
java.util.*
org.bouncycastle.openpgp.PGPPublicKey
org.eclipse.equinox.p2.metadata.*
org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService
org.eclipse.oomph.p2.internal.core.RepositoryIntegrityAnalyzer.IndexReport
org.eclipse.oomph.p2.internal.core.RepositoryIntegrityAnalyzer.IUReport
org.eclipse.oomph.p2.internal.core.RepositoryIntegrityAnalyzer.Report
org.eclipse.oomph.p2.internal.core.RepositoryIntegrityAnalyzer.Report.LicenseDetail
org.eclipse.oomph.p2.internal.core.RepositoryIntegrityAnalyzer.Reporter
"
minimize="true"
skeleton="Skeleton.java"%>
<%Reporter reporter = (Reporter)argument;
IUReport iuReport = argument instanceof IUReport ? (IUReport)argument : null;
Report report = argument instanceof Report ? (Report)argument : iuReport == null ? null : iuReport.getReport();
IndexReport indexReport = argument instanceof IndexReport ? (IndexReport)argument : null;
class Helper {
public String getStyle(LicenseDetail license) {
StringBuilder result = new StringBuilder();
result.append(license.isMatchedSUA() ? "color: DarkOrange;" : "color: SaddleBrown;");
result.append(license.isSUA() ? " font-weight: bold;" : " text-decoration: line-through;");
return result.toString();
}
public String htmlEscape(String value, boolean nbsp) {
if (value == null) {
return "null";
}
String result = value.replace("&", "&amp;").replace("<", "&lt;");
if (nbsp) {
result = result.replace(" ", "&nbsp;");
}
return result;
}
}
Helper helper = new Helper();%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title><%=reporter.getTitle()%></title>
<meta name="keywords" content="eclipse,update site"/>
<meta name="description" content="Update Sites Reports"/>
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,700,300,600,100" rel="stylesheet" type="text/css"/>
<link rel="stylesheet" href="https://www.eclipse.org/eclipse.org-common/themes/solstice/public/stylesheets/styles.min.css"/>
<link rel="icon" type="image/ico" href="https://www.eclipse.org/eclipse.org-common/themes/solstice/public/images/favicon.ico"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<%-[StyleSheet]-%>
<style>
.text-nowrap {
white-space: nowrap;
}
.font-smaller {
font-size: 90%;
}
.fit-image {
width: 2ex;
height: 2ex;
}
span:target {
font-size: 125%;
border: 1px solid black;
}
.xml-repo {
white-space: pre;
border: none;
padding: 0px 0px;
margin-top: -2ex;
margin-bottom: -2ex;
margin-left: 0em;
}
.bad-absolute-location {
color: FireBrick;
font-size: 90%;
}
.xml-iu {
white-space: pre;
border: none;
padding: 0px 0px;
margin-top: -2ex;
margin-bottom: -2ex;
margin-left: 0em;
}
.xml-token {
color: SteelBlue;
font-family: monospace;
font-size: 80%;
}
.xml-attribute {
color: MediumAquaMarine;
font-family: monospace;
font-size: 80%;
}
.xml-element {
color: MediumOrchid;
font-family: monospace;
font-size: 80%;
}
.xml-attribute-value {
color: DarkSlateGray;
font-size: 90%;
}
.xml-element-value {
color: SaddleBrown;
font-size: 90%;
}
.bb {
background-color: white;
border: none;
padding: 0px 0px;
}
.filter {
background-color: white;
}
.iu-link {
padding: -2pt -2pt -2pt -2pt;
margin: 0px 0px 0px 0px;
}
.resolved-requirement {
color: SeaGreen;
font-size: 90%;
}
.used-capability {
color: Teal;
font-size: 90%;
}
.unused-capability {
font-size: 90%;
}
.unresolved-requirement {
color: IndianRed;
font-size: 90%;
}
</style>
</head>
<body id="body_solstice">
<%-[Script]-%>
<script>
function match(id) {
var filter = document.querySelector('input[name="filter"]:checked');
var currentFilter = 'iu-li';
if (filter != null && filter.value != 'all') {
currentFilter = filter.value;
}
var e = document.getElementById(id);
var message = document.getElementById(id + '-error');
var matchText = e.value;
var ius = document.getElementsByClassName('iu-li');
var targets = document.getElementsByClassName(currentFilter);
var targetsArray = [].slice.call(targets);
var count = 0;
for (var i = 0; i < ius.length; i++) {
var iu = ius[i];
var text = iu.textContent;
try {
if ((matchText == '' || text.match(matchText) != null) && targetsArray.includes(iu)) {
iu.style.display = 'block';
++count;
} else {
iu.style.display = 'none';
}
message.innerHTML = "";
}
catch (err) {
var errMessage = err.message;
message.innerHTML = errMessage;
break;
}
}
if (count == 0 && message.innerHTML == '') {
message.innerHTML = 'No matches';
}
}
function filterIU(className) {
var e = document.getElementById('subset');
var matchText = e.value;
var count = 0;
var ius = document.getElementsByClassName('iu-li');
var targets = document.getElementsByClassName(className);
var targetsArray = [].slice.call(targets);
for (var i = 0; i < ius.length; i++) {
var iu = ius[i];
if (!targetsArray.includes(iu)) {
iu.style.display = 'none';
} else {
try
{
if (matchText != '' && iu.textContent.match(matchText) == null) {
iu.style.display = 'none';
continue;
}
}
catch (err) {
}
iu.style.display = 'block';
++count;
}
}
var message = document.getElementById('subset-error');
if (count == 0) {
message.innerHTML = 'No matches';
} else {
message.innerHTML = '';
}
}
function copyToClipboard(element) {
var $temp = $("<input>");
$("body").append($temp);
$temp.val($(element).text()).select();
document.execCommand("copy");
$temp.remove();
}
function clickOnButton(id) {
var e = document.getElementById(id);
e.click();
}
function clickOnToggleButton(id) {
var e = document.getElementById(id);
var state = e.innerHTML;
if (e.innerHTML == '<%='\u25B7'%>'){
e.click();
}
}
function navigateTo(id) {
var e = document.getElementById(id);
e.scrollIntoView();
}
function toggle(id) {
var e = document.getElementById(id);
if (e.title == 'Expand All') {
e.title= 'Collapse All';
e.innerHTML = '&#x25E2;';
} else {
e.title= 'Expand All';
e.innerHTML = '&#x25B7;';
}
}
function expand2(self, id) {
var t = document.getElementById(self);
var e = document.getElementById(id);
var f = document.getElementById(id+"_arrows");
if (t.title == 'Collapse All'){
e.style.display = 'block';
f.innerHTML = '&#x25E2;';
} else {
e.style.display = 'none';
f.innerHTML = '&#x25B7;';
}
}
function expand3(self, id) {
var t = document.getElementById(self);
var e = document.getElementById(id);
var f = document.getElementById(id+"_arrows");
if (t.title != 'Collapse All'){
e.style.display = 'none';
f.innerHTML = '&#x25B7;';
}
}
function expand(id) {
var t = document.getElementById('all');
var e = document.getElementById(id);
var f = document.getElementById(id+"_arrows");
if (t.title == 'Collapse All'){
e.style.display = 'block';
f.innerHTML = '&#x25E2;';
} else {
e.style.display = 'none';
f.innerHTML = '&#x25B7;';
}
}
function expand_collapse(id) {
var e = document.getElementById(id);
var f = document.getElementById(id+"_arrows");
if (e.style.display == 'none'){
e.style.display = 'block';
f.innerHTML = '&#x25E2;';
} else {
e.style.display = 'none';
f.innerHTML = '&#x25B7;';
}
}
function expand_collapse_inline(id) {
var e = document.getElementById(id);
var f = document.getElementById(id+"_arrows");
if (e.style.display == 'none'){
e.style.display = 'inline';
if (f != null) {
f.innerHTML = '&#x25E2;';
}
} else {
e.style.display = 'none';
if (f !=null) {
f.innerHTML = '&#x25B7;';
}
}
}
function expand_collapse_inline_block(id) {
var e = document.getElementById(id);
var f = document.getElementById(id+"_arrows");
if (e.style.display == 'none'){
e.style.display = 'inline-block';
if (f != null) {
f.innerHTML = '&#x25E2;';
}
} else {
e.style.display = 'none';
if (f !=null) {
f.innerHTML = '&#x25B7;';
}
}
}
function expand_collapse_all(base) {
var e = document.getElementById(base);
var buttonTargets = document.getElementsByClassName(base + '_button');
var spanTargets = document.getElementsByClassName(base);
if (e.innerHTML == '\u25E2') {
e.innerHTML = '&#x25B7;';
for (var i = 0; i < buttonTargets.length; i++) {
buttonTargets.item(i).innerHTML = '&#x25B7;';
}
for (var i = 0; i < spanTargets.length; i++) {
spanTargets.item(i).style.display = 'none';
}
} else {
e.innerHTML = '&#x25E2;';
for (var i = 0; i < buttonTargets.length; i++) {
buttonTargets.item(i).innerHTML = '&#x25E2;';
}
for (var i = 0; i < spanTargets.length; i++) {
spanTargets.item(i).style.display = 'inline-block';
}
}
}
</script>
<header role="banner" id="header-wrapper">
<div class="container">
<div class="row" id="header-row">
<div class="hidden-xs col-sm-8 col-md-6 col-lg-5" id="header-left">
<div class="wrapper-logo-default">
<a href="https://www.eclipse.org/">
<img class="logo-eclipse-default img-responsive hidden-xs" alt="Eclipse Log" src="https://www.eclipse.org/eclipse.org-common/themes/solstice/public/images/logo/eclipse-426x100.png"/>
</a>
</div>
</div>
</div>
</div>
</header>
<%-[Breadcrumb]-%>
<section class="hidden-print default-breadcrumbs" id="breadcrumb">
<div class="container">
<h3 class="sr-only">Breadcrumbs</h3>
<div class="row">
<div class="col-sm-16 padding-left-30">
<ol class="breadcrumb">
<li><a href="https://www.eclipse.org/">Home</a></li>
<li><a href="https://www.eclipse.org/downloads/">Downloads</a></li>
<%for (Map.Entry<String, String> entry : reporter.getBreadcrumbs().entrySet()) {%>
<%if (entry.getValue() == null) {%>
<li class="active"><%=entry.getKey()%></li>
<%} else {%>
<li><a href="<%=entry.getValue()%>"><%=entry.getKey()%></a></li>
<%}%>
<%}%>
</ol>
</div>
</div>
</div>
</section>
<main class="no-promo">
<div class="novaContent container" id="novaContent">
<%-[NavigationBar]-%>
<!-- navigation sidebar -->
<aside id="leftcol" class="col-md-4 font-smaller">
<ul id="leftnav" class="ul-left-nav fa-ul hidden-print">
<li class="separator">
<a class="separator" href="https://www.eclipse.org">Home</a>
</li>
<li class="separator">
<a class="separator" href="https://www.eclipse.org/downloads">Downloads</a>
</li>
<%for (Map.Entry<String, String> entry : reporter.getBreadcrumbs().entrySet()) {%>
<%if (entry.getValue() != null) {%>
<li class="separator">
<a class="separator" href="<%=entry.getValue()%>"><%=entry.getKey()%></a>
</li>
<%} else {
if (iuReport == null) {%>
<li class="separator">
<tt style="float: right;" class="orange">&#xab;</tt>
<a class="separator" href="."><%=entry.getKey()%></a>
</li>
<%}
break;
}%>
<%}%>
<%for (Map.Entry<String, String> entry : reporter.getNavigation().entrySet()) {
String label = entry.getValue();
int index = label.indexOf('@');
if (index != -1)
label = label.substring(0, label.length() - 1);
{%>
<li class="separator" style="font-size: 90%;">
<tt style="float: left;" class="orange">&#xbb;</tt>
<%if (index != -1) {%>
<tt style="float: right;" class="orange">&#xab;</tt>
<%}%>
<a class="separator" style="display: inline-block; margin-left: 0.25em;" href="<%=entry.getKey()%>">
<%=label%>
</a>
</li>
<%}%>
<%}%>
</ul>
</aside>
<div id="maincontent">
<div id="midcolumn" style="width: 70%;">
<%if (iuReport == null) {%>
<h2 style="text-align: center;"><%=reporter.getTitle(true)%></h2>
<%} else {%>
<h2 style="text-align: center;">
<img class="fit-image" src="../<%=report.getIUImage(iuReport.getIU())%>"/>
<%String name = report.getName(iuReport.getIU(), false);
if (name != null) {%>
<%=helper.htmlEscape(name, true)%><br/>
<%} else {%>
No Name<br/>
<%}%>
<%=reporter.getTitle(true)%>
</h2>
<%}%>
<p style="font-size: 125%; text-align: center;">
<%-[Prelude]-%>
<%if (report != null && report.getDate() != null) {%>
<b>Built: <%=report.getDate()%></b>
<%}%>
<br/><b>Reported: <%=reporter.getNow()%></b>
</p>
<%if (report != null && !report.getSiteURL().startsWith("file:")) {%>
<p style="text-align: center;">
<button title="Copy to Clipboard" class="orange bb" style="font-size: 150%;" onclick="copyToClipboard('#p1')">&#x270e;</button>
<span id="p1" style="font-size: 125%"><%=report.getSiteURL()%></span>
</p>
<br/>
<%}%>
<a style="float:right; font-size: 200%;" href="<%=reporter.getHelpLink()%>" target="oomph_wiki"/>
<img src="<%=reporter.getReportBrandingImage()%>" alt=""/><img style="margin-top: -2ex;" class="fit-image" src="<%=reporter.getHelpImage()%>" alt=""/>
</a>
<%-[Index]-%>
<%if (indexReport != null) {%>
<p>
This is a generated
<a href="https://wiki.eclipse.org/Oomph_Repository_Analyzer#Description" target="oomph_wiki">
<img class="fit-image" src="<%=reporter.getHelpImage()%>"/>
<%=reporter.getHelpText()%></a> report.
</p>
<p>This report is produced by <a href="<%=reporter.getReportSource()%>" target="report_source"><%=reporter.getReportSource()%></a>.</p>
<%Map<String, String> allReports = indexReport.getAllReports();
if (allReports != null && !allReports.isEmpty()) {%>
<p>Reports are generated specifically for the following sites:</p>
<ul>
<%for (Map.Entry<String, String> entry : allReports.entrySet()) {%>
<li><a href="<%=entry.getValue()%>"><%=entry.getKey()%></a></li>
<%}%>
</ul>
<%}%>
<%} else if (iuReport != null) {%>
<%-[IU]-%>
<p>
This
<a href="<%=reporter.getHelpLink()%>" target="oomph_wiki">
<img class="fit-image" src="<%=reporter.getHelpImage()%>"/>
<%=reporter.getHelpText()%></a>
report is produced by <a href="<%=report.getReportSource()%>" target="report_source"><%=report.getReportSource()%></a>.
</p>
<%String provider = iuReport.getProvider();
if (provider != null) {%>
<h3 style="font-weight: bold;">Provider</h3>
<p><%=helper.htmlEscape(provider, false)%></p>
<%}%>
<%String description = iuReport.getDescription();
if (description != null) {%>
<h3 style="font-weight: bold;">Description</h3>
<p><%=helper.htmlEscape(description, false)%></p>
<%}%>
<%Map<String, Boolean> artifacts = report.getIUArtifacts(iuReport.getIU());
if (!artifacts.isEmpty()) {
Set<PGPPublicKey> pgpKeys = report.getPGPKeys(iuReport.getIU());
if (!pgpKeys.isEmpty()) {%>
<h3 style="font-weight: bold;">
PGP Keys
</h3>
<%for (PGPPublicKey pgpPublicKey : pgpKeys) {
String fingerPrint = PGPPublicKeyService.toHexFingerprint(pgpPublicKey);%>
<div class="font-smaller">
<img alt="Signed" class="fit-image" src="../<%=report.getSignedImage(true)%>"/>
<span class="text-nowrap"><a href="<%=report.getKeyServerURL(pgpPublicKey)%>" target="keyserver">0x<%=fingerPrint%></a></span>
</div>
<%}
}
Set<List<Certificate>> allCertificates = report.getCertificates(iuReport.getIU());
if (!allCertificates.isEmpty()) {
Set<Certificate> expiredCertificates = new HashSet<Certificate>();
for (List<Certificate> certificates : allCertificates) {
for (Certificate certificate : certificates) {
if (report.isExpired(certificate)) {
expiredCertificates.add(certificate);
}
break;
}
}%>
<h3 style="font-weight: bold;">
Certificates
<%if (!expiredCertificates.isEmpty()) {%>
<span style="color: FireBrick; font-size: 60%;">(<%=expiredCertificates.size()%> Expired Certificate<%if (expiredCertificates.size() > 1) {%>s<%}%>)</span>
<%}%>
</h3>
<%for (List<Certificate> certificates : allCertificates) {%>
<%if (certificates.isEmpty()) {%>
<div>
<img class="fit-image" src="../<%=report.getSignedImage(false)%>"/>
<span style="color: FireBrick;">Unsigned</span>
</div>
<%} else {%>
<%int count = 0;
for (Certificate certificate : certificates) {
Map<String, String> components = report.getCertificateComponents(certificate);%>
<div class="font-smaller" style="margin-left: <%=count++%>em;">
<img alt="Signed" class="fit-image" src="../<%=report.getSignedImage(true)%>"/>
<%for (Map.Entry<String, String> component : components.entrySet()) {
String key = component.getKey();
String value = component.getValue();
String keyStyle;
String spanStyle;
if ("to".equals(key) && expiredCertificates.contains(certificate)) {
keyStyle = "color: Firebrick; ";
spanStyle = " style='font-weight: bold; color: Firebrick;'";
} else {
keyStyle = "color: SteelBlue; ";
spanStyle = "";
}%>
<span class="text-nowrap"<%=spanStyle%>><span style="<%=keyStyle%>font-size: 75%;"><%=key%>=</span><%=value%></span>
<%}%>
</div>
<%}%>
<%}%>
<%}%>
<%}%>
<h3 style="font-weight: bold;">Artifacts</h3>
<%for (Map.Entry<String, Boolean> entry : artifacts.entrySet()) {
String artifact = entry.getKey();
Boolean signed = entry.getValue();%>
<p>
<%if (signed != null) {%>
<img class="fit-image" src="../<%=report.getSignedImage(signed)%>"/>
<%}%>
<img class="fit-image" src="../<%=report.getArtifactImage(artifact)%>"/>
<span style="color: DarkCyan;"><%=report.getArtifactSize(artifact)%></span>
<a href="<%=report.getRepositoryURL(artifact) + '/' + artifact%>"><%=artifact%></a>
<%for (String status : report.getArtifactStatus(artifact)) {%>
<br/>
<span style="color: FireBrick; font-size: 90%;"><%=status%></span>
<%}%>
</p>
<%}%>
<%}%>
<%List<Report.LicenseDetail> licenses = report.getLicenses(iuReport.getIU());
if (licenses != null) {%>
<h3 style="font-weight: bold;">Licenses</h3>
<%for (LicenseDetail license : licenses) {%>
<%String id = license.getUUID();
String backgroundColor = license.isSUA() ? "HoneyDew" : license.isMatchedSUA() ? "SeaShell" : "MistyRose";
String replacementFontSize = !license.getReplacement().isEmpty() && license.getReplacement().length() < 5 ? "font-size: 300%;" : "";
String mismatchingFontSize = license.getMismatching().length() < 5 ? "font-size: 300%;" : "";%>
<button id="__<%=id%>_arrows" class="orange bb" onclick="expand_collapse('__<%=id%>');">&#x25B7;</button>
<img class="fit-image" src="../<%=report.getLicenseImage()%>"/>
<span style="<%=helper.getStyle(license)%>"><%=license.getVersion()%></span>
<%=id%>
<pre id="__<%=id%>" style="display:none; margin-left: 2em; background-color: <%=backgroundColor%>"><%=license.getMatchingPrefix()%><span style="color: red; text-decoration: line-through; <%=mismatchingFontSize%>"><%=license.getMismatching()%></span><span style="color: green; text-decoration: underline; <%=replacementFontSize%>"><%=license.getReplacement()%></span><%=license.getMatchingSuffix()%></pre>
<%}%>
<%}%>
<h3 style="font-weight: bold;">
Content Metadata
<button id="xml-links" class="orange bb" onclick="expand_collapse_all('xml-links');">&#x25B7;</button>
</h3>
<div class="xml-iu" style="display:block;">
<%for (String xml : report.getXML(iuReport.getIU(), Collections.<String, String> emptyMap())) {%>
<!-----------><%=xml%>
<%}%>
</div>
<%} else {%>
<p>
This
<a href="<%=report.getHelpLink()%>" target="oomph_wiki">
<img class="fit-image" src="<%=reporter.getHelpImage()%>"/>
<%=report.getHelpText()%></a>
report is produced by <a href="<%=report.getReportSource()%>" target="report_source"><%=report.getReportSource()%></a>.
</p>
<%List<Report> children = report.getChildren();
if (!children.isEmpty()) {%>
<p>
<%if (!report.isRoot()) {%>
This is a composite update site.
<%}%>
In addition to this composite report, reports are also generated for each of the composed children listed in the navigation bar to the left.
</p>
<%}%>
<%-[RepositoryXML]-%>
<%String metadataXML = report.getMetadataXML();
String artifactXML = report.getArtifactML();
if (metadataXML != null || artifactXML != null) {%>
<h3 style="font-weight: bold;">
<button id="repos_arrows" class="orange bb" onclick="expand_collapse('repos');">&#x25B7;</button>
<img class="fit-image" src="<%=report.getRepositoryImage()%>"/>
XML
<%if (metadataXML != null && metadataXML.contains("bad-absolute-location") || artifactXML != null && artifactXML.contains("bad-absolute-location")) {%>
<span style="color: FireBrick; font-size: 60%;">(Inappropriate absolute location)</span>
<%}%>
</h3>
<div class="xml-repo" id="repos" style="display: none;">
<%if (metadataXML != null) {%>
<!-----------><%=metadataXML%>
<%}%>
<%if (artifactXML != null) {%>
<%if (metadataXML != null) {%>
<%}%>
<!-----------><%=artifactXML%>
<%}%>
</div>
<%}%>
<%-[License]-%>
<%Map<LicenseDetail, Set<IInstallableUnit>> licenses = report.getLicenses();
if (!licenses.isEmpty()) {
String display = "block";
String displayButton = "inline";
int nonConformant = 0;
for (LicenseDetail license : licenses.keySet()) {
if (!license.isSUA())
++nonConformant;
}
String licenseImage = report.getLicenseImage();%>
<h3 style="font-weight: bold;">
<button id="licenses_arrows" class="orange bb" onclick="expand_collapse('licenses'); expand_collapse_inline('licenses_all_arrows');">&#x25B7;</button>
<img class="fit-image" src="<%=licenseImage%>"/>
Licenses
<span style="color: DarkCyan;"><%=licenses.size()%></span>
<%if (nonConformant != 0) {%>
<span style="color: FireBrick; font-size: 60%;">(<%=nonConformant%> Invalid Licenses)</span>
<%}%>
<%{
StringBuilder onClick = new StringBuilder();
for (LicenseDetail license : licenses.keySet()) {
String id = license.getUUID();
onClick.append("expand2('licenses_all_arrows', '").append("_" + id).append("');");
onClick.append("expand2('licenses_all_arrows', '").append("__" + id).append("');");
onClick.append("expand3('licenses_all_arrows', '").append("_f" + id).append("');");
}%>
<button id="licenses_all_arrows" title="Expand All" class="orange bb" style="display: <%=displayButton%>;" onclick="toggle('licenses_all_arrows');<%=onClick%>">&#x25B7;</button>
<%}%>
</h3>
<ul id="licenses" style="display: <%=display%>; margin-left: -1em; list-style-type: none; padding: 0; margin: 0;">
<%for (Map.Entry<LicenseDetail, Set<IInstallableUnit>> entry : licenses.entrySet()) {
LicenseDetail license = entry.getKey();
String id = license.getUUID();
Set<IInstallableUnit> ius = entry.getValue();
String backgroundColor = license.isSUA() ? "HoneyDew" : license.isMatchedSUA() ? "SeaShell" : "MistyRose";
String replacementFontSize = !license.getReplacement().isEmpty() && license.getReplacement().length() < 5 ? "font-size: 300%;" : "";
String mismatchingFontSize = license.getMismatching().length() < 5 ? "font-size: 300%;" : "";
{%>
<li>
<button id="__<%=id%>_arrows" class="orange bb" style="margin-left: 1em;" onclick="expand_collapse('__<%=id%>');">&#x25B7;</button>
<img class="fit-image" src="<%=licenseImage%>"/>
<span style="<%=helper.getStyle(license)%>"><%=license.getVersion()%></span>
-
<span style="color: DarkCyan;"><%=ius.size()%></span>
<ul style="display:none; list-style-type: none; padding: 0; margin: 0;" id="__<%=id%>">
<li style="margin-left: 1em;">
<button id="_<%=id%>_arrows" class="orange bb" style="margin-left: 1em;" onclick="expand_collapse('_<%=id%>');">&#x25B7;</button>
<%=id%><br/>
<pre id="_<%=id%>" style="display:none; margin-left: 2em; background-color: <%=backgroundColor%>"><%=license.getMatchingPrefix()%><span style="color: red; text-decoration: line-through; <%=mismatchingFontSize%>"><%=license.getMismatching()%></span><span style="color: green; text-decoration: underline; <%=replacementFontSize%>"><%=license.getReplacement()%></span><%=license.getMatchingSuffix()%></pre>
</li>
<li style="margin-left: 1em;">
<button id="_f<%=id%>_arrows" class="orange bb" style="margin-left: 1em;" onclick="expand_collapse('_f<%=id%>');">&#x25B7;</button>
Features/Products
<ul style="list-style-type: none; display:none; padding: 0; margin: 0; margin-left: 2em;" id="_f<%=id%>">
<%for (IInstallableUnit iu : ius) {%>
<li class="font-smaller text-nowrap">
<a href="<%=report.getRelativeIUReportURL(iu)%>">
<img class="fit-image" src="<%=report.getIUImage(iu)%>"/>
<%=helper.htmlEscape(report.getName(iu, true), true)%>
<span style="color: DarkOliveGreen;"><%=report.getVersion(iu)%></span>
</a>
</li>
<%}%>
</ul>
</li>
</ul>
</li>
<%}%>
<%}%>
</ul>
<%}%>
<%-[PGP Keys]-%>
<%Map<PGPPublicKey, Map<String, IInstallableUnit>> pgpKeys = report.getPGPKeys();
if (!pgpKeys.isEmpty()) {
int idCount = 0;
boolean isInitiallyExpanded = false;
String display = isInitiallyExpanded ? "block" : "none";
String displayButton = isInitiallyExpanded ? "inline" : "none";%>
<p></p>
<h3 style="font-weight: bold;">
<button id="pgpKeys_arrows" class="orange bb" onclick="expand_collapse('pgpKeys'); expand_collapse_inline('pgpKeys_all_arrows');">&#x25B7;</button>
<img class="fit-image" src="<%=report.getSignedImage(true)%>"/>
Signing PGP Keys
<span style="color: DarkCyan;"><%=pgpKeys.size()%></span>
<%{
StringBuilder onClick = new StringBuilder();
for (int i = 0, size = pgpKeys.size(); i < size; ++i) {
String id = "pgpKeys" + ++idCount;
onClick.append("expand2('pgpKeys_all_arrows', '").append(id).append("');");
}
idCount = 0;%>
<button id="pgpKeys_all_arrows" title="Expand All" class="orange bb" style="display: <%=displayButton%>;" onclick="toggle('pgpKeys_all_arrows');<%=onClick%>">&#x25B7;</button>
<%}%>
</h3>
<ul id="pgpKeys" style="display:<%=display%>; margin-left: -1em; list-style-type: none;">
<%for (Map.Entry<PGPPublicKey, Map<String, IInstallableUnit>> entry : pgpKeys.entrySet()) {
PGPPublicKey pgpPublicKey = entry.getKey();
String fingerPrint = PGPPublicKeyService.toHexFingerprint(pgpPublicKey);
String id = "pgpKeys" + ++idCount;%>
<li>
<div class="font-smaller" style="margin-left: <%=2%>em; text-indent: -4em;">
<button id="<%=id%>_arrows" class="orange bb" style="margin-left: 1em;" onclick="expand_collapse('<%=id%>');">&#x25B7;</button>
<img alt="Signed" class="fit-image" src="<%=report.getSignedImage(true)%>"/>
<span class="text-nowrap"><a href="<%=report.getKeyServerURL(pgpPublicKey)%>" target="keyserver">0x<%=fingerPrint%></a></span>
<span style="color: DarkCyan; font-size: 110%;">(<%=entry.getValue().size()%>)</span>
</div>
<ul class="font-smaller" style="list-style-type: none; display:none; margin-left: -3em;" id="<%=id%>">
<%Map<String, IInstallableUnit> artifacts = entry.getValue();
for (Map.Entry<String, IInstallableUnit> artifact : artifacts.entrySet()) {%>
<li>
<a href="<%=report.getRelativeIUReportURL(artifact.getValue())%>"><img class="fit-image" src="<%=report.getIUImage(artifact.getValue())%>"/> <%=artifact.getKey()%></a>
</li>
<%}%>
</ul>
</li>
<%}%>
</ul>
<%}%>
<%-[Certificates]-%>
<%Map<List<Certificate>, Map<String, IInstallableUnit>> allCertificates = report.getCertificates();
if (!allCertificates.isEmpty()) {
int idCount = 0;
Map<String, IInstallableUnit> unsigned = allCertificates.get(Collections.emptyList());
int expiredChainCount = 0;
Set<Certificate> expiredCertificates = new HashSet<Certificate>();
for (List<Certificate> list : allCertificates.keySet()) {
boolean expired = false;
for (Certificate certificate : list) {
if (report.isExpired(certificate)) {
expiredCertificates.add(certificate);
expired = true;
}
}
if (expired) {
++expiredChainCount;
}
}
boolean isInitiallyExpanded = false;
String display = isInitiallyExpanded ? "block" : "none";
String displayButton = isInitiallyExpanded ? "inline" : "none";%>
<p></p>
<h3 style="font-weight: bold;">
<button id="certificates_arrows" class="orange bb" onclick="expand_collapse('certificates'); expand_collapse_inline('certificates_all_arrows');">&#x25B7;</button>
<img class="fit-image" src="<%=report.getSignedImage(true)%>"/>
Signing Certificates
<span style="color: DarkCyan;"><%=allCertificates.size()%></span>
<%if (unsigned != null) {%>
<span style="color: FireBrick; font-size: 60%;">(<%=unsigned.size()%> Unsigned Artifacts)</span>
<%}%>
<%if (expiredChainCount > 0) {%>
<span style="color: FireBrick; font-size: 60%;">(<%=expiredChainCount%> Expired)</span>
<%}%>
<%{
StringBuilder onClick = new StringBuilder();
for (int i = 0, size = allCertificates.size(); i < size; ++i) {
String id = "certificates" + ++idCount;
onClick.append("expand2('certificates_all_arrows', '").append(id).append("');");
}
idCount = 0;%>
<button id="certificates_all_arrows" title="Expand All" class="orange bb" style="display: <%=displayButton%>;" onclick="toggle('certificates_all_arrows');<%=onClick%>">&#x25B7;</button>
<%}%>
</h3>
<ul id="certificates" style="display:<%=display%>; margin-left: -1em; list-style-type: none;">
<%for (Map.Entry<List<Certificate>, Map<String, IInstallableUnit>> entry : allCertificates.entrySet()) {
List<Certificate> certificates = entry.getKey();
String id = "certificates" + ++idCount;%>
<li>
<%if (certificates.isEmpty()) {%>
<div style="text-indent: -2em">
<button id="<%=id%>_arrows" class="orange bb" style="margin-left: 1em;" onclick="expand_collapse('<%=id%>');">&#x25B7;</button>
<img class="fit-image" src="<%=report.getSignedImage(false)%>"/>
<span style="color: FireBrick;">(<%=entry.getValue().size()%>) Unsigned</span>
</div>
<%} else {%>
<%int count = 0;
for (Certificate certificate : certificates) {
Map<String, String> components = report.getCertificateComponents(certificate);%>
<div class="font-smaller" style="margin-left: <%=count++ + 2%>em; text-indent: -4em;">
<%if (count == 1) {%>
<button id="<%=id%>_arrows" class="orange bb" style="margin-left: 1em;" onclick="expand_collapse('<%=id%>');">&#x25B7;</button>
<%} else {%>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<%}%>
<img alt="Signed" class="fit-image" src="<%=report.getSignedImage(true)%>"/>
<%if (count == 1) {%>
<span style="color: DarkCyan; font-size: 110%;">(<%=entry.getValue().size()%>)</span>
<%}%>
<%for (Map.Entry<String, String> component : components.entrySet()) {
String key = component.getKey();
String value = component.getValue();
String keyStyle;
String spanStyle;
if ("to".equals(key) && expiredCertificates.contains(certificate)) {
keyStyle = "color: Firebrick; ";
spanStyle = " style='font-weight: bold; color: Firebrick;'";
} else {
keyStyle = "color: SteelBlue; ";
spanStyle = "";
}%>
<span class="text-nowrap"<%=spanStyle%>><span style="<%=keyStyle%>font-size: 75%;"><%=key%>=</span><%=value%></span>
<%}%>
</div>
<%}%>
<%}%>
<ul class="font-smaller" style="list-style-type: none; display:none; margin-left: -3em;" id="<%=id%>">
<%Map<String, IInstallableUnit> artifacts = entry.getValue();
for (Map.Entry<String, IInstallableUnit> artifact : artifacts.entrySet()) {%>
<li>
<a href="<%=report.getRelativeIUReportURL(artifact.getValue())%>"><img class="fit-image" src="<%=report.getIUImage(artifact.getValue())%>"/> <%=artifact.getKey()%></a>
</li>
<%}%>
</ul>
</li>
<%}%>
</ul>
<%}%>
<!--- providers -->
<%-[Providers]-%>
<%Map<String, Set<IInstallableUnit>> featureProviders = report.getFeatureProviders();
if (!featureProviders.isEmpty()) {
int nonEclipse = 0;
for (String provider : featureProviders.keySet()) {
if (!provider.toLowerCase().contains("eclipse"))
++nonEclipse;
}%>
<p></p>
<h3 style="font-weight: bold;">
<button id="feature_providers_arrows" class="orange bb" onclick="expand_collapse('feature_providers');">&#x25B7;</button>
<img class="fit-image" src="<%=report.getProviderImage()%>"/>
Providers
<span style="color: DarkCyan;"><%=featureProviders.size()%></span>
<%if (nonEclipse != 0) {%>
<span style="color: FireBrick; font-size: 60%;">(<%=nonEclipse%> Not Provided by Eclipse)</span>
<%}%>
</h3>
<ul id="feature_providers" style="display:none; margin-left: -2em; list-style-type: none;">
<%int count = 0;
for (Map.Entry<String, Set<IInstallableUnit>> provider : featureProviders.entrySet()) {
String style = !provider.getKey().toLowerCase().contains("eclipse") ? " style=\"color: FireBrick;\"" : "";
Set<IInstallableUnit> features = provider.getValue();
String id = "nested_feature_providers" + ++count;%>
<li>
<button id="<%=id%>_arrows" class="orange bb" onclick="expand_collapse('<%=id%>');">&#x25B7;</button>
<%for (String image : report.getBrandingImages(features)) {%>
<img alt="Branding Image" class="fit-image" src="<%=image%>"/>
<%}%>
<span <%=style%>><%=provider.getKey()%></span>
<span style="color: DarkCyan;"><%=features.size()%></span>
<ul id="<%=id%>" style="display:none; margin-left: -2em; list-style-type: none;">
<%for (IInstallableUnit feature : features) {
String brandingImage = report.getBrandingImage(feature);%>
<li>
<a href="<%=report.getRelativeIUReportURL(feature)%>">
<img alt="Branding Image" class="fit-image" src="<%=brandingImage%>"/>
<%=helper.htmlEscape(report.getName(feature, true), true)%>
<span style="color: DarkOliveGreen;"><%=report.getVersion(feature)%></span>
</a>
</li>
<%}%>
</ul>
</li>
<%}%>
</ul>
<%}%>
<%-[Features]-%>
<%List<IInstallableUnit> features = report.getFeatureIUs();
if (!features.isEmpty()) {
int brokenBranding = 0;
int noBranding = 0;
for (IInstallableUnit feature : features) {
if (report.hasBrokenBrandingImage(feature))
++brokenBranding;
else if (!report.hasBrandingImage(feature))
++noBranding;
}%>
<p></p>
<h3 style="font-weight: bold;">
<button id="features_arrows" class="orange bb" onclick="expand_collapse('features');">&#x25B7;</button>
<img class="fit-image" src="<%=report.getFeatureImage()%>"/>
Features
<span style="color: DarkCyan;"><%=features.size()%></span>
<%if (brokenBranding != 0) {%>
<span style="color: FireBrick; font-size: 60%;">(<%=brokenBranding%> Broken Branding Images)</span>
<%}%>
<%if (noBranding != 0) {%>
<span style="color: FireBrick; font-size: 60%;">(<%=noBranding%> No Branding Images)</span>
<%}%>
</h3>
<ul id="features" style="display: none; list-style-type: none; margin-left: -2em;">
<%for (IInstallableUnit feature : features) {
String brandingImage = report.getBrandingImage(feature);%>
<li style="font-size: 100%; white-space: nowrap;">
<a href="<%=report.getRelativeIUReportURL(feature)%>">
<img class="fit-image" src="<%=brandingImage%>"/>
<%=helper.htmlEscape(report.getName(feature, true), true)%>
<span style="color: DarkOliveGreen;"><%=report.getVersion(feature)%></span>
</a>
<%Map<String, String> licenseReplacements = new HashMap<String, String>();
for (LicenseDetail license : report.getLicenses(feature)) {
String id = license.getUUID();
licenseReplacements.put(">" + id, "><button class='bb search-for-me' style='" + helper.getStyle(license) + "' onclick=\"clickOnButton('lic_" + id
+ "');\">" + license.getVersion() + "</button>");%>
<button id="lic_<%=id%>" class="bb" style="<%=helper.getStyle(license)%>" onclick="clickOnToggleButton('licenses_arrows'); clickOnToggleButton('__<%=id%>_arrows'); clickOnToggleButton('_<%=id%>_arrows'); navigateTo('_<%=id%>');"><%=license.getVersion()%></button>
<%}%>
</li>
<%}%>
</ul>
<%}%>
<%-[Products]-%>
<%Collection<IInstallableUnit> products = report.getProducts();
if (!products.isEmpty()) {
boolean isInitiallyExpanded = false;
String display = isInitiallyExpanded ? "block" : "none";
String displayButton = isInitiallyExpanded ? "inline" : "none";%>
<p></p>
<h3 style="font-weight: bold;">
<button id="products_arrows" class="orange bb" onclick="expand_collapse('products'); expand_collapse_inline('products_all_arrows');">&#x25B7;</button>
<img class="fit-image> src="<%=report.getProductImage()%>"/>
Products
<span style="color: DarkCyan;"><%=products.size()%></span>
<%{
StringBuilder onClick = new StringBuilder();
for (IInstallableUnit product : products) {
String productID = "_product_" + report.getIUID(product);
onClick.append("expand2('products_all_arrows', '").append(productID).append("');");
}%>
<button id="products_all_arrows" title="Expand All" class="orange bb" style="display: <%=displayButton%>;" onclick="toggle('products_all_arrows');<%=onClick%>">&#x25B7;</button>
<%}%>
</h3>
<ul id="products" style="display: <%=display%>; margin-left: -1em; list-style-type: none; padding: 0; margin: 0;">
<%for (IInstallableUnit product : products) {
String productImage = report.getIUImage(product);
String productID = "_product_" + report.getIUID(product);
Set<IInstallableUnit> requiredIUs = report.getSortedByName(report.getResolvedRequirements(product));%>
<li style="font-size: 100%; white-space: nowrap;">
<%if (!requiredIUs.isEmpty()) {%>
<button id="<%=productID%>_arrows" class="orange bb" style="margin-left: 1em;" onclick="expand_collapse('<%=productID%>');">&#x25B7;</button>
<%}%>
<a href="<%=report.getRelativeIUReportURL(product)%>">
<img class="fit-image" src="<%=productImage%>"/>
<%=helper.htmlEscape(report.getName(product, true), true)%>
<span style="color: DarkOliveGreen;"><%=report.getVersion(product)%></span>
</a>
<%if (!requiredIUs.isEmpty()) {%>
<ul class="font-smaller" id="<%=productID%>" style="display: none;">
<%for (IInstallableUnit requiredIU : requiredIUs) {%>
<li>
<a href="<%=report.getRelativeIUReportURL(requiredIU)%>">
<img class="fit-image" src="<%=report.getIUImage(requiredIU)%>"/>
<%=helper.htmlEscape(report.getName(requiredIU, true), true)%>
<span style="color: DarkOliveGreen;"><%=report.getVersion(requiredIU)%></span>
</a>
</li>
<%}%>
</ul>
<%}%>
</li>
<%}%>
</ul>
<%}%>
<%-[Categories]-%>
<%Collection<IInstallableUnit> categories = report.getCategories();
if (!categories.isEmpty()) {
boolean isInitiallyExpanded = false;
String display = isInitiallyExpanded ? "block" : "none";
String displayButton = isInitiallyExpanded ? "inline" : "none";%>
<p></p>
<h3 style="font-weight: bold;">
<button id="categories_arrows" class="orange bb" onclick="expand_collapse('categories'); expand_collapse_inline('categories_all_arrows');">&#x25B7;</button>
<img class="fit-image" src="<%=report.getCategoryImage()%>"/>
Categories
<span style="color: DarkCyan;"><%=categories.size()%></span>
<%{
StringBuilder onClick = new StringBuilder();
for (IInstallableUnit category : categories) {
String categoryID = "_category_" + report.getIUID(category);
onClick.append("expand2('categories_all_arrows', '").append(categoryID).append("');");
}%>
<button id="categories_all_arrows" title="Expand All" class="orange bb" style="display: <%=displayButton%>;" onclick="toggle('categories_all_arrows');<%=onClick%>">&#x25B7;</button>
<%}%>
</h3>
<ul id="categories" style="display: <%=display%>; margin-left: -1em; list-style-type: none; padding: 0; margin: 0;">
<%for (IInstallableUnit category : categories) {
String categoryImage = report.getIUImage(category);
String categoryID = "_category_" + report.getIUID(category);
Set<IInstallableUnit> requiredIUs = report.getSortedByName(report.getResolvedRequirements(category));%>
<li style="font-size: 100%; white-space: nowrap;">
<%if (!requiredIUs.isEmpty()) {%>
<button id="<%=categoryID%>_arrows" class="orange bb" style="margin-left: 1em;" onclick="expand_collapse('<%=categoryID%>');">&#x25B7;</button>
<%}%>
<a href="<%=report.getRelativeIUReportURL(category)%>">
<img class="fit-image" src="<%=categoryImage%>"/>
<%=helper.htmlEscape(report.getName(category, true), true)%>
</a>
<%if (!requiredIUs.isEmpty()) {%>
<ul class="font-smaller" id="<%=categoryID%>" style="list-style-type: none; display: none; margin-left: -1em;">
<%for (IInstallableUnit requiredIU : requiredIUs) {%>
<li>
<a href="<%=report.getRelativeIUReportURL(requiredIU)%>">
<img class="fit-image" src="<%=report.getIUImage(requiredIU)%>"/>
<%=helper.htmlEscape(report.getName(requiredIU, true), true)%>
<span style="color: DarkOliveGreen;"><%=report.getVersion(requiredIU)%></span>
</a>
</li>
<%}%>
</ul>
<%}%>
</li>
<%}%>
</ul>
<%}%>
<%-[IUs]-%>
<%Collection<IInstallableUnit> ius = report.getAllIUs();
if (!ius.isEmpty()) {
Set<IInstallableUnit> unsignedIUs = report.getUnsignedIUs();
Set<IInstallableUnit> badProviderIUs = report.getBadProviderIUs();
Set<IInstallableUnit> badLicenseIUs = report.getBadLicenseIUs();
Set<IInstallableUnit> brokenBrandingIUs = report.getBrokenBrandingIUs();
Map<String, Set<Version>> iuVersions = report.getIUVersions();
boolean isSimple = report.isSimple();
int duplicateCount = 0;
if (isSimple) {
for (Map.Entry<String, Set<Version>> entry : iuVersions.entrySet()) {
if (entry.getValue().size() > 1 && !report.isDuplicationExpected(entry.getKey())) {
++duplicateCount;
}
}
}%>
<h3 style="font-weight: bold;">
<button id="ius_arrows" class="orange bb" onclick="expand_collapse('ius'); match('subset');">&#x25B7;</button>
<img class="fit-image" src="<%=report.getBundleImage()%>"/>
Installable Units
<span style="color: DarkCyan;"><%=ius.size()%></span>
<%if (duplicateCount > 0) {%>
<span style="color: FireBrick; font-size: 60%;">(<%=duplicateCount%> with Multiple Versions)</span>
<%}%>
</h3>
<div id="ius" style="display:none;">
<span style="margin-left: 1em;" class="nowrap">Filter Pattern: <input id="subset" type="text" oninput="match('subset');"> <span style="color: firebrick;" id="subset-error"></span></input></span><br/>
<%if (duplicateCount > 0 || !unsignedIUs.isEmpty() || !badProviderIUs.isEmpty() || !badLicenseIUs.isEmpty() || !brokenBrandingIUs.isEmpty()) {%>
<span style="margin-left: 1em;">
<input id="filter" type="radio" name="filter" value="all" class="filter" onclick="filterIU('iu-li');" checked="checked"> All </input>
<%if (!badLicenseIUs.isEmpty()) {%>
<input id="bad-license" type="radio" name="filter" value="bad-license" class="filter" onclick="filterIU('bad-license');"> Bad License </input>
<%}%>
<%if (!unsignedIUs.isEmpty()) {%>
<input id="unsigned" type="radio" name="filter" value="unsigned" class="filter" onclick="filterIU('unsigned');"> Unsigned </input>
<%}%>
<%if (!badProviderIUs.isEmpty()) {%>
<input id="bad-provider" type="radio" name="filter" value="bad-provider" class="filter" onclick="filterIU('bad-provider');"> Bad Provider </input>
<%}%>
<%if (!brokenBrandingIUs.isEmpty()) {%>
<input id="broken-branding" type="radio" name="filter" value="broken-branding" class="filter" onclick="filterIU('broken-branding');"> Broken Branding </input>
<%}%>
<%if (duplicateCount > 0) {%>
<input id="duplicates" type="radio" name="filter" value="duplicate" class="filter" onclick="filterIU('duplicate');"> Duplicates </input>
<%}%>
</span>
<%}%>
<ul style="list-style-type: none; padding: 0; margin-left: 1em;">
<%for (IInstallableUnit iu : ius) {
String iuID = iu.getId();
String id = report.getIUID(iu);
boolean duplicateVersions = isSimple && !report.isDuplicationExpected(iu.getId()) && iuVersions.get(iu.getId()).size() > 1;
String versionStyle = duplicateVersions ? " font-weight: bold;" : "";
StringBuilder classNames = new StringBuilder();
if (duplicateVersions) {
classNames.append(" duplicate");
}
if (unsignedIUs.contains(iu)) {
classNames.append(" unsigned");
}
if (badProviderIUs.contains(iu)) {
classNames.append(" bad-provider");
}
if (badLicenseIUs.contains(iu)) {
classNames.append(" bad-license");
}
if (brokenBrandingIUs.contains(iu)) {
classNames.append(" broken-branding");
}%>
<li id="_iu_<%=id%>" class="iu-li<%=classNames%> font-smaller">
<a href="<%=report.getRelativeIUReportURL(iu)%>">
<img class="fit-image" src="<%=report.getIUImage(iu)%>"/>
<span style="font-size:100%;"><%=iuID%></span>
<span style="color: DarkOliveGreen;<%=versionStyle%>"><%=report.getVersion(iu)%></span>
</a>
<%Map<String, String> licenseReplacements = new HashMap<String, String>();
if (report.isFeature(iu)) {
for (LicenseDetail license : report.getLicenses(iu)) {
String licenseID = license.getUUID();
licenseReplacements.put(">" + licenseID, "><button class='bb search-for-me' style='" + helper.getStyle(license)
+ "' onclick=\"clickOnButton('lic_" + licenseID + "');\">" + license.getVersion() + "</button>");%>
<button id="lic_<%=licenseID%>" class="bb" style="<%=helper.getStyle(license)%>" onclick="clickOnToggleButton('licenses_arrows'); clickOnToggleButton('__<%=licenseID%>_arrows'); clickOnToggleButton('_<%=licenseID%>_arrows'); navigateTo('_<%=licenseID%>');"><%=license.getVersion()%></button>
<%}%>
<%}%>
<%Map<String, Boolean> artifacts = report.getIUArtifacts(iu);
for (Map.Entry<String, Boolean> entry : artifacts.entrySet()) {
String artifact = entry.getKey();
Boolean signed = entry.getValue();%>
(
<%if (signed != null) {%>
<img class="fit-image" src="<%=report.getSignedImage(signed)%>"/>
<%}%>
<img class="fit-image" src="<%=report.getArtifactImage(artifact)%>"/>
<span style="color: DarkCyan;"><%=report.getArtifactSize(artifact)%></span>
)
<%}%>
<%String brandingImage = report.getBrandingImage(iu);
if (brandingImage != null) {%>
[<img class="fit-image" src="<%=brandingImage%>"/>]
<%}%>
</li>
<%}%>
</ul>
</div>
<div style="height: 40ex;">
</div>
<%}%>
<%}%>
</div>
</div>
</div>
</main>
</body>
</html>