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