0e5040ef9f5f8ada6304594df9e3c1d1d3e28157
[mono.git] / mcs / class / Microsoft.JScript / Microsoft.Vsa / BaseVsaEngine.cs
1 //
2 // BaseVsaEngine.cs: 
3 //
4 // Author:
5 //      Cesar Lopez Nataren (cesar@ciencias.unam.mx)
6 //
7 // (C) 2003, Cesar Lopez Nataren
8 //
9
10 using System;
11 using System.Reflection;
12 using System.Security.Policy;
13 using System.Threading;
14 using Microsoft.JScript;
15 using Microsoft.JScript.Vsa;
16
17 namespace Microsoft.Vsa {
18
19         public abstract class BaseVsaEngine : IVsaEngine {
20                 
21                 private const int ROOT_MONIKER_MAX_SIZE = 256;
22                 private bool monikerAlreadySet;
23                 private string rootMoniker;
24
25                 private bool closed;
26                 private bool busy;
27                 private bool empty;
28                 private bool siteAlreadySet;
29                 private bool running;
30
31                 private bool namespaceNotSet;
32                 private bool supportDebug;
33                 private bool generateDebugInfo;
34                 protected bool compiled;
35                 private bool dirty;
36
37                 private bool initNewCalled;
38
39                 private IVsaSite site;
40                 private IVsaItems items;
41
42                 // its default value has to be "JScript"
43                 private string language;
44
45                 private string version;
46                 private int lcid;
47                 private Assembly assembly;
48                 private Evidence evidence;
49                 private string name;
50                 private string rootNamespace;
51
52                 // FIXME: must set vars to proper values                
53                 internal BaseVsaEngine ()
54                 {}
55
56                 public BaseVsaEngine (string language, string version, bool supportDebug)
57                 {
58                         this.language = language;
59
60                         // FIXME: I think we must ensure that version it's 
61                         // compliant with versionformat Major.Minor.Build.Revision. 
62                         // Not sure about what Exception throw.
63                         this.version = version;
64
65                         this.supportDebug = supportDebug;
66                         this.site = null;
67                         this.rootMoniker = "";
68                         this.running = false;
69                         this.evidence = null;
70                         this.compiled = false;
71                         this.dirty = false;
72
73                         this.lcid = Thread.CurrentThread.CurrentCulture.LCID;
74                         this.name = "";
75                         
76                         this.rootNamespace = "";
77                         this.namespaceNotSet = true;    
78
79                         this.initNewCalled = false;
80                         this.generateDebugInfo = false;
81                         this.closed = false;
82                         this.items = null;
83                         this.siteAlreadySet = false;
84                 }
85
86                 public System._AppDomain AppDomain {
87                         get { throw new NotImplementedException (); }
88                         set { throw new NotImplementedException (); }
89                 }
90
91                 // FIXME: research if we can use "get" Evidence when: running and busy.
92                 public Evidence Evidence {
93                         get { 
94                                 if (closed)
95                                         throw new VsaException (VsaError.EngineClosed);
96                                 else if (!initNewCalled)
97                                         throw new VsaException (VsaError.EngineNotInitialized);
98
99                                 return evidence; 
100                         }
101
102                         set {
103                                 if (closed)
104                                         throw new VsaException (VsaError.EngineClosed);
105                                 else if (running)
106                                         throw new VsaException (VsaError.EngineRunning);
107                                 else if (busy)
108                                         throw new VsaException (VsaError.EngineBusy);
109                                 else if (!initNewCalled)
110                                         throw new VsaException (VsaError.EngineNotInitialized);
111
112                                 evidence = value;
113                         }
114                 }
115
116                 public string ApplicationBase {
117                         get { throw new NotImplementedException (); }
118                         set { throw new NotImplementedException (); }
119                 }
120
121                 public Assembly Assembly {
122                         get {
123                                 if (closed)
124                                         throw new VsaException (VsaError.EngineClosed);
125                                 else if (!running)
126                                         throw new VsaException (VsaError.EngineNotRunning);
127                                 else if (busy)
128                                         throw new VsaException (VsaError.EngineBusy);
129
130                                 return assembly;
131                         }
132                 }
133
134
135                 // FIXME: research if we can "get" it when running and busy.
136                 // FIXME: when do we throw VsaException with 
137                 //        VsaError set to DebugInfoNotSupported?
138
139                 public bool GenerateDebugInfo {
140                         get {
141                                 if (closed)
142                                         throw new VsaException (VsaError.EngineClosed);
143                                 else if (!initNewCalled)
144                                         throw new VsaException (VsaError.EngineNotInitialized);
145
146                                 return generateDebugInfo;
147                         }
148
149                         set {
150                                 if (closed)
151                                         throw new VsaException (VsaError.EngineClosed);
152                                 else if (running)
153                                         throw new VsaException (VsaError.EngineRunning);
154                                 else if (busy)
155                                         throw new VsaException (VsaError.EngineBusy);
156                                 else if (!initNewCalled)
157                                         throw new VsaException (VsaError.EngineNotInitialized);
158                                 else if (!supportDebug)
159                                         throw new VsaException (VsaError.DebugInfoNotSupported);
160
161                                 generateDebugInfo = value;
162                         }
163                 }
164
165                 public bool IsCompiled {
166                         get {                           
167                                 if (dirty)
168                                         return false;
169                                 else if (closed)
170                                         throw new VsaException (VsaError.EngineClosed);
171                                 else if (busy)
172                                         throw new VsaException (VsaError.EngineBusy);
173                                 else if (!initNewCalled)
174                                         throw new VsaException (VsaError.EngineNotInitialized);
175
176                                 return compiled;
177                         }
178                 }
179
180
181                 // FIXME: Research if we can "set" it when running
182                 public bool IsDirty {
183                         set {
184                                 if (closed)
185                                         throw new VsaException (VsaError.EngineClosed);
186
187                                 dirty = value;
188                         }
189
190                         get {
191                                 if (closed)
192                                         throw new VsaException (VsaError.EngineClosed);
193                                 else if (busy)
194                                         throw new VsaException (VsaError.EngineBusy);
195                                 else if (!initNewCalled)
196                                         throw new VsaException (VsaError.EngineNotInitialized);
197
198                                 return dirty;
199                         }
200                 }
201
202                 public bool IsRunning {
203                         get {
204                                 if (closed)
205                                         throw new VsaException (VsaError.EngineClosed);
206                                 else if (busy)
207                                         throw new VsaException (VsaError.EngineBusy);
208                                 else if (!initNewCalled)
209                                         throw new VsaException (VsaError.EngineNotInitialized);
210                                 
211                                 return running;
212                          }
213                 }
214
215                 public IVsaItems Items {
216                         get {
217                                 if (closed)
218                                         throw new VsaException (VsaError.EngineClosed);
219                                 else if (busy)
220                                         throw new VsaException (VsaError.EngineBusy);
221                                 else if (!initNewCalled)
222                                         throw new VsaException (VsaError.EngineNotInitialized);
223
224                                 items = new VsaItems ((VsaEngine) this);
225                                 return items;
226                         }
227                 }
228
229
230                 public string Language {
231                         get {
232                                 if (closed)
233                                         throw new VsaException (VsaError.EngineClosed);
234                                 else if (busy)
235                                         throw new VsaException (VsaError.EngineBusy);
236                                 else if (!initNewCalled)
237                                         throw new VsaException (VsaError.EngineNotInitialized);
238
239                                 return language;
240                         }
241                 }
242
243                 // FIXME: research when LCIDNotSupported gets thrown.
244                 public int LCID {
245                         get { 
246                                 if (closed)
247                                         throw new VsaException (VsaError.EngineClosed);
248                                 else if (busy)
249                                         throw new VsaException (VsaError.EngineBusy);
250                                 else if (!initNewCalled)
251                                         throw new VsaException (VsaError.EngineNotInitialized);
252                                 else if (running)
253                                         throw new VsaException (VsaError.EngineRunning);
254
255                                 return lcid; 
256                         }
257
258                         set { 
259                                 if (closed)
260                                         throw new VsaException (VsaError.EngineClosed);
261                                 else if (busy)
262                                         throw new VsaException (VsaError.EngineBusy);
263                                 else if (!initNewCalled)
264                                         throw new VsaException (VsaError.EngineNotInitialized);
265                                 else if (running)
266                                         throw new VsaException (VsaError.EngineRunning);
267
268                                 lcid = value;
269                         }
270                 }
271
272
273                 // FIXME: we must throw VsaException, VsaError set to EngineNameInUse
274                 // when setting and name is already in use.
275                 public string Name {
276                         get {
277                                 if (closed)
278                                         throw new VsaException (VsaError.EngineClosed);
279                                 else if (busy)
280                                         throw new VsaException (VsaError.EngineBusy);
281                                 else if (!initNewCalled)
282                                         throw new VsaException (VsaError.EngineNotInitialized);
283                                 else if (running)
284                                         throw new VsaException (VsaError.EngineRunning);
285
286                                 return name;
287                         }
288
289                         set {
290                                 if (closed)
291                                         throw new VsaException (VsaError.EngineClosed);
292                                 else if (busy)
293                                         throw new VsaException (VsaError.EngineBusy);
294                                 else if (!initNewCalled)
295                                         throw new VsaException (VsaError.EngineNotInitialized);
296                                 else if (running)
297                                         throw new VsaException (VsaError.EngineRunning);
298
299                                 name = value;
300                         }
301                 }
302
303                 // FIXME: We have to check - when setting - that the moniker 
304                 // is not already in use.           
305                 public string RootMoniker {
306                         get { 
307                                 if (closed)
308                                         throw new VsaException (VsaError.EngineClosed);
309                                 else if (busy)
310                                         throw new VsaException (VsaError.EngineBusy);
311
312                                 return rootMoniker; 
313                         }
314
315                         set {
316                                 if (monikerAlreadySet)
317                                         throw new VsaException (VsaError.RootMonikerAlreadySet);
318                                 else if (closed)
319                                         throw new VsaException (VsaError.EngineClosed);
320                                 else if (busy)
321                                         throw new VsaException (VsaError.EngineBusy);
322                                 else {
323                                         MonikerState state = ValidateRootMoniker (value);
324
325                                         switch (state) {
326                                         case MonikerState.Valid:
327                                                 rootMoniker = value;
328                                                 monikerAlreadySet = true;
329                                                 break;
330
331                                         case MonikerState.Invalid:
332                                                 throw new VsaException (VsaError.RootMonikerInvalid);
333
334                                         case MonikerState.ProtocolInvalid:
335                                                 throw new VsaException (VsaError.RootMonikerProtocolInvalid);
336                                         }
337                                 }
338                         }       
339                 }
340
341                 internal static MonikerState ValidateRootMoniker (string n)
342                 {
343                         if (n == null || n == "" || n.Length > ROOT_MONIKER_MAX_SIZE)
344                                 return MonikerState.Invalid;
345
346                         try {
347                                 Uri uri = new Uri (n);
348                                 string protocol = uri.Scheme;
349
350                                 if (protocol == "http" || protocol == "file" || 
351                                     protocol == "ftp" || protocol == "gopher" || 
352                                     protocol == "https" || protocol == "mailto")
353                                         return MonikerState.ProtocolInvalid;
354
355                                 return MonikerState.Valid;
356
357                         } catch (UriFormatException e) {
358                                 return MonikerState.Invalid;
359                         }
360                 }
361
362
363                 // FIXME: we must check - when setting - that the value is a valid 
364                 // namespace (research what does that mean :-)). If not the case
365                 // VsaException must be thrown, set to VsaError.NamespaceInvalid
366                 public string RootNamespace {
367                         get { 
368                                 if (closed)
369                                         throw new VsaException (VsaError.EngineClosed);
370                                 else if (busy)
371                                         throw new VsaException (VsaError.EngineBusy);
372                                 else if (!initNewCalled)
373                                         throw new VsaException (VsaError.EngineNotInitialized);
374                                 else if (running)
375                                         throw new VsaException (VsaError.EngineRunning);
376
377                                 return rootNamespace; 
378                         }
379
380                         set {
381                                 if (closed)
382                                         throw new VsaException (VsaError.EngineClosed);
383                                 else if (busy)
384                                         throw new VsaException (VsaError.EngineBusy);
385                                 else if (!initNewCalled)
386                                         throw new VsaException (VsaError.EngineNotInitialized);
387                                 else if (running)
388                                         throw new VsaException (VsaError.EngineRunning);
389                                 
390                                 rootNamespace = value;
391                                 namespaceNotSet = false;                                
392                         }
393                 }
394
395                 public IVsaSite Site {
396                         get {
397                                 if (closed)
398                                         throw new VsaException (VsaError.EngineClosed);
399                                 else if (busy)
400                                         throw new VsaException (VsaError.EngineBusy);
401                                 else if (!monikerAlreadySet)
402                                         throw new VsaException (VsaError.RootMonikerNotSet);
403
404                                 return site;
405                         }
406
407                         set {
408                                 if (!monikerAlreadySet)
409                                         throw new VsaException (VsaError.RootMonikerNotSet);
410                                 else if (siteAlreadySet)
411                                         throw new VsaException (VsaError.SiteAlreadySet);
412                                 else if (closed)
413                                         throw new VsaException (VsaError.EngineClosed);
414                                 else if (busy)
415                                         throw new VsaException (VsaError.EngineBusy);
416                                 else if (value == null)
417                                         throw new VsaException (VsaError.SiteInvalid);
418
419                                 site = value;
420                                 siteAlreadySet = true;
421                         }
422                 }
423
424                 //
425                 // Version Format: Major.Minor.Revision.Build
426                 //
427                 public string Version {
428                         get {
429                                 if (closed)
430                                         throw new VsaException (VsaError.EngineClosed);
431                                 else if (busy)
432                                         throw new VsaException (VsaError.EngineBusy);
433                                 else if (!initNewCalled)
434                                         throw new VsaException (VsaError.EngineNotInitialized);
435
436                                 return version;
437                         }
438                 }
439
440                 public virtual void Close ()
441                 {
442                         if (running)
443                                 Reset ();
444                         else if (closed)
445                                 throw new VsaException (VsaError.EngineClosed);
446                         else if (busy)
447                                 throw new VsaException (VsaError.EngineBusy);
448
449                         running = false;
450                         closed = true;
451                 }
452
453
454                 //
455                 // Count that AssemblyExpected exception may be thrown.
456                 //
457                 public virtual bool Compile ()
458                 {
459                         if (closed)
460                                 throw new VsaException (VsaError.EngineClosed);
461                         else if (busy)
462                                 throw new VsaException (VsaError.EngineBusy);
463                         else if (empty)
464                                 throw new VsaException (VsaError.EngineEmpty);
465                         else if (running)
466                                 throw new VsaException (VsaError.EngineRunning);
467                         else if (!initNewCalled)
468                                 throw new VsaException (VsaError.EngineNotInitialized);
469                         else if (namespaceNotSet)
470                                 throw new VsaException (VsaError.RootNamespaceNotSet);
471
472                         return false;
473                 }
474
475                 public virtual object GetOption (string name)
476                 {
477                         object opt;
478                         
479                         try {                   
480                                 opt =  GetSpecificOption (name);
481                         } catch (VsaException e) {
482                                 throw;
483                         }
484                         return opt;
485                 }
486
487                 protected abstract object GetSpecificOption (string name);
488
489                 protected abstract void SetSpecificOption (string name, object val);
490
491                 public virtual void InitNew ()
492                 {
493                         if (closed)
494                                 throw new VsaException (VsaError.EngineClosed);
495                         else if (busy)
496                                 throw new VsaException (VsaError.EngineBusy);
497                         else if (initNewCalled)
498                                 throw new VsaException (VsaError.EngineInitialized);
499                         else if (!monikerAlreadySet)
500                                 throw new VsaException (VsaError.RootMonikerNotSet);
501                         else if (!siteAlreadySet)
502                                 throw new VsaException (VsaError.SiteNotSet);
503
504                         initNewCalled = true;
505                 }
506
507                 public virtual void LoadSourceState (IVsaPersistSite site)
508                 {
509                         throw new NotImplementedException ();
510                 }
511
512                 public virtual void Reset ()
513                 {
514                         if (closed)
515                                 throw new VsaException (VsaError.EngineClosed);
516                         else if (busy)
517                                 throw new VsaException (VsaError.EngineBusy);
518                         else if (!running)
519                                 throw new VsaException (VsaError.EngineNotRunning);
520
521                         running = false;
522                         assembly = null;
523                 }
524
525                 public virtual void RevokeCache ()
526                 {
527                         throw new NotImplementedException ();
528                 }
529
530                 public virtual void Run ()
531                 {
532                         if (closed)
533                                 throw new VsaException (VsaError.EngineClosed);
534                         else if (busy)
535                                 throw new VsaException (VsaError.EngineBusy);
536                         else if (running)
537                                 throw new VsaException (VsaError.EngineRunning);
538                         else if (!monikerAlreadySet)
539                                 throw new VsaException (VsaError.RootMonikerNotSet);
540                         else if (!siteAlreadySet)
541                                 throw new VsaException (VsaError.SiteNotSet);
542                         else if (namespaceNotSet)
543                                 throw new VsaException (VsaError.RootNamespaceNotSet);
544
545                         running = true;
546                 }
547
548                 public virtual void SetOption (string name, object value)
549                 {
550                         dirty = true;
551                 }
552
553                 public virtual void SaveCompiledState (out byte [] pe, out byte [] debugInfo)
554                 {
555                         throw new NotImplementedException ();
556                 }
557
558                 public virtual void SaveSourceState (IVsaPersistSite site)
559                 {
560                         throw new NotImplementedException ();
561                 }
562
563                 public abstract bool IsValidIdentifier (string ident);
564
565                 internal bool Closed {
566                         get { return closed; }
567                 }
568
569                 internal bool Running {
570                         get { return running; }
571                 }
572
573                 internal bool Busy {
574                         get { return busy; }
575                 }
576
577                 internal bool InitNewCalled {
578                         get { return initNewCalled; }
579                         set { initNewCalled = value; }
580                 }
581         }
582
583         public class BaseVsaSite : IVsaSite {
584
585                 public virtual byte [] Assembly {
586                         get { throw new NotImplementedException (); }
587                 }
588
589                 public virtual byte [] DebugInfo {
590                         get { throw new NotImplementedException (); }
591                 }
592
593                 public virtual void GetCompiledState (out byte [] pe, out byte [] debugInfo)
594                 {
595                         throw new NotImplementedException ();
596                 }
597
598                 public virtual object GetEventSourceInstance (string itemName, string eventSourceName)
599                 {
600                         throw new NotImplementedException ();
601                 }
602
603                 public virtual object GetGlobalInstance (string name)
604                 {
605                         throw new NotImplementedException ();
606                 }
607
608                 public virtual void Notify (string notify, object optional)
609                 {
610                         throw new NotImplementedException ();
611                 }
612
613                 public virtual bool OnCompilerError (IVsaError error)
614                 {
615                         throw new NotImplementedException ();
616                 }
617         }
618
619
620         public abstract class BaseVsaStartup {
621
622                 public void SetSite (IVsaSite site)
623                 {
624                         throw new NotImplementedException ();
625                 }
626
627                 public abstract void Startup ();
628                 
629                 public abstract void Shutdown ();
630         }
631
632         internal enum MonikerState {
633                 Valid,
634                 Invalid,
635                 ProtocolInvalid
636         }               
637 }