public void runChecks()
{
ocf.setReport(getReport());
if (!ocf.hasEntry(OCFData.containerEntry))
{
getReport().message(MessageId.RSC_002, new MessageLocation(ocf.getName(), 0, 0));
return;
}
long l = ocf.getTimeEntry(OCFData.containerEntry);
if (l > 0)
{
Date d = new Date(l);
String formattedDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(d);
getReport().info(OCFData.containerEntry, FeatureEnum.CREATION_DATE, formattedDate);
}
OCFData containerHandler = ocf.getOcfData();
// retrieve the paths of root files
List<String> opfPaths = containerHandler.getEntries(OPFData.OPF_MIME_TYPE);
if (opfPaths == null || opfPaths.isEmpty())
{
getReport().message(MessageId.RSC_003, new MessageLocation(OCFData.containerEntry, -1, -1));
return;
}
else if (opfPaths.size() > 0)
{
if(opfPaths.size() > 1)
{
getReport().info(null, FeatureEnum.EPUB_RENDITIONS_COUNT, Integer.toString(opfPaths.size()));
}
// test every element for empty or missing @full-path attribute
// bugfix for issue 236 / issue 95
int rootfileErrorCounter = 0;
for (String opfPath : opfPaths)
{
if (opfPath == null)
{
++rootfileErrorCounter;
getReport().message(MessageId.OPF_016, new MessageLocation(OCFData.containerEntry, -1, -1));
}
else if (opfPath.isEmpty())
{
++rootfileErrorCounter;
getReport().message(MessageId.OPF_017, new MessageLocation(OCFData.containerEntry, -1, -1));
}
else if (!ocf.hasEntry(opfPath))
{
getReport().message(MessageId.OPF_002, new MessageLocation(OCFData.containerEntry, -1, -1), opfPath);
return;
}
}
if(rootfileErrorCounter == opfPaths.size())
{
// end validation at this point when @full-path attribute is missing in container.xml
// otherwise, tons of errors would be thrown ("XYZ exists in the zip file, but is not declared in the OPF file")
return;
}
}
// Detect the version of the first root file
// and compare with the asked version (if set)
EPUBVersion detectedVersion = null;
EPUBVersion validationVersion;
OPFData opfData = ocf.getOpfData().get(opfPaths.get(0));
if (opfData == null)
return;// The error must have been reported during parsing
detectedVersion = opfData.getVersion();
report.info(null, FeatureEnum.FORMAT_VERSION, detectedVersion.toString());
assert (detectedVersion != null);
if (version != null && version != detectedVersion)
{
getReport().message(MessageId.PKG_001, new MessageLocation(opfPaths.get(0), -1, -1), version, detectedVersion);
validationVersion = version;
}
else
{
validationVersion = detectedVersion;
}
// EPUB 2.0 says there SHOULD be only one OPS rendition
if (validationVersion == EPUBVersion.VERSION_2 && opfPaths.size() > 1)
{
getReport().message(MessageId.PKG_013, new MessageLocation(OCFData.containerEntry, -1, -1));
}
// Check the mimetype file
InputStream mimetype = null;
try
{
mimetype = ocf.getInputStream("mimetype");
StringBuilder sb = new StringBuilder(2048);
if (ocf.hasEntry("mimetype")
&& !CheckUtil.checkTrailingSpaces(mimetype,
validationVersion, sb))
{
getReport().message(MessageId.PKG_007, new MessageLocation("mimetype", 0, 0));
}
if (sb.length() != 0)
{
getReport().info(null, FeatureEnum.FORMAT_NAME, sb.toString().trim());
}
}
catch (IOException ignored)
{
// missing file will be reported later
}
finally
{
try
{
if (mimetype != null)
{
mimetype.close();
}
}
catch (IOException ignored)
{
// eat it
}
}
// Validate the OCF files against the schema definitions
validate(validationVersion);
// Validate each OPF and keep a reference of the OPFHandler
List<OPFHandler> opfHandlers = new LinkedList<OPFHandler>();
for (String opfPath : opfPaths)
{
OPFChecker opfChecker;
if (validationVersion == EPUBVersion.VERSION_2)
{
opfChecker = new OPFChecker(ocf, getReport(), opfPath, validationVersion);
}
else
{
opfChecker = new OPFChecker30(ocf, getReport(), opfPath, validationVersion);
}
opfChecker.runChecks();
opfHandlers.add(opfChecker.getOPFHandler());
}
// Check all file and directory entries in the container
try
{
Set<String> entriesSet = new HashSet<String>();
Set<String> normalizedEntriesSet = new HashSet<String>();
for (String entry : ocf.getFileEntries())
{
if (!entriesSet.add(entry.toLowerCase(Locale.ENGLISH)))
{
getReport().message(MessageId.OPF_060, new MessageLocation(ocf.getPackagePath(), 0, 0), entry);
}
else if (!normalizedEntriesSet.add(Normalizer.normalize(entry, Form.NFC)))
{
getReport().message(MessageId.OPF_061, new MessageLocation(ocf.getPackagePath(), 0, 0), entry);
}
ocf.reportMetadata(entry, report);
if (!entry.startsWith("META-INF/")
&& !entry.startsWith("META-INF\\")
&& !entry.equals("mimetype")
&& !containerHandler.getEntries().contains(entry))
{
boolean isDeclared = false;
for (OPFHandler opfHandler : opfHandlers)
{
if (opfHandler.getItemByPath(entry) != null)
{
isDeclared = true;
break;
}
}
if (!isDeclared)
{
report.message(MessageId.OPF_003, new MessageLocation(ocf.getName(), -1, -1), entry);
}
}
OCFFilenameChecker.checkCompatiblyEscaped(entry, getReport(), validationVersion);
}
for (String directory : ocf.getDirectoryEntries())
{
boolean hasContents = false;
for (String file : ocf.getFileEntries())
{
if (file.startsWith(directory))
{
hasContents = true;
break;
}
}
if (!hasContents)
{
getReport().message(MessageId.PKG_014, new MessageLocation(ocf.getName(), -1, -1), directory);
}
}
}
catch (IOException e)
{
getReport().message(MessageId.PKG_015, new MessageLocation(ocf.getName(), -1, -1), e.getMessage());
}
Report r = getReport();
}