allow profiles to build System.dll with the profile compiler rather than the bootstra...
[mono.git] / mcs / class / System / System.ComponentModel.Design.Serialization / MemberRelationshipService.cs
1 //
2 // System.ComponentModel.Design.Serialization.MemberRelationshipService
3 //
4 // Authors:      
5 //        Ivan N. Zlatev (contact@i-nZ.net)
6 //
7 // (C) 2007 Ivan N. Zlatev
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 #if NET_2_0
31
32 using System;
33 using System.CodeDom;
34 using System.ComponentModel;
35 using System.Collections;
36
37 namespace System.ComponentModel.Design.Serialization
38 {
39         public abstract class MemberRelationshipService
40         {
41
42                 // MSDN: The default implementation stores relationships in a dictionary using weak references
43                 //       so the relationship table does not keep objects alive.
44                 // 
45                 private class MemberRelationshipWeakEntry
46                 {
47
48                         private WeakReference _ownerWeakRef;
49                         private MemberDescriptor _member;
50
51                         public MemberRelationshipWeakEntry (MemberRelationship relation)
52                         {
53                                 _ownerWeakRef = new WeakReference (relation.Owner);
54                                 _member = relation.Member;
55                         }
56
57                         public object Owner {
58                                 get {
59                                         if (_ownerWeakRef.IsAlive)
60                                                 return _ownerWeakRef.Target; 
61                                         return null;
62                                 }
63                         }
64
65                         public MemberDescriptor Member {
66                                 get { return _member; }
67                         }
68
69                         public static bool operator == (MemberRelationshipWeakEntry left, MemberRelationshipWeakEntry right)
70                         {
71                                 if (left.Owner == right.Owner && left.Member == right.Member)
72                                         return true;
73                                 else
74                                         return false;
75                         }
76
77                         public static bool operator != (MemberRelationshipWeakEntry left, MemberRelationshipWeakEntry right)
78                         {
79                                 return !(left == right);
80                         }
81
82                         public override int GetHashCode ()
83                         {
84                                 if (this.Owner != null && _member != null)
85                                         return _member.GetHashCode () ^ _ownerWeakRef.Target.GetHashCode ();
86                                 return base.GetHashCode ();
87                         }
88
89                         public override bool Equals (object o)
90                         {
91                                 if (o is MemberRelationshipWeakEntry) {
92                                         return ((MemberRelationshipWeakEntry) o) == this;
93                                 }
94                                 return false;
95                         }
96                 }
97
98                 private Hashtable _relations;
99
100                 protected MemberRelationshipService ()
101                 {
102                         _relations = new Hashtable ();
103                 }
104
105                 public abstract bool SupportsRelationship (MemberRelationship source, MemberRelationship relationship);
106
107                 protected virtual MemberRelationship GetRelationship (MemberRelationship source)
108                 {
109                         if (source.IsEmpty)
110                                 throw new ArgumentNullException ("source");
111
112                         MemberRelationshipWeakEntry entry = _relations[new MemberRelationshipWeakEntry (source)] as MemberRelationshipWeakEntry;
113                         if (entry != null)
114                                 return new MemberRelationship (entry.Owner, entry.Member);
115                         return MemberRelationship.Empty;
116                 }
117
118                 protected virtual void SetRelationship (MemberRelationship source, MemberRelationship relationship)
119                 {
120                         if (source.IsEmpty)
121                                 throw new ArgumentNullException ("source");
122
123                         if (!relationship.IsEmpty && !this.SupportsRelationship (source, relationship))
124                                 throw new ArgumentException ("Relationship not supported.");
125
126                         _relations[new MemberRelationshipWeakEntry (source)] = new MemberRelationshipWeakEntry (relationship);
127                 }
128
129                 public MemberRelationship this [object owner, MemberDescriptor member] {
130                         get { return GetRelationship (new MemberRelationship (owner,  member)); }
131                         set { SetRelationship (new MemberRelationship (owner,  member), value); }
132                 }
133
134                 public MemberRelationship this [MemberRelationship source] {
135                         get { return GetRelationship (source); }
136                         set { SetRelationship (source, value); }
137                 }
138         }
139 }
140 #endif