
com.adobe.epubcheck.messages.MessageDictionary Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of epubcheck Show documentation
Show all versions of epubcheck Show documentation
EPUBCheck is a tool to validate the conformance of EPUB publications against
the EPUB specifications. EPUBCheck can be run as a standalone command-line tool or used
as a Java library.
package com.adobe.epubcheck.messages;
import com.adobe.epubcheck.api.Report;
import com.adobe.epubcheck.util.PathUtil;
import com.adobe.epubcheck.util.outWriter;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This is a dictionary that maps the text of a message to a severity.
*/
public class MessageDictionary
{
File overrideFile;
Report report;
static Map defaultSeverityMap = null;
static Pattern parameterPattern = Pattern.compile("%(\\d+)\\$s");
public void setOverrideFile(File value)
{
overrideFile = value;
initMessageMap();
}
public MessageDictionary(File overrideFile, Report report)
{
this.report = report;
this.overrideFile = overrideFile;
initMessageMap();
}
Map messages = new HashMap();
static final ResourceBundle labels = ResourceBundle.getBundle("com.adobe.epubcheck.messages.MessageBundle");
public Message getMessage(MessageId id)
{
return this.messages.get(id);
}
static Map getDefaultSeverities()
{
if (defaultSeverityMap == null)
{
Map map = new HashMap(MessageId.values().length);
//Accessibility
map.put(MessageId.ACC_001, Severity.WARNING);
map.put(MessageId.ACC_002, Severity.WARNING);
map.put(MessageId.ACC_003, Severity.WARNING);
map.put(MessageId.ACC_004, Severity.WARNING);
map.put(MessageId.ACC_005, Severity.WARNING);
map.put(MessageId.ACC_006, Severity.USAGE);
map.put(MessageId.ACC_007, Severity.USAGE);
map.put(MessageId.ACC_008, Severity.USAGE);
map.put(MessageId.ACC_009, Severity.USAGE);
map.put(MessageId.ACC_010, Severity.USAGE);
map.put(MessageId.ACC_011, Severity.USAGE);
map.put(MessageId.ACC_012, Severity.USAGE);
map.put(MessageId.ACC_013, Severity.WARNING);
map.put(MessageId.ACC_014, Severity.WARNING);
map.put(MessageId.ACC_015, Severity.WARNING);
map.put(MessageId.ACC_016, Severity.USAGE);
map.put(MessageId.ACC_017, Severity.USAGE);
// CHK
map.put(MessageId.CHK_001, Severity.ERROR);
map.put(MessageId.CHK_002, Severity.ERROR);
map.put(MessageId.CHK_003, Severity.ERROR);
map.put(MessageId.CHK_004, Severity.ERROR);
map.put(MessageId.CHK_005, Severity.ERROR);
map.put(MessageId.CHK_006, Severity.ERROR);
map.put(MessageId.CHK_007, Severity.ERROR);
//CSS
map.put(MessageId.CSS_001, Severity.ERROR);
map.put(MessageId.CSS_002, Severity.ERROR);
map.put(MessageId.CSS_003, Severity.ERROR);
map.put(MessageId.CSS_004, Severity.ERROR);
map.put(MessageId.CSS_005, Severity.ERROR);
map.put(MessageId.CSS_006, Severity.WARNING);
map.put(MessageId.CSS_007, Severity.WARNING);
map.put(MessageId.CSS_008, Severity.ERROR);
map.put(MessageId.CSS_009, Severity.USAGE);
map.put(MessageId.CSS_010, Severity.WARNING);
map.put(MessageId.CSS_011, Severity.USAGE);
map.put(MessageId.CSS_012, Severity.USAGE);
map.put(MessageId.CSS_013, Severity.USAGE);
map.put(MessageId.CSS_015, Severity.WARNING);
map.put(MessageId.CSS_016, Severity.WARNING);
map.put(MessageId.CSS_017, Severity.WARNING);
map.put(MessageId.CSS_019, Severity.WARNING);
map.put(MessageId.CSS_020, Severity.WARNING);
map.put(MessageId.CSS_021, Severity.WARNING);
map.put(MessageId.CSS_022, Severity.WARNING);
map.put(MessageId.CSS_023, Severity.USAGE);
map.put(MessageId.CSS_024, Severity.USAGE);
map.put(MessageId.CSS_025, Severity.USAGE);
map.put(MessageId.CSS_027, Severity.USAGE);
map.put(MessageId.CSS_028, Severity.USAGE);
//HTML
map.put(MessageId.HTM_001, Severity.ERROR);
map.put(MessageId.HTM_002, Severity.WARNING);
map.put(MessageId.HTM_003, Severity.ERROR);
map.put(MessageId.HTM_004, Severity.ERROR);
map.put(MessageId.HTM_005, Severity.USAGE);
map.put(MessageId.HTM_006, Severity.USAGE);
map.put(MessageId.HTM_007, Severity.WARNING);
map.put(MessageId.HTM_008, Severity.ERROR);
map.put(MessageId.HTM_009, Severity.ERROR);
map.put(MessageId.HTM_011, Severity.ERROR);
map.put(MessageId.HTM_012, Severity.WARNING);
map.put(MessageId.HTM_013, Severity.USAGE);
map.put(MessageId.HTM_014, Severity.WARNING);
map.put(MessageId.HTM_015, Severity.WARNING);
map.put(MessageId.HTM_016, Severity.WARNING);
map.put(MessageId.HTM_017, Severity.ERROR);
map.put(MessageId.HTM_018, Severity.ERROR);
map.put(MessageId.HTM_019, Severity.ERROR);
map.put(MessageId.HTM_020, Severity.USAGE);
map.put(MessageId.HTM_021, Severity.USAGE);
map.put(MessageId.HTM_022, Severity.USAGE);
map.put(MessageId.HTM_025, Severity.WARNING);
map.put(MessageId.HTM_027, Severity.WARNING);
map.put(MessageId.HTM_028, Severity.WARNING);
map.put(MessageId.HTM_029, Severity.WARNING);
map.put(MessageId.HTM_033, Severity.WARNING);
map.put(MessageId.HTM_036, Severity.WARNING);
map.put(MessageId.HTM_038, Severity.USAGE);
map.put(MessageId.HTM_043, Severity.USAGE);
map.put(MessageId.HTM_044, Severity.USAGE);
map.put(MessageId.HTM_045, Severity.INFO);
map.put(MessageId.HTM_046, Severity.ERROR);
map.put(MessageId.HTM_047, Severity.ERROR);
map.put(MessageId.HTM_048, Severity.ERROR);
//Media
map.put(MessageId.MED_001, Severity.ERROR);
map.put(MessageId.MED_002, Severity.ERROR);
map.put(MessageId.MED_003, Severity.ERROR);
map.put(MessageId.MED_004, Severity.ERROR);
map.put(MessageId.MED_005, Severity.ERROR);
map.put(MessageId.MED_006, Severity.WARNING);
//NAV
map.put(MessageId.NAV_001, Severity.ERROR);
//NCX
map.put(MessageId.NCX_002, Severity.ERROR);
map.put(MessageId.NCX_003, Severity.USAGE);
//OPF
map.put(MessageId.OPF_001, Severity.ERROR);
map.put(MessageId.OPF_002, Severity.FATAL);
map.put(MessageId.OPF_003, Severity.WARNING);
map.put(MessageId.OPF_004, Severity.ERROR);
map.put(MessageId.OPF_005, Severity.ERROR);
map.put(MessageId.OPF_006, Severity.ERROR);
map.put(MessageId.OPF_007, Severity.ERROR);
map.put(MessageId.OPF_008, Severity.ERROR);
map.put(MessageId.OPF_009, Severity.ERROR);
map.put(MessageId.OPF_010, Severity.ERROR);
map.put(MessageId.OPF_011, Severity.ERROR);
map.put(MessageId.OPF_012, Severity.ERROR);
map.put(MessageId.OPF_013, Severity.ERROR);
map.put(MessageId.OPF_014, Severity.ERROR);
map.put(MessageId.OPF_015, Severity.ERROR);
map.put(MessageId.OPF_016, Severity.ERROR);
map.put(MessageId.OPF_017, Severity.ERROR);
map.put(MessageId.OPF_018, Severity.WARNING);
map.put(MessageId.OPF_019, Severity.FATAL);
map.put(MessageId.OPF_020, Severity.WARNING);
map.put(MessageId.OPF_021, Severity.WARNING);
map.put(MessageId.OPF_022, Severity.ERROR);
map.put(MessageId.OPF_023, Severity.ERROR);
map.put(MessageId.OPF_024, Severity.ERROR);
map.put(MessageId.OPF_025, Severity.ERROR);
map.put(MessageId.OPF_026, Severity.ERROR);
map.put(MessageId.OPF_027, Severity.ERROR);
map.put(MessageId.OPF_028, Severity.ERROR);
map.put(MessageId.OPF_029, Severity.ERROR);
map.put(MessageId.OPF_030, Severity.ERROR);
map.put(MessageId.OPF_031, Severity.ERROR);
map.put(MessageId.OPF_032, Severity.ERROR);
map.put(MessageId.OPF_033, Severity.ERROR);
map.put(MessageId.OPF_034, Severity.ERROR);
map.put(MessageId.OPF_035, Severity.WARNING);
map.put(MessageId.OPF_036, Severity.WARNING);
map.put(MessageId.OPF_037, Severity.WARNING);
map.put(MessageId.OPF_038, Severity.WARNING);
map.put(MessageId.OPF_039, Severity.WARNING);
map.put(MessageId.OPF_040, Severity.ERROR);
map.put(MessageId.OPF_041, Severity.ERROR);
map.put(MessageId.OPF_042, Severity.ERROR);
map.put(MessageId.OPF_043, Severity.ERROR);
map.put(MessageId.OPF_044, Severity.ERROR);
map.put(MessageId.OPF_045, Severity.ERROR);
map.put(MessageId.OPF_046, Severity.ERROR);
map.put(MessageId.OPF_047, Severity.USAGE);
map.put(MessageId.OPF_048, Severity.ERROR);
map.put(MessageId.OPF_049, Severity.ERROR);
map.put(MessageId.OPF_050, Severity.ERROR);
map.put(MessageId.OPF_051, Severity.WARNING);
map.put(MessageId.OPF_052, Severity.ERROR);
map.put(MessageId.OPF_053, Severity.WARNING);
map.put(MessageId.OPF_054, Severity.ERROR);
map.put(MessageId.OPF_055, Severity.WARNING);
map.put(MessageId.OPF_056, Severity.WARNING);
map.put(MessageId.OPF_057, Severity.WARNING);
map.put(MessageId.OPF_058, Severity.USAGE);
map.put(MessageId.OPF_059, Severity.USAGE);
map.put(MessageId.OPF_060, Severity.ERROR);
map.put(MessageId.OPF_061, Severity.WARNING);
//PKG
map.put(MessageId.PKG_001, Severity.WARNING);
map.put(MessageId.PKG_003, Severity.ERROR);
map.put(MessageId.PKG_004, Severity.FATAL);
map.put(MessageId.PKG_005, Severity.ERROR);
map.put(MessageId.PKG_006, Severity.ERROR);
map.put(MessageId.PKG_007, Severity.ERROR);
map.put(MessageId.PKG_008, Severity.FATAL);
map.put(MessageId.PKG_009, Severity.ERROR);
map.put(MessageId.PKG_010, Severity.WARNING);
map.put(MessageId.PKG_011, Severity.ERROR);
map.put(MessageId.PKG_012, Severity.WARNING);
map.put(MessageId.PKG_013, Severity.ERROR);
map.put(MessageId.PKG_014, Severity.WARNING);
map.put(MessageId.PKG_015, Severity.FATAL);
map.put(MessageId.PKG_016, Severity.WARNING);
map.put(MessageId.PKG_017, Severity.WARNING);
map.put(MessageId.PKG_018, Severity.FATAL);
map.put(MessageId.PKG_020, Severity.ERROR);
map.put(MessageId.PKG_021, Severity.ERROR);
//Resources
map.put(MessageId.RSC_001, Severity.ERROR);
map.put(MessageId.RSC_002, Severity.FATAL);
map.put(MessageId.RSC_003, Severity.ERROR);
map.put(MessageId.RSC_004, Severity.ERROR);
map.put(MessageId.RSC_005, Severity.ERROR);
map.put(MessageId.RSC_006, Severity.ERROR);
map.put(MessageId.RSC_007, Severity.ERROR);
map.put(MessageId.RSC_008, Severity.ERROR);
map.put(MessageId.RSC_009, Severity.ERROR);
map.put(MessageId.RSC_010, Severity.ERROR);
map.put(MessageId.RSC_011, Severity.WARNING);
map.put(MessageId.RSC_012, Severity.ERROR);
map.put(MessageId.RSC_013, Severity.ERROR);
map.put(MessageId.RSC_014, Severity.ERROR);
map.put(MessageId.RSC_015, Severity.ERROR);
map.put(MessageId.RSC_016, Severity.FATAL);
map.put(MessageId.RSC_017, Severity.WARNING);
map.put(MessageId.RSC_018, Severity.WARNING);
//Scripting
map.put(MessageId.SCP_001, Severity.USAGE);
map.put(MessageId.SCP_002, Severity.USAGE);
map.put(MessageId.SCP_003, Severity.USAGE);
map.put(MessageId.SCP_004, Severity.ERROR);
map.put(MessageId.SCP_005, Severity.ERROR);
map.put(MessageId.SCP_006, Severity.USAGE);
map.put(MessageId.SCP_007, Severity.WARNING);
map.put(MessageId.SCP_008, Severity.WARNING);
map.put(MessageId.SCP_009, Severity.USAGE);
map.put(MessageId.SCP_010, Severity.USAGE);
defaultSeverityMap = map;
}
return defaultSeverityMap;
}
void initDefaultMessageMap()
{
messages.clear();
for (Map.Entry entry : getDefaultSeverities().entrySet())
{
this.addMessage(entry.getKey(), entry.getValue());
}
}
void initMessageMap()
{
initDefaultMessageMap();
loadOverriddenMessageSeverities();
}
void loadOverriddenMessageSeverities()
{
if (overrideFile != null)
{
int lineNumber = -1;
int columnNumber = -1;
String line;
FileInputStream fis = null;
BufferedReader br = null;
try
{
fis = new FileInputStream(overrideFile);
br = new BufferedReader(new InputStreamReader(fis, Charset.forName("UTF-8")));
lineNumber = 1;
while (null != (line = br.readLine()))
{
if (1 == lineNumber)
{
if (line.toLowerCase().startsWith("id"))
{
// optionally eat the first line
continue;
}
}
columnNumber = 0;
String[] fields = line.split("\t");
if (fields.length >= 2)
{
MessageId id;
try
{
id = MessageId.fromString(fields[0]);
}
catch (NoSuchElementException unused)
{
report.message(MessageId.CHK_002, new MessageLocation("", lineNumber, 0), fields[0], PathUtil.removeWorkingDirectory(overrideFile.getAbsolutePath()));
continue;
}
Severity newSeverity;
try
{
columnNumber += 1 + fields[0].length();
newSeverity = Severity.fromString(fields[1]);
}
catch (NoSuchElementException ignored)
{
report.message(MessageId.CHK_003, new MessageLocation("", lineNumber, columnNumber), fields[1], PathUtil.removeWorkingDirectory(overrideFile.getAbsolutePath()));
continue;
}
Message message = messages.get(id);
String messageText = message.getMessage();
if (fields.length >= 3 && fields[2] != null && fields[2].length() > 0)
{
columnNumber += 1 + fields[1].length();
messageText = checkMessageForParameterCount(lineNumber, columnNumber, message.getMessage(), fields[2]);
if (messageText == null)
{
report.message(MessageId.CHK_004, new MessageLocation("", lineNumber, 0, fields[2]), PathUtil.removeWorkingDirectory(overrideFile.getAbsolutePath()));
continue;
}
}
if (messageText != null)
{
Severity oldSeverity = getDefaultSeverities().get(message.getID());
if (newSeverity != oldSeverity)
{
messageText = String.format(" (severity overridden from %1$s) %2$s", oldSeverity, messageText);
}
}
String suggestionText = message.getSuggestion();
if (fields.length >= 4 && fields[3] != null && fields[3].length() > 0)
{
columnNumber += 1 + fields[1].length();
suggestionText = checkMessageForParameterCount(lineNumber, columnNumber, message.getSuggestion(), fields[3]);
if (suggestionText == null)
{
report.message(MessageId.CHK_005, new MessageLocation("", lineNumber, 0, fields[3]), PathUtil.removeWorkingDirectory(overrideFile.getAbsolutePath()));
continue;
}
}
if (message != null &&
((newSeverity != message.getSeverity()) ||
(messageText.compareTo(message.getMessage()) != 0) ||
(suggestionText.compareTo(message.getSuggestion()) != 0)))
{
messages.put(id, new Message(message.getID(), newSeverity, message.getSeverity(), messageText, suggestionText));
}
}
++lineNumber;
}
}
catch (FileNotFoundException fnf)
{
report.message(MessageId.CHK_001, new MessageLocation(overrideFile.getAbsolutePath(), -1, -1));
}
catch (IOException ex)
{
report.message(MessageId.CHK_007, new MessageLocation("", lineNumber, columnNumber), PathUtil.removeWorkingDirectory(overrideFile.getAbsolutePath()), ex.getMessage());
}
finally
{
try
{
if (br != null)
{
br.close();
}
if (fis != null)
{
fis.close();
}
}
catch (IOException ignored)
{
}
}
}
}
String checkMessageForParameterCount(int lineNumber, int columnNumber, String originalText, String newText)
{
if (newText != null)
{
int maxOriginal = getParameterCount(lineNumber, columnNumber, originalText);
int maxNew = getParameterCount(lineNumber, columnNumber, newText);
if (maxNew <= maxOriginal)
{
return newText;
}
return null;
}
return originalText;
}
int getParameterCount(int lineNumber, int columnNumber, String text)
{
int max = 0;
{
Matcher m = parameterPattern.matcher(text);
while (m.find())
{
int absoluteColumnNumber = columnNumber + m.start();
String s = m.group(1);
try
{
Integer number = Integer.parseInt(s);
if (number > max)
{
max = number;
}
}
catch (NumberFormatException ex)
{
String pathAdjustedFileName = PathUtil.removeWorkingDirectory(overrideFile.getAbsolutePath());
report.message(MessageId.CHK_006, new MessageLocation("", lineNumber, absoluteColumnNumber, text), pathAdjustedFileName);
}
}
}
return max;
}
void addMessage(MessageId messageId, Severity severity)
{
try
{
messages.put(messageId, new Message(messageId, severity, labels.getString(messageId.name()), getSuggestion(messageId)));
}
catch (Exception e)
{
outWriter.println("Couldn't locate message " + messageId.name());
}
}
String getSuggestion(MessageId messageId)
{
String result;
try
{
result = labels.getString(messageId.name() + "_SUG");
}
catch (Exception ignore)
{
result = "";
}
return result;
}
public void dumpMessages(OutputStreamWriter outputStream) throws
IOException
{
// Output the messages in a tab separated format
outputStream.write("ID\tSeverity\tMessage\tSuggestion\n");
for (MessageId id : MessageId.values())
{
StringBuilder sb = new StringBuilder();
sb.append(id.toString());
sb.append("\t");
Message message = this.getMessage(id);
if (message != null)
{
sb.append(message.getSeverity());
sb.append("\t");
sb.append(message.getMessage());
sb.append("\t");
sb.append(message.getSuggestion());
}
else
{
sb.append("null\tnull\tnull\tnull");
}
sb.append("\n");
outputStream.write(sb.toString());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy