001/*
002 *  Copyright (c) 2023-2026, Agents-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.agentsflex.core.file2text.extractor.impl;
017
018import com.agentsflex.core.file2text.extractor.FileExtractor;
019import com.agentsflex.core.file2text.source.DocumentSource;
020import org.apache.pdfbox.pdmodel.PDDocument;
021import org.apache.pdfbox.text.PDFTextStripper;
022
023import java.io.IOException;
024import java.io.InputStream;
025import java.util.Collections;
026import java.util.HashSet;
027import java.util.Set;
028
029/**
030 * PDF 文本提取器
031 * 支持标准 PDF(非扫描件)
032 */
033public class PdfTextExtractor implements FileExtractor {
034
035    private static final Set<String> SUPPORTED_MIME_TYPES;
036    private static final Set<String> SUPPORTED_EXTENSIONS;
037
038    static {
039        Set<String> mimeTypes = new HashSet<>();
040        mimeTypes.add("application/pdf");
041        SUPPORTED_MIME_TYPES = Collections.unmodifiableSet(mimeTypes);
042
043        Set<String> extensions = new HashSet<>();
044        extensions.add("pdf");
045        SUPPORTED_EXTENSIONS = Collections.unmodifiableSet(extensions);
046    }
047
048    @Override
049    public boolean supports(DocumentSource source) {
050        String mimeType = source.getMimeType();
051        String fileName = source.getFileName();
052
053        if (mimeType != null && SUPPORTED_MIME_TYPES.contains(mimeType)) {
054            return true;
055        }
056
057        if (fileName != null) {
058            String ext = getExtension(fileName);
059            return "pdf".equalsIgnoreCase(ext);
060        }
061
062        return false;
063    }
064
065    @Override
066    public String extractText(DocumentSource source) throws IOException {
067        try (InputStream is = source.openStream();
068             PDDocument doc = PDDocument.load(is)) {
069            PDFTextStripper stripper = new PDFTextStripper();
070            return stripper.getText(doc).trim();
071        } catch (Exception e) {
072            throw new IOException("Failed to extract PDF text: " + e.getMessage(), e);
073        }
074    }
075
076    @Override
077    public int getOrder() {
078        return 10;
079    }
080
081    private String getExtension(String fileName) {
082        if (fileName == null || !fileName.contains(".")) return null;
083        int lastDot = fileName.lastIndexOf('.');
084        return fileName.substring(lastDot + 1);
085    }
086}