Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
dpfmanager.conformancechecker.tiff.reporting.HtmlReport Maven / Gradle / Ivy
/**
* HtmlReport.java This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version; or, at your
* choice, under the terms of the Mozilla Public License, v. 2.0. SPDX GPL-3.0+ or MPL-2.0+.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License and the Mozilla Public License for more details.
You should
* have received a copy of the GNU General Public License and the Mozilla Public License along with
* this program. If not, see http://www.gnu.org/licenses/
* and at http://mozilla.org/MPL/2.0 .
NB: for the
* © statement, include Easy Innova SL or other company/Person contributing the code.
©
* 2015 Easy Innova, SL
*
* @author Víctor Muñoz Solà
* @version 1.0
* @since 23/7/2015
*/
package dpfmanager.conformancechecker.tiff.reporting;
import dpfmanager.conformancechecker.tiff.TiffConformanceChecker;
import dpfmanager.conformancechecker.tiff.implementation_checker.ImplementationCheckerLoader;
import dpfmanager.conformancechecker.tiff.implementation_checker.rules.RuleResult;
import dpfmanager.conformancechecker.tiff.implementation_checker.rules.model.RuleType;
import dpfmanager.shell.modules.report.core.IndividualReport;
import dpfmanager.shell.modules.report.core.ReportGenerator;
import com.easyinnova.tiff.model.Metadata;
import com.easyinnova.tiff.model.TagValue;
import com.easyinnova.tiff.model.TiffDocument;
import com.easyinnova.tiff.model.TiffTags;
import com.easyinnova.tiff.model.types.IFD;
import com.easyinnova.tiff.model.types.IPTC;
import com.easyinnova.tiff.model.types.XMP;
import com.easyinnova.tiff.model.types.abstractTiffType;
import org.apache.commons.lang.StringUtils;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
/**
* Created by easy on 05/05/2016.
*/
public class HtmlReport extends Report {
/**
* Parse an individual report to HTML.
*
* @param ir the individual report.
* @param mode the mode (1, 2).
*/
public String parseIndividual(IndividualReport ir, int mode, int id) {
String templatePath = "templates/individual.html";
String htmlBody = readFilefromResources(templatePath);
// Image
String fileName = getReportName("", ir.getFilePath(), id);
String imgPath = "img/" + fileName + ".jpg";
BufferedImage thumb = tiff2Jpg(ir.getFilePath());
if (thumb == null) {
imgPath = "img/noise.jpg";
}
htmlBody = StringUtils.replace(htmlBody, "##IMG_PATH##", encodeUrl(imgPath));
/**
* Basic info / divs conforms
*/
htmlBody = StringUtils.replace(htmlBody, "##IMG_NAME##", ir.getFileName());
htmlBody = StringUtils.replace(htmlBody, "##IMG_FILEPATH##", ir.getFilePath());
String divs = "";
for (String iso : ir.getCheckedIsos()) {
if (ir.hasValidation(iso) || ir.getErrors(iso).isEmpty()) {
divs += makeConformsText(ir, iso);
}
}
htmlBody = StringUtils.replace(htmlBody, "##DIVS_CONFORMS##", divs);
if (mode == 1) {
htmlBody = StringUtils.replace(htmlBody, "##CL_LINKR2##", "show");
htmlBody = StringUtils.replace(htmlBody, "##LINK2##", encodeUrl(new File(fileName).getName() + "_fixed.html"));
}
if (mode == 2) {
htmlBody = StringUtils.replace(htmlBody, "##CL_LINKR1##", "show");
htmlBody = StringUtils.replace(htmlBody, "##LINK1##", encodeUrl(new File(fileName).getName() + ".html"));
}
/**
* Table errors / warnings count
*/
String rowTmpl = "\n" +
" ##TITLE## \n" +
" ##ERR## \n" +
" ##WAR## \n" +
" ";
String rows = "";
for (String iso : ir.getIsosCheck()) {
if (ir.hasValidation(iso)) {
String name = ImplementationCheckerLoader.getIsoName(iso);
String row = rowTmpl;
int errorsCount = ir.getNErrors(iso);
int warningsCount = ir.getNWarnings(iso);
row = StringUtils.replace(row, "##TITLE##", name);
String difErr = ir.getCompareReport() != null ? getDif(ir.getCompareReport().getNErrors(iso), ir.getNErrors(iso)) : "";
String difWar = ir.getCompareReport() != null ? getDif(ir.getCompareReport().getNWarnings(iso), ir.getNWarnings(iso)) : "";
row = StringUtils.replace(row, "##ERR##", "" + errorsCount + difErr);
row = StringUtils.replace(row, "##WAR##", "" + warningsCount + difWar);
row = StringUtils.replace(row, "##ERR_CLASS##", errorsCount > 0 ? "error" : "info");
row = StringUtils.replace(row, "##WAR_CLASS##", warningsCount > 0 ? "warning" : "info");
rows += row;
}
}
htmlBody = StringUtils.replace(htmlBody, "##TABLE_RESUME_ERRORS##", rows);
/**
* Errors / Warnings resume
*/
String fullTmpl = "\n" +
"\t\t\t\t##CHECK##\n" +
"\t\t\t\t
\n" +
"\t\t\t\t\t
##TITLE##\n" +
"\t\t\t\t\t##CONTENT##\n" +
"\t\t\t\t\n" +
"\t\t\t
";
String checkInfos = " Show infos
";
String errorsTmpl = "\n" +
"\t\t\t\t \n" +
"\t\t\t\t Type \n" +
"\t\t\t\t ID \n" +
"\t\t\t\t Location \n" +
"\t\t\t\t Description \n" +
"\t\t\t\t \n" +
"\t\t\t\t ##ROWS##\n" +
"\t\t\t\t\t
";
String policyTmpl = "\n" +
"\t\t\t\t \n" +
"\t\t\t\t Type \n" +
"\t\t\t\t Rule \n" +
"\t\t\t\t Description \n" +
"\t\t\t\t \n" +
"\t\t\t\t ##ROWS##\n" +
"\t\t\t\t\t
";
String tdTmpl = "##ID## ##LOC## ##DESC## ";
String pcTmpl = "##LOC## ##DESC## ";
rows = "";
int count = 0;
for (String iso : ir.getIsosCheck()) {
if (ir.hasValidation(iso)) {
String name = ImplementationCheckerLoader.getIsoName(iso);
String row = fullTmpl, icon = "exclamation";
int errorsCount = ir.getNErrors(iso);
int warningsCount = ir.getNWarnings(iso);
int infosCount = ir.getNInfos(iso);
int addedRows = 0, addedInfos = 0;
if (errorsCount > 0){
icon = "fa-times-circle";
} else if (warningsCount > 0) {
icon = "fa-exclamation-circle";
} else {
icon = "fa-check-circle";
}
String content = "";
if (errorsCount + warningsCount + infosCount > 0) {
if (iso.equals(TiffConformanceChecker.POLICY_ISO)) {
content += policyTmpl;
} else {
content += errorsTmpl;
}
String allRows = "";
// Errors, Warnings and Infos
for (RuleResult val : ir.getAllRuleResults(iso)) {
String tdRow, display = "", clasz = "", location = "";
if (val.getRule() == null) {
// Policy value
tdRow = pcTmpl;
if (!val.ok() && !val.getWarning()) {
tdRow = tdRow.replace("##FA_CLASS##", "times");
} else if (!val.ok()) {
tdRow = tdRow.replace("##FA_CLASS##", "exclamation");
}
location = val.getRuleDescription();
} else {
// Rule value
tdRow = tdTmpl;
if (val.getRule().isError() || val.getRule().isCritical()) {
tdRow = tdRow.replace("##FA_CLASS##", "times");
} else if (val.getRule().isWarning()) {
tdRow = tdRow.replace("##FA_CLASS##", "exclamation");
} else if (val.getRule().isInfo()) {
tdRow = tdRow.replace("##FA_CLASS##", "info");
display = "style='display: none;'";
clasz = "class='info##COUNT##'";
addedInfos++;
}
location = val.getLocation();
}
tdRow = tdRow.replace("##ID##", val.getRule() != null ? val.getRule().getId() : "");
tdRow = tdRow.replace("##LOC##", location);
tdRow = tdRow.replace("##DESC##", val.getDescription());
tdRow = tdRow.replace("##POPOVER##", makePopoverAttributes(val));
tdRow = tdRow.replace("##DISPLAY##", display);
tdRow = tdRow.replace("##CLASS##", clasz);
addedRows++;
allRows += tdRow;
}
content = StringUtils.replace(content, "##ROWS##", allRows);
}
if (addedRows == 0) {
content = "";
}
if (addedInfos == 0) {
row = StringUtils.replace(row, "##CHECK##", "");
}
row = StringUtils.replace(row, "##CHECK##", checkInfos);
row = StringUtils.replace(row, "##CONTENT##", content);
row = StringUtils.replace(row, "##COUNT##", (++count) + "");
row = StringUtils.replace(row, "##TITLE##", name);
row = StringUtils.replace(row, "##ICON##", icon);
rows += row;
}
}
htmlBody = StringUtils.replace(htmlBody, "##DIVS_ERRORS##", rows);
/**
* Tags divs
*/
htmlBody = StringUtils.replace(htmlBody, "##TAGS_DIVS##", generateTagsDivs(ir));
/**
* File Structure
*/
String ul = "";
int index = 0;
TiffDocument td = ir.getTiffModel();
IFD ifd = td.getFirstIFD();
boolean hasIFDList = false;
if (ifd != null && ifd.hasNextIFD()) {
hasIFDList = ifd.hasNextIFD();
}
while (ifd != null) {
String typ = " - Main image";
if (ifd.hasSubIFD() && ifd.getImageSize() < ifd.getsubIFD().getImageSize()) {
typ = " - Thumbnail";
}
String aIni = "";
String aBody = " " + ifd.toString() + typ;
String aEnd = "";
String bold = "";
if (index == 0) {
bold = "bold";
}
aIni = "";
aEnd = " ";
ul += " " + aIni + aBody + aEnd;
if (ifd.getsubIFD() != null) {
typ = "";
if (ifd.getImageSize() < ifd.getsubIFD().getImageSize()) typ = " - Main image";
else typ = " - Thumbnail";
ul += "";
}
if (ifd.containsTagId(34665)) {
ul += "";
}
if (ifd.containsTagId(700)) {
ul += "";
}
if (ifd.containsTagId(33723)) {
ul += "";
}
if (index == 0) {
if (ir.getTiffModel().getIccProfile() != null) {
String creat = "";
if (ir.getTiffModel().getIccProfile().getCreator() != null) {
creat = "Creator: " + ir.getTiffModel().getIccProfile().getCreator().getCreator() + " ";
}
ul += " ICC" +
"Description: " + ir.getTiffModel().getIccProfile().getDescription() + " " +
creat +
"Version: " + ir.getTiffModel().getIccProfile().getVersion() + " " +
"Class: " + ir.getTiffModel().getIccProfile().getProfileClass().toString() + " " +
" ";
}
}
ul += "";
index++;
ifd = ifd.getNextIFD();
}
ul += " ";
htmlBody = StringUtils.replace(htmlBody, "##UL##", ul);
/**
* Metadata incoherencies
*/
IFD tdifd = td.getFirstIFD();
int nifd = 1;
rows = "";
while (tdifd != null) {
XMP xmp = null;
IPTC iptc = null;
if (tdifd.containsTagId(TiffTags.getTagId("XMP")))
xmp = (XMP) tdifd.getTag("XMP").getValue().get(0);
if (tdifd.containsTagId(TiffTags.getTagId("IPTC")))
iptc = (IPTC) tdifd.getTag("IPTC").getValue().get(0);
// Author
String authorTag = null;
if (tdifd.containsTagId(TiffTags.getTagId("Artist")))
authorTag = tdifd.getTag("Artist").toString();
String authorIptc = null;
if (iptc != null) authorIptc = iptc.getCreator();
String authorXmp = null;
if (xmp != null) authorXmp = xmp.getCreator();
rows += detectIncoherency(authorTag, authorIptc, authorXmp, "Author", nifd);
tdifd = tdifd.getNextIFD();
nifd++;
}
if (rows.isEmpty()){
rows = "No metadata incoherencies found ";
}
htmlBody = StringUtils.replace(htmlBody, "##META_ROWS##", rows);
/**
* Finish, write to html file
*/
htmlBody = StringUtils.replace(htmlBody, "\\.\\./html/", "");
return htmlBody;
}
private String generateTagsDivs(IndividualReport ir) {
Map hasExpert = new HashMap<>();
Map tagsMap = new HashMap<>();
Map templates = new HashMap<>();
String row;
/**
* Parse TAGs
*/
for (ReportTag tag : getTags(ir)) {
if (tag.tv.getId() == 700) {
String mapId = "xmp" + tag.index;
String mapIdH = "xmp" + tag.index + "h";
// XMP
for (abstractTiffType to : tag.tv.getValue()) {
XMP xmp = (XMP) to;
try {
Metadata metadata = xmp.createMetadata();
for (String key : metadata.keySet()) {
row = "" + key + " " + metadata.get(key).toString().trim() + " ";
String rows = tagsMap.containsKey(mapId) ? tagsMap.get(mapId) : "";
tagsMap.put(mapId, rows + row);
}
if (xmp.getHistory() != null) {
for (Hashtable kv : xmp.getHistory()) {
// TODO WORKARROUND
String key = kv.keySet().iterator().next();
String value = kv.get(key);
row = "##ATTR## ##VALUE## ";
if (key.equals("action")) {
row = row.replace("##LINE##", "line-top");
} else {
row = row.replace("##LINE##", "");
}
row = row.replace("##ATTR##", key);
row = row.replace("##VALUE##", value);
String rows = tagsMap.containsKey(mapIdH) ? tagsMap.get(mapIdH) : "";
tagsMap.put(mapIdH, rows + row);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
continue;
}
if (tag.tv.getId() == 34665) {
// EXIF
String mapId = "exi" + tag.index;
IFD exif = (IFD) tag.tv.getValue().get(0);
for (TagValue tv : exif.getTags().getTags()) {
if (tv.getId() == 36864){
tv.toString();
}
row = "##ICON## "+tv.getId()+" " + (tv.getName().equals(tv.getId()+"") ? "Private tag" : tv.getName()) + " " + tv.getDescriptiveValue() + " ";
row = row.replace("##ICON##", " ");
String rows = tagsMap.containsKey(mapId) ? tagsMap.get(mapId) : "";
tagsMap.put(mapId, rows + row);
}
continue;
}
if (tag.tv.getId() == 330) {
// Sub IFD
String mapId = "sub" + tag.index;
IFD sub = (IFD) tag.tv.getValue().get(0);
for (TagValue tv : sub.getTags().getTags()) {
String expert = "";
if (!showTag(tv)) {
expert = "expert";
hasExpert.put(mapId, true);
}
row = "##ICON## ##ID## ##KEY## ##VALUE## ";
row = row.replace("##ICON##", " ");
row = row.replace("##ID##", tv.getId() + "");
row = row.replace("##KEY##", (tv.getName().equals(tv.getId()+"") ? "Private tag" : tv.getName()));
row = row.replace("##VALUE##", tv.getDescriptiveValue());
String rows = tagsMap.containsKey(mapId) ? tagsMap.get(mapId) : "";
tagsMap.put(mapId, rows + row);
}
continue;
}
if (tag.tv.getId() == 33723) {
String mapId = "ipt" + tag.index;
// IPTC
for (abstractTiffType to : tag.tv.getValue()) {
IPTC iptc = (IPTC) to;
try {
Metadata metadata = iptc.createMetadata();
for (String key : metadata.keySet()) {
row = "" + key + " " + metadata.get(key).toString().trim() + " ";
String rows = tagsMap.containsKey(mapId) ? tagsMap.get(mapId) : "";
tagsMap.put(mapId, rows + row);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
continue;
}
// IFD
String mapId = "ifd" + tag.index;
String expert = "";
if (tag.expert) {
expert = " expert";
hasExpert.put(mapId, true);
}
row = "##ICON## ##ID## ##KEY## ##VALUE## ";
String sDif = "";
if (tag.dif < 0) sDif = " ";
else if (tag.dif > 0) sDif = " ";
row = row.replace("##ICON##", " ");
row = row.replace("##ID##", tag.tv.getId() + sDif);
row = row.replace("##KEY##", (tag.tv.getName().equals(tag.tv.getId()) ? "Private tag" : tag.tv.getName()));
row = row.replace("##VALUE##", tag.tv.getDescriptiveValue());
String rows = tagsMap.containsKey(mapId) ? tagsMap.get(mapId) : "";
tagsMap.put(mapId, rows + row);
}
/**
* Generate divs
*/
String finalResult = "";
String expertTmpl = " Expert mode
";
String genTmpl = "";
String subTmpl = StringUtils.replace(genTmpl, "##TITLE##", "Sub IFD Tags");
String ifdTmpl = StringUtils.replace(genTmpl, "##TITLE##", "IFD Tags");
String exifTmpl = StringUtils.replace(genTmpl, "##TITLE##", "EXIF");
String iptcTmpl = "";
String xmpTmpl = "";
templates.put("ifd", ifdTmpl);
templates.put("sub", subTmpl);
templates.put("ipt", iptcTmpl);
templates.put("xmp", xmpTmpl);
templates.put("exi", exifTmpl);
/**
* Generate HTMLs
*/
for (String key : tagsMap.keySet()) {
if (key.endsWith("h")) continue;
String type = key.substring(0, 3);
String display = "none;", expert = "";
if (key.equals("ifd0")) display = "block;";
if (hasExpert.containsKey(key)) expert = expertTmpl;
String tmpl = templates.get(type);
tmpl = StringUtils.replace(tmpl, "##EXPERT##", expert);
tmpl = StringUtils.replace(tmpl, "##INDEX##", key);
tmpl = StringUtils.replace(tmpl, "##DISPLAY##", display);
tmpl = StringUtils.replace(tmpl, "##ROWS##", tagsMap.get(key));
if (type.equals("xmp") && tagsMap.containsKey(key + "h")) {
tmpl = StringUtils.replace(tmpl, "##ROWSH##", tagsMap.get(key + "h"));
tmpl = StringUtils.replace(tmpl, "##DISH##", "block");
} else {
tmpl = StringUtils.replace(tmpl, "##DISH##", "none");
}
finalResult += tmpl;
}
return finalResult;
}
private String detectIncoherency(String valueTag, String valueIptc, String valueXmp, String name, int nifd) {
String tmpl = "##TEXT## ";
String incoherencies = "";
if (valueTag != null && valueIptc != null && !valueTag.equals(valueIptc)) {
incoherencies += StringUtils.replace(tmpl, "##TEXT##", name + " on TAG and IPTC in IFD " + nifd + " (" + valueTag + ", " + valueIptc + ")");
}
if (valueTag != null && valueXmp != null && !valueTag.equals(valueXmp)) {
incoherencies += StringUtils.replace(tmpl, "##TEXT##", name + " on TAG and XMP in IFD " + nifd + " (" + valueTag + ", " + valueXmp + ")");
}
if (valueIptc != null && valueXmp != null && !valueIptc.equals(valueXmp)) {
incoherencies += StringUtils.replace(tmpl, "##TEXT##", name + " on IPTC and XMP in IFD " + nifd + " (" + valueIptc + ", " + valueXmp + ")");
}
return incoherencies;
}
private String makePopoverAttributes(RuleResult val) {
RuleType rule = val.getRule();
if (rule != null && !rule.getTitle().getValue().isEmpty() && !rule.getDescription().getValue().isEmpty()) {
String description = rule.getDescription().getValue();
if (val.getReference() != null) {
description += "" + val.getReference() + " ";
}
if (rule.getId().equals("RECOMMENDED-TAG-270")){
val.toString();
}
description = description.replaceAll("\"","'");
return "data-toggle=\"popover\" title=\"" + rule.getTitle().getValue() + "\" data-content=\"" + description + "\" data-placement=\"auto bottom\" data-trigger=\"hover\"";
}
return "";
}
private String makeConformsText(IndividualReport ir, String iso) {
String tmplPassed = " ##TITLE##
";
// String tmplWarn = " ##TITLE##
";
String tmplError = " ##TITLE##
";
String name = ImplementationCheckerLoader.getIsoName(iso);
int err = ir.getNErrors(iso);
int war = ir.getNWarnings(iso);
if (err == 0 && war == 0) {
return StringUtils.replace(tmplPassed, "##TITLE##", name);
} else if (err == 0 && war > 0) {
return StringUtils.replace(tmplPassed, "##TITLE##", name);
} else {
return StringUtils.replace(tmplError, "##TITLE##", name);
}
}
/**
* Gets the report name of a given tiff file.
*
* @param internalReportFolder the internal report folder
* @param realFilename the real file name
* @param idReport the report id
* @return the report name
*/
public static String getReportName(String internalReportFolder, String realFilename, int idReport) {
String reportName = internalReportFolder + idReport + "-" + new File(realFilename).getName();
File file = new File(reportName);
int index = 0;
while (file.exists()) {
index++;
String ext = getFileType(reportName);
reportName =
internalReportFolder + idReport + "-"
+ new File(realFilename.substring(0, realFilename.lastIndexOf(".")) + index + "." + ext)
.getName();
file = new File(reportName);
}
return reportName;
}
/**
* Gets the file type.
*
* @param path the path
* @return the file type
*/
static String getFileType(String path) {
String fileType = null;
fileType = path.substring(path.lastIndexOf('.') + 1).toUpperCase();
return fileType;
}
/**
* Read filefrom resources string.
*
* @param pathStr the path str
* @return the string
*/
public String readFilefromResources(String pathStr) {
String text = "";
Path path = Paths.get(pathStr);
try {
if (Files.exists(path)) {
// Look in current dir
BufferedReader br = new BufferedReader(new FileReader(pathStr));
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
text = sb.toString();
br.close();
} else {
// Look in JAR
Class cls = ReportGenerator.class;
ClassLoader cLoader = cls.getClassLoader();
InputStream in = cLoader.getResourceAsStream(pathStr);
if (in != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
String newLine = System.getProperty("line.separator");
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
out.append(newLine);
}
text = out.toString();
}
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
return text;
}
private String encodeUrl(String str) {
return str.replaceAll("#", "%23");
}
}