public string ExposedAbout(ExecutionContext ctx) { ctx.AddCacheRule(CacheRuleForFederationProperties); return AboutWikiString; }
public ContentBase ExposedContentBaseForNamespace(ExecutionContext ctx, string ns) { ctx.AddCacheRule(this.CacheRuleForNamespaces); ContentBase answer = ContentBaseForNamespace(ns); if (answer != null) { ctx.AddCacheRule(answer.CacheRuleForDefinition); } return answer; }
public IBELObject EvaluateToObject(TopicContext topicContext, Hashtable externalWikimap) { _CacheRules = new ArrayList(); if (ParseTree == null) { ErrorString = "Expression can not be evaluated; parse failed."; State = InterpreterState.EvaluationFailure; return null; } ExecutionContext ctx = new ExecutionContext(topicContext); ctx.WikiTalkVersion = WikiTalkVersion; IBELObject answer = null; try { ctx.ExternalWikiMap = externalWikimap; IScope theScope = null; ctx.Presenter = Presenter; TopicInfo topic = topicContext != null ? topicContext.CurrentTopic : null; if (topic != null && topic.Fullname != null) { // Locate any topics via the NamespaceWith property to see if there's anybody else we should import (for all topics in the namespace) ArrayList nswith = topicContext.CurrentFederation.GetTopicInfo(ctx, topicContext.CurrentTopic.ContentBase.DefinitionTopicName.Fullname).GetListProperty("NamespaceWith"); if (nswith != null) { nswith.Reverse(); foreach (string top in nswith) { AbsoluteTopicName abs = topic.ContentBase.UnambiguousTopicNameFor(new RelativeTopicName(top)); if (abs == null) { throw new Exception("No such topic: " + top + " (as specifed in NamespaceWith: property for " + topicContext.CurrentTopic.ContentBase.DefinitionTopicName.Fullname + ")"); } theScope = new TopicScope(theScope, new DynamicTopic(topic.Federation, abs)); ctx.AddCacheRule(new TopicsCacheRule(topic.Federation, abs)); } } // Locate any topics via the with property to see if there's anybody else we should import ArrayList with = topicContext.CurrentTopic.GetListProperty("With"); if (with != null) { with.Reverse(); foreach (string top in with) { AbsoluteTopicName abs = topic.ContentBase.UnambiguousTopicNameFor(new RelativeTopicName(top)); if (abs == null) { throw new Exception("No such topic: " + top + " (as specifed in With: property for " + topicContext.CurrentTopic + ")"); } theScope = new TopicScope(theScope, new DynamicTopic(topic.Federation, abs)); ctx.AddCacheRule(new TopicsCacheRule(topic.Federation, abs)); } } // add the topic to the current scope (this guy goes at the front of the queue!) theScope = new TopicScope(theScope, new DynamicTopic(topic.Federation, topic.Fullname)); } if (theScope != null) ctx.PushScope(theScope); // make sure we can use local references // parse tree -> live objects answer = ParseTree.Expose(ctx); if (theScope != null) ctx.PopScope(); _CacheRules = ctx.CacheRules; } catch (Exception e) { _CacheRules = ctx.CacheRules; ErrorString = e.Message; State = InterpreterState.EvaluationFailure; return null; } State = InterpreterState.EvaluationSuccess; return answer; }
public DynamicTopic DynamicTopicForTopic(ExecutionContext ctx, string top) { AbsoluteTopicName abs = new AbsoluteTopicName(top); if (abs.Namespace == null) { throw new Exception("Only fully-qualified topic names can be used with GetTopic(): only got " + top); } DynamicNamespace dns = DynamicNamespaceForNamespace(ctx, abs.Namespace); ctx.AddCacheRule(new TopicsCacheRule(this, abs)); return dns.DynamicTopicFor(abs.Name); }
public string Property(ExecutionContext ctx, string topic, string property) { AbsoluteTopicName abs = null; bool ambig = false; string answer = null; try { ContentBase cb = ctx.CurrentContentBase; if (cb == null) cb = ctx.CurrentFederation.DefaultContentBase; RelativeTopicName rel = new RelativeTopicName(topic); ctx.AddCacheRule(cb.CacheRuleForAllPossibleInstancesOfTopic(rel)); abs = cb.UnambiguousTopicNameFor(rel); } catch (TopicIsAmbiguousException) { ambig = true; } if (abs != null) { // Got a unique one! answer = ctx.CurrentFederation.GetTopicProperty(abs, property); } else { if (ambig) throw new ArgumentException("Ambiguous topic name: " + topic); else throw new ArgumentException("Unknown topic name: " + topic); } return answer; }
public ArrayList Topics(ExecutionContext ctx) { ArrayList answer = new ArrayList(); foreach (AbsoluteTopicName name in AllTopics(false)) answer.Add(new TopicInfo(Federation, name)); // Add cache rules for all the topics in the namespaces and for the definition (in case the imports change) ctx.AddCacheRule(new AllTopicsInNamespaceCacheRule(Federation, Namespace)); return answer; }
public string ExposedName(ExecutionContext ctx) { ctx.AddCacheRule(CacheRuleForDefinition); return Namespace; }
public IBELObject ValueOf(string name, ArrayList arguments, ExecutionContext ctx) { BELMember mi = Type.BELMembers[name] as BELMember; if (mi== null) return null; ParameterInfo []parms = mi.MethodInfo.GetParameters(); int need = parms.Length; int got = (arguments == null) ? 0 : arguments.Count; bool needExecutionContext = mi.NeedsExecutionContext; if (needExecutionContext && (parms.Length == 0 || parms[0].ParameterType != typeof(ExecutionContext))) throw new ImplementationException("Incorrectly defined ExposedMethod property or function. First parameter of " + mi.MethodInfo.DeclaringType.FullName + "." + mi.MethodInfo.Name + " must be an ExecutionContext"); if (needExecutionContext) need--; if (got > need && !(mi.ExposedMethod.AllowsVariableArguments)) throw new MemberInvocationException(ctx.CurrentLocation, "Incorrect number of arguments (too many) for " + ExternalTypeName + "." + name + " (need " + need + ", got " + got + ")"); // Figure out what arguments we should be passing ArrayList args = new ArrayList(); InvocationFrame invocationFrame = new InvocationFrame(); if (needExecutionContext) args.Add(ctx); ArrayList parameterPresentFlags = null; if (needExecutionContext) { parameterPresentFlags = new ArrayList(); parameterPresentFlags.Add(true); // we know for sure the first arg is supplied; it's the execution context :-) } int offset = (needExecutionContext ? 1 : 0); for (int each = offset; each < parms.Length; each++) { object arg = null; if (arguments != null && (each - offset) < arguments.Count) arg = (ParseTreeNode)(arguments[each - offset]); if (!BELMember.IsOptionalParameter(parms[each]) && arg == null) throw new MemberInvocationException(ctx.CurrentLocation, "Missing argument " + (each - offset) + " for " + ExternalTypeName + "." + name); if (parameterPresentFlags != null) parameterPresentFlags.Add(arg != null); if (mi.ExposedMethod.IsCustomArgumentProcessor) { args.Add(arg); } else { if (arg == null) args.Add(AbsentValueForParameter(parms[each])); else args.Add(ConvertFromBELObjectIfNeeded(((ExposableParseTreeNode)arg).Expose(ctx))); } } invocationFrame.WasParameterSuppliedFlags = parameterPresentFlags; // If we have extras (beyond those needed) and they're allowed, stash them in the MIC, too if (mi.ExposedMethod.AllowsVariableArguments) { ArrayList extras = new ArrayList(); int extraCount = got - need; if (arguments != null) { for (int i = need; i < got; i++) { object arg = arguments[i]; if (mi.ExposedMethod.IsCustomArgumentProcessor) { extras.Add(arg); } else { if (arg == null) extras.Add(null); else extras.Add(ConvertFromBELObjectIfNeeded(((ExposableParseTreeNode)arg).Expose(ctx))); } } } invocationFrame.ExtraArguments = extras; } // Check types for (int each = 0; each < parms.Length; each++) { bool bad = false; if (args[each] == null) { if (parms[each].ParameterType.IsValueType) bad = true; } else { if (!parms[each].ParameterType.IsAssignableFrom(args[each].GetType())) bad = true; } if (bad) throw new MemberInvocationException(ctx.CurrentLocation, "Argument " + (each + 1) + " for " + ExternalTypeName + "." + name + " is not of the correct type (was " + ExternalTypeNameForType(args[each].GetType()) + ", but needed " + ExternalTypeNameForType(parms[each].ParameterType) + ")"); } // And now, invoke away!! object result = null; invocationFrame.PushScope(ctx.CurrentScope); // the new frame starts with the same scope as this one ctx.PushFrame(invocationFrame); if (Federation.GetPerformanceCounter(Federation.PerformanceCounterNames.MethodInvocation) != null) Federation.GetPerformanceCounter(Federation.PerformanceCounterNames.MethodInvocation).Increment(); try { result = mi.MethodInfo.Invoke(this, args.ToArray()); } catch (TargetInvocationException ex) { throw ex.InnerException; } ctx.PopFrame(); if (mi.ExposedMethod.CachePolicy == ExposedMethodFlags.CachePolicyNever) ctx.AddCacheRule(new CacheRuleNever()); return Wrap(result); }
public string ExposedImageURL(ExecutionContext ctx) { ctx.AddCacheRule(CacheRuleForDefinition); return ImageURL; }
public string ExposedTitle(ExecutionContext ctx) { ctx.AddCacheRule(CacheRuleForDefinition); return FriendlyTitle; }
public string ExposedContact(ExecutionContext ctx) { ctx.AddCacheRule(CacheRuleForDefinition); return Contact; }
public string ExposedDescription(ExecutionContext ctx) { ctx.AddCacheRule(CacheRuleForDefinition); return Description; }
public string AllNamespacesWithDetails(ExecutionContext ctx) { ArrayList files = new ArrayList(); StringBuilder b = new StringBuilder(); ArrayList bases = new ArrayList(); Federation fed =ctx.CurrentFederation; foreach (string ns in fed.Namespaces) { ContentBase cb = fed.ContentBaseForNamespace(ns); bases.Add(cb); ctx.AddCacheRule(cb.CacheRuleForDefinition); } // And now add the namespace map itself ctx.AddCacheRule(fed.CacheRuleForNamespaces); bases.Sort(); foreach (ContentBase info in bases) { b.Append( "||\"" + info.FriendlyTitle + "\":" + info.Namespace + "." + info.HomePage + "||" + info.Description + "||" + (info.Contact == null ? "" : info.Contact) + "||\n"); } return b.ToString(); }
public ArrayList ExposedNamespaces(ExecutionContext ctx) { ctx.AddCacheRule(this.CacheRuleForNamespaces); return AllNamespaces; }
public ArrayList ExposedImports(ExecutionContext ctx) { ctx.AddCacheRule(CacheRuleForDefinition); ArrayList answer = new ArrayList(); foreach (ContentBase cb in ImportedContentBases) answer.Add(cb); return answer; }
public TopicInfo GetTopicInfo(ExecutionContext ctx, string top) { AbsoluteTopicName abs = new AbsoluteTopicName(top); ctx.AddCacheRule(new TopicsCacheRule(this, abs)); return GetTopicInfo(top); }
public TopicInfoArray AllTopicsWith(ExecutionContext ctx, string property, [ExposedParameter(true)] string desiredValue) { ctx.AddCacheRule(new PropertyCacheRule(this.Federation, property)); return this.RetrieveAllTopicsWith(property, desiredValue, true); }
public override IBELObject ValueOf(string name, System.Collections.ArrayList arguments, ExecutionContext ctx) { Hashtable members = ctx.CurrentFederation.GetTopicProperties(Name); string val = (string)(members[name]); if (val == null) return null; val = val.Trim(); bool isBlock = val.StartsWith("{"); if (!isBlock) return new BELString(val); // It's a block, so fire up the interpreter if (!val.EndsWith("}")) throw new ExecutionException("Topic member " + name + " defined in " + Name.Fullname + " is not well-formed; missing closing '}' for code block."); ContentBase cb = CurrentFederation.ContentBaseForTopic(Name); TopicContext newContext = new TopicContext(ctx.CurrentFederation, cb, CurrentTopicInfo); BehaviorInterpreter interpreter = new BehaviorInterpreter(val, CurrentFederation, CurrentFederation.WikiTalkVersion, ctx.Presenter); if (!interpreter.Parse()) throw new ExecutionException("Parsing error evaluating topic member " + name + " defined in " + Name.Fullname + ": " + interpreter.ErrorString); IBELObject b1 = interpreter.EvaluateToObject(newContext, ctx.ExternalWikiMap); if (b1 == null) throw new ExecutionException("Error while evaluating topic member " + name + " defined in " + Name.Fullname + ": " + interpreter.ErrorString); Block block = (Block)b1; ArrayList evaluatedArgs = new ArrayList(); foreach (object each in arguments) { IBELObject add = null; if (each != null && each is IBELObject) add = each as IBELObject; else { ExposableParseTreeNode ptn = each as ExposableParseTreeNode; add = ptn.Expose(ctx); } evaluatedArgs.Add(add); } InvocationFrame invocationFrame = new InvocationFrame(); ctx.PushFrame(invocationFrame); TopicScope topicScope = new TopicScope(null, this); ctx.PushScope(topicScope); // make sure we can use local references IBELObject answer = block.Value(ctx, evaluatedArgs); ctx.PopScope(); ctx.PopFrame(); // make sure to transfer any new cache rules // BELTODO - want a test case for this foreach (CacheRule r in interpreter.CacheRules) ctx.AddCacheRule(r); return answer; }
public ArrayList AllTopicsInfo(ExecutionContext ctx) { ArrayList answer = new ArrayList(); foreach (AbsoluteTopicName name in AllTopics(true)) { answer.Add(new TopicInfo(Federation, name)); } // Add cache rules for all the topics in the namespaces and for the definition (in case the imports change) ctx.AddCacheRule(new AllTopicsInNamespaceCacheRule(Federation, Namespace)); ctx.AddCacheRule(CacheRuleForDefinition); foreach (string ns in ImportedNamespaces) { ctx.AddCacheRule(new AllTopicsInNamespaceCacheRule(Federation, ns)); } return answer; }