
****************************************
Csatolt állományok kinyerése PDF fájlból
****************************************

A tesztelt fájl:

	com.sun.pdfview.attachements.PDFWithFileAttachmentAnnotation.pdf

	Tartalma:
	
		- two_pilots.bmp
		- License.rtf

A csomagot tartalmazó JAR fájl:

	PDFRenderer.jar

A PDFFile osztályban implementált metódus visszaadja a csatolt fájlok listáját:

	public List<Attachement> getAttachements();

Az Attachement osztály tartalmazza a
	- csatolt fájlt nevét
	- csatolt fájl byte tömbjét
	- save(String path) metódust, amellyel közvetlenül elmenthető egy megadott elérési útvonalú fájlba

Az érintett osztályok helye:
	com.sun.pdfview.PDFFile.java
	com.sun.pdfview.Attachement.java
	com.sun.pdfview.attachements.GetAttachementsTest.java

****************************************************************************************

                                   Implementáció

****************************************************************************************
*************** com.sun.pdfview.attachements.GetAttachementsTest.java ******************
****************************************************************************************

    public static void main(String[] args) {
        try {
            String path = GetAttachementsTest.class.getResource("./PDFWithFileAttachmentAnnotation.pdf").getFile();
            ByteBuffer b = ByteBuffer.wrap(getBytesFromFile(new File(path)));
            PDFFile file = new PDFFile(b);
            List<Attachement> attachements = file.getAttachements();
            for (Attachement a : attachements) {
                System.out.println("Save file : "+a.toString());
                a.save(a.getName());
            }
        } catch (IOException ex) {
            Logger.getLogger(GetAttachementsTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Output:
	
	Save file : Attachement{name=two_pilots.bmp, bytes=[B@2d8eef25}
	Save file : Attachement{name=License.rtf, bytes=[B@2f67d81}

****************************************************************************************
**************************  com.sun.pdfview.PDFFile.java *******************************
****************************************************************************************

   public List<Attachement> getAttachements() {
        List<Attachement> list = new ArrayList<>();
        try {
            // store the current position in the buffer
            int startPos = fileBuf.position();

            // move to where this object is
            fileBuf.position(0);

            PDFObject obj;
            do {
                obj = readObject(fileBuf, -1, -1, IdentityDecrypter.getInstance());
                parseAttachement(obj, list);
            } while (obj != null && fileBuf.position() < fileBuf.limit() - 50);

            for (Attachement a : list) {
                a.save(a.getName());
            }

            // reset to the previous position
            fileBuf.position(startPos);
        } catch (IOException ex) {
            Logger.getLogger(PDFFile.class.getName()).log(Level.SEVERE, null, ex);
        }
        return list;
    }

   private String parseFileName(String path) {
        int i = path.lastIndexOf('/');
        int j = path.lastIndexOf('\\');
        int k = Math.max(i, j);
        if (k != -1) {
            return path.substring(k+1);
        }
        return path;
    }

    private void parseAttachement(PDFObject obj, List<Attachement> list) {
        try {
            if (obj.getType() == PDFObject.DICTIONARY) {
                if (obj.isDictType("Filespec")) {
                    Attachement a = new Attachement();
                    HashMap hm = obj.getDictionary();
                    Iterator it = hm.entrySet().iterator();
                    Map.Entry entry;
                    String key;
                    PDFObject o;
                    while (it.hasNext()) {
                        entry = (Map.Entry) it.next();
                        key = (String) entry.getKey();
                        o = (PDFObject) entry.getValue();
                        if (key.equals("F")) {
                            a.setName(parseFileName(o.getStringValue()));
                        }
                        if (key.equals("EF")) {
                            if (o.getType() == PDFObject.DICTIONARY) {
                                HashMap m = o.getDictionary();
                                Iterator i = m.entrySet().iterator();
                                Map.Entry e;
                                PDFObject so;
                                while (i.hasNext()) {
                                    e = (Map.Entry) i.next();
                                    so = (PDFObject) e.getValue();
                                    if (so.getType() == PDFObject.STREAM) {
                                        a.setBytes(so.getStream());
                                    }
                                }
                            }
                        }
                    }
                    list.add(a);
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(PDFFile.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

****************************************************************************************
************************** com.sun.pdfview.Attachement.java ****************************
****************************************************************************************
    

public class Attachement {

    private String name;
    private byte[] bytes;

    public byte[] getBytes() {
        return bytes;
    }

    public void setBytes(byte[] bytes) {
        this.bytes = bytes;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void save(String path) {
        FileOutputStream fos = null;
        try {
            File f = new File(path);
            fos = new FileOutputStream(f);
            fos.write(bytes);
        } catch (Exception ex) {
            Logger.getLogger(Attachement.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                fos.close();
            } catch (IOException ex) {
                Logger.getLogger(Attachement.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    @Override
    public String toString() {
        return "Attachement{" + "name=" + name + ", bytes=" + bytes + '}';
    }
}

