Beispiele zur Behandlung strukturell defekter PDF Dokumente

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);                      (1)
settings.setPDFStructureReadStrategy(
    PDFStructureReadStrategy.LENIENT_ON_ERROR);                                (2)
reader.read(inputStream);

1

Anfrage des Konfigurations-Objekts

2

Setzen der gewünschten Lesestrategie

3

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();     (1)
LoggingConfiguration.getGlobal().
    addThreadLocalQualifiedLogListener(structureFixIndicator);

1

StructureFixIndicator erzeugen

2

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();                                                 (1)
reader.read(inputStream);                                                      (2)
if (structureFixIndicator.fixedBrokenDocumentStructure()) {                    (3)
  // handle broken document
  …
}

1

Eventuell vorhandene Ergebnisse eines vorigen Ladevorgangs zurückzusetzen

2

Lesevorgang durchführen

3

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();     (1)
LoggingConfiguration.getGlobal().
    addThreadLocalQualifiedLogListener(structureFixIndicator);                 (2)
try {
  reader.read(inputStream);                                                    (3)
} finally {
  LoggingConfiguration.getGlobal().
      removeThreadLocalQualifiedLogListener(structureFixIndicator);            (4)
}
if (structureFixIndicator.fixedBrokenDocumentStructure()) {                    (5)
  // handle broken document
  …
}

1

StructureFixIndicator erzeugen

2

Registrierung als LogListener

3

Lesevorgang durchführen

4

StructureFixIndicator wieder entfernen

5

Abfrage, ob es sich um ein defektes Dokument handelt


[jadice document platform Version 5.5.12.1: Dokumentation für Entwickler. Veröffentlicht: 2021-08-17]