1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
<sect1 id="observers_in_cobjects">
<title>Observers in cobjects</title>
<para>
Generic observer mechanism described in <xref linkend="general_utils_observers"/>
is used in our cobject implementation. <classname>IProperty</classname> base class implements
<classname>IObserverHandler</classname> interface and so all its descendants are responsible
for notifying about changes (see <xref linkend="kernel_part_cobjects"/>.
</para>
<para>
All cobjects provides <classname>BasicChangeContext</classname> which contains previous value
of changed one. Because complex types can add and remove its elements,
special behaviour is specified. New value given as mandatory parameter
of notify method may be <classname>CNull</classname> if element is deleted from comlex type.
Old value in the context may also <classname>CNull</classname> if element was added. It is
imposible to have both of them <classname>CNull</classname>.
</para>
</sect1>
<sect1 id="observers_in_cpdf">
<title>Observers in CPdf</title>
<para>
CPdf class as PDF file maintainer uses observers for synchronization
of structures which may be changed in two ways. This may occure
because all attributes can be accesible through properties (cobjects)
and also special objects provided by CPdf - CPage for page
manipulation, COutline for outlines manipulation and so on. Special
objects keeps logic of concrete entities and manipulates with cobject
in that way. Property part is without any logic and enables making
changes which are not covered by special objects. This advantage and
extensibility is payed by additional synchronization.
<note>Property tree doesn't know the way how it was changed.</note>
</para>
<sect2 id="page_tree_synchronization">
<title>Page tree synchronization</title>
<para>
Page tree, as mentiont above, can be changed from property site of
view by making changes directly to the <xref linkend="page_tree"/>
or by CPdf using
<programlisting>
CPdf::insertPage
Cpdf::removePage
</programlisting>
methods. Second way is safer, because all necessary workaround are
done correctly here which is not guaranteed by property site, where
any kind of data can be supplied.
</para>
<para>
Synchronization is guarantied by 3 internal
<footnote>
<para>
Classes are internal because they need access to CPdf internals, such as
pageList and protected methods for page tree and page list
consolidation.
</para>
</footnote>
classes which implements <classname>IObserver</classname> interface.
To make their logic easier, each observer is specialized for one
type of change. So that we have
<itemizedlist>
<listitem>
<classname>PageTreeRootObserver</classname> - which is registered on
Pages entry in <xref linkend="document_catalog"/>. If this
value changes, we have to throw away and invalidate all pages
which were returned until now.
</listitem>
<listitem>
<classname>PageTreeNodeObserver</classname> - which is registered on
all intermediate nodes. If any of node's dictionary is changed,
checks whether it is entry which may affect page tree (Kids, Count
or Parent properties are added, removed, or their value is changed).
it has to invalidate all subtree of this node.
</listitem>
<listitem>
<classname>PageTreeKidsObserver</classname> - which is registered on
all elements of intermediate node's Kids array. If any of this
element changes its value (they all should be referencies to Pages
or Page dictionary), original node has to be invalidated and also
its children if it is intermediate node.
</listitem>
</itemizedlist>
Whenever Kids array changes and as a result subtree of intermediate node is
changed, Count entry in node's dictionary has to be changed too and
propagated to the page tree root.
</para>
<para>
All this stuff is implemented by <classname>consolidatePageTree</classname>
and <classname>consolidatePageList</classname> methods in CPdf. For more
implementation details, please see doxygen documentation.
</para>
</sect2>
</sect1>
<sect1 id="observer_cpage">
<title>Observers in CPage</title>
<sect2 id="observer_for_annotation">
<title>Observer for annotation</title>
<para>
CPage stores all CAnnotation instance from its Annots array in
internal <classname>annotStorage</classname>. User can change
annotatations with <classname>addAnnotation</classname> or
<classname>delAnnotation</classname> methods but also by changing
Annots array directly.
</para>
<para>
To prevent from problems with inconsistency, CPage instance
registers <classname>AnnotsArrayWatchDog</classname> observer
implementation on Annots array and all its members (because they are
referencies and someone may change reference value to target which
is not annotation dictionary). Whenever this array changes,
observer will force to reload annotStorage (see doxygen
documentation for more precise information because they are out of
scope of this documentation).
</para>
</sect2>
</sect1>
<!--
<sect1 id="kernel_part_ccontentstream_observers">
<title>Observers in CContentStream</title>
<para>
Content stream object uses observer TODO Jozo - describe Observer
implementation - maybe some image whould be good
</para>
</sect1>
-->
|