I see. That's a tough one.

I'm still learning the PDFBox object model, but is there a reason why we
would need to share a mutable dictionary across different abstractions
(views) like that?

One solution might be that the dictionary (model) be an observable source of
change events and so dependent views properly reflect changes to the model
by updating their cached members.

Alternatively, wrap the shared dictionary object with a single suitable
abstraction that caches the derived objects for all use cases.

The first one is best if the answer is "Yes we need to."  The second is best
if the answer is "No, we do not."

The first solution (event listener) is actually fairly straightforward to
retro-fit.

-----Original Message-----
From: Johannes Koch [mailto:[email protected]] 
Sent: Wednesday, January 20, 2010 1:00 PM
To: [email protected]
Subject: Re: COSDictionariable?

Hi Mel

Martinez, Mel - 1004 - MITLL schrieb:
> This goes to some basic principles of object design.
> 
> When you add state members to an object you should think about the life
> cycle of the member.  I try to follow three basic rules:
> 
> 1) Favor immutability.  I.E. - set state upon initialization and don't
allow
> it to change.  No setters or other mutators (and make the object 'final').
> Immutable objects are gold for optimizing for speed and memory efficiency.
> 
> 2) Use accessor methods.  Even for internal access to a member field, use
a
> getter method.  This allows you to optimize access to the member or to use
> lazy initialization when appropriate.  Let the compiler and runtime
optimize
> the method access away.  You are kidding yourself if you think it is
faster
> to directly access a member field.  This is not C.
> 
> 3) If an object is to have mutable state, all mutation of a member should
be
> through a single point - a setter or a specific mutator.  Do not ever
assign
> the value of the member directly.  This allows you to implement any
caching
> or optimizations in one place.

Agreed.

> So per your question below, so long as all attributes are properly wrapped
> in getter/setters, then the act of pulling their values out of the
> underlying dictionary stream and storing them in instance fields is simply
> done within the accessors.  If you mutate a field, the setter updates the
> dictionary AND the member field.  Per Jukka's comments, that
implementation
> detail is completely hidden behind the getter/setter abstractions.

Consider the following: A PDAnnotation and a PDStructureElement object 
give access to PDPage objects wrapping the same COSDictionary. PDPage 
objects give access to their contents (PDStream). All of these members 
are lazy initialized.

PDAnnotation:

private PDPage page;

public PDPage getPage()
{
   if (this.page == null)
   {
     this.page = new PDPage(
       this.getCOSDictionary().getDictionaryObject(COSName.P));
   }
}


PDStructureElement:

private PDPage page;

public PDPage getPage()
{
   if (this.page == null)
   {
     this.page = new PDPage(
       this.getCOSDictionary().getDictionaryObject("Pg"));
   }
}


PDPage:

private PDStream contents;

public PDStream getContents()
{
   if (this.contents == null)
   {
     this.contents = PDStream.createFromCOS(
       this.getCOSDictionary().getDictionaryObject(COSName.CONTENTS));
   }
   return this.contents;
}

public void setContents(PDStream contents)
{
   this.contents = contents;
   this.getCOSDictionary().setItem(COSName.CONTENTS, contents);
}


Now,

PDAnnotation annotation = ...;
PDStructureElement se = ...;
PDPage pageA = annotation.getPage();
PDPage pageSE = se.getPage();
// COSDictionary for pageA is the same as for pageSE
PDStream streamA = pageA.getContents();
PDStream streamSE = pageSE.getContents();
PDStream stream3 = ...;
pageA.setContents(stream3);

This last operation (change of pageA's contents) will not have any 
influence on pageSE's contents, although the COSDictionary wrapped by 
both PDPage objects will be changed. So pageSE's contents member is not 
in synch with the COSDictionary's entry any more.

-- 
Johannes Koch
Fraunhofer Institute for Applied Information Technology FIT
Web Compliance Center
Schloss Birlinghoven, D-53757 Sankt Augustin, Germany
Phone: +49-2241-142628    Fax: +49-2241-142065

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to