COSObject.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pdfbox.cos;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* This class represents a PDF object.
*
* @author Ben Litchfield
*
*/
public class COSObject extends COSBase implements COSUpdateInfo
{
private COSBase baseObject;
private long objectNumber;
private int generationNumber;
private ICOSParser parser;
private boolean isDereferenced = false;
private final COSUpdateState updateState;
private static final Log LOG = LogFactory.getLog(COSObject.class);
/**
* Constructor.
*
* @param object The object that this encapsulates.
*
*/
public COSObject(COSBase object)
{
updateState = new COSUpdateState(this);
baseObject = object;
isDereferenced = true;
}
/**
* Constructor.
*
* @param object The object that this encapsulates.
* @param objectKey The COSObjectKey of the encapsulated object
*/
public COSObject(COSBase object, COSObjectKey objectKey)
{
this(objectKey, null);
baseObject = object;
isDereferenced = true;
}
/**
* Constructor.
*
* @param object The object that this encapsulates.
* @param parser The parser to be used to load the object on demand
*
*/
public COSObject(COSBase object, ICOSParser parser)
{
updateState = new COSUpdateState(this);
baseObject = object;
isDereferenced = object != null;
this.parser = parser;
}
/**
* Constructor.
*
* @param key The object number of the encapsulated object.
* @param parser The parser to be used to load the object on demand
*
*/
public COSObject(COSObjectKey key, ICOSParser parser)
{
updateState = new COSUpdateState(this);
this.parser = parser;
objectNumber = key.getNumber();
generationNumber = key.getGeneration();
setKey(key);
}
/**
* Indicates if the referenced object is present or not.
*
* @return true if the indirect object is dereferenced
*/
public boolean isObjectNull()
{
return baseObject == null;
}
/**
* This will get the object that this object encapsulates.
*
* @return The encapsulated object.
*/
public COSBase getObject()
{
if (!isDereferenced && parser != null)
{
try
{
// mark as dereferenced to avoid endless recursions
isDereferenced = true;
baseObject = parser.dereferenceCOSObject(this);
getUpdateState().dereferenceChild(baseObject);
}
catch (IOException e)
{
LOG.error("Can't dereference " + this, e);
}
finally
{
parser = null;
}
}
return baseObject;
}
/**
* Sets the referenced object to COSNull and removes the initially assigned parser.
*/
public final void setToNull()
{
if(baseObject != null)
{
getUpdateState().update();
}
baseObject = COSNull.NULL;
parser = null;
}
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
return "COSObject{" + objectNumber + ", " + generationNumber + "}";
}
/**
* Getter for property objectNumber.
* @return Value of property objectNumber.
*/
public long getObjectNumber()
{
return objectNumber;
}
/**
* Getter for property generationNumber.
* @return Value of property generationNumber.
*/
public int getGenerationNumber()
{
return generationNumber;
}
/**
* visitor pattern double dispatch method.
*
* @param visitor The object to notify when visiting this object.
* @throws IOException If an error occurs while visiting this object.
*/
@Override
public void accept( ICOSVisitor visitor ) throws IOException
{
COSBase object = getObject();
if (object != null)
{
object.accept(visitor);
}
else
{
COSNull.NULL.accept(visitor);
}
}
/**
* Returns {@code true}, if the hereby referenced {@link COSBase} has already been parsed and loaded.
*
* @return {@code true}, if the hereby referenced {@link COSBase} has already been parsed and loaded.
*/
public boolean isDereferenced()
{
return isDereferenced;
}
/**
* Returns the current {@link COSUpdateState} of this {@link COSObject}.
*
* @return The current {@link COSUpdateState} of this {@link COSObject}.
* @see COSUpdateState
*/
@Override
public COSUpdateState getUpdateState()
{
return updateState;
}
}