com.adobe.epubcheck.messages.OverriddenMessages 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.EPUBLocation;
import com.adobe.epubcheck.api.Report;
import com.adobe.epubcheck.util.PathUtil;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.EnumMap;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Loads a list of messages from an override file and manages logic to choose
* between an override or default message based on which is available.
*/
public class OverriddenMessages
{
private final DefaultSeverities defaultSeverities = new DefaultSeverities();
private final Map overridenMessages = new EnumMap(MessageId.class);
// We could provide other localizations here as well, but it's probably better
// to keep this simple.
private final LocalizedMessages defaultMessages = LocalizedMessages.getInstance();
private final Pattern parameterPattern = Pattern.compile("%(\\d+)\\$s");
private final File overrideFile;
private final Report report;
public OverriddenMessages(File overrideFile, Report report)
{
this.overrideFile = overrideFile;
this.report = report;
loadOverriddenMessageSeverities();
}
public Message getMessage(MessageId id)
{
// First, check for an overridden message
Message m = overridenMessages.get(id);
if (m == null)
{
// If not overridden, fall back to the default
m = defaultMessages.getMessage(id);
if (m == null)
{
// Indicates a programmer error
throw new IllegalArgumentException("MessageId " + id.name() + " is invalid.");
}
}
return m;
}
private void loadOverriddenMessageSeverities()
{
// Method lifted directly from the old MessageDictionary class. I've avoided
// making any changes, but this method deserves a refactor. -mm
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(Locale.ROOT).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, EPUBLocation.create("", 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, EPUBLocation.create("", lineNumber, columnNumber),
fields[1], PathUtil.removeWorkingDirectory(overrideFile.getAbsolutePath()));
continue;
}
Message message = defaultMessages.getMessage(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, EPUBLocation.create("", lineNumber, 0, fields[2]),
PathUtil.removeWorkingDirectory(overrideFile.getAbsolutePath()));
continue;
}
}
if (messageText != null)
{
Severity oldSeverity = defaultSeverities.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, EPUBLocation.create("", 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)))
{
overridenMessages.put(id, new Message(message.getID(), newSeverity, message.getSeverity(),
messageText, suggestionText));
}
}
++lineNumber;
}
} catch (FileNotFoundException fnf)
{
report.message(MessageId.CHK_001, EPUBLocation.create(overrideFile.getAbsolutePath()));
} catch (IOException ex)
{
report.message(MessageId.CHK_007, EPUBLocation.create("", lineNumber, columnNumber),
PathUtil.removeWorkingDirectory(overrideFile.getAbsolutePath()), ex.getMessage());
} finally
{
try
{
if (br != null)
{
br.close();
}
if (fis != null)
{
fis.close();
}
} catch (IOException ignored)
{
}
}
}
}
private 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;
}
private 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,
EPUBLocation.create("", lineNumber, absoluteColumnNumber, text),
pathAdjustedFileName);
}
}
}
return max;
}
}