PDFlib
KAUFEN
PDFlib

interactive/javascript

Count javascript occurences in the document.

Download Java Code     Show Output     Show Input PDF

package com.pdflib.cookbook.pcos.interactive;


import com.pdflib.pCOS;

import com.pdflib.pCOSException;

import com.pdflib.cookbook.pcos.pcos_cookbook_example;


/**

 * Count javascript occurences in document.

 * <p>

 * Required software: pCOS interface 3 (pCOS 3.x, PDFlib+PDI/PPS 7.x, TET 2.2,

 * PLOP 3.x) <br>

 * Required data: PDF document

 *

 * @version $Id: javascript.java,v 1.8 2010/09/27 13:24:25 stm Exp $

 */

public class javascript extends pcos_cookbook_example {


    /* This is where the data files are. Adjust as necessary. */

    private final static String SEARCH_PATH = "../input";


    private interface script_info_printer {

        /**

         * Prints information about a JavaScript found in an action dictionary.

         *

         * @param scriptnr

         *            number of the script

         * @param length

         *            length of script in bytes

         */

        void print_info(int scriptnr, int length);

    }


    public void example_code(pCOS p, String filename) throws pCOSException,

        Exception {

        /* Open the PDF document */

        int doc = p.open_document(filename, "");

        if (doc == -1)

            throw new Exception("Error: " + p.get_errmsg());


        System.out.println("File name: " + p.pcos_get_string(doc, "filename"));


        /* Document-level JavaScript */

        int docscripts = get_documentscripts(p, doc);


        /* Open action JavaScript */

        int openscripts = get_openscripts(p, doc);


        /* Page-level JavaScript */

        int pagescripts = get_pagescripts(p, doc);


        /* Annotation-level JavaScript */

        int annotscripts = get_annotscripts(p, doc);


        /* Field-level JavaScript */

        int fieldscripts = get_fieldscripts(p, doc);


        /* Bookmark-level JavaScript */

        int bookmarkscripts = get_bookmarkscripts(p, doc);


        System.out.println();

        System.out.println(openscripts + " JavaScript(s) for open action");

        System.out.println(docscripts + " JavaScript(s) on document level");

        System.out.println(pagescripts + " JavaScript(s) on page level");

        System.out.println(annotscripts + " JavaScript(s) on annotation level");

        System.out.println(fieldscripts + " JavaScript(s) on field level");

        System.out

            .println(bookmarkscripts + " JavaScript(s) on bookmark level");


        p.close_document(doc);

    }


    private class bookmark_info_printer implements script_info_printer {

        private String title;


        bookmark_info_printer(String title) {

            this.title = title;

        }


        public void print_info(int scriptnr, int length) {

            System.out.println("Bookmark '" + title + "', script number "

                + (scriptnr + 1) + ", length=" + length);

        }

    }


    private int get_bookmarkscripts(pCOS p, int doc) throws pCOSException {

        int bookmarkscripts = 0;

        int bookmarkcount = (int) p.pcos_get_number(doc, "length:bookmarks");


        for (int bookmark = 0; bookmark < bookmarkcount; bookmark++) {

            int objid;


            String base = "bookmarks[" + bookmark + "]/A";

            objid = (int) p.pcos_get_number(doc, "pcosid:" + base);


            String bookmark_name = p.pcos_get_string(doc, "bookmarks["

                + bookmark + "]/Title");


            script_info_printer info_printer = new bookmark_info_printer(

                bookmark_name);


            bookmarkscripts += walk_action_dictionary(p, doc, objid, 0,

                info_printer);

        }


        return bookmarkscripts;

    }


    private class field_trigger_info_printer implements script_info_printer {

        private String trigger;

        private String fullname;


        field_trigger_info_printer(String trigger, String fullname) {

            this.trigger = trigger;

            this.fullname = fullname;

        }


        public void print_info(int scriptnr, int length) {

            System.out.println("Form field '" + fullname + "', " + "trigger '"

                + trigger + "', script number " + (scriptnr + 1) + ", length="

                + length);

        }

    }


