diff --git a/src/main/java/org/liblouis/CompilationException.java b/src/main/java/org/liblouis/CompilationException.java index 6404456..2583d59 100644 --- a/src/main/java/org/liblouis/CompilationException.java +++ b/src/main/java/org/liblouis/CompilationException.java @@ -1,5 +1,7 @@ package org.liblouis; +import java.util.List; + @SuppressWarnings("serial") public class CompilationException extends Exception { @@ -7,6 +9,10 @@ public CompilationException(String message) { super(message); } + public CompilationException(String message, List errors) { + this(addErrorsToMessage(message, errors)); + } + public CompilationException(Throwable cause) { super(cause); } @@ -14,4 +20,13 @@ public CompilationException(Throwable cause) { public CompilationException(String message, Throwable cause) { super(message, cause); } + + private static String addErrorsToMessage(String message, List errors) { + if (errors != null && !errors.isEmpty()) { + message += "\nErrors:"; + for (String e : errors) + message += ("\n" + e); + } + return message; + } } diff --git a/src/main/java/org/liblouis/Louis.java b/src/main/java/org/liblouis/Louis.java index 05e095f..c70c021 100644 --- a/src/main/java/org/liblouis/Louis.java +++ b/src/main/java/org/liblouis/Louis.java @@ -8,9 +8,11 @@ import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -136,11 +138,22 @@ private File[] _invoke(String table, File base) { private static Lou_LogCallback lou_logCallback = null; private static boolean loggerIsRegistered = false; + // capture errors so that Translator can include them in CompilationException or TranslationException + static List errors = new ArrayList<>(); + public static synchronized void setLogger(final Logger logger) { logCallback = logger; lou_logCallback = new Lou_LogCallback() { public void invoke(int level, String message) { - logger.log(Logger.Level.from(level), message); + Logger.Level lvl = Logger.Level.from(level); + switch (lvl) { + case ERROR: + case FATAL: + errors.add(message); + break; + } + if (logger != null) + logger.log(lvl, message); } }; loggerIsRegistered = false; diff --git a/src/main/java/org/liblouis/TranslationException.java b/src/main/java/org/liblouis/TranslationException.java index 55e64b9..2bfad99 100644 --- a/src/main/java/org/liblouis/TranslationException.java +++ b/src/main/java/org/liblouis/TranslationException.java @@ -1,11 +1,17 @@ package org.liblouis; +import java.util.List; + @SuppressWarnings("serial") public class TranslationException extends Exception { public TranslationException(String message) { super(message); } + + public TranslationException(String message, List errors) { + this(addErrorsToMessage(message, errors)); + } public TranslationException(Throwable throwable) { super(throwable); @@ -14,4 +20,13 @@ public TranslationException(Throwable throwable) { public TranslationException(String message, Throwable throwable) { super(message, throwable); } + + private static String addErrorsToMessage(String message, List errors) { + if (errors != null && !errors.isEmpty()) { + message += "\nErrors:"; + for (String e : errors) + message += ("\n" + e); + } + return message; + } } diff --git a/src/main/java/org/liblouis/Translator.java b/src/main/java/org/liblouis/Translator.java index a22c715..7833e05 100644 --- a/src/main/java/org/liblouis/Translator.java +++ b/src/main/java/org/liblouis/Translator.java @@ -33,8 +33,11 @@ public class Translator { */ public Translator(String table) throws CompilationException { Louis.log(Logger.Level.DEBUG, "Loading table %s", table); - if (Louis.getLibrary().lou_getTable(table) == Pointer.NULL) - throw new CompilationException("Unable to compile table '" + table + "'"); + synchronized (Louis.errors) { + Louis.errors.clear(); + if (Louis.getLibrary().lou_getTable(table) == Pointer.NULL) + throw new CompilationException("Unable to compile table '" + table + "'", Louis.errors); + } this.table = table; } @@ -45,8 +48,11 @@ public Translator(String table) throws CompilationException { public Translator(URL table) throws CompilationException { Louis.log(Logger.Level.DEBUG, "Loading table %s", table); this.table = Louis.getTableNameForURL(table); - if (Louis.getLibrary().lou_getTable(this.table) == Pointer.NULL) - throw new CompilationException("Unable to compile table '" + table + "'"); + synchronized (Louis.errors) { + Louis.errors.clear(); + if (Louis.getLibrary().lou_getTable(this.table) == Pointer.NULL) + throw new CompilationException("Unable to compile table '" + table + "'", Louis.errors); + } } /** @@ -192,9 +198,12 @@ private TranslationResult translate(String text, if (characterAttributes != null || interCharacterAttributes != null) inputPos = getIntegerBuffer("inputpos", textLength * OUTLEN_MULTIPLIER); int mode = displayTable.getMode().value(); - if (Louis.getLibrary().lou_translate(table, inbuf, inlen, outbuf, outlen, typeform, - null, null, inputPos, null, mode) == 0) - throw new TranslationException("Unable to complete translation"); + synchronized (Louis.errors) { + Louis.errors.clear(); + if (Louis.getLibrary().lou_translate(table, inbuf, inlen, outbuf, outlen, typeform, + null, null, inputPos, null, mode) == 0) + throw new TranslationException("Unable to complete translation", Louis.errors); + } return new TranslationResult(outbuf, outlen, inputPos, characterAttributes, interCharacterAttributes, displayTable); } @@ -210,10 +219,12 @@ public String backTranslate(String text) throws TranslationException { WideCharString outbuf = getWideCharBuffer("text-out", textLength * OUTLEN_MULTIPLIER); IntByReference inlen = new IntByReference(textLength); IntByReference outlen = new IntByReference(outbuf.length()); - - if (Louis.getLibrary().lou_backTranslate(table, inbuf, inlen, outbuf, outlen, - null, null, null, null, null, 0) == 0) - throw new TranslationException("Unable to complete translation"); + synchronized (Louis.errors) { + Louis.errors.clear(); + if (Louis.getLibrary().lou_backTranslate(table, inbuf, inlen, outbuf, outlen, + null, null, null, null, null, 0) == 0) + throw new TranslationException("Unable to complete translation", Louis.errors); + } try { return outbuf.read(outlen.getValue()); } catch (IOException e) { @@ -251,8 +262,11 @@ public byte[] hyphenate(String text) throws TranslationException { while (matcher.find()) { int start = matcher.start(); int end = matcher.end(); - if (louis.lou_hyphenate(table, inbuf.substring(start), end - start, wordHyphens, 0) == 0) - throw new TranslationException("Unable to complete hyphenation"); + synchronized (Louis.errors) { + Louis.errors.clear(); + if (louis.lou_hyphenate(table, inbuf.substring(start), end - start, wordHyphens, 0) == 0) + throw new TranslationException("Unable to complete hyphenation", Louis.errors); + } for (int i = 0; i < end - start; i++) hyphens[start + i] = wordHyphens[i]; } byte[] hyphenPositions = readHyphens(new byte[inlen - 1], hyphens);