edu.harvard.hul.ois.jhove.module.pdf.Destination Maven / Gradle / Ivy
/**********************************************************************
* Jhove - JSTOR/Harvard Object Validation Environment
* Copyright 2003 by JSTOR and the President and Fellows of Harvard College
**********************************************************************/
package edu.harvard.hul.ois.jhove.module.pdf;
import java.io.IOException;
import edu.harvard.hul.ois.jhove.messages.JhoveMessage;
import edu.harvard.hul.ois.jhove.messages.JhoveMessages;
import edu.harvard.hul.ois.jhove.module.PdfModule;
/**
* Class encapsulating PDF destination objects, which refer
* to a page in the document.
*
* We need to make two different kinds of distinctions: between
* destinations that make an indirect and a direct reference to
* a page; and between destinations that have been reached by
* a direct and an indirect reference. The PDF spec allows
* only one level of indirection, so each of these forms has
* options not available to the other.
*
* We call a destination which has been reached directly an
* unnamed destination, and one which has been reached indirectly
* a named destination. We call a destination which has an
* indirect target an indirect destination, and one which has
* a page object as a target a direct destination. Applying
* the PDF documentation, we find that a destination can never
* be both named and indirect. In other words, there are really
* two cases, involving three kinds of destinations:
*
*
* - An unnamed, direct destination, which refers to the page
* object.
*
- An unnamed, indirect destination, which refers to a
* named, direct destination, which refers to the page object.
*
*/
public final class Destination {
/******************************************************************
* PRIVATE CLASS FIELDS.
******************************************************************/
/* Flag indicating destination is indirect. */
private boolean _indirect = false;
/* Name of indirect destination. */
private PdfSimpleObject _indirectDest;
/* Page object for explicit destination. */
private PdfDictionary _pageDest;
/**
* Constructor. If this is a named destination, the destObj
* may be a PdfArray or a PdfDictionary; if this is not a
* named destination, the destObj may be a PdfSimpleObject
* (encapsulating a Literal or Name) or a PdfDictionary.
*
* @param destObj
* The destination object
* @param module
* The invoking PdfModule
* @param named
* Flag indicating whether this object came
* from a named destination.
*/
public Destination(final PdfObject destObj, final PdfModule module,
final boolean named) throws PdfException {
if (destObj == null) {
throw new IllegalArgumentException("Parameter destObj cannot be null.");
}
if (!named && destObj instanceof PdfSimpleObject) {
_indirect = true;
_indirectDest = (PdfSimpleObject) destObj;
return;
}
PdfArray destArray = null;
try {
if (destObj instanceof PdfArray) {
destArray = (PdfArray) destObj;
// We extract only the page reference, not the view.
_pageDest = findDirectDest(module, destArray);
} else if (named && destObj instanceof PdfDictionary) {
destArray = (PdfArray) ((PdfDictionary) destObj).get("D");
// The D entry is just like the array above.
_pageDest = findDirectDest(module, destArray);
} else {
throw new PdfInvalidException(MessageConstants.PDF_HUL_1); // PDF-HUL-1
}
} catch (ClassCastException e) {
throw new PdfInvalidException(MessageConstants.PDF_HUL_2); // PDF-HUL-2
} catch (IOException e) {
JhoveMessage message = JhoveMessages.getMessageInstance(
MessageConstants.PDF_HUL_3.getId(),
String.format(MessageConstants.PDF_HUL_3.getMessage(), // PDF-HUL-3
e.getLocalizedMessage(), Integer.valueOf(destArray._objNumber)));
throw new PdfInvalidException(message);
}
}
/**
* Returns true
if the destination is indirect.
*/
public boolean isIndirect() {
return _indirect;
}
/**
* Returns the string naming the indirect destination.
* Returns null if the destination is not indirect.
*/
public PdfSimpleObject getIndirectDest() {
return _indirectDest;
}
/**
* Returns the page object dictionary if the destination
* is direct. Returns null if the destination is not
* direct.
*/
public PdfDictionary getPageDest() {
return _pageDest;
}
/**
* Returns the object number of the page object dictionary
* if the destination is direct. Throws a NullPointerException
* otherwise.
*/
public int getPageDestObjNumber() throws NullPointerException {
return _pageDest.getObjNumber();
}
private static PdfDictionary findDirectDest(final PdfModule module,
final PdfArray destObj) throws PdfException, IOException {
return (PdfDictionary) module
.resolveIndirectObject(destObj.getContent().elementAt(0));
}
}