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