    private int get_fieldscripts(pCOS p, int doc) throws pCOSException {

        int fieldcount = (int) p.pcos_get_number(doc, "length:fields");

        int fieldscripts = 0;


        for (int field = 0; field < fieldcount; field++) {

            int actioncount = (int) p.pcos_get_number(doc, "length:fields["

                + field + "]/AA");


            for (int action = 0; action < actioncount; action++) {

                String base = "fields[" + field + "]/AA[" + action + "]";

                int objid = (int) p.pcos_get_number(doc, "pcosid:" + base);


                String trigger = p.pcos_get_string(doc, base + ".key");

                String form_field = p.pcos_get_string(doc, "fields[" + field

                    + "]/fullname");


                script_info_printer info_printer = new field_trigger_info_printer(

                    trigger, form_field);


                fieldscripts += walk_action_dictionary(p, doc, objid, 0,

                    info_printer);

            }

        }


        return fieldscripts;

    }


    private class annot_activation_info_printer implements script_info_printer {

        private String subtype;

        private int pagenr;


        annot_activation_info_printer(String subtype, int pagenr) {

            this.subtype = subtype;

            this.pagenr = pagenr;

        }


        public void print_info(int scriptnr, int length) {

            System.out.print("Page " + (pagenr + 1) + ", " + subtype

                + " annotation, script number " + (scriptnr + 1) + ", ");

            System.out.println("activation script, length=" + length);

        }

    }


    private class annot_trigger_info_printer implements script_info_printer {

        private String subtype;

        private String trigger;

        private int pagenr;


        annot_trigger_info_printer(String subtype, String trigger, int pagenr) {

            this.subtype = subtype;

            this.trigger = trigger;

            this.pagenr = pagenr;

        }


        public void print_info(int scriptnr, int length) {

            System.out.print("Page " + (pagenr + 1) + ", " + subtype

                + " annotation, script number " + scriptnr + ", ");


            System.out.println("trigger '" + trigger + "', length=" + length);

        }

    }


    private int get_annotscripts(pCOS p, int doc) throws pCOSException {

        int annotscripts = 0;

        int pagecount = (int) p.pcos_get_number(doc, "length:pages");


        for (int page = 0; page < pagecount; page++) {

            int annotcount = (int) p.pcos_get_number(doc, "length:pages["

                + page + "]/annots");


            for (int ann = 0; ann < annotcount; ann++) {

                /* Avoid double-counting of form field Widgets */

                String subtype = p.pcos_get_string(doc, "pages[" + page

                    + "]/annots[" + ann + "]/Subtype");


                if ("Widget".equals(subtype))

                    continue;


                /* old-style A entry with a single action */

                String base = "pages[" + page + "]/annots[" + ann + "]/A";

                int objid = (int) p.pcos_get_number(doc, "pcosid:" + base);


                script_info_printer info_printer = new annot_activation_info_printer(

                    subtype, page);

                annotscripts += walk_action_dictionary(p, doc, objid, 0,

                    info_printer);


                /* newer AA entry with multiple actions */

                int actioncount = (int) p.pcos_get_number(doc, "length:pages["

                    + page + "]/annots[" + ann + "]/AA");

                for (int action = 0; action < actioncount; action++) {

                    base = "pages[" + page + "]/annots[" + ann + "]/AA["

                        + action + "]";

                    objid = (int) p.pcos_get_number(doc, "pcosid:" + base);


                    String trigger = p.pcos_get_string(doc, base + ".key");


                    info_printer = new annot_trigger_info_printer(subtype,

                        trigger, page);

                    annotscripts += walk_action_dictionary(p, doc, objid, 0,

                        info_printer);

                }

            }

        }


        return annotscripts;

    }


    private class open_action_info_printer implements script_info_printer {

        public void print_info(int scriptnr, int length) {

            System.out.println("Open action script number " + (scriptnr + 1)

                + ", length=" + length);

        }

    }


