BASKET
Search
PDFlib

interactive/link_destinations

Enumerate all links in the document and determine the destination. The program is capable of printing out information about the following kinds of objects:
Link annotations containing a destination and
Link annotations containing a "GoTo", "GoToE", "GoToR" or "URI" action.

Download Java Code     Show Output     Show Input PDF

package com.pdflib.cookbook.pcos.interactive;


import java.math.BigDecimal;


import com.pdflib.IpCOS;

import com.pdflib.cookbook.pcos.pcos_cookbook_example;


/**

 * Enumerate all links in the document and determine the destination.

 * <p>

 * The program is capable of printing out information about the following kinds

 * of objects:

 *

 * - Link annotations containing a destination

 * - Link annotations containing a "GoTo", "GoToE", "GoToR" or "URI" action

 *

 * 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: link_destinations.java,v 1.8 2015/11/16 11:53:16 stm Exp $

 */

public class link_destinations extends pcos_cookbook_example {


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

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


    public void example_code(IpCOS p, int doc) throws

        Exception {


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


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


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

            final String annots_path = "pages[" + page + "]/annots";


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

            if (objtype.equals("null"))

                continue;


            int anncount = (int) p

                .pcos_get_number(doc, "length:" + annots_path);

            if (anncount == 0)

                continue;


            System.out.println("Link annotations on page " + (page + 1) + ":");

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

                final String annot_path = annots_path + "[" + ann + "]";

                String subtype = p

                    .pcos_get_string(doc, annot_path + "/Subtype");


                if (!subtype.equals("Link"))

                    continue;


                /*

                 * Check whether the annotation is a Link annotation with a

                 * destination.

                 */

                String dest_path = annot_path + "/Dest";

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

                if (objtype.equals("string") || objtype.equals("name")

                    || objtype.equals("array")) {

                    System.out.println("\tAnnotation #" + (ann + 1)

                        + ": Link with destination");

                    print_link_info(p, doc, annot_path, dest_path);

                    continue;

                }


                /*

                 * Check whether the annotation is a Link annotation with an

                 * action.

                 */

                String action_path = annot_path + "/A";

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

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

                    System.out.println("\tAnnotation #" + (ann + 1)

                        + ": Link with action");

                    print_link_action(p, doc, annot_path);

                }

            }

        }

    }


    /**

     * Print out information about a link.

     * <p>

     * This method implements the different options for the destination syntax

     * that are described in chapter "8.2.1 Destinations" in the Adobe PDF

     * Reference 1.7.

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid document handle

     * @param annot_path

     *            The pCOS path to the link annotation dictionary

     * @param dest_path

     *            The pCOS path to the actual destination description

     *

     * @throws Exception

     */

    private void print_link_info(IpCOS p, int doc, String annot_path,

        String dest_path) throws Exception {

        print_rect(p, doc, annot_path);


        String contents_path = annot_path + "/Contents";

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

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

            System.out.println("\t\tDestination contents: \""

                + p.pcos_get_string(doc, contents_path) + "\"");

        }


        int dest_page_number = (int) p.pcos_get_number(doc, annot_path

            + "/destpage");

        if (dest_page_number != -1) {

            System.out.println("\t\tDestination page: " + dest_page_number);

        }


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

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

            String dest_kind = p.pcos_get_string(doc, dest_path + "[1]");


            System.out.print("\t\t\"" + dest_kind + "\" destination: ");


            if (dest_kind.equals("XYZ")) {

                print_dest_value(p, doc, "left", dest_path + "[2]");

                System.out.print(" ");

                print_dest_value(p, doc, "top", dest_path + "[3]");

                System.out.print(" ");

                print_dest_value(p, doc, "zoom", dest_path + "[4]");

            }

            else if (dest_kind.equals("Fit")) {

                System.out.print("<no parameters>");

            }

            else if (dest_kind.equals("FitH")) {

                print_dest_value(p, doc, "top", dest_path + "[2]");

            }

            else if (dest_kind.equals("FitV")) {

                print_dest_value(p, doc, "left", dest_path + "[2]");

            }

            else if (dest_kind.equals("FitR")) {

                print_dest_value(p, doc, "left", dest_path + "[2]");

                System.out.print(" ");

                print_dest_value(p, doc, "bottom", dest_path + "[3]");

                System.out.print(" ");

                print_dest_value(p, doc, "right", dest_path + "[4]");

                System.out.print(" ");

                print_dest_value(p, doc, "top", dest_path + "[5]");

            }

            else if (dest_kind.equals("FitB")) {

                System.out.print("<no parameters>");

            }

            else if (dest_kind.equals("FitBH")) {

                print_dest_value(p, doc, "top", dest_path + "[2]");

            }

            else if (dest_kind.equals("FitBV")) {

                print_dest_value(p, doc, "left", dest_path + "[2]");

            }

            else {

                System.out.println("illegal destination type!");

            }

            System.out.println();

        }

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

            String destination = p.pcos_get_string(doc, dest_path);

            System.out.println("\t\tNamed destination (type string): "

                + destination);

        }

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

            String destination = p.pcos_get_string(doc, dest_path);

            System.out.println("\t\tNamed destination (type name): "

                + destination);

        }

        else {

            System.out.println("\t\tIllegal destination type \"" + objtype);

        }

    }


    /**

     * Print a single value in a destination array.

     * <p>

     * The member can either be a NULL object or a number.

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid document handle

     * @param dest_member_name

     *            The name of the destination array element

     * @param dest_value_path

     *            The pCOS path for the destination array element

     *

     * @throws Exception

     */

    private void print_dest_value(IpCOS p, int doc, String dest_member_name,

        String dest_value_path) throws Exception {

        System.out.print(dest_member_name + " ");


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

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

            System.out.print("NULL");

        }

        else {

            System.out.print(p.pcos_get_number(doc, dest_value_path));

        }

    }


    /**

     * Print out information about the action contained in a Link annotation

     * dictionary.

     * <p>

     * Prints out the "URI", "Goto", "GotoR" and "GotoE" actions stored under

     * the "A" key in a link annotation dictionary (see chapter "8.5.3 Action

     * Types" in the Adobe PDF Reference 1.7).

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid document handle

     * @param annot_path

     *            The pCOS path to the link annotation dictionary

     *

     * @throws Exception

     */

    private void print_link_action(IpCOS p, int doc, String annot_path)

        throws Exception {

        String action_type = p.pcos_get_string(doc, annot_path + "/A/S");


        System.out.println("\t\tAction type: \"" + action_type + "\"");


        if (action_type.equals("URI")) {

            print_uri(p, doc, annot_path);

        }

        else if (action_type.equals("GoTo")) {

            print_goto(p, doc, annot_path);

        }

        else if (action_type.equals("GoToR")) {

            print_goto_r(p, doc, annot_path);

        }

        else if (action_type.equals("GoToE")) {

            print_goto_e(p, doc, annot_path);

        }

        else {

            System.out.print("\t\tAction type \"" + action_type

                + "\" is not analyzed in this Cookbook example...");

        }


        System.out.println();

    }


    /**

     * Prints out information about a Link annotation dictionary containing an

     * "URI" action (see "TABLE 8.56 Additional entries specific to a URI

     * action" in the Adobe PDF Reference 1.7).

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid document handle

     * @param annot_path

     *            The pCOS path to the link annotation dictionary

     *

     * @throws Exception

     */

    private void print_uri(IpCOS p, int doc, String annot_path)

        throws Exception {

        print_rect(p, doc, annot_path);


        String uri_path = annot_path + "/A/URI";

        String uri = p.pcos_get_string(doc, uri_path);

        System.out.println("\t\tURI: " + uri);


        String ismap_path = annot_path + "/A/IsMap";

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

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

            System.out.println("\t\tTrack mouse position: "

                + p.pcos_get_string(doc, ismap_path));

        }

        else {

            System.out.println("\t\tTrack mouse position: <not specified>");

        }

    }


    /**

     * Print out the "Rect" dictionary member for an annotation dictionary. The

     * numbers are rounded to two digits after the decimal point.

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid  document handle

     * @param annot_path

     *            The pCOS path to the link annotation dictionary

     *

     * @throws Exception

     */

    private void print_rect(IpCOS p, int doc, String annot_path)

        throws Exception {

        System.out.print("\t\tAnnotation rectangle: ");

        for (int i = 0; i < 4; i++) {

            BigDecimal value = new BigDecimal(p.pcos_get_number(doc, annot_path

                + "/Rect[" + i + "]"));

            BigDecimal roundedValue = value.setScale(2,

                BigDecimal.ROUND_HALF_UP);

            System.out.print(roundedValue.toString() + " ");

        }

        System.out.println();

    }


    /**

     * Print out information about a Link annotation dictionary containing a

     * "GoTo" action (see "TABLE 8.49 Additional entries specific to a go-to

     * action" in the Adobe PDF Reference 1.7).

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid document handle

     * @param annot_path

     *            The pCOS path to the link annotation dictionary

     *

     * @throws Exception

     */

    private void print_goto(IpCOS p, int doc, String annot_path)

        throws Exception {

        print_action_info(p, doc, annot_path);

    }


    /**

     * Print out information about a link annotation with a "GoToE" action (see

     * "TABLE 8.51 Additional entries specific to an embedded go-to action" in

     * the Adobe PDF Reference 1.7).

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid document handle

     * @param annot_path

     *            The pCOS path to the link annotation dictionary

     *

     * @throws Exception

     */

    private void print_goto_e(IpCOS p, int doc, String annot_path)

        throws Exception {

        print_goto_r_e_common(p, doc, annot_path);

        print_target_dictionary(p, doc, annot_path + "/A/T", "");

    }


    /**

     * Print out information about a Link annotation dictionary containing a

     * "GoToR" action (see "TABLE 8.50 Additional entries specific to a remote

     * go-to action" in the Adobe PDF Reference 1.7).

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid document handle

     * @param annot_path

     *            The pCOS path to the link annotation dictionary

     *

     * @throws Exception

     */

    private void print_goto_r(IpCOS p, int doc, String annot_path)

        throws Exception {

        print_goto_r_e_common(p, doc, annot_path);

    }


    /**

     * Print the common information for the "GoToR" and "GoToE" actions.

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid document handle

     * @param annot_path

     *            The pCOS path to the link annotation dictionary

     *

     * @throws Exception

     */

    private void print_goto_r_e_common(IpCOS p, int doc, String annot_path)

        throws Exception {

        print_action_info(p, doc, annot_path);

        print_filespec(p, doc, annot_path);


        System.out.print("\t\tOpen destination in new window: ");

        String new_window_path = annot_path + "/A/NewWindow";

        if (p.pcos_get_string(doc, "type:" + new_window_path).equals("boolean")) {

            System.out.println(p.pcos_get_string(doc, new_window_path));

        }

        else {

            System.out.println("<not specified>");

        }

    }


    /**

     * Print out information about a target dictionary (see "TABLE 8.52 Entries

     * specific to a target dictionary" in the Adobe PDF Reference 1.7). Target

     * dictionaries can contain target dictionaries, so this routine is

     * recursive.

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid pCOS document handle

     * @param annot_path

     *            The path to the link annotation dictionary

     * @param tabs

     *            A string of \t characters to indent in recursive invocations

     *

     * @throws Exception

     */

    private void print_target_dictionary(IpCOS p, int doc,

        String target_dict_path, String tabs) throws Exception {

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


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

            System.out.println(tabs + "\t\tTarget dictionary:");


            String relationship_path = target_dict_path + "/R";

            String relationship = p.pcos_get_string(doc, relationship_path);

            if (relationship.equals("P")) {

                System.out

                    .println(tabs

                        + "\t\t\tRelationship: Target is parent of current document");

            }

            else if (relationship.equals("C")) {

                System.out

                    .println(tabs

                        + "\t\t\tRelationship: Target is child of current document");


                String embedded_files_name_path = target_dict_path + "/N";

                objtype = p.pcos_get_string(doc, "type:"

                    + embedded_files_name_path);

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

                    System.out.println(tabs

                        + "\t\t\tName of file in EmbeddedFiles name tree: "

                        + p.pcos_get_string(doc, embedded_files_name_path));

                }


                String file_attachment_info_path = target_dict_path + "/P";

                objtype = p.pcos_get_string(doc, "type:"

                    + file_attachment_info_path);

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

                    System.out

                        .println(tabs

                            + "\t\t\tNamed destination for page number of file attachment annotation: "

                            + p.pcos_get_string(doc, file_attachment_info_path));

                }

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

                    int page_number_of_file_attachment_annotation = (int) p

                        .pcos_get_number(doc, file_attachment_info_path);

                    System.out.println(tabs

                        + "\t\t\tPage number of file attachment annotation: "

                        + (page_number_of_file_attachment_annotation + 1));

                }


                String annot_identifier_path = target_dict_path + "/A";

                objtype = p.pcos_get_string(doc, "type:"

                    + annot_identifier_path);

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

                    System.out.println(tabs

                        + "\t\t\tUnique annotation identifier: "

                        + p.pcos_get_string(doc, annot_identifier_path));

                }

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

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

                        annot_identifier_path);

                    System.out.println(tabs

                        + "\t\t\tIndex in \"Annots\" array: " + annot_index);

                }


                /*

                 * Recursive invocation to resolve embedded target dictionaries.

                 * The routine will simple return if there is no target

                 * dictionary present.

                 */

                print_target_dictionary(p, doc, target_dict_path + "/T", tabs

                    + "\t");

            }

            else {

                System.out.println("\t\t\tRelationship: Illegal value "

                    + relationship);

            }

        }

    }


    /**

     * Print out a file specification dictionary (see chapter "3.10.2 File

     * Specification Dictionaries" in the Adobe PDF Reference 1.7).

     * <p>

     * This implementation only looks at the "F", "DOS", "Mac" and "Unix" keys

     * of the dictionary.

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid document handle

     * @param annot_path

     *            The pCOS path to the link annotation dictionary

     *

     * @throws Exception

     */

    private void print_filespec(IpCOS p, int doc, String annot_path)

        throws Exception {

        String filespec_path = annot_path + "/A/F";


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


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

            System.out.println("\t\tFile specification:");


            print_filespec_member(p, doc, filespec_path, "DOS");

            print_filespec_member(p, doc, filespec_path, "Mac");

            print_filespec_member(p, doc, filespec_path, "Unix");

            print_filespec_member(p, doc, filespec_path, "F");

        }

    }


    /**

     * Prints out a member of a file specification dictionary.

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid document handle

     * @param filespec_path

     *            The path to the file specification dictionary

     * @param platform

     *            The member of the file specification dictionary to print

     *

     * @throws Exception

     */

    private void print_filespec_member(IpCOS p, int doc, String filespec_path,

        String platform) throws Exception {

        String platform_path = filespec_path + "/" + platform;

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

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

            System.out.println("\t\t\t" + platform + ": "

                + p.pcos_get_string(doc, platform_path));

        }

    }


    /**

     * Print common information about a Link annotation dictionary containing an

     * action.

     *

     * @param p

     *            An IpCOS object

     * @param doc

     *            A valid document handle

     * @param annot_path

     *            The pCOS path to the link annotation dictionary

     *

     * @throws Exception

     */

    private void print_action_info(IpCOS p, int doc, String annot_path)

        throws Exception {

        print_link_info(p, doc, annot_path, annot_path + "/A/D");

    }


    public link_destinations(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[]) {

        link_destinations example = new link_destinations(argv,

            "Link destinations", SEARCH_PATH,

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

        example.execute();

    }

}