private ConstructorInfo GetConstructor(IConstructorDef constructor) { Type clazz = (Type)this.classHierarchy.ClassForName(constructor.GetClassName()); IConstructorArg[] args = constructor.GetArgs().ToArray(); Type[] parameterTypes = new Type[args.Length]; for (int i = 0; i < args.Length; i++) { if (args[i].IsInjectionFuture()) { parameterTypes[i] = typeof(IInjectionFuture <>).MakeGenericType(new Type[] { this.classHierarchy.ClassForName(args[i].Gettype()) }); } else { parameterTypes[i] = this.classHierarchy.ClassForName(args[i].Gettype()); } } ConstructorInfo cons = clazz.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null); //// TODO //// cons.setAccessible(true); if (cons == null) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Failed to look up constructor: " + constructor.ToString()), LOGGER); } return(cons); }
// Return true if our list of args is a superset of those in def. public bool IsMoreSpecificThan(IConstructorDef def) { // Is everything in def also in this? for (int i = 0; i < def.GetArgs().Count; i++) { bool found = false; for (int j = 0; j < this.GetArgs().Count; j++) { if (GetArgs()[j].Equals(def.GetArgs()[i])) { found = true; break; } } // If not, then argument j from def is not in our list. Return false. if (found == false) { return(false); } } // Everything in def's arg list is in ours. Do we have at least one extra // argument? return(GetArgs().Count > def.GetArgs().Count); }
public static InjectionPlan Deserialize(IClassHierarchy ch, InjectionPlanProto.InjectionPlan ip) { string fullName = ip.name; if (ip.constructor != null) { InjectionPlanProto.Constructor cons = ip.constructor; IClassNode cn = (IClassNode)ch.GetNode(fullName); InjectionPlanProto.InjectionPlan[] protoBufArgs = cons.args.ToArray(); IClassNode[] cnArgs = new IClassNode[protoBufArgs.Length]; for (int i = 0; i < protoBufArgs.Length; i++) { INode no = ch.GetNode(protoBufArgs[i].name); if (no is IClassNode) { cnArgs[i] = (IClassNode)no; } else if (no is INamedParameterNode) { INamedParameterNode np = (INamedParameterNode)no; cnArgs[i] = (IClassNode)ch.GetNode(np.GetFullArgName()); } } InjectionPlan[] ipArgs = new InjectionPlan[protoBufArgs.Length]; for (int i = 0; i < protoBufArgs.Length; i++) { ipArgs[i] = (InjectionPlan)Deserialize(ch, protoBufArgs[i]); } IConstructorDef constructor = cn.GetConstructorDef(cnArgs); return(new Constructor(cn, constructor, ipArgs)); } if (ip.instance != null) { InjectionPlanProto.Instance ins = ip.instance; object instance = Parse(ip.name, ins.value); return(new CsInstance(ch.GetNode(ip.name), instance)); } if (ip.subplan != null) { InjectionPlanProto.Subplan subplan = ip.subplan; InjectionPlanProto.InjectionPlan[] protoBufPlans = subplan.plans.ToArray(); InjectionPlan[] subPlans = new InjectionPlan[protoBufPlans.Length]; for (int i = 0; i < protoBufPlans.Length; i++) { subPlans[i] = (InjectionPlan)Deserialize(ch, protoBufPlans[i]); } INode n = ch.GetNode(fullName); return(new Subplan(n, subPlans)); } Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Encountered unknown type of InjectionPlan: " + ip), LOGGER); return(null); }
private void AddConfiguration(IClassHierarchy ns, ConfigurationBuilderImpl builder) { this.ClassHierarchy = this.ClassHierarchy.Merge(ns); //TODO //((ClassHierarchyImpl) ClassHierarchy).parameterParser // .mergeIn(((ClassHierarchyImpl) namespace).parameterParser); foreach (IClassNode cn in builder.BoundImpls.Keys) { IClassNode n = null; builder.BoundImpls.TryGetValue(cn, out n); if (n != null) { Bind(cn.GetFullName(), n.GetFullName()); } } foreach (IClassNode cn in builder.BoundConstructors.Keys) { IClassNode n = null; builder.BoundConstructors.TryGetValue(cn, out n); if (n != null) { Bind(cn.GetFullName(), n.GetFullName()); } } // The namedParameters set contains the strings that can be used to // instantiate new // named parameter instances. Create new ones where we can. foreach (INamedParameterNode np in builder.NamedParameters.Keys) { string v = null; builder.NamedParameters.TryGetValue(np, out v); Bind(np.GetFullName(), v); } foreach (IClassNode cn in builder.LegacyConstructors.Keys) { IConstructorDef cd = null; builder.LegacyConstructors.TryGetValue(cn, out cd); //RegisterLegacyConstructor(cn, cd.GetArgs()); TODO } //for (Entry<NamedParameterNode<Set<?>>, Object> e: builder.boundSetEntries) { // String name = ((NamedParameterNode<Set<T>>)(NamedParameterNode<?>)e.getKey()).getFullName(); // if(e.getValue() instanceof Node) { // bindSetEntry(name, (Node)e.getValue()); // } else if(e.getValue() instanceof String) { // bindSetEntry(name, (String)e.getValue()); // } else { // throw new IllegalStateException(); // } //} }
private static ConstructorDef SerializeConstructorDef(IConstructorDef def) { IList <ConstructorArg> args = new List <ConstructorArg>(); foreach (IConstructorArg arg in def.GetArgs()) { args.Add(NewConstructorArg(arg.Gettype(), arg.GetNamedParameterName(), arg.IsInjectionFuture())); } return(newConstructorDef(def.GetClassName(), args)); }
public static InjectionPlan Deserialize(IClassHierarchy ch, InjectionPlanProto.InjectionPlan ip) { string fullName = ip.name; if (ip.constructor != null) { InjectionPlanProto.Constructor cons = ip.constructor; IClassNode cn = (IClassNode)ch.GetNode(fullName); InjectionPlanProto.InjectionPlan[] protoBufArgs = cons.args.ToArray(); INode[] cnArgs = new INode[protoBufArgs.Length]; for (int i = 0; i < protoBufArgs.Length; i++) { cnArgs[i] = (INode)ch.GetNode(protoBufArgs[i].name); } InjectionPlan[] ipArgs = new InjectionPlan[protoBufArgs.Length]; for (int i = 0; i < protoBufArgs.Length; i++) { ipArgs[i] = (InjectionPlan)Deserialize(ch, protoBufArgs[i]); } IConstructorDef constructor = cn.GetConstructorDef(cnArgs); return(new Constructor(cn, constructor, ipArgs)); } else if (ip.instance != null) { InjectionPlanProto.Instance ins = ip.instance; object instance = Parse(ip.name, ins.value); return(new CsInstance(ch.GetNode(ip.name), instance)); } else if (ip.subplan != null) { InjectionPlanProto.Subplan subplan = ip.subplan; InjectionPlanProto.InjectionPlan[] protoBufPlans = subplan.plans.ToArray(); InjectionPlan[] subPlans = new InjectionPlan[protoBufPlans.Length]; for (int i = 0; i < protoBufPlans.Length; i++) { subPlans[i] = (InjectionPlan)Deserialize(ch, protoBufPlans[i]); } INode n = ch.GetNode(fullName); return(new Subplan(n, subPlans)); } else { throw new IllegalStateException("Encountered unknown type of injection plan: " + ip); } }
private static void ParseSubHierarchy(INode parent, ClassHierarchyProto.Node n) { INode parsed; if (n.package_node != null) { parsed = new PackageNodeImpl(parent, n.name, n.full_name); } else if (n.named_parameter_node != null) { ClassHierarchyProto.NamedParameterNode np = n.named_parameter_node; parsed = new NamedParameterNodeImpl(parent, n.name, n.full_name, np.full_arg_class_name, np.simple_arg_class_name, np.is_set, np.documentation, np.short_name, np.instance_default.ToArray()); } else if (n.class_node != null) { ClassHierarchyProto.ClassNode cn = n.class_node; IList <IConstructorDef> injectableConstructors = new List <IConstructorDef>(); IList <IConstructorDef> allConstructors = new List <IConstructorDef>(); foreach (ClassHierarchyProto.ConstructorDef injectable in cn.InjectableConstructors) { IConstructorDef def = ParseConstructorDef(injectable, true); injectableConstructors.Add(def); allConstructors.Add(def); } foreach (ClassHierarchyProto.ConstructorDef other in cn.OtherConstructors) { IConstructorDef def = ParseConstructorDef(other, false); allConstructors.Add(def); } IConstructorDef[] dummy = new ConstructorDefImpl[0]; parsed = new ClassNodeImpl(parent, n.name, n.full_name, cn.is_unit, cn.is_injection_candidate, cn.is_external_constructor, injectableConstructors, allConstructors, cn.default_implementation); } else { throw new IllegalStateException("Bad protocol buffer: got abstract node" + n); } foreach (ClassHierarchyProto.Node child in n.children) { ParseSubHierarchy(parsed, child); } }
private void ParseSubHierarchy(INode parent, AvroNode n) { INode parsed = null; if (n.packageNode != null && !n.packageNode.Equals(string.Empty)) { parsed = new PackageNodeImpl(parent, n.name, n.fullName); } else if (n.namedParameterNode != null && !n.namedParameterNode.Equals(string.Empty)) { AvroNamedParameterNode np = (AvroNamedParameterNode)n.namedParameterNode; parsed = new NamedParameterNodeImpl(parent, n.name, n.fullName, np.fullArgClassName, np.simpleArgClassName, np.isSet, np.isList, np.documentation, np.shortName, np.instanceDefault.ToArray()); } else if (n.classNode != null && !n.classNode.Equals(string.Empty)) { AvroClassNode cn = (AvroClassNode)n.classNode; IList <IConstructorDef> injectableConstructors = new List <IConstructorDef>(); IList <IConstructorDef> allConstructors = new List <IConstructorDef>(); foreach (AvroConstructorDef injectable in cn.injectableConstructors) { IConstructorDef def = ParseConstructorDef(injectable, true); injectableConstructors.Add(def); allConstructors.Add(def); } foreach (AvroConstructorDef other in cn.otherConstructors) { IConstructorDef def = ParseConstructorDef(other, false); allConstructors.Add(def); } parsed = new ClassNodeImpl(parent, n.name, n.fullName, cn.isUnit, cn.isInjectionCandidate, cn.isExternalConstructor, injectableConstructors, allConstructors, cn.defaultImplementation); } else { Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Bad protocol buffer: got abstract node" + n), LOGGER); } foreach (AvroNode child in n.children) { ParseSubHierarchy(parsed, child); } }
public Constructor(IClassNode classNode, IConstructorDef constructor, InjectionPlan[] args) : base(classNode) { this.constructor = constructor; this.args = args; int curAlternatives = 1; bool curAmbiguous = false; bool curInjectable = true; foreach (InjectionPlan plan in args) { curAlternatives *= plan.GetNumAlternatives(); curAmbiguous |= plan.IsAmbiguous(); curInjectable &= plan.IsInjectable(); } this.numAlternatives = curAlternatives; this.isAmbiguous = curAmbiguous; this.isInjectable = curInjectable; }
private AvroConstructorDef NewConstructorDef(IConstructorDef def) { IList <AvroConstructorArg> args = new List <AvroConstructorArg>(); foreach (IConstructorArg arg in def.GetArgs()) { args.Add(NewConstructorArg(arg.Gettype(), arg.GetNamedParameterName(), arg.IsInjectionFuture())); } AvroConstructorDef constDef = new AvroConstructorDef(); constDef.fullClassName = def.GetClassName(); constDef.constructorArgs = new List <AvroConstructorArg>(); foreach (AvroConstructorArg arg in args) { constDef.constructorArgs.Add(arg); } return(constDef); }
private ConstructorInfo GetConstructor(IConstructorDef constructor) { Type clazz = (Type)this.classHierarchy.ClassForName(constructor.GetClassName()); IConstructorArg[] args = constructor.GetArgs().ToArray(); Type[] parameterTypes = new Type[args.Length]; for (int i = 0; i < args.Length; i++) { if (args[i].IsInjectionFuture()) { parameterTypes[i] = typeof(InjectionFuture); } else { parameterTypes[i] = this.classHierarchy.ClassForName(args[i].Gettype()); } } ConstructorInfo cons = clazz.GetConstructor(parameterTypes); //cons.setAccessible(true); return(cons); }
//A(int i, string j) vs. A(string i, int j) is Ambiguous in injection private bool EqualsIgnoreOrder(IConstructorDef def) { if (GetArgs().Count != def.GetArgs().Count) { return(false); } for (int i = 0; i < GetArgs().Count; i++) { bool found = false; for (int j = 0; j < def.GetArgs().Count; j++) { if (GetArgs()[i].GetName().Equals(def.GetArgs()[j].GetName())) { found = true; } } if (!found) { return(false); } } return(true); }
private List <InjectionPlan> FilterCandidateConstructors( List <IClassNode> candidateImplementations, IDictionary <INode, InjectionPlan> memo) { List <InjectionPlan> sub_ips = new List <InjectionPlan>(); foreach (IClassNode thisCN in candidateImplementations) { List <InjectionPlan> constructors = new List <InjectionPlan>(); List <IConstructorDef> constructorList = new List <IConstructorDef>(); if (null != this.configuration.GetLegacyConstructor(thisCN)) { constructorList.Add(this.configuration.GetLegacyConstructor(thisCN)); } foreach (var c in thisCN.GetInjectableConstructors()) { constructorList.Add(c); } foreach (IConstructorDef def in constructorList) { List <InjectionPlan> args = new List <InjectionPlan>(); IConstructorArg[] defArgs = def.GetArgs().ToArray <IConstructorArg>(); foreach (IConstructorArg arg in defArgs) { if (!arg.IsInjectionFuture()) { try { INode argNode = this.classHierarchy.GetNode(arg.GetName()); BuildInjectionPlan(argNode, memo); InjectionPlan ip = null; memo.TryGetValue(argNode, out ip); args.Add(ip); } catch (NameResolutionException e) { throw new IllegalStateException("Detected unresolvable " + "constructor arg while building injection plan. " + "This should have been caught earlier!", e); } } else { try { args.Add(new InjectionFuturePlan(this.classHierarchy.GetNode(arg.GetName()))); } catch (NameResolutionException e) { throw new IllegalStateException("Detected unresolvable " + "constructor arg while building injection plan. " + "This should have been caught earlier!", e); } } } Constructor constructor = new Constructor(thisCN, def, args.ToArray()); constructors.Add(constructor); } // The constructors are embedded in a lattice defined by // isMoreSpecificThan(). We want to see if, amongst the injectable // plans, there is a unique dominant plan, and select it. // First, compute the set of injectable plans. List <Int32> liveIndices = new List <Int32>(); for (int i = 0; i < constructors.Count; i++) { if (constructors[i].GetNumAlternatives() > 0) { liveIndices.Add(i); } } // Now, do an all-by-all comparison, removing indices that are dominated // by others. for (int i = 0; i < liveIndices.Count; i++) { for (int j = i + 1; j < liveIndices.Count; j++) { IConstructorDef ci = ((Constructor)constructors[(liveIndices[i])]).GetConstructorDef(); IConstructorDef cj = ((Constructor)constructors[(liveIndices[j])]).GetConstructorDef(); if (ci.IsMoreSpecificThan(cj)) { liveIndices.Remove(j); j--; } else if (cj.IsMoreSpecificThan(ci)) { liveIndices.Remove(j); // Done with this inner loop invocation. Check the new ci. i--; break; } } } sub_ips.Add(WrapInjectionPlans(thisCN, constructors, false, liveIndices.Count == 1 ? liveIndices[0] : -1)); } return(sub_ips); }
// A(int i, string j) vs. A(string i, int j) is Ambiguous in injection private bool EqualsIgnoreOrder(IConstructorDef def) { if (GetArgs().Count != def.GetArgs().Count) { return false; } for (int i = 0; i < GetArgs().Count; i++) { bool found = false; for (int j = 0; j < def.GetArgs().Count; j++) { if (GetArgs()[i].GetName().Equals(def.GetArgs()[j].GetName())) { found = true; } } if (!found) { return false; } } return true; }
private static void ParseSubHierarchy(INode parent, Org.Apache.REEF.Tang.Protobuf.Node n) { INode parsed = null; if (n.package_node != null) { parsed = new PackageNodeImpl(parent, n.name, n.full_name); } else if (n.named_parameter_node != null) { Org.Apache.REEF.Tang.Protobuf.NamedParameterNode np = n.named_parameter_node; if (!string.IsNullOrWhiteSpace(np.alias_name) && !string.IsNullOrWhiteSpace(np.alias_language)) { Language language; try { Enum.TryParse(np.alias_language, true, out language); } catch (Exception) { string msg = string.Format(CultureInfo.CurrentCulture, "Language {0} passed in is not supported", np.alias_language); throw new ArgumentException(msg); } parsed = new NamedParameterNodeImpl(parent, n.name, n.full_name, np.full_arg_class_name, np.simple_arg_class_name, np.is_set, np.is_list, np.documentation, np.short_name, np.instance_default.ToArray(), np.alias_name, language); } else { parsed = new NamedParameterNodeImpl(parent, n.name, n.full_name, np.full_arg_class_name, np.simple_arg_class_name, np.is_set, np.is_list, np.documentation, np.short_name, np.instance_default.ToArray()); } } else if (n.class_node != null) { Org.Apache.REEF.Tang.Protobuf.ClassNode cn = n.class_node; IList <IConstructorDef> injectableConstructors = new List <IConstructorDef>(); IList <IConstructorDef> allConstructors = new List <IConstructorDef>(); foreach (Org.Apache.REEF.Tang.Protobuf.ConstructorDef injectable in cn.InjectableConstructors) { IConstructorDef def = ParseConstructorDef(injectable, true); injectableConstructors.Add(def); allConstructors.Add(def); } foreach (Org.Apache.REEF.Tang.Protobuf.ConstructorDef other in cn.OtherConstructors) { IConstructorDef def = ParseConstructorDef(other, false); allConstructors.Add(def); } IConstructorDef[] dummy = new ConstructorDefImpl[0]; parsed = new ClassNodeImpl(parent, n.name, n.full_name, cn.is_unit, cn.is_injection_candidate, cn.is_external_constructor, injectableConstructors, allConstructors, cn.default_implementation); } else { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Bad protocol buffer: got abstract node" + n), LOGGER); } foreach (Org.Apache.REEF.Tang.Protobuf.Node child in n.children) { ParseSubHierarchy(parsed, child); } }
// Return true if our list of args is a superset of those in def. public bool IsMoreSpecificThan(IConstructorDef def) { // Is everything in def also in this? for (int i = 0; i < def.GetArgs().Count; i++) { bool found = false; for (int j = 0; j < this.GetArgs().Count; j++) { if (GetArgs()[j].Equals(def.GetArgs()[i])) { found = true; break; } } // If not, then argument j from def is not in our list. Return false. if (found == false) { return false; } } // Everything in def's arg list is in ours. Do we have at least one extra // argument? return GetArgs().Count > def.GetArgs().Count; }
private void AddConfiguration(IClassHierarchy ns, ConfigurationBuilderImpl builder) { this.ClassHierarchy = this.ClassHierarchy.Merge(ns); if ((ClassHierarchy is ClassHierarchyImpl || builder.ClassHierarchy is ClassHierarchyImpl)) { if ((ClassHierarchy is ClassHierarchyImpl && builder.ClassHierarchy is ClassHierarchyImpl)) { ((ClassHierarchyImpl)ClassHierarchy).Parameterparser.MergeIn(((ClassHierarchyImpl)builder.ClassHierarchy).Parameterparser); } else { Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException("Attempt to merge Java and non-Java class hierarchy! Not supported."), LOGGER); } } foreach (IClassNode cn in builder.BoundImpls.Keys) { IClassNode n = null; builder.BoundImpls.TryGetValue(cn, out n); if (n != null) { Bind(cn.GetFullName(), n.GetFullName()); } } foreach (IClassNode cn in builder.BoundConstructors.Keys) { IClassNode n = null; builder.BoundConstructors.TryGetValue(cn, out n); if (n != null) { Bind(cn.GetFullName(), n.GetFullName()); } } // The namedParameters set contains the strings that can be used to // instantiate new // named parameter instances. Create new ones where we can. foreach (INamedParameterNode np in builder.NamedParameters.Keys) { string v = null; builder.NamedParameters.TryGetValue(np, out v); Bind(np.GetFullName(), v); } foreach (IClassNode cn in builder.LegacyConstructors.Keys) { IConstructorDef cd = null; builder.LegacyConstructors.TryGetValue(cn, out cd); RegisterLegacyConstructor(cn, cd.GetArgs()); } foreach (KeyValuePair <INamedParameterNode, object> e in builder.BoundSetEntries) { String name = ((INamedParameterNode)e.Key).GetFullName(); if (e.Value is INode) { BindSetEntry(name, (INode)e.Value); } else if (e.Value is string) { BindSetEntry(name, (string)e.Value); } else { var ex = new IllegalStateException(string.Format(CultureInfo.CurrentCulture, "The value {0} set to the named parameter {1} is illegel.", e.Value, name)); Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } } foreach (var p in builder.BoundLists) { BoundLists.Add(p.Key, p.Value); } }
private static ConstructorDef SerializeConstructorDef(IConstructorDef def) { IList<ConstructorArg> args = new List<ConstructorArg>(); foreach (IConstructorArg arg in def.GetArgs()) { args.Add(NewConstructorArg(arg.Gettype(), arg.GetNamedParameterName(), arg.IsInjectionFuture())); } return newConstructorDef(def.GetClassName(), args); }
public object InjectFromPlan(InjectionPlan plan) { if (!plan.IsFeasible()) { throw new InjectionException("Cannot inject " + plan.GetNode().GetFullName() + ": " + plan.ToCantInjectString()); } if (plan.IsAmbiguous()) { throw new InjectionException("Cannot inject " + plan.GetNode().GetFullName() + " " + plan.ToCantInjectString()); } if (plan is InjectionFuturePlan) { InjectionFuturePlan fut = (InjectionFuturePlan)plan; string key = fut.GetNode().GetFullName(); try { //we will see if we need to introduce T to replace object InjectionFuture ret = new InjectionFuture(this, classHierarchy.ClassForName(fut.GetNode().GetFullName())); pendingFutures.Add(ret); return(ret); } catch (TypeLoadException e) { throw new InjectionException("Could not get class for " + key); } } else if (plan.GetNode() is IClassNode && null != GetCachedInstance((IClassNode)plan.GetNode())) { return(GetCachedInstance((IClassNode)plan.GetNode())); } else if (plan is CsInstance) { // TODO: Must be named parameter node. Check. // throw new IllegalStateException("Instance from plan not in Injector's set of instances?!?"); return(((CsInstance)plan).instance); } else if (plan is Constructor) { Constructor constructor = (Constructor)plan; object[] args = new object[constructor.GetArgs().Length]; InjectionPlan[] argPlans = constructor.GetArgs(); for (int i = 0; i < argPlans.Length; i++) { args[i] = InjectFromPlan(argPlans[i]); } try { concurrentModificationGuard = true; object ret; try { IConstructorDef def = (IConstructorDef)constructor.GetConstructorDef(); ConstructorInfo c = GetConstructor(def); if (aspect != null) { ret = aspect.Inject(def, c, args); } else { ret = c.Invoke(args); } } catch (ArgumentException e) { StringBuilder sb = new StringBuilder("Internal Tang error? Could not call constructor " + constructor.GetConstructorDef() + " with arguments ["); foreach (Object o in args) { sb.Append("\n\t" + o); } sb.Append("]"); throw new IllegalStateException(sb.ToString(), e); } if (ret is IExternalConstructor) { ret = ((IExternalConstructor)ret).NewInstance(); } instances.Add(constructor.GetNode(), ret); return(ret); } catch (Exception e) { throw new InjectionException("Could not invoke constructor: " + plan, e); //check what exception might be got and refine it } finally { concurrentModificationGuard = false; } } else if (plan is Subplan) { Subplan ambiguous = (Subplan)plan; return(InjectFromPlan(ambiguous.GetDelegatedPlan())); } else if (plan is SetInjectionPlan) { SetInjectionPlan setPlan = (SetInjectionPlan)plan; ISet <object> ret = new MonotonicSet <object>(); foreach (InjectionPlan subplan in setPlan.GetEntryPlans()) { ret.Add(InjectFromPlan(subplan)); } return(ret); } else { throw new IllegalStateException("Unknown plan type: " + plan); } }
public object InjectFromPlan(InjectionPlan plan) { if (!plan.IsFeasible()) { var ex = new InjectionException("Cannot inject " + plan.GetNode().GetFullName() + ": " + plan.ToCantInjectString()); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } if (plan.IsAmbiguous()) { var ex = new InjectionException("Cannot inject " + plan.GetNode().GetFullName() + " " + plan.ToCantInjectString()); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } if (plan is InjectionFuturePlan) { InjectionFuturePlan fut = (InjectionFuturePlan)plan; INode node = fut.GetNode(); string key = node.GetFullName(); try { Type t = null; Type nodeType = classHierarchy.ClassForName(node.GetFullName()); if (node is IClassNode) { t = nodeType; } else if (node is INamedParameterNode) { var nn = (INamedParameterNode)node; t = classHierarchy.ClassForName(nn.GetFullArgName()); if (nn.IsSet()) { t = typeof(ISet <>).MakeGenericType(new Type[] { t }); } } else { var ex = new ApplicationException("Unexpected node type. Wanted ClassNode or NamedParameterNode. Got: " + node); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } // Java - InjectionFuture<?> ret = new InjectionFuture<>(this, javaNamespace.classForName(fut.getNode().getFullName())); // C# - InjectionFuture<object> ret = new InjectionFutureImpl<object>(this, classHierarchy.ClassForName(fut.GetNode().GetFullName())); // We cannot simply create an object from generic with object as <T> // typeof(InjectionFutureImpl<>).MakeGenericType(t) will get the InjectionFutureImpl generic Type with <T> as t // for ClassNode, t is the Type of the class, for NamedParameterNode, t is the Type of the argument // we then use reflection to invoke the constructor // To retain generic argument information?? Type injectionFuture = typeof(InjectionFutureImpl <>).MakeGenericType(t); var constructor = injectionFuture.GetConstructor(new Type[] { typeof(IInjector), typeof(Type) }); IInjectionFuture <object> ret = (IInjectionFuture <object>)constructor.Invoke(new object[] { this, nodeType }); pendingFutures.Add(ret); return(ret); } catch (TypeLoadException e) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new InjectionException("Could not get class for " + key), LOGGER); } } else if (plan.GetNode() is IClassNode && null != GetCachedInstance((IClassNode)plan.GetNode())) { return(GetCachedInstance((IClassNode)plan.GetNode())); } else if (plan is CsInstance) { // TODO: Must be named parameter node. Check. // throw new IllegalStateException("Instance from plan not in Injector's set of instances?!?"); return(((CsInstance)plan).instance); } else if (plan is Constructor) { Constructor constructor = (Constructor)plan; object[] args = new object[constructor.GetArgs().Length]; InjectionPlan[] argPlans = constructor.GetArgs(); for (int i = 0; i < argPlans.Length; i++) { args[i] = InjectFromPlan(argPlans[i]); } try { concurrentModificationGuard = true; object ret = null; try { IConstructorDef def = (IConstructorDef)constructor.GetConstructorDef(); ConstructorInfo c = GetConstructor(def); if (aspect != null) { ret = aspect.Inject(def, c, args); } else { ret = c.Invoke(args); } } catch (ArgumentException e) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER); StringBuilder sb = new StringBuilder("Internal Tang error? Could not call constructor " + constructor.GetConstructorDef() + " with arguments ["); foreach (object o in args) { sb.Append("\n\t" + o); } sb.Append("]"); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(sb.ToString(), e), LOGGER); } if (ret is IExternalConstructor <object> ) { ret = ((IExternalConstructor <object>)ret).NewInstance(); } instances.Add(constructor.GetNode(), ret); return(ret); } catch (TargetInvocationException e) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new InjectionException("Could not invoke constructor: " + plan, e), LOGGER); } finally { concurrentModificationGuard = false; } } else if (plan is Subplan) { Subplan ambiguous = (Subplan)plan; return(InjectFromPlan(ambiguous.GetDelegatedPlan())); } else if (plan is SetInjectionPlan) { SetInjectionPlan setPlan = (SetInjectionPlan)plan; INode n = setPlan.GetNode(); string typeOfSet = null; // TODO: This doesn't work for sets of generics (e.g., Set<Foo<int>> // because GetFullName and GetFullArgName strip generic info). if (n is INamedParameterNode) { INamedParameterNode np = (INamedParameterNode)n; typeOfSet = np.GetFullArgName(); } else if (n is IClassNode) { typeOfSet = n.GetFullName(); } else { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Unknown node type :" + n.ToString()), LOGGER); } Type t = classHierarchy.ClassForName(typeOfSet); // MakeGenericType(t = int: MonotonicHashSet<> -> MonotonicHashSet<int> // Get constructor: MonotonicHashSet<int> -> public MonotonicHashSet<int>() { ... } // Invoke: public MonotonicHashSet<int> -> new MonotonicHashSet<int>() object ret = typeof(MonotonicHashSet <>).MakeGenericType(t).GetConstructor(new Type[] { }).Invoke(new object[] { }); // (this, classHierarchy.ClassForName(fut.GetNode().GetFullName())); MethodInfo mf = ret.GetType().GetMethod("Add"); foreach (InjectionPlan subplan in setPlan.GetEntryPlans()) { // ret.Add(InjectFromPlan(subplan)); mf.Invoke(ret, new object[] { InjectFromPlan(subplan) }); } return(ret); } else if (plan is ListInjectionPlan) { ListInjectionPlan listPlan = (ListInjectionPlan)plan; INode n = listPlan.GetNode(); string typeOfList = null; if (n is INamedParameterNode) { INamedParameterNode np = (INamedParameterNode)n; typeOfList = np.GetFullArgName(); } else if (n is IClassNode) { typeOfList = n.GetFullName(); } else { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Unknown node type :" + n.ToString()), LOGGER); } Type t = classHierarchy.ClassForName(typeOfList); object ret = typeof(List <>).MakeGenericType(t).GetConstructor(new Type[] { }).Invoke(new object[] { }); MethodInfo mf = ret.GetType().GetMethod("Add"); foreach (InjectionPlan subplan in listPlan.GetEntryPlans()) { mf.Invoke(ret, new object[] { InjectFromPlan(subplan) }); } return(ret); } else { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Unknown plan type: " + plan), LOGGER); } return(null); // should never reach here }
public int CompareTo(object obj) { IConstructorDef o = (IConstructorDef)obj; return(ToString().CompareTo(o.ToString())); }
private ConstructorInfo GetConstructor(IConstructorDef constructor) { Type clazz = (Type) this.classHierarchy.ClassForName(constructor.GetClassName()); IConstructorArg[] args = constructor.GetArgs().ToArray(); Type[] parameterTypes= new Type[args.Length]; for (int i = 0; i < args.Length; i++) { if (args[i].IsInjectionFuture()) { parameterTypes[i] = typeof(InjectionFuture); } else { parameterTypes[i] = this.classHierarchy.ClassForName(args[i].Gettype()); } } ConstructorInfo cons = clazz.GetConstructor(parameterTypes); //cons.setAccessible(true); return cons; }
private AvroConstructorDef NewConstructorDef(IConstructorDef def) { IList<AvroConstructorArg> args = new List<AvroConstructorArg>(); foreach (IConstructorArg arg in def.GetArgs()) { args.Add(NewConstructorArg(arg.Gettype(), arg.GetNamedParameterName(), arg.IsInjectionFuture())); } AvroConstructorDef constDef = new AvroConstructorDef(); constDef.fullClassName = def.GetClassName(); constDef.constructorArgs = new List<AvroConstructorArg>(); foreach (AvroConstructorArg arg in args) { constDef.constructorArgs.Add(arg); } return constDef; }
private List <InjectionPlan> FilterCandidateConstructors( List <IClassNode> candidateImplementations, IDictionary <INode, InjectionPlan> memo) { List <InjectionPlan> sub_ips = new List <InjectionPlan>(); // each implementation foreach (IClassNode thisCN in candidateImplementations) { List <InjectionPlan> constructors = new List <InjectionPlan>(); List <IConstructorDef> constructorList = new List <IConstructorDef>(); if (null != this.configuration.GetLegacyConstructor(thisCN)) { constructorList.Add(this.configuration.GetLegacyConstructor(thisCN)); } foreach (var c in thisCN.GetInjectableConstructors()) { constructorList.Add(c); } // each constructor foreach (IConstructorDef def in constructorList) { List <InjectionPlan> args = new List <InjectionPlan>(); IConstructorArg[] defArgs = def.GetArgs().ToArray <IConstructorArg>(); // each argument foreach (IConstructorArg arg in defArgs) { if (!arg.IsInjectionFuture()) { try { INode argNode = this.classHierarchy.GetNode(arg.GetName()); BuildInjectionPlan(argNode, memo); InjectionPlan ip = null; memo.TryGetValue(argNode, out ip); args.Add(ip); } catch (NameResolutionException e) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER); var ex = new IllegalStateException("Detected unresolvable " + "constructor arg while building injection plan. " + "This should have been caught earlier!", e); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } } else { try { args.Add(new InjectionFuturePlan(this.classHierarchy.GetNode(arg.GetName()))); } catch (NameResolutionException e) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER); var ex = new IllegalStateException("Detected unresolvable " + "constructor arg while building injection plan. " + "This should have been caught earlier!", e); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } } } Constructor constructor = new Constructor(thisCN, def, args.ToArray()); constructors.Add(constructor); } // The constructors are embedded in a lattice defined by // isMoreSpecificThan(). We want to see if, amongst the injectable // plans, there is a unique dominant plan, and select it. // First, compute the set of injectable plans. List <int> liveIndices = new List <int>(); for (int i = 0; i < constructors.Count; i++) { if (constructors[i].GetNumAlternatives() > 0) { liveIndices.Add(i); } } // Now, do an all-by-all comparison, removing indices that are dominated // by others. int k = -1; for (int i = 0; i < liveIndices.Count; i++) { for (int j = i + 1; j < liveIndices.Count; j++) { IConstructorDef ci = ((Constructor)constructors[liveIndices[i]]).GetConstructorDef(); IConstructorDef cj = ((Constructor)constructors[liveIndices[j]]).GetConstructorDef(); if (ci.IsMoreSpecificThan(cj)) { // ci's arguments is a superset of cj's k = i; } else if (cj.IsMoreSpecificThan(ci)) { k = j; } } } if (liveIndices.Count == 1) { k = 0; } if (constructors.Count > 0) { sub_ips.Add(WrapInjectionPlans(thisCN, constructors, false, k != -1 ? liveIndices[k] : -1)); } } return(sub_ips); }