    private int get_openscripts(pCOS p, int doc) throws pCOSException {

        int openscripts = 0;

        String base = "/Root/OpenAction";


        /*

         * The "OpenAction" entry can be a "destination" or an "action

         * dictionary". Only examine the latter case for JavaScript occurences.

         */

        String type = p.pcos_get_string(doc, "type:" + base);


        if (type.equals("dict")) {

            int objid = (int) p.pcos_get_number(doc, "pcosid:" + base);

            script_info_printer info_printer = new open_action_info_printer();

            openscripts = walk_action_dictionary(p, doc, objid, 0, info_printer);

        }


        return openscripts;

    }


    private class document_info_printer implements script_info_printer {

        private String scriptname;


        document_info_printer(String scriptname) {

            this.scriptname = scriptname;

        }


        public void print_info(int scriptnr, int length) {

            System.out.println("Document-level script '" + scriptname

                + "', length=" + length);

        }

    }


    private class document_action_info_printer implements script_info_printer {

        private String trigger;


        document_action_info_printer(String trigger) {

            this.trigger = trigger;

        }


        public void print_info(int scriptnr, int length) {

            System.out.println("Document-level script, trigger '" + trigger

                + "', number " + (scriptnr + 1) + ", length=" + length);

        }

    }


    private int get_documentscripts(pCOS p, int doc) throws pCOSException {

        int docscripts = 0;


        int scriptcount = (int) p.pcos_get_number(doc,

            "length:names/JavaScript");


        for (int script = 0; script < scriptcount; script++) {

            String base = "names/JavaScript[" + script + "]";

            int objid = (int) p.pcos_get_number(doc, "pcosid:" + base);


            String script_name = p.pcos_get_string(doc, base + ".key");

            script_info_printer info_printer = new document_info_printer(

                script_name);


            if (check_for_script(p, doc, objid, docscripts, info_printer)) {

                docscripts++;

            }

        }


        /* Additional document-level JavaScript */

        int actioncount = (int) p.pcos_get_number(doc, "length:/Root/AA");


        for (int action = 0; action < actioncount; action++) {

            String base = "/Root/AA[" + action + "]";

            int objid = (int) p.pcos_get_number(doc, "pcosid:" + base);

            String trigger = p.pcos_get_string(doc, base + ".key");


            script_info_printer info_printer = new document_action_info_printer(

                trigger);


            docscripts += walk_action_dictionary(p, doc, objid, 0, info_printer);

        }

        return docscripts;

    }


    private class page_info_printer implements script_info_printer {

        private int pagenr;

        private String trigger;


        page_info_printer(int pagenr, String trigger) {

            this.trigger = trigger;

            this.pagenr = pagenr;

        }


        public void print_info(int scriptnr, int length) {

            System.out.println("Page " + (pagenr + 1) + ", trigger '" + trigger

                + "', script number " + (scriptnr + 1) + ", length=" + length);

        }

    }


    private int get_pagescripts(pCOS p, int doc) throws pCOSException {

        int pagecount = (int) p.pcos_get_number(doc, "length:pages");

        int pagescripts = 0;


        for (int page = 0; page < pagecount; page++) {

            int actioncount = (int) p.pcos_get_number(doc, "length:pages["

                + page + "]/AA");


            for (int action = 0; action < actioncount; action++) {

                String base = "pages[" + page + "]/AA[" + action + "]";

                int objid = (int) p.pcos_get_number(doc, "pcosid:" + base);


                String trigger = p.pcos_get_string(doc, base + ".key");


                script_info_printer info_printer = new page_info_printer(page,

                    trigger);


                pagescripts += walk_action_dictionary(p, doc, objid, 0,

                    info_printer);

            }

        }


        return pagescripts;

    }


    /**

     * Traverses an action dictionary.

     * <p>

     * An action dictionary can contain a tree of action definitions, and a

     * subset of them can be JavaScript actions. This routine recursively

     * traverses the action tree and counts the JavaScript occurrences.

     * <p>

     * For the definition of an action dictionary, see for example "8.5.1 Action

     * Dictionaries" in the PDF Reference version 1.7. The

     *

     * @param p

     *            pCOS object

     * @param doc

     *            pCOS document handle

     * @param objid

     *            pCOS id of the action dictionary to traverse

     * @param scriptnr

     *            counter for the JavaScript occurrences in the action

     *            dictionary tree

     * @param info_printer

     *            used to print out the information about the action

     *

     * @return number of scripts found in the action dictionary tree

     *

     * @throws pCOSException

     *             an error was detected in the PDF structure

     */

    private int walk_action_dictionary(pCOS p, int doc, int objid,

        int scriptnr, script_info_printer info_printer) throws pCOSException {

        int scripts = 0;


        while (objid != -1) {

            if (check_for_script(p, doc, objid, scriptnr + scripts,

                info_printer)) {

                scripts += 1;

            }


            String type = p.pcos_get_string(doc, "type:objects[" + objid

                + "]/Next");

            if (type.equals("dict")) {

                objid = (int) p.pcos_get_number(doc, "pcosid:objects[" + objid

                    + "]/Next");

            }

            else if (type.equals("array")) {

                int length = (int) p.pcos_get_number(doc, "length:objects["

                    + objid + "]/Next");

                for (int child = 0; child < length; child += 1) {

                    objid = (int) p.pcos_get_number(doc, "pcosid:objects["

                        + objid + "]/Next[" + child + "]");

                    scripts += walk_action_dictionary(p, doc, objid, scriptnr

                        + scripts, info_printer);

                }

                objid = -1;

            }

            else {

                objid = -1;

            }

        }


        return scripts;

    }


    /**

     * Checks whether the given action dictionary entry is a JavaScript action.

     *

     * @param p

     *            pCOS object

     * @param doc

     *            pCOS document handle

     * @param objid

     *            pCOS id of the action dictionary entry

     * @param scriptnr

     *            counter for the JavaScript occurrences in the action

     *            dictionary tree

     * @param info_printer

     *            for printing the information about the action

     *

     * @return true if a script was found, false otherwise

     * @throws pCOSException

     */

    private boolean check_for_script(pCOS p, int doc, int objid, int scriptnr,

        script_info_printer info_printer) throws pCOSException {

        boolean retval = false;

        String action_dict_obj = "objects[" + objid + "]";

        String objtype = p.pcos_get_string(doc, "type:" + action_dict_obj);


        if (objtype.equals("dict")) {

            /* The action type, not the type of PDF object */

            String actiontype = p.pcos_get_string(doc, action_dict_obj + "/S");


            if (actiontype.equals("JavaScript")) {

                int len;


                String js_path = action_dict_obj + "/JS";


                objtype = p.pcos_get_string(doc, "type:" + js_path);


                if (objtype.equals("string")) {

                    /* fetch string contents to determine length */

                    String js = p.pcos_get_string(doc, js_path);

                    len = js.length();

                }

                else if (objtype.equals("stream")) {

                    /* fetch uncompressed stream data to determine length */

                    byte[] js = p.pcos_get_stream(doc, "convert=unicode",

                        js_path);


                    len = js.length;


                    /* Unicode detection: test for BOM, determine proper length */

                    if (js[0] == 0xFF && js[1] == 0xFE) {

                        len = (len - 2) / 2;

                    }

                }

                else {

                    throw new pCOSException("Could not get JavaScript contents"

                        + "for object with id " + objid);

                }


                /* call the method that prints action-specific information */

                info_printer.print_info(scriptnr, len);


                retval = true;

            }

        }


        return retval;

    }


    public javascript(String[] argv, String readable_name, String search_path,

        String full_rcs_file_name, String revision) {

        super(argv, readable_name, search_path, full_rcs_file_name, revision);

    }


    public static void main(String argv[]) {

        javascript example = new javascript(argv, "JavaScript", SEARCH_PATH,

            "$RCSfile: javascript.java,v $", "$Revision: 1.8 $");

        example.execute();

    }

}