/// <summary>
        /// Creates a Javascript execution environment
        /// </summary>
        /// <param name="fileContainer">The object that will be accessed through Javascript</param>
        /// <param name="javascriptContainer">The text file that contains the javascript</param>
        public ExecutionEnvironment(
            FileHandlerFactoryLocator fileHandlerFactoryLocator,
            IFileContainer javascriptContainer,
            IFileContainer fileContainer,
            SubProcess subProcess,
            ParentScope parentScope)
        {
            _FileHandlerFactoryLocator = fileHandlerFactoryLocator;
            _JavascriptContainer = javascriptContainer;
            _JavascriptLastModified = javascriptContainer.LastModified;

            parentScope.WebHandlersWithThisAsParent.Enqueue(fileContainer.WebHandler);

            object toDiscard;

            ISession ownerSession = FileHandlerFactoryLocator.SessionManagerHandler.CreateSession();

            try
            {
                if (null != fileContainer.Owner)
                    ownerSession.Login(fileContainer.Owner);

                IWebConnection ownerWebConnection = new BlockingShellWebConnection(
                    FileHandlerFactoryLocator.WebServer,
                    ownerSession,
                    fileContainer.FullPath,
                    null,
                    null,
                    new CookiesFromBrowser(),
                    CallingFrom.Web,
                    WebMethod.GET);

                ScopeWrapper = new ScopeWrapper(
                    fileHandlerFactoryLocator,
                    subProcess,
                    fileContainer,
                    parentScope,
                    ownerWebConnection,
                    out toDiscard);
            }
            catch (Exception e)
            {
                // If the Javascript has an error in it, it must be ignored.  If an error were returned, then malformed Javascript could hose the system!
                this._ExecutionEnvironmentErrors = e.ToString();
                log.Error("Error creating scope", e);
            }
            finally
            {
                FileHandlerFactoryLocator.SessionManagerHandler.EndSession(ownerSession.SessionId);
            }
        }
Exemple #2
0
        /// <summary>
        /// Creates a scope wrapper
        /// </summary>
        /// <param name="fileHandlerFactoryLocator"></param>
        /// <param name="webConnection"></param>
        /// <param name="javascript"></param>
        /// <param name="fileContainer"></param>
        /// <param name="constructScopeResults"></param>
        public ScopeWrapper(
            FileHandlerFactoryLocator fileHandlerFactoryLocator,
            SubProcess subProcess,
            IFileContainer fileContainer,
            ParentScope parentScope,
            IWebConnection constructWebConnection,
            out object constructScopeResults)
        {
            _FileContainer = fileContainer;
            _SubProcess = subProcess;
            _ParentScope = parentScope;

            _ScopeId = GetScopeID();

            _FileHandlerFactoryLocator = fileHandlerFactoryLocator;

            constructScopeResults = ConstructScope(constructWebConnection);
        }
        private ParentScope CreateParentScope(IFileContainer javascriptContainer)
        {
            List<string> scriptsToEval = new List<string>();
            List<string> requestedScripts = new List<string>(new string[] { "/API/AJAX_serverside.js", "/API/json2.js" });

            string fileType = null;
            StringBuilder javascriptBuilder = new StringBuilder();
            foreach (string line in javascriptContainer.CastFileHandler<ITextHandler>().ReadLines())
            {
                // find file type
                if (line.Trim().StartsWith("// FileType:"))
                    fileType = line.Substring(12).Trim();

                // Find dependant scripts
                else if (line.Trim().StartsWith("// Scripts:"))
                    foreach (string script in line.Substring(11).Split(','))
                        requestedScripts.Add(script.Trim());

                else
                    javascriptBuilder.AppendFormat("{0}\n", line);
            }

            string javascript = javascriptBuilder.ToString();

            Dictionary<string, MethodInfo> functionsInScope = new Dictionary<string, MethodInfo>();
            List<KeyValuePair<IFileContainer, DateTime>> loadedScriptsModifiedTimes = new List<KeyValuePair<IFileContainer, DateTime>>();
            ISession ownerSession = FileHandlerFactoryLocator.SessionManagerHandler.CreateSession();

            try
            {
                ownerSession.Login(javascriptContainer.Owner);

                IWebConnection ownerWebConnection = new BlockingShellWebConnection(
                    FileHandlerFactoryLocator.WebServer,
                    ownerSession,
                    javascriptContainer.FullPath,
                    null,
                    null,
                    new CookiesFromBrowser(),
                    CallingFrom.Web,
                    WebMethod.GET);

                IEnumerable<ScriptAndMD5> dependantScriptsAndMD5s = FileHandlerFactoryLocator.WebServer.WebComponentResolver.DetermineDependantScripts(
                    requestedScripts,
                    ownerWebConnection);

                // Load static methods that are passed into the Javascript environment as-is
                foreach (Type javascriptFunctionsType in GetTypesThatHaveJavascriptFunctions(fileType))
                    foreach (MethodInfo method in javascriptFunctionsType.GetMethods(BindingFlags.Static | BindingFlags.Public))
                        functionsInScope[method.Name] = method;

                // Load all dependant scripts
                foreach (ScriptAndMD5 dependantScript in dependantScriptsAndMD5s)
                {
                    string scriptName = dependantScript.ScriptName;

                    if (scriptName.Contains("?"))
                        scriptsToEval.Add(ownerWebConnection.ShellTo(scriptName).ResultsAsString);
                    else
                    {
                        IFileContainer scriptFileContainer = FileHandlerFactoryLocator.FileSystemResolver.ResolveFile(scriptName);

                        if (scriptFileContainer.FileHandler is ITextHandler)
                        {
                            loadedScriptsModifiedTimes.Add(new KeyValuePair<IFileContainer, DateTime>(scriptFileContainer, scriptFileContainer.LastModified));
                            scriptsToEval.Add(scriptFileContainer.CastFileHandler<ITextHandler>().ReadAll());
                        }
                        else
                            scriptsToEval.Add(ownerWebConnection.ShellTo(scriptName).ResultsAsString);
                    }
                }

                loadedScriptsModifiedTimes.Add(new KeyValuePair<IFileContainer, DateTime>(javascriptContainer, javascriptContainer.LastModified));

                // Construct Javascript to shell to the "base" webHandler
                HashSet<Type> webHandlerTypes = new HashSet<Type>(FileHandlerFactoryLocator.WebHandlerPlugins);
                if (null != fileType)
                    webHandlerTypes.Add(FileHandlerFactoryLocator.WebHandlerClasses[fileType]);

                string baseWrapper = GetJavascriptWrapperForBase("base", webHandlerTypes);

                scriptsToEval.Add(baseWrapper);
                scriptsToEval.Add(javascript);
                scriptsToEval.Add("if (this.options) options; else null;");

                ParentScope parentScope = new ParentScope(loadedScriptsModifiedTimes, functionsInScope);

                Dictionary<string, object> data = new Dictionary<string, object>();
                data["Scripts"] = scriptsToEval;
                data["Functions"] = functionsInScope.Keys;

                _SubProcess.CreateParentScope(parentScope.ParentScopeId, Thread.CurrentThread.ManagedThreadId, data);
                return parentScope;
            }
            finally
            {
                FileHandlerFactoryLocator.SessionManagerHandler.EndSession(ownerSession.SessionId);
            }
        }