/* * $Id: AnalyzePDF.java,v 1.4 2006/05/30 09:11:45 blowagie Exp $ * $Name: $ * * Copyright 2005 by Anonymous. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.tools.plugins.treeview; import java.io.IOException; import java.util.ArrayList; import java.util.Vector; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import com.lowagie.text.pdf.*; import java.util.Set; import java.util.Iterator; import javax.swing.table.TableModel; import javax.swing.table.AbstractTableModel; public class AnalyzePDF extends Thread implements TreeModel, ICommonAnalyzer { DefaultMutableTreeNode root; DefaultMutableTreeNode filenode; int pagecount; ProgressDialog progressdialog; int numberofpages; ArrayList pageInh = new ArrayList(); private transient Vector treeModelListeners; PdfReader reader; public AnalyzePDF(String infile, com.lowagie.tools.plugins.treeview.ProgressDialog blubb) { this.progressdialog = blubb; try { reader = new PdfReader(infile); root = new SimpletextTreeNode("Dokument"); filenode = new FileTreeNode(infile, reader); root.add(filenode); this.numberofpages = reader.getNumberOfPages(); } catch (IOException ex) { } pagecount = 0; } public TableModel getXReftable() { TableModel tm = new AbstractTableModel() { public int getColumnCount() { return 2; } public int getRowCount() { return reader.getXrefSize() - 1; } public Object getValueAt(int rowIndex, int columnIndex) { switch (columnIndex) { case 0: return new Integer(rowIndex + 1); case 1: PdfObject pdfob=reader.getPdfObject(rowIndex + 1); if(pdfob.isStream()){ return "Stream "+pdfob; }else{ return pdfob; } default: return null; } } /** * Returns the name of the column at columnIndex. * * @param columnIndex the index of the column * @return the name of the column * @todo Implement this javax.swing.table.TableModel method */ public String getColumnName(int columnIndex) { switch (columnIndex) { case 0: return "XRefNr"; case 1: return "Object"; default: return null; } } }; return tm; } /** * Walk down the Pagetree * @param page PdfDictionary * @param pdfreader PdfReader * @param count_in_leaf int * @param node DefaultMutableTreeNode */ protected void iteratePages(PdfDictionary page, PdfReader pdfreader, DefaultMutableTreeNode node) { DefaultMutableTreeNode leaf; PdfArray kidsPR = (PdfArray) PdfReader.getPdfObject(page.get(PdfName.KIDS)); if (kidsPR == null) { node.add(new Pagetreenode(page, pagecount, this, pdfreader)); System.out.println("Page= " + (pagecount + 1)); pageInh.add(pagecount, page); pagecount++; } else { leaf = new PagelistTreeNode(kidsPR); node.add(leaf); page.put(PdfName.TYPE, PdfName.PAGES); ArrayList kids = kidsPR.getArrayList(); for (int k = 0; k < kids.size(); ++k) { PdfDictionary kid = (PdfDictionary) PdfReader.getPdfObject( ( PRIndirectReference) kids.get(k)); iteratePages(kid, pdfreader, leaf); } } } protected void iterateOutlines(PdfDictionary outlines, PdfReader pdfreader, DefaultMutableTreeNode node) { DefaultMutableTreeNode leaf; PdfDictionary kid = outlines; do { PdfString title = (PdfString) pdfreader.getPdfObject( kid.get(PdfName.TITLE)); leaf = new OutlinelistTreeNode(title, kid); node.add(leaf); PdfDictionary first = (PdfDictionary) PdfReader.getPdfObject( ( PRIndirectReference) kid.get(PdfName.FIRST)); if (first != null) { iterateOutlines(first, pdfreader, leaf); } else { PdfDictionary se = (PdfDictionary) PdfReader.getPdfObject( ( PRIndirectReference) kid.get(new PdfName("SE"))); if (se != null) { iterateObjects(se, pdfreader, leaf); } PdfObject dest = (PdfObject) pdfreader.getPdfObject(kid.get(PdfName. DEST)); if (dest != null) { iterateObjects(dest, pdfreader, leaf); } PdfObject a = (PdfObject) pdfreader.getPdfObject(kid.get(PdfName.A)); if (a != null) { iterateObjects(a, pdfreader, leaf); } } } while ( (kid = (PdfDictionary) pdfreader.getPdfObject(kid.get(PdfName.NEXT))) != null); } /** * Recursive investigate PDF Objecttree (other than pagetree objects!) * @param pdfobj PdfObject * @param pdfreader PdfReader * @param node DefaultMutableTreeNode */ public void iterateObjects(PdfObject pdfobj, PdfReader pdfreader, DefaultMutableTreeNode node) { DefaultMutableTreeNode leaf; if (pdfobj.isDictionary()) { leaf = new DictionaryTreeNode("PdfDictionary " + pdfobj, (PdfDictionary) pdfobj); node.add(leaf); Set s = ( (PdfDictionary) pdfobj).getKeys(); Iterator it = s.iterator(); int i = 0; while (it.hasNext()) { i++; Object obj = it.next(); // System.out.println("Feld:" + obj); PdfObject value = PdfReader.getPdfObject( ( (PdfDictionary) pdfobj).get( ( PdfName) obj)); // System.out.println("Value:" + value); SimpletextTreeNode sttn = new SimpletextTreeNode(obj + " " + value); leaf.add(sttn); if (obj.equals(PdfName.PARENT)) { continue; } if (value != null) { iterateObjects(value, pdfreader, sttn); } } } else if (pdfobj.isArray()) { leaf = new ArrayTreeNode("PdfArray " + pdfobj, (PdfArray) pdfobj); node.add(leaf); ArrayList kids = ( (PdfArray) pdfobj).getArrayList(); for (int k = 0; k < kids.size(); ++k) { PdfObject curkid = (PdfObject) kids.get(k); if (curkid.isIndirect()) { PdfObject kid = PdfReader.getPdfObject( ( PRIndirectReference) kids.get(k)); if (kid != null) { iterateObjects(kid, pdfreader, leaf); } } else if (curkid.isNumber()) { } else { PdfObject kid = (PdfObject) kids.get(k); iterateObjects(kid, pdfreader, leaf); } } } else if (pdfobj.isIndirect()) { leaf = new SimpletextTreeNode("PRIndirectReference " + pdfobj); node.add(leaf); PdfObject target = PdfReader.getPdfObject( ( PRIndirectReference) pdfobj); if (target != null) { iterateObjects(target, pdfreader, leaf); } } else if (pdfobj.isBoolean()) { // leaf = new SimpletextTreeNode("Boolean " + pdfobj); // node.add(leaf); } else if (pdfobj.isName()) { // leaf = new SimpletextTreeNode("Name " + pdfobj); // node.add(leaf); } else if (pdfobj.isNull()) { // leaf = new SimpletextTreeNode("Null " + pdfobj); // node.add(leaf); } else if (pdfobj.isNumber()) { // leaf = new SimpletextTreeNode("Number " + pdfobj); // node.add(leaf); } else if (pdfobj.isString()) { // leaf = new SimpletextTreeNode("String " + pdfobj); // node.add(leaf); } else if (pdfobj.isStream()) { leaf = new TextpaneTreeNode(pdfobj,"Stream"); node.add(leaf); leaf = new DictionaryTreeNode("PdfDictionary " + pdfobj, (PdfDictionary) pdfobj); node.add(leaf); Set s = ( (PdfDictionary) pdfobj).getKeys(); Iterator it = s.iterator(); int i = 0; while (it.hasNext()) { i++; Object obj = it.next(); // System.out.println("Feld:" + obj); PdfObject value = PdfReader.getPdfObject( ( (PdfDictionary) pdfobj).get( ( PdfName) obj)); // System.out.println("Value:" + value); SimpletextTreeNode sttn = new SimpletextTreeNode(obj + " " + value); leaf.add(sttn); if (obj.equals(PdfName.PARENT)) { continue; } if (value != null) { iterateObjects(value, pdfreader, sttn); } } } else { leaf = new SimpletextTreeNode("Unknown " + pdfobj); node.add(leaf); } } /** * Returns the root of the tree. * * @return the root of the tree * @todo Diese javax.swing.tree.TreeModel-Methode implementieren */ public Object getRoot() { return root; } /** * Returns the child of parent at index index in the * parent's child array. * * @param parent a node in the tree, obtained from this data source * @param index int * @return the child of parent at index index * @todo Diese javax.swing.tree.TreeModel-Methode implementieren */ public Object getChild(Object parent, int index) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) parent; return node.getChildAt(index); } /** * Returns the number of children of parent. * * @param parent a node in the tree, obtained from this data source * @return the number of children of the node parent * @todo Diese javax.swing.tree.TreeModel-Methode implementieren */ public int getChildCount(Object parent) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) parent; return node.getChildCount(); } /** * Returns true if node is a leaf. * * @param node a node in the tree, obtained from this data source * @return true if node is a leaf * @todo Diese javax.swing.tree.TreeModel-Methode implementieren */ public boolean isLeaf(Object node) { DefaultMutableTreeNode leaf = (DefaultMutableTreeNode) node; return leaf.isLeaf(); } /** * Messaged when the user has altered the value for the item identified by * path to newValue. * * @param path path to the node that the user has altered * @param newValue the new value from the TreeCellEditor * @todo Diese javax.swing.tree.TreeModel-Methode implementieren */ public void valueForPathChanged(TreePath path, Object newValue) { throw new RuntimeException("Manipulation of objecttree not yet supported!"); } /** * Returns the index of child in parent. * * @param parent a note in the tree, obtained from this data source * @param child the node we are interested in * @return the index of the child in the parent, or -1 if either * child or parent are null * @todo Diese javax.swing.tree.TreeModel-Methode implementieren */ public int getIndexOfChild(Object parent, Object child) { DefaultMutableTreeNode parentobj = (DefaultMutableTreeNode) parent; DefaultMutableTreeNode childobj = (DefaultMutableTreeNode) child; return parentobj.getIndex(childobj); } public synchronized void removeTreeModelListener(TreeModelListener l) { if (treeModelListeners != null && treeModelListeners.contains(l)) { Vector v = (Vector) treeModelListeners.clone(); v.removeElement(l); treeModelListeners = v; } } public synchronized void addTreeModelListener(TreeModelListener l) { Vector v = treeModelListeners == null ? new Vector(2) : (Vector) treeModelListeners.clone(); if (!v.contains(l)) { v.addElement(l); treeModelListeners = v; } } protected void fireTreeNodesChanged(TreeModelEvent e) { if (treeModelListeners != null) { Vector listeners = treeModelListeners; int count = listeners.size(); for (int i = 0; i < count; i++) { ( (TreeModelListener) listeners.elementAt(i)).treeNodesChanged(e); } } } protected void fireTreeNodesInserted(TreeModelEvent e) { if (treeModelListeners != null) { Vector listeners = treeModelListeners; int count = listeners.size(); for (int i = 0; i < count; i++) { ( (TreeModelListener) listeners.elementAt(i)).treeNodesInserted(e); } } } protected void fireTreeNodesRemoved(TreeModelEvent e) { if (treeModelListeners != null) { Vector listeners = treeModelListeners; int count = listeners.size(); for (int i = 0; i < count; i++) { ( (TreeModelListener) listeners.elementAt(i)).treeNodesRemoved(e); } } } protected void fireTreeStructureChanged(TreeModelEvent e) { if (treeModelListeners != null) { Vector listeners = treeModelListeners; int count = listeners.size(); for (int i = 0; i < count; i++) { ( (TreeModelListener) listeners.elementAt(i)).treeStructureChanged(e); } } } /** * When an object implementing interface Runnable is used to * create a thread, starting the thread causes the object's run * method to be called in that separately executing thread. * * @todo Diese java.lang.Runnable-Methode implementieren */ public void run() { try { PdfDictionary catalog = reader.getCatalog(); PdfDictionary rootPages = (PdfDictionary) PdfReader.getPdfObject( catalog.get(PdfName.PAGES)); DefaultMutableTreeNode rootPagesGUI = new SimpletextTreeNode("Pagetree " + rootPages); filenode.add(rootPagesGUI); iteratePages(rootPages, reader, rootPagesGUI); PdfDictionary rootOutlines = (PdfDictionary) PdfReader.getPdfObject( catalog.get(PdfName.OUTLINES)); if (rootOutlines != null) { DefaultMutableTreeNode outlinetree = new SimpletextTreeNode( "Outlinetree " + rootOutlines); filenode.add(outlinetree); PdfObject firstindref = rootOutlines.get(PdfName.FIRST); if (firstindref != null) { PdfDictionary first = (PdfDictionary) PdfReader.getPdfObject( ( PRIndirectReference) firstindref); if (first != null) { iterateOutlines(first, reader, outlinetree); } } } System.out.println(" Pagecount= " + pagecount); progressdialog.setVisible(false); } catch (Exception e) { e.printStackTrace(System.out); } } public int getPagecount() { return pagecount; } public void updatecount() { progressdialog.setAktuelleseite(getPagecount()); } }