aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/General/ConfigurationMember.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/General/ConfigurationMember.cs')
-rw-r--r--OpenSim/Framework/General/ConfigurationMember.cs414
1 files changed, 414 insertions, 0 deletions
diff --git a/OpenSim/Framework/General/ConfigurationMember.cs b/OpenSim/Framework/General/ConfigurationMember.cs
new file mode 100644
index 0000000..c71982a
--- /dev/null
+++ b/OpenSim/Framework/General/ConfigurationMember.cs
@@ -0,0 +1,414 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System;
30using System.Reflection;
31using System.Collections;
32using System.Collections.Generic;
33using System.Text;
34using System.Net;
35
36using libsecondlife;
37
38using OpenSim.Framework.Console;
39using System.Globalization;
40
41namespace OpenSim.Framework
42{
43 public class ConfigurationMember
44 {
45 public delegate bool ConfigurationOptionResult(string configuration_key, object configuration_result);
46 public delegate void ConfigurationOptionsLoad();
47
48 private List<ConfigurationOption> configurationOptions = new List<ConfigurationOption>();
49 private string configurationFilename = "";
50 private string configurationDescription = "";
51
52 private ConfigurationOptionsLoad loadFunction;
53 private ConfigurationOptionResult resultFunction;
54
55 private IGenericConfig configurationPlugin = null;
56 /// <summary>
57 /// This is the default configuration DLL loaded
58 /// </summary>
59 private string configurationPluginFilename = "OpenSim.Framework.Configuration.XML.dll";
60 public ConfigurationMember(string configuration_filename, string configuration_description, ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function)
61 {
62 this.configurationFilename = configuration_filename;
63 this.configurationDescription = configuration_description;
64 this.loadFunction = load_function;
65 this.resultFunction = result_function;
66 }
67
68 public void setConfigurationFilename(string filename)
69 {
70 configurationFilename = filename;
71 }
72 public void setConfigurationDescription(string desc)
73 {
74 configurationDescription = desc;
75 }
76
77 public void setConfigurationResultFunction(ConfigurationOptionResult result)
78 {
79 resultFunction = result;
80 }
81
82 public void forceConfigurationPluginLibrary(string dll_filename)
83 {
84 configurationPluginFilename = dll_filename;
85 }
86 public void addConfigurationOption(string configuration_key, ConfigurationOption.ConfigurationTypes configuration_type, string configuration_question, string configuration_default, bool use_default_no_prompt)
87 {
88 ConfigurationOption configOption = new ConfigurationOption();
89 configOption.configurationKey = configuration_key;
90 configOption.configurationQuestion = configuration_question;
91 configOption.configurationDefault = configuration_default;
92 configOption.configurationType = configuration_type;
93 configOption.configurationUseDefaultNoPrompt = use_default_no_prompt;
94
95 if ((configuration_key != "" && configuration_question != "") || (configuration_key != "" && use_default_no_prompt))
96 {
97 if (!configurationOptions.Contains(configOption))
98 {
99 configurationOptions.Add(configOption);
100 }
101 }
102 else
103 {
104 MainLog.Instance.Notice("Required fields for adding a configuration option is invalid. Will not add this option (" + configuration_key + ")");
105 }
106 }
107
108 public void performConfigurationRetrieve()
109 {
110 configurationPlugin = this.LoadConfigDll(configurationPluginFilename);
111 configurationOptions.Clear();
112 if(loadFunction == null)
113 {
114 MainLog.Instance.Error("Load Function for '" + this.configurationDescription + "' is null. Refusing to run configuration.");
115 return;
116 }
117
118 if(resultFunction == null)
119 {
120 MainLog.Instance.Error("Result Function for '" + this.configurationDescription + "' is null. Refusing to run configuration.");
121 return;
122 }
123
124 MainLog.Instance.Verbose("Calling Configuration Load Function...");
125 this.loadFunction();
126
127 if(configurationOptions.Count <= 0)
128 {
129 MainLog.Instance.Error("No configuration options were specified for '" + this.configurationOptions + "'. Refusing to continue configuration.");
130 return;
131 }
132
133 bool useFile = true;
134 if (configurationPlugin == null)
135 {
136 MainLog.Instance.Error("Configuration Plugin NOT LOADED!");
137 return;
138 }
139
140 if (configurationFilename.Trim() != "")
141 {
142 configurationPlugin.SetFileName(configurationFilename);
143 configurationPlugin.LoadData();
144 useFile = true;
145 }
146 else
147 {
148 MainLog.Instance.Notice("XML Configuration Filename is not valid; will not save to the file.");
149 useFile = false;
150 }
151
152 foreach (ConfigurationOption configOption in configurationOptions)
153 {
154 bool convertSuccess = false;
155 object return_result = null;
156 string errorMessage = "";
157 bool ignoreNextFromConfig = false;
158 while (convertSuccess == false)
159 {
160
161 string console_result = "";
162 string attribute = null;
163 if (useFile)
164 {
165 if (!ignoreNextFromConfig)
166 {
167 attribute = configurationPlugin.GetAttribute(configOption.configurationKey);
168 }
169 else
170 {
171 ignoreNextFromConfig = false;
172 }
173 }
174
175 if (attribute == null)
176 {
177 if (configOption.configurationUseDefaultNoPrompt)
178 {
179 console_result = configOption.configurationDefault;
180 }
181 else
182 {
183
184 if (configurationDescription.Trim() != "")
185 {
186 console_result = MainLog.Instance.CmdPrompt(configurationDescription + ": " + configOption.configurationQuestion, configOption.configurationDefault);
187 }
188 else
189 {
190 console_result = MainLog.Instance.CmdPrompt(configOption.configurationQuestion, configOption.configurationDefault);
191 }
192 }
193 }
194 else
195 {
196 console_result = attribute;
197 }
198
199 switch (configOption.configurationType)
200 {
201 case ConfigurationOption.ConfigurationTypes.TYPE_STRING:
202 return_result = console_result;
203 convertSuccess = true;
204 break;
205 case ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY:
206 if (console_result.Length > 0)
207 {
208 return_result = console_result;
209 convertSuccess = true;
210 }
211 errorMessage = "a string that is not empty";
212 break;
213 case ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN:
214 bool boolResult;
215 if (Boolean.TryParse(console_result, out boolResult))
216 {
217 convertSuccess = true;
218 return_result = boolResult;
219 }
220 errorMessage = "'true' or 'false' (Boolean)";
221 break;
222 case ConfigurationOption.ConfigurationTypes.TYPE_BYTE:
223 byte byteResult;
224 if (Byte.TryParse(console_result, out byteResult))
225 {
226 convertSuccess = true;
227 return_result = byteResult;
228 }
229 errorMessage = "a byte (Byte)";
230 break;
231 case ConfigurationOption.ConfigurationTypes.TYPE_CHARACTER:
232 char charResult;
233 if (Char.TryParse(console_result, out charResult))
234 {
235 convertSuccess = true;
236 return_result = charResult;
237 }
238 errorMessage = "a character (Char)";
239 break;
240 case ConfigurationOption.ConfigurationTypes.TYPE_INT16:
241 short shortResult;
242 if (Int16.TryParse(console_result, out shortResult))
243 {
244 convertSuccess = true;
245 return_result = shortResult;
246 }
247 errorMessage = "a signed 32 bit integer (short)";
248 break;
249 case ConfigurationOption.ConfigurationTypes.TYPE_INT32:
250 int intResult;
251 if (Int32.TryParse(console_result, out intResult))
252 {
253 convertSuccess = true;
254 return_result = intResult;
255
256 }
257 errorMessage = "a signed 32 bit integer (int)";
258 break;
259 case ConfigurationOption.ConfigurationTypes.TYPE_INT64:
260 long longResult;
261 if (Int64.TryParse(console_result, out longResult))
262 {
263 convertSuccess = true;
264 return_result = longResult;
265 }
266 errorMessage = "a signed 32 bit integer (long)";
267 break;
268 case ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS:
269 IPAddress ipAddressResult;
270 if (IPAddress.TryParse(console_result, out ipAddressResult))
271 {
272 convertSuccess = true;
273 return_result = ipAddressResult;
274 }
275 errorMessage = "an IP Address (IPAddress)";
276 break;
277 case ConfigurationOption.ConfigurationTypes.TYPE_LLUUID:
278 LLUUID uuidResult;
279 if (LLUUID.TryParse(console_result, out uuidResult))
280 {
281 convertSuccess = true;
282 return_result = uuidResult;
283 }
284 errorMessage = "a UUID (LLUUID)";
285 break;
286 case ConfigurationOption.ConfigurationTypes.TYPE_LLVECTOR3:
287 LLVector3 vectorResult;
288 if (LLVector3.TryParse(console_result, out vectorResult))
289 {
290 convertSuccess = true;
291 return_result = vectorResult;
292 }
293 errorMessage = "a vector (LLVector3)";
294 break;
295 case ConfigurationOption.ConfigurationTypes.TYPE_UINT16:
296 ushort ushortResult;
297 if (UInt16.TryParse(console_result, out ushortResult))
298 {
299 convertSuccess = true;
300 return_result = ushortResult;
301 }
302 errorMessage = "an unsigned 16 bit integer (ushort)";
303 break;
304 case ConfigurationOption.ConfigurationTypes.TYPE_UINT32:
305 uint uintResult;
306 if (UInt32.TryParse(console_result, out uintResult))
307 {
308 convertSuccess = true;
309 return_result = uintResult;
310
311 }
312 errorMessage = "an unsigned 32 bit integer (uint)";
313 break;
314 case ConfigurationOption.ConfigurationTypes.TYPE_UINT64:
315 ulong ulongResult;
316 if (UInt64.TryParse(console_result, out ulongResult))
317 {
318 convertSuccess = true;
319 return_result = ulongResult;
320 }
321 errorMessage = "an unsigned 64 bit integer (ulong)";
322 break;
323 case ConfigurationOption.ConfigurationTypes.TYPE_FLOAT:
324 float floatResult;
325 if (float.TryParse(console_result, NumberStyles.AllowDecimalPoint, Culture.NumberFormatInfo, out floatResult))
326 {
327 convertSuccess = true;
328 return_result = floatResult;
329 }
330 errorMessage = "a single-precision floating point number (float)";
331 break;
332 case ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE:
333 double doubleResult;
334 if (Double.TryParse(console_result, NumberStyles.AllowDecimalPoint, Culture.NumberFormatInfo, out doubleResult))
335 {
336 convertSuccess = true;
337 return_result = doubleResult;
338 }
339 errorMessage = "an double-precision floating point number (double)";
340 break;
341 }
342
343 if (convertSuccess)
344 {
345 if (useFile)
346 {
347 configurationPlugin.SetAttribute(configOption.configurationKey, console_result);
348 }
349
350
351 if (!this.resultFunction(configOption.configurationKey, return_result))
352 {
353 Console.MainLog.Instance.Notice("The handler for the last configuration option denied that input, please try again.");
354 convertSuccess = false;
355 ignoreNextFromConfig = true;
356 }
357 }
358 else
359 {
360 if (configOption.configurationUseDefaultNoPrompt)
361 {
362 MainLog.Instance.Error("CONFIG", string.Format("[{3}]:[{1}] is not valid default for parameter [{0}].\nThe configuration result must be parsable to {2}.\n", configOption.configurationKey, console_result, errorMessage, configurationFilename));
363 convertSuccess = true;
364 }
365 else
366 {
367 MainLog.Instance.Warn("CONFIG", string.Format("[{3}]:[{1}] is not a valid value [{0}].\nThe configuration result must be parsable to {2}.\n", configOption.configurationKey, console_result, errorMessage, configurationFilename));
368 ignoreNextFromConfig = true;
369 }
370 }
371 }
372 }
373
374 if(useFile)
375 {
376 configurationPlugin.Commit();
377 configurationPlugin.Close();
378 }
379 }
380
381 private IGenericConfig LoadConfigDll(string dllName)
382 {
383 Assembly pluginAssembly = Assembly.LoadFrom(dllName);
384 IGenericConfig plug = null;
385
386 foreach (Type pluginType in pluginAssembly.GetTypes())
387 {
388 if (pluginType.IsPublic)
389 {
390 if (!pluginType.IsAbstract)
391 {
392 Type typeInterface = pluginType.GetInterface("IGenericConfig", true);
393
394 if (typeInterface != null)
395 {
396 plug = (IGenericConfig)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
397 }
398 }
399 }
400 }
401
402 pluginAssembly = null;
403 return plug;
404 }
405
406 public void forceSetConfigurationOption(string configuration_key, string configuration_value)
407 {
408 this.configurationPlugin.LoadData();
409 this.configurationPlugin.SetAttribute(configuration_key, configuration_value);
410 this.configurationPlugin.Commit();
411 this.configurationPlugin.Close();
412 }
413 }
414}