Beispiel 7.30. Setzen von PDFStructureReaderSettings
für das Lesen fehlerhafter
Dokumente
Im folgenden Beispiel wird gezeigt, wie man den in Kapitel „Existierende Lese-Strategien“ beschriebenen Modus
LENIENT_ON_ERROR
aktiviert. Ebenso ist ersichtlich, wie
man erfahren kann, ob das PDF wirklich strukturell defekt ist.
Aktivierung des Modus LENIENT_ON_ERROR
:
Reader reader = new Reader(); PDFStructureReaderSettings settings = reader.getSettings(PDFStructureReaderSettings.class); settings.setPDFStructureReadStrategy( PDFStructureReadStrategy.LENIENT_ON_ERROR); reader.read(inputStream);
|
Anfrage des Konfigurations-Objekts |
|
Setzen der gewünschten Lesestrategie |
|
Durchführung des Lesevorgangs. |
Beispiel 7.31. Behandlung/Erkennung von strukturell defekten Dokumenten
Zunächst wird ein spezieller QualifiedLogListener
benötigt, der auf eine
bestimmte Meldung im Log hört. Sobald diese Meldung eintrifft, weiß man, dass es
sich um ein strukturell defektes Dokument handelt.
Beispiel für einen solchen Log-Listener:
import org.jadice.util.log.internal.config.LoggingConfiguration; import org.jadice.util.log.qualified.QualifiedLogEvent; import org.jadice.util.log.qualified.QualifiedLogListener; /** * Can be registered as {@link QualifiedLogListener}. This class will check for a specific message * ID which is produced when loading a PDF document with invalid structure. If such a message * arrives, a boolean flag will be set which can be checked via * {@link #fixedBrokenDocumentStructure()}. * <p> * To use the StructureFixIndicator there are generally 2 options: * <ul> * <li>Register a StructureFixIndicator before loading a document; Remove the StructureFixIndicator * afterwards.</li> * <li>Register a StructureFixIndicator once; call {@link #reset()} before loading a document to * ensure the flag is set correctly.</li> * </ul> * * After loading a document, use {@link #fixedBrokenDocumentStructure()} to see if the warning * message arrived. * * @see LoggingConfiguration */ public class StructureFixIndicator implements QualifiedLogListener { private static final String MSG_ID_STRUCTURAL_ERRORS_WERE_FIXED = "DOCP.FORMAT.PDF.STRUCT-WARNING_STRUCTURAL_ERRORS_WERE_FIXED"; private boolean fixedBrokenDocumentStructure = false; @Override public void warn(QualifiedLogEvent event) { handleEvent(event); } @Override public void error(QualifiedLogEvent event) { handleEvent(event); } @Override public void fatal(QualifiedLogEvent event) { handleEvent(event); } private void handleEvent(QualifiedLogEvent event) { if (MSG_ID_STRUCTURAL_ERRORS_WERE_FIXED.equals(event.getId())) { fixedBrokenDocumentStructure = true; } } /** * Resets the StructureFixIndicator flags. When using a global StructureFixIndicator which is not * removed after loading a document, this method should be called before starting the read process * of the document. */ public void reset() { fixedBrokenDocumentStructure = false; } /** * Check if the StructureFixIndicator received a warning message (structural errors in PDF * document). * * @return true: the document has structural errors; false otherwise */ public boolean fixedBrokenDocumentStructure() { return fixedBrokenDocumentStructure; } }
Dieser Listener kann beispielsweise global für den aktuellen Thread einmalig registriert werden:
StructureFixIndicator structureFixIndicator = new StructureFixIndicator(); LoggingConfiguration.getGlobal(). addThreadLocalQualifiedLogListener(structureFixIndicator);
|
StructureFixIndicator erzeugen |
|
als Log-Listener registrieren |
Die Registrierung für sämtliche Threads ist ebenfalls möglich. Der beispielhafte Log-Listener ist jedoch nicht auf gleichzeitig laufende Lesevorgänge vorbereitet.
Die eigentliche Überprüfung beziehungsweise der Aufruf sieht folgendermaßen aus:
structureFixIndicator.reset();
reader.read(inputStream);
if (structureFixIndicator.fixedBrokenDocumentStructure()) {
// handle broken document
…
}
|
Eventuell vorhandene Ergebnisse eines vorigen Ladevorgangs zurückzusetzen |
|
Lesevorgang durchführen |
|
Abfrage, ob es sich um ein defektes Dokument handelt |
Wenn der Listener nicht global registriert werden soll, kann die Überprüfung auch beim Lesevorgang stattfinden:
StructureFixIndicator structureFixIndicator = new StructureFixIndicator();
LoggingConfiguration.getGlobal().
addThreadLocalQualifiedLogListener(structureFixIndicator);
try {
reader.read(inputStream);
} finally {
LoggingConfiguration.getGlobal().
removeThreadLocalQualifiedLogListener(structureFixIndicator);
}
if (structureFixIndicator.fixedBrokenDocumentStructure()) {
// handle broken document
…
}
|
StructureFixIndicator erzeugen |
|
Registrierung als LogListener |
|
Lesevorgang durchführen |
|
StructureFixIndicator wieder entfernen |
|
Abfrage, ob es sich um ein defektes Dokument handelt |