class ExtractAttachments extends AbstractTool {

    static {
        addVersion("$Id: ExtractAttachments.java 3712 2009-02-20 20:11:31Z xlv $");
    }

    /**
     * Constructs a ExtractAttachements object.
     */
    public ExtractAttachments() {
        FileArgument f = new FileArgument(this, "srcfile",
                "The file you want to operate on", false, new PdfFilter());
        f.setLabel(new PdfInformationPanel());
        arguments.add(f);
    }

    /**
     * Extract the attachments of a PDF.
     *
     * @param args String[]
     */
    public static void main(String[] args) {
        ExtractAttachments tool = new ExtractAttachments();
        if (args.length < 1) {
            System.err.println(tool.getUsage());
        }
        tool.setMainArguments(args);
        tool.execute();
    }

    /**
     * Unpacks a file attachment.
     *
     * @param reader   The object that reads the PDF document
     * @param filespec The dictionary containing the file specifications
     * @param outPath  The path where the attachment has to be written
     * @throws IOException on error
     */
    public static void unpackFile(PdfReader reader, PdfDictionary filespec,
            String outPath) throws IOException {<FILL_FUNCTION_BODY>}

    /**
     * @see com.lowagie.toolbox.AbstractTool#createFrame()
     */
    protected void createFrame() {
        internalFrame = new JInternalFrame("ExtractAttachments", true, false,
                true);
        internalFrame.setSize(300, 80);
        internalFrame.setJMenuBar(getMenubar());
        System.out.println("=== ExtractAttachments OPENED ===");
    }

    /**
     * @see com.lowagie.toolbox.AbstractTool#execute()
     */
    public void execute() {
        try {
            if (getValue("srcfile") == null) {
                throw new InstantiationException(
                        "You need to choose a sourcefile");
            }
            File src = (File) getValue("srcfile");

            // we create a reader for a certain document
            PdfReader reader = new PdfReader(src.getAbsolutePath());
            final File parentFile = src.getParentFile();
            final String outPath;
            if (parentFile != null) {
                outPath = parentFile.getAbsolutePath();
            } else {
                outPath = "";
            }
            PdfDictionary catalog = reader.getCatalog();
            PdfDictionary names = catalog.getAsDict(PdfName.NAMES);
            if (names != null) {
                PdfDictionary embFiles = names.getAsDict(new PdfName("EmbeddedFiles"));
                if (embFiles != null) {
                    HashMap<String, PdfObject> embMap = PdfNameTree.readTree(embFiles);
                    for (PdfObject pdfObject : embMap.values()) {
                        PdfDictionary filespec = (PdfDictionary) PdfReader
                                .getPdfObject(pdfObject);
                        unpackFile(reader, filespec, outPath);
                    }
                }
            }
            for (int k = 1; k <= reader.getNumberOfPages(); ++k) {
                PdfArray annots = reader.getPageN(k).getAsArray(PdfName.ANNOTS);
                if (annots == null) {
                    continue;
                }
                for (PdfObject pdfObject : annots.getElements()) {
                    PdfDictionary annot = (PdfDictionary) PdfReader.getPdfObject(pdfObject);
                    PdfName subType = annot.getAsName(PdfName.SUBTYPE);
                    if (!PdfName.FILEATTACHMENT.equals(subType)) {
                        continue;
                    }
                    PdfDictionary filespec = annot.getAsDict(PdfName.FS);
                    unpackFile(reader, filespec, outPath);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param arg StringArgument
     * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument)
     */
    public void valueHasChanged(AbstractArgument arg) {
        if (internalFrame == null) {
            // if the internal frame is null, the tool was called from the
            // command line
            return;
        }
        // represent the changes of the argument in the internal frame
    }

    /**
     * @return File
     * @throws InstantiationException on error
     * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF()
     */
    protected File getDestPathPDF() throws InstantiationException {
        throw new InstantiationException("There is more than one destfile.");
    }

}

        if (filespec == null) {
            return;
        }
        PdfName type = filespec.getAsName(PdfName.TYPE);
        if (!PdfName.F.equals(type) && !PdfName.FILESPEC.equals(type)) {
            return;
        }
        PdfDictionary ef = filespec.getAsDict(PdfName.EF);
        if (ef == null) {
            return;
        }
        PdfString fn = filespec.getAsString(PdfName.F);
        System.out.println("Unpacking file '" + fn + "' to " + outPath);
        if (fn == null) {
            return;
        }
        File fLast = new File(fn.toUnicodeString());
        File fullPath = new File(outPath, fLast.getName());
        if (fullPath.exists()) {
            return;
        }
        PRStream prs = (PRStream) PdfReader.getPdfObject(ef.get(PdfName.F));
        if (prs == null) {
            return;
        }
        byte[] b = PdfReader.getStreamBytes(prs);
        FileOutputStream fout = new FileOutputStream(fullPath);
        fout.write(b);
        fout.close();
    
<methods>public void <init>() ,public void actionPerformed(java.awt.event.ActionEvent) ,public abstract void execute() ,public ArrayList<com.lowagie.toolbox.arguments.AbstractArgument> getArguments() ,public javax.swing.JInternalFrame getInternalFrame() ,public javax.swing.JMenuBar getMenubar() ,public java.lang.String getUsage() ,public java.lang.Object getValue(java.lang.String) throws java.lang.InstantiationException,public void setArguments(ArrayList<com.lowagie.toolbox.arguments.AbstractArgument>) ,public void setInternalFrame(javax.swing.JInternalFrame) ,public void setMainArguments(java.lang.String[]) ,public void setMenubar(javax.swing.JMenuBar) ,public abstract void valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) <variables>public static final int MENU_EXECUTE,public static final int MENU_EXECUTE_PRINT,public static final int MENU_EXECUTE_PRINT_SILENT,public static final int MENU_EXECUTE_SHOW,protected ArrayList<com.lowagie.toolbox.arguments.AbstractArgument> arguments,private java.awt.Desktop awtdesktop,protected javax.swing.JInternalFrame internalFrame,private javax.swing.JMenuBar menubar,protected int menuoptions,public static ArrayList<java.lang.String> versionsarray