Datei: NDOEnhancer/Enhancer/TypeManager.cs
Last Commit (e72aa8e)
1 | // |
2 | // Copyright (c) 2002-2016 Mirko Matytschak |
3 | // (www.netdataobjects.de) |
4 | // |
5 | // Author: Mirko Matytschak |
6 | // |
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated |
8 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation |
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
10 | // Software, and to permit persons to whom the Software is furnished to do so, subject to the following |
11 | // conditions: |
12 | |
13 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions |
14 | // of the Software. |
15 | // |
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
17 | // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
19 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. |
21 | |
22 | |
23 | #if PRO |
24 | using System; |
25 | using System.Collections; |
26 | using System.Collections.Specialized; |
27 | using System.IO; |
28 | using System.Xml; |
29 | using System.Xml.Serialization; |
30 | using NDO; |
31 | using NDO.Mapping; |
32 | |
33 | namespace NDOEnhancer |
34 | { |
35 | ····/// <summary> |
36 | ····/// This class handles the mapping from types to integer ids. |
37 | ····/// </summary> |
38 | ····internal class TypeManager |
39 | ····{ |
40 | |
41 | ········/// <summary> |
42 | ········/// Map from id to type. |
43 | ········/// </summary> |
44 | ········private Hashtable types = new Hashtable(); |
45 | ········/// <summary> |
46 | ········/// Map from type to id. |
47 | ········/// </summary> |
48 | ········private Hashtable ids = new Hashtable(); |
49 | |
50 | ········private string filename; |
51 | ········private NDOMapping mapping; |
52 | |
53 | ········public TypeManager(string filename, NDOMapping mapping) |
54 | ········{ |
55 | ············this.mapping = mapping; |
56 | ············this.filename = filename; |
57 | ············this.Load(); |
58 | ········} |
59 | |
60 | |
61 | ········public void CheckTypeList(Hashtable allTypes) |
62 | ········{ |
63 | ············foreach(DictionaryEntry e in allTypes) |
64 | ············{ |
65 | ················ClassNode classNode = (ClassNode) e.Value; |
66 | ················if (classNode.IsAbstractOrInterface) |
67 | ····················classNode.IsPoly = true;····// Must be polymorphic |
68 | |
69 | ················// Make sure, all types get a type code |
70 | ················if (!classNode.IsAbstractOrInterface) |
71 | ····················CheckAndAddType(classNode.Name, classNode.AssemblyName); |
72 | |
73 | ················if (classNode.BaseName == null) // Keine Basisklasse angegeben |
74 | ····················continue;····················// sollte eigentlich nicht vorkommen |
75 | ················ClassNode baseNode = (ClassNode)allTypes[classNode.BaseName]; |
76 | ················if (baseNode == null)··// kein persistenter Typ |
77 | ····················continue; |
78 | ················ |
79 | ················if (!baseNode.IsAbstractOrInterface) |
80 | ····················CheckAndAddType(baseNode.Name, baseNode.AssemblyName); |
81 | |
82 | ················baseNode.IsPoly = true; |
83 | ············} |
84 | ············this.Store(); |
85 | ········} |
86 | |
87 | |
88 | ········private void CheckAndAddType(string typeFullName, string assName) |
89 | ········{ |
90 | ············Class cls = this.mapping.FindClass(typeFullName); |
91 | ············if (ids.Contains(cls))··// we have already a type code. |
92 | ················return; |
93 | ············if(cls != null) |
94 | ············{ |
95 | ················// We make sure, that a type of a given name has always the same id. |
96 | ················// Therefore we compute a Hash Code from the type name. |
97 | ················// In the rare case, that two types have the same HashCode, we must decline from |
98 | ················// this rule. |
99 | ················int newId = TypeHashGenerator.GetHash(typeFullName); |
100 | ················while (0 == newId || types.Contains(newId)) |
101 | ····················newId++; |
102 | ················cls.TypeCode = newId; |
103 | ················types[newId] = cls; |
104 | ················ids[cls] = newId; |
105 | ············} |
106 | ········} |
107 | |
108 | ········public Class[] Entries |
109 | ········{ |
110 | ············get |
111 | ············{ |
112 | ················Class[] arr = new Class[types.Count]; |
113 | ················int i = 0; |
114 | ················foreach (DictionaryEntry de in types) |
115 | ····················arr[i++] = (Class)de.Value; |
116 | ················return arr; |
117 | ············} |
118 | ········} |
119 | |
120 | ········public void Load() |
121 | ········{ |
122 | ············foreach (Class cls in mapping.Classes) |
123 | ············{ |
124 | ················if (cls.TypeCode != 0) |
125 | ················{ |
126 | ····················this.types[cls.TypeCode] = cls; |
127 | ····················ids[cls] = cls.TypeCode; |
128 | ················} |
129 | ············} |
130 | ············if (this.types.Count == 0) |
131 | ············{ |
132 | ················FileInfo fi = new FileInfo(filename); |
133 | ················if (fi.Exists) |
134 | ················{ |
135 | ····················XmlSerializer xs = new XmlSerializer(typeof(NDOTypeMapping)); |
136 | ····················using (FileStream fs = |
137 | ······························ fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) |
138 | ····················{ |
139 | ························NDOTypeMapping typeMapping = (NDOTypeMapping)xs.Deserialize(fs); |
140 | ························if (typeMapping.TypeDescriptor != null) |
141 | ························{ |
142 | ····························foreach (NDOTypeDescriptor d in typeMapping.TypeDescriptor) |
143 | ····························{ |
144 | ································Class cls = this.mapping.FindClass(d.TypeName); |
145 | ································if (cls == null)··// NDOTypes.xml describes types which don't exist in this context |
146 | ····································continue; |
147 | ································cls.TypeCode = d.TypeId; |
148 | ································types[d.TypeId] = cls; |
149 | ································ids[cls] = d.TypeId; |
150 | ····························} |
151 | ························} |
152 | ····················} |
153 | ················} |
154 | ············} |
155 | ········} |
156 | |
157 | ········public void Store() |
158 | ········{ |
159 | ············if (File.Exists(this.filename)) |
160 | ············{ |
161 | ················if (!File.Exists(this.filename + ".deprecated")) |
162 | ····················File.Move(this.filename, this.filename + ".deprecated"); |
163 | ················else |
164 | ····················File.Delete(this.filename); |
165 | ············} |
166 | ········} |
167 | |
168 | ········public void Update() |
169 | ········{ |
170 | ············Store(); |
171 | ········} |
172 | ····} |
173 | } |
174 | #endif |
New Commit (dac62ee)
1 | // |
2 | // Copyright (c) 2002-2016 Mirko Matytschak |
3 | // (www.netdataobjects.de) |
4 | // |
5 | // Author: Mirko Matytschak |
6 | // |
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated |
8 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation |
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
10 | // Software, and to permit persons to whom the Software is furnished to do so, subject to the following |
11 | // conditions: |
12 | |
13 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions |
14 | // of the Software. |
15 | // |
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
17 | // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
19 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. |
21 | |
22 | |
23 | #if PRO |
24 | using System; |
25 | using System.Collections; |
26 | using System.Collections.Specialized; |
27 | using System.IO; |
28 | using System.Xml; |
29 | using System.Xml.Serialization; |
30 | using NDO; |
31 | using NDO.Mapping; |
32 | |
33 | namespace NDOEnhancer |
34 | { |
35 | ····/// <summary> |
36 | ····/// This class handles the mapping from types to integer ids. |
37 | ····/// </summary> |
38 | ····internal class TypeManager |
39 | ····{ |
40 | |
41 | ········/// <summary> |
42 | ········/// Map from id to type. |
43 | ········/// </summary> |
44 | ········private Hashtable types = new Hashtable(); |
45 | ········/// <summary> |
46 | ········/// Map from type to id. |
47 | ········/// </summary> |
48 | ········private Hashtable ids = new Hashtable(); |
49 | |
50 | ········private string filename; |
51 | ········private NDOMapping mapping; |
52 | |
53 | ········public TypeManager(string filename, NDOMapping mapping) |
54 | ········{ |
55 | ············this.mapping = mapping; |
56 | ············this.filename = filename; |
57 | ············this.Load(); |
58 | ········} |
59 | |
60 | |
61 | ········public void CheckTypeList(Hashtable allTypes) |
62 | ········{ |
63 | ············foreach(DictionaryEntry e in allTypes) |
64 | ············{ |
65 | ················ClassNode classNode = (ClassNode) e.Value; |
66 | ················if (classNode.IsAbstractOrInterface) |
67 | ····················classNode.IsPoly = true;····// Must be polymorphic |
68 | |
69 | ················// Make sure, all types get a type code |
70 | ················if (!classNode.IsAbstractOrInterface) |
71 | ····················CheckAndAddType(classNode.Name, classNode.AssemblyName); |
72 | |
73 | ················if (classNode.BaseName == null) // Keine Basisklasse angegeben |
74 | ····················continue;····················// sollte eigentlich nicht vorkommen |
75 | ················ClassNode baseNode = (ClassNode)allTypes[classNode.BaseName]; |
76 | ················if (baseNode == null)··// kein persistenter Typ |
77 | ····················continue; |
78 | ················ |
79 | ················if (!baseNode.IsAbstractOrInterface) |
80 | ····················CheckAndAddType(baseNode.Name, baseNode.AssemblyName); |
81 | |
82 | ················baseNode.IsPoly = true; |
83 | ············} |
84 | ············this.Store(); |
85 | ········} |
86 | |
87 | |
88 | ········private void CheckAndAddType(string typeFullName, string assName) |
89 | ········{ |
90 | ············Class cls = this.mapping.FindClass(typeFullName); |
91 | ············if (cls == null) |
92 | ················throw new Exception( $"Can't find class {typeFullName} in the mapping file" ); |
93 | ············if (ids.Contains(cls))··// we have already a type code. |
94 | ················return; |
95 | ············if(cls != null) |
96 | ············{ |
97 | ················// We make sure, that a type of a given name has always the same id. |
98 | ················// Therefore we compute a Hash Code from the type name. |
99 | ················// In the rare case, that two types have the same HashCode, we must decline from |
100 | ················// this rule. |
101 | ················int newId = TypeHashGenerator.GetHash(typeFullName); |
102 | ················while (0 == newId || types.Contains(newId)) |
103 | ····················newId++; |
104 | ················cls.TypeCode = newId; |
105 | ················types[newId] = cls; |
106 | ················ids[cls] = newId; |
107 | ············} |
108 | ········} |
109 | |
110 | ········public Class[] Entries |
111 | ········{ |
112 | ············get |
113 | ············{ |
114 | ················Class[] arr = new Class[types.Count]; |
115 | ················int i = 0; |
116 | ················foreach (DictionaryEntry de in types) |
117 | ····················arr[i++] = (Class)de.Value; |
118 | ················return arr; |
119 | ············} |
120 | ········} |
121 | |
122 | ········public void Load() |
123 | ········{ |
124 | ············foreach (Class cls in mapping.Classes) |
125 | ············{ |
126 | ················if (cls.TypeCode != 0) |
127 | ················{ |
128 | ····················this.types[cls.TypeCode] = cls; |
129 | ····················ids[cls] = cls.TypeCode; |
130 | ················} |
131 | ············} |
132 | ············if (this.types.Count == 0) |
133 | ············{ |
134 | ················FileInfo fi = new FileInfo(filename); |
135 | ················if (fi.Exists) |
136 | ················{ |
137 | ····················XmlSerializer xs = new XmlSerializer(typeof(NDOTypeMapping)); |
138 | ····················using (FileStream fs = |
139 | ······························ fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) |
140 | ····················{ |
141 | ························NDOTypeMapping typeMapping = (NDOTypeMapping)xs.Deserialize(fs); |
142 | ························if (typeMapping.TypeDescriptor != null) |
143 | ························{ |
144 | ····························foreach (NDOTypeDescriptor d in typeMapping.TypeDescriptor) |
145 | ····························{ |
146 | ································Class cls = this.mapping.FindClass(d.TypeName); |
147 | ································if (cls == null)··// NDOTypes.xml describes types which don't exist in this context |
148 | ····································continue; |
149 | ································cls.TypeCode = d.TypeId; |
150 | ································types[d.TypeId] = cls; |
151 | ································ids[cls] = d.TypeId; |
152 | ····························} |
153 | ························} |
154 | ····················} |
155 | ················} |
156 | ············} |
157 | ········} |
158 | |
159 | ········public void Store() |
160 | ········{ |
161 | ············if (File.Exists(this.filename)) |
162 | ············{ |
163 | ················if (!File.Exists(this.filename + ".deprecated")) |
164 | ····················File.Move(this.filename, this.filename + ".deprecated"); |
165 | ················else |
166 | ····················File.Delete(this.filename); |
167 | ············} |
168 | ········} |
169 | |
170 | ········public void Update() |
171 | ········{ |
172 | ············Store(); |
173 | ········} |
174 | ····} |
175 | } |
176 | #endif |