/*
Copyright 2006,2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
Contributors:
* Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
This file should be part of the source code distribution of "PDF Clown library"
(the Program): see the accompanying README files for more info.
This Program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later version.
This Program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY, either expressed or implied; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
You should have received a copy of the GNU General Public License along with this
Program (see README files); if not, go to the GNU website (http://www.gnu.org/).
Redistribution and use, with or without modification, are permitted provided that such
redistributions retain the above copyright notice, license and disclaimer, along with
this list of conditions.
*/
using it.stefanochizzolini.clown.documents;
using it.stefanochizzolini.clown.files;
namespace it.stefanochizzolini.clown.objects{
/**
<summary>This is the base high-level representation of a weakly-typed PDF object.</summary>
<remarks>
<para>Its split from the generic PdfObjectWrapper<TDataObject> was forced by
the lack of Java-wildcards-like semantics to support covariance in C# generics,
which caused derived classes (e.g. Page) to be unable to smoothly cast to
supertype-parametered generic types.</para>
<para>For example, an ICollection<PdfObjectWrapper<PdfDictionary>> method parameter
could directly accept collections of PdfObjectWrapper<PdfDictionary> objects only,
while NOT of Page objects (although they inherit from
PdfObjectWrapper<PdfDictionary>). Anyway, this problem (shared with Java, as both
stress type safety excluding covariance) can be addressed within some extent
through the 'where' keyword, but with so limited flexibility that it proves
unwieldy for common use. On the other hand, Java wildcards mechanism (use-site
variance) yields a much better support to solve such an issue.</para>
</remarks>
*/
public abstract class PdfObjectWrapper
{
#region dynamic
#region fields
private PdfDirectObject baseObject;
private PdfIndirectObject container;
#endregion
#region constructors
/**
<param name="baseObject">Base PDF object. MUST be a <see cref="PdfReference"/>
everytime available.</param>
<param name="container">Indirect object containing the base object.</param>
*/
protected PdfObjectWrapper(
PdfDirectObject baseObject,
PdfIndirectObject container
)
{
BaseObject = baseObject;
Container = container;
}
#endregion
#region interface
#region public
/**
<summary>Gets the underlying reference object; if it's not available,
gets the underlying data object.</summary>
*/
public virtual PdfDirectObject BaseObject
{
get{return baseObject;}
protected set{baseObject = value;}
}
/**
<summary>Gets a clone of the object, registered inside the given document context.</summary>
<param name="context">Which document the clone has to be registered in.</param>
*/
public abstract object Clone(
Document context
);
/**
<summary>Gets the indirect object containing the base object.</summary>
<remarks>It's used for update purposes.</remarks>
*/
public PdfIndirectObject Container
{
get
{
return container;
}
internal set
{
// Is base object indirect (self-contained)?
if(baseObject is PdfReference) // Base object is indirect (self-contained).
container = ((PdfReference)baseObject).IndirectObject;
else // Base object is direct (contained).
container = value;
}
}
/**
<summary>Removes the object from its document context.</summary>
<remarks>
<para>The object is no more usable after this method returns.</para>
</remarks>
<returns>Whether the object was actually decontextualized (only indirect objects can be
decontextualize).</returns>
*/
public bool Delete(
)
{
// Is the object indirect?
if(baseObject is PdfReference) // Indirect object.
{
((PdfReference)baseObject).Delete();
return true;
}
else // Direct object.
{return false;}
}
/**
<summary>Gets the document context.</summary>
*/
public Document Document
{get{return container.File.Document;}}
/**
<summary>Gets the file context.</summary>
*/
public File File
{get{return container.File;}}
/**
<summary>Manually update the underlying indirect object.</summary>
*/
public void Update(
)
{container.Update();}
#endregion
#endregion
#endregion
}
}
|