GibsonParser.java 11.6 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.fontengine.font.Font
 *  com.adobe.fontengine.font.FontLoadingException
 *  com.adobe.fontengine.fontmanagement.FontLoader
 *  com.adobe.internal.io.ByteReader
 *  com.adobe.internal.io.RandomAccessFileByteReader
 *  com.adobe.internal.pdftoolkit.core.exceptions.PDFException
 *  com.adobe.internal.pdftoolkit.core.fontset.PDFFontSet
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.ReferenceCardinality
 *  org.apache.felix.scr.annotations.ReferencePolicy
 *  org.apache.tika.exception.TikaException
 *  org.apache.tika.io.IOExceptionWithCause
 *  org.apache.tika.io.TemporaryResources
 *  org.apache.tika.io.TikaInputStream
 *  org.apache.tika.metadata.Metadata
 *  org.apache.tika.metadata.PagedText
 *  org.apache.tika.metadata.Property
 *  org.apache.tika.mime.MediaType
 *  org.apache.tika.parser.AbstractParser
 *  org.apache.tika.parser.ParseContext
 *  org.apache.tika.sax.XHTMLContentHandler
 */
package com.adobe.internal.pdf.tika;

import com.adobe.fontengine.font.Font;
import com.adobe.fontengine.font.FontLoadingException;
import com.adobe.fontengine.fontmanagement.FontLoader;
import com.adobe.internal.io.ByteReader;
import com.adobe.internal.io.RandomAccessFileByteReader;
import com.adobe.internal.pdf.tika.PDFFontSetDefault;
import com.adobe.internal.pdf.tika.PDFFontSetInterface;
import com.adobe.internal.pdftoolkit.core.exceptions.PDFException;
import com.adobe.internal.pdftoolkit.core.fontset.PDFFontSet;
import com.adobe.internal.pdftoolkit.pdf.document.PDFDocument;
import com.adobe.internal.pdftoolkit.pdf.document.PDFOpenOptions;
import com.adobe.internal.pdftoolkit.pdf.interactive.annotation.PDFAnnotation;
import com.adobe.internal.pdftoolkit.pdf.interactive.annotation.PDFAnnotationIterator;
import com.adobe.internal.pdftoolkit.pdf.interactive.annotation.PDFAnnotationMarkup;
import com.adobe.internal.pdftoolkit.pdf.page.PDFPage;
import com.adobe.internal.pdftoolkit.pdf.page.PDFPageTree;
import com.adobe.internal.pdftoolkit.services.readingorder.ReadingOrderTextExtractor;
import com.adobe.internal.pdftoolkit.services.textextraction.ParagraphIterator;
import com.adobe.internal.pdftoolkit.services.textextraction.Word;
import com.adobe.internal.pdftoolkit.services.xmp.DocumentMetadata;
import com.adobe.internal.pdftoolkit.services.xmp.XMPService;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.tika.exception.TikaException;
import org.apache.tika.io.IOExceptionWithCause;
import org.apache.tika.io.TemporaryResources;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.metadata.PagedText;
import org.apache.tika.metadata.Property;
import org.apache.tika.mime.MediaType;
import org.apache.tika.parser.AbstractParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.sax.XHTMLContentHandler;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
public class GibsonParser
extends AbstractParser {
    private static final long serialVersionUID = 1776775061856503811L;
    private PDFFontSet pdfFontSet = null;
    @Reference(policy=ReferencePolicy.DYNAMIC, cardinality=ReferenceCardinality.MANDATORY_UNARY)
    private PDFFontSetInterface fontSet;
    private static final MediaType PDF = MediaType.application((String)"pdf");
    private boolean extractAnnotationText = true;

    public Set<MediaType> getSupportedTypes(ParseContext context) {
        return Collections.singleton(PDF);
    }

    public void parse(InputStream stream, ContentHandler handler, Metadata metadata, ParseContext context) throws IOException, SAXException, TikaException {
        TemporaryResources tmp = new TemporaryResources();
        try {
            TikaInputStream tis = TikaInputStream.get((InputStream)stream, (TemporaryResources)tmp);
            RandomAccessFile file = new RandomAccessFile(tis.getFile(), "r");
            tmp.addResource((Closeable)file);
            RandomAccessFileByteReader reader = new RandomAccessFileByteReader(file);
            tmp.addResource(new Closeable((ByteReader)reader){
                final /* synthetic */ ByteReader val$reader;

                public void close() throws IOException {
                    this.val$reader.close();
                }
            });
            final PDFDocument document = PDFDocument.newInstance((ByteReader)reader, PDFOpenOptions.newInstance());
            tmp.addResource(new Closeable(){

                public void close() throws IOException {
                    try {
                        document.close();
                    }
                    catch (PDFException e) {
                        throw new IOExceptionWithCause((Throwable)e);
                    }
                }
            });
            metadata.set("Content-Type", PDF.toString());
            this.extractMetadata(document, metadata);
            if (this.fontSet != null) {
                byte[] fontByteArray;
                this.pdfFontSet = this.fontSet.getPdfFontSet();
                FontLoader loader = new FontLoader();
                if (this.pdfFontSet == null) {
                    Font[] fonts = null;
                    File[] directories = this.fontSet.getFontDirectories();
                    if (directories != null && directories.length > 0) {
                        for (int i = 0; i < directories.length; ++i) {
                            if (!directories[i].exists() || (fonts = loader.load(directories[i], true, new ArrayList())) == null || fonts.length <= 0) continue;
                            int j = 0;
                            while (i < fonts.length) {
                                this.pdfFontSet.addFont(fonts[j]);
                                ++i;
                            }
                        }
                    }
                }
                if (this.pdfFontSet == null && (fontByteArray = this.fontSet.getFontSetStream()) != null) {
                    ByteArrayInputStream inputStream = new ByteArrayInputStream(fontByteArray);
                    try {
                        loader.load((InputStream)inputStream, inputStream.available(), false);
                    }
                    catch (FontLoadingException e) {
                        throw new IOExceptionWithCause("Unable to load font from provided font stream", (Throwable)e);
                    }
                }
            }
            if (this.pdfFontSet == null) {
                this.fontSet = new PDFFontSetDefault();
                this.pdfFontSet = this.fontSet.getPdfFontSet();
            }
            ReadingOrderTextExtractor extractor = ReadingOrderTextExtractor.newInstance(document, this.pdfFontSet);
            XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
            xhtml.startDocument();
            Iterator<PDFPage> pageIter = document.requirePages().iterator();
            while (pageIter.hasNext()) {
                PDFPage page = pageIter.next();
                xhtml.startElement("div", "class", "page");
                xhtml.startElement("p");
                ParagraphIterator iterator = extractor.getParagraphIterator(page, page.getIndex());
                while (iterator.hasNext()) {
                    xhtml.startElement("p");
                    List<List<Word>> lines = iterator.next();
                    for (List<Word> line : lines) {
                        for (Word word : line) {
                            xhtml.characters(word.toString());
                        }
                        xhtml.characters("\n");
                    }
                    xhtml.endElement("p");
                }
                xhtml.endElement("p");
                if (this.extractAnnotationText) {
                    xhtml.startElement("div", "class", "annotation");
                    PDFAnnotationIterator annotsIterator = page.getAnnotationsIterator();
                    while (annotsIterator.hasNext()) {
                        String subject;
                        String contents;
                        PDFAnnotation annot = annotsIterator.next();
                        if (!(annot instanceof PDFAnnotationMarkup)) continue;
                        PDFAnnotationMarkup markupAnnot = (PDFAnnotationMarkup)annot;
                        String title = markupAnnot.getTitle();
                        if (title != null) {
                            xhtml.startElement("p", "class", "annotationTitle");
                            xhtml.characters(title);
                            xhtml.endElement("p");
                        }
                        if ((subject = markupAnnot.getSubject()) != null) {
                            xhtml.startElement("p", "class", "annotationSubject");
                            xhtml.characters(subject);
                            xhtml.endElement("p");
                        }
                        if ((contents = markupAnnot.getContents()) == null) continue;
                        xhtml.startElement("p", "class", "annotationContents");
                        xhtml.characters(contents);
                        xhtml.endElement("p");
                    }
                    xhtml.endElement("div");
                }
                xhtml.endElement("div");
            }
            xhtml.endDocument();
        }
        catch (PDFException e) {
            throw new TikaException("PDF parse error", (Throwable)e);
        }
        finally {
            tmp.close();
        }
    }

    private void extractMetadata(PDFDocument document, Metadata metadata) {
        try {
            DocumentMetadata info = XMPService.getDocumentMetadata(document);
            metadata.set(PagedText.N_PAGES, document.requirePages().getCount());
            metadata.set(Metadata.CREATION_DATE, info.getCreationDate());
            metadata.set(Metadata.LAST_MODIFIED, info.getModificationDate());
            this.addMetadata(metadata, "title", info.getTitle());
            this.addMetadata(metadata, "Author", info.getAuthor());
            this.addMetadata(metadata, "creator", info.getCreator());
            this.addMetadata(metadata, "Keywords", info.getKeywordsAsString());
            this.addMetadata(metadata, "producer", info.getProducer());
            this.addMetadata(metadata, "subject", info.getSubject());
            this.addMetadata(metadata, "trapped", info.getTrapped());
            List<String> handledMetadata = Arrays.asList("Author", "Creator", "CreationDate", "ModDate", "Keywords", "Producer", "Subject", "Title", "Trapped");
            List customPropertyNames = info.getCustomPropertyNames();
            if (customPropertyNames != null && customPropertyNames.size() > 0) {
                for (String name : info.getCustomPropertyNames()) {
                    if (handledMetadata.contains(name)) continue;
                    this.addMetadata(metadata, name, info.getCustomProperty(name));
                }
            }
        }
        catch (PDFException e) {
            // empty catch block
        }
    }

    private void addMetadata(Metadata metadata, String name, String value) {
        if (value != null) {
            metadata.add(name, value);
        }
    }

}