Files
Umbraco-CMS/umbraco.MacroEngines/Scripting/ScriptEngine.cs
hartvig 9dfe873de0 WIP IMacroEngine
[TFS Changeset #81536]
2010-12-06 13:49:34 +00:00

200 lines
6.5 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
namespace umbraco.MacroEngines.Scripting
{
internal class MacroScriptEngine
{
ScriptRuntime m_runTime;
ScriptEngine m_engine;
ExceptionOperations m_exceptionOperations;
SortedDictionary<string, object> m_inputVariables;
SortedDictionary<string, object> m_outputVariables;
string m_script;
MemoryStream m_output;
internal MacroScriptEngine() { }
internal MacroScriptEngine(string scriptType)
{
loadRunTime();
m_engine = m_runTime.GetEngine(scriptType);
m_exceptionOperations = m_engine.GetService<ExceptionOperations>();
}
internal static MacroScriptEngine LoadEngineByFileExtension(string fileExtension)
{
MacroScriptEngine mse = new MacroScriptEngine();
mse.loadRunTime();
mse.m_engine = mse.m_runTime.GetEngineByFileExtension(fileExtension);
mse.m_exceptionOperations = mse.m_engine.GetService<ExceptionOperations>();
return mse;
}
internal static MacroScriptEngine GetEngineByType(string scriptType)
{
MacroScriptEngine mse = new MacroScriptEngine();
mse.loadRunTime();
mse.m_engine = mse.m_runTime.GetEngine(scriptType);
mse.m_exceptionOperations = mse.m_engine.GetService<ExceptionOperations>();
return mse;
}
private void loadRunTime()
{
m_output = new MemoryStream();
m_runTime = ScriptRuntime.CreateFromConfiguration();
m_runTime.IO.SetOutput(m_output, new StreamWriter(m_output));
m_runTime.IO.SetErrorOutput(m_output, new StreamWriter(m_output));
Assembly pluginsAssembly = Assembly.LoadFile(IO.IOHelper.MapPath(IO.SystemDirectories.Bin + "/umbraco.dll"));
m_runTime.LoadAssembly(pluginsAssembly);
m_runTime.LoadAssembly(typeof(String).Assembly);
m_runTime.LoadAssembly(typeof(Uri).Assembly);
m_runTime.LoadAssembly(typeof(umbraco.presentation.nodeFactory.Node).Assembly);
}
internal SortedDictionary<string, object> ScriptVariables
{
set { m_inputVariables = value; }
}
internal SortedDictionary<string, object> OutPutVariables
{
get { return m_outputVariables; }
}
internal string Script
{
set { m_script = value; }
}
internal ExceptionOperations ExceptionOperations
{
get { return m_exceptionOperations; }
}
internal string Evaluate()
{
//Create structures
SourceCodeKind sc = SourceCodeKind.Expression;
ScriptSource source = m_engine.CreateScriptSourceFromString(m_script, sc);
ScriptScope scope = m_engine.CreateScope();
//Fill input variables
foreach (KeyValuePair<string, object> variable in m_inputVariables)
{
scope.SetVariable(variable.Key, variable.Value);
}
string result = "";
try
{
object r = source.Execute(scope);
if (r != null)
result = r.ToString();
}
catch (Exception e)
{
umbraco.BusinessLogic.Log.Add(umbraco.BusinessLogic.LogTypes.Debug, -1, e.ToString());
result = m_exceptionOperations.FormatException(e);
}
return result;
}
internal string Execute()
{
SourceCodeKind sc = SourceCodeKind.Statements;
ScriptSource source = m_engine.CreateScriptSourceFromString(m_script, sc);
ScriptScope scope = m_engine.CreateScope();
//Fill input variables
foreach (KeyValuePair<string, object> variable in m_inputVariables)
{
scope.SetVariable(variable.Key, variable.Value);
}
source.Execute(scope);
m_outputVariables = new SortedDictionary<string, object>();
foreach (string variable in scope.GetVariableNames())
{
m_outputVariables.Add(variable, scope.GetVariable(variable));
}
return ReadFromStream(m_output);
}
internal string ExecuteFile(string path)
{
string rbCode;
// OpenText will strip the BOM and keep the Unicode intact
using (var rdr = File.OpenText(path))
{
rbCode = rdr.ReadToEnd();
}
m_script = rbCode;
return Execute();
}
internal SortedDictionary<string, object> _Execute()
{
//Create structures
SourceCodeKind sc = SourceCodeKind.Statements;
ScriptSource source = m_engine.CreateScriptSourceFromString(m_script, sc);
ScriptScope scope = m_engine.CreateScope();
//Fill input variables
foreach (KeyValuePair<string, object> variable in m_inputVariables)
{
scope.SetVariable(variable.Key, variable.Value);
}
SortedDictionary<string, object> outputVariables = new SortedDictionary<string, object>();
//Execute the script
try
{
source.Execute(scope);
//Recover variables
foreach (string variable in scope.GetVariableNames())
{
outputVariables.Add(variable, scope.GetVariable(variable));
}
}
catch (Exception e)
{
string error = m_exceptionOperations.FormatException(e);
//Do something with the pretty printed error
throw;
}
return outputVariables;
}
private static string ReadFromStream(MemoryStream ms)
{
int length = (int)ms.Length;
Byte[] bytes = new Byte[length];
ms.Seek(0, SeekOrigin.Begin);
ms.Read(bytes, 0, (int)ms.Length);
return Encoding.GetEncoding("utf-8").GetString(bytes, 0, (int)ms.Length);
}
}
}