1+ /*==============================================================================================================================
2+ | Author Ignia, LLC
3+ | Client Ignia, LLC
4+ | Project Topics Library
5+ \=============================================================================================================================*/
6+ using System ;
7+ using OnTopic . Collections . Specialized ;
8+ using OnTopic . Repositories ;
9+
10+ namespace OnTopic . References {
11+
12+ /*============================================================================================================================
13+ | CLASS: TOPIC REFERENCE COLLECTION
14+ \---------------------------------------------------------------------------------------------------------------------------*/
15+ /// <summary>
16+ /// Represents a collection of <see cref="Topic"/> objects associated with particular reference keys.
17+ /// </summary>
18+ public class TopicReferenceCollection : TrackedCollection < TopicReference , Topic , ReferenceSetterAttribute > {
19+
20+ /*==========================================================================================================================
21+ | CONSTRUCTOR
22+ \-------------------------------------------------------------------------------------------------------------------------*/
23+ /// <summary>
24+ /// Initializes a new instance of the <see cref="TopicReferenceCollection"/>.
25+ /// </summary>
26+ /// <param name="parentTopic">A reference to the topic that the current collection is bound to.</param>
27+ public TopicReferenceCollection ( Topic parentTopic ) : base ( parentTopic ) { }
28+
29+ /*==========================================================================================================================
30+ | PROPERTY: PARENT COLLECTION
31+ \-------------------------------------------------------------------------------------------------------------------------*/
32+ /// <inheritdoc/>
33+ protected override TrackedCollection < TopicReference , Topic , ReferenceSetterAttribute > ? ParentCollection =>
34+ AssociatedTopic . Parent ? . References ;
35+
36+ /*==========================================================================================================================
37+ | PROPERTY: BASE COLLECTION
38+ \-------------------------------------------------------------------------------------------------------------------------*/
39+ /// <inheritdoc/>
40+ protected override TrackedCollection < TopicReference , Topic , ReferenceSetterAttribute > ? BaseCollection =>
41+ AssociatedTopic . BaseTopic ? . References ;
42+
43+ /*==========================================================================================================================
44+ | IS FULLY LOADED?
45+ \-------------------------------------------------------------------------------------------------------------------------*/
46+ /// <summary>
47+ /// Determines whether or not the collection was fully loaded from the persistence store.
48+ /// </summary>
49+ /// <remarks>
50+ /// <para>
51+ /// When loading an individual <see cref="Topic"/> or branch from the persistence store, it is possible that topic
52+ /// references may not be fully available. In this scenario, updating topic references while e.g. deleting unmatched
53+ /// relationships can result in unintended data loss. To account for this, the <see cref="IsFullyLoaded"/> property '
54+ /// tracks whether a collection was fully loaded from the persistence store; if it wasn't, the <see cref="
55+ /// ITopicRepository"/> should not deleted unmatched topic references.
56+ /// </para>
57+ /// <para>
58+ /// The <see cref="IsFullyLoaded"/> property defaults to <c>true</c>. It should be set to <c>false</c> during the <see cref="
59+ /// ITopicRepository.Load(String?, Topic?, Boolean)"/> method if any members of the collection cannot be mapped back to
60+ /// a valid <see cref="Topic"/> reference in memory.
61+ /// </para>
62+ /// </remarks>
63+ public bool IsFullyLoaded { get ; set ; } = true ;
64+
65+ /*==========================================================================================================================
66+ | INSERT ITEM
67+ \-------------------------------------------------------------------------------------------------------------------------*/
68+ /// <inheritdoc/>
69+ protected override void InsertItem ( int index , TopicReference item ) {
70+
71+ /*------------------------------------------------------------------------------------------------------------------------
72+ | Provide base logic
73+ \-----------------------------------------------------------------------------------------------------------------------*/
74+ base . InsertItem ( index , item ) ;
75+
76+ /*------------------------------------------------------------------------------------------------------------------------
77+ | Handle recipricol references
78+ \-----------------------------------------------------------------------------------------------------------------------*/
79+ item ? . Value ? . IncomingRelationships . SetTopic ( item . Key , AssociatedTopic , null , true ) ;
80+
81+ }
82+
83+ /*==========================================================================================================================
84+ | OVERRIDE: SET ITEM
85+ \-------------------------------------------------------------------------------------------------------------------------*/
86+ /// <inheritdoc/>
87+ protected override void SetItem ( int index , TopicReference item ) {
88+
89+ /*------------------------------------------------------------------------------------------------------------------------
90+ | Get existing reference
91+ \-----------------------------------------------------------------------------------------------------------------------*/
92+ var existingItem = this [ index ] ;
93+
94+ /*------------------------------------------------------------------------------------------------------------------------
95+ | Provide base logic
96+ \-----------------------------------------------------------------------------------------------------------------------*/
97+ base . SetItem ( index , item ) ;
98+
99+ /*------------------------------------------------------------------------------------------------------------------------
100+ | Handle recipricol references
101+ \-----------------------------------------------------------------------------------------------------------------------*/
102+ item ? . Value ? . IncomingRelationships . SetTopic ( item . Key , AssociatedTopic , null , true ) ;
103+ existingItem ? . Value ? . IncomingRelationships . SetTopic ( existingItem . Key , AssociatedTopic , null , true ) ;
104+
105+ }
106+
107+ /*==========================================================================================================================
108+ | OVERRIDE: REMOVE ITEM
109+ \-------------------------------------------------------------------------------------------------------------------------*/
110+ /// <inheritdoc/>
111+ protected override sealed void RemoveItem ( int index ) {
112+
113+ /*------------------------------------------------------------------------------------------------------------------------
114+ | Handle recipricol references
115+ \-----------------------------------------------------------------------------------------------------------------------*/
116+ var existing = this [ index ] ;
117+
118+ existing . Value ? . IncomingRelationships . RemoveTopic ( existing . Key , AssociatedTopic , true ) ;
119+
120+ /*------------------------------------------------------------------------------------------------------------------------
121+ | Provide base logic
122+ \-----------------------------------------------------------------------------------------------------------------------*/
123+ base . RemoveItem ( index ) ;
124+
125+ }
126+
127+ /*==========================================================================================================================
128+ | OVERRIDE: CLEAR ITEMS
129+ \-------------------------------------------------------------------------------------------------------------------------*/
130+ /// <inheritdoc/>
131+ protected override sealed void ClearItems ( ) {
132+
133+
134+ /*------------------------------------------------------------------------------------------------------------------------
135+ | Provide base logic
136+ \-----------------------------------------------------------------------------------------------------------------------*/
137+ base . ClearItems ( ) ;
138+
139+ /*------------------------------------------------------------------------------------------------------------------------
140+ | Handle recipricol references
141+ \-----------------------------------------------------------------------------------------------------------------------*/
142+ foreach ( var item in Items ) {
143+ item . Value ? . IncomingRelationships . RemoveTopic ( item . Key , AssociatedTopic , true ) ;
144+ }
145+
146+ }
147+
148+ } //Class
149+ } //Namespace
0 commit comments