public ConstructorDefImpl(string className, IConstructorArg[] args, bool injectable) { this.args = args; this.className = className; if (injectable) { var duplicateItems = from x in args group x by x into grouped where grouped.Count() > 1 select grouped.Key; if (duplicateItems.Any()) { var e = new ClassHierarchyException( "Repeated constructor parameter detected. " + "Cannot inject constructor " + ToString()); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } } }
public static INode CreateClassNode(INode parent, Type clazz) { // var namedParameter = clazz.GetCustomAttribute<NamedParameterAttribute>(); var unit = null != clazz.GetCustomAttribute<UnitAttribute>(); string simpleName = ReflectionUtilities.GetName(clazz); string fullName = ReflectionUtilities.GetAssemblyQualifiedName(clazz); // bool isStatic = true; // clazz.IsSealed && clazz.IsAbstract; always true in C# for Java static class // bool injectable = true; // always true in C# bool isAssignableFromExternalConstructor = ReflectionUtilities.IsAssignableFromIgnoreGeneric(typeof(IExternalConstructor<>), clazz); // bool parentIsUnit = false; ////No such thing in C#, should be false ////bool foundNonStaticInnerClass = false; ////foreach (Type c in clazz.getNestedTypes()) { //// if (!Modifier.isStatic(c.getModifiers())) { //// foundNonStaticInnerClass = true; //// } ////} var injectableConstructors = new List<IConstructorDef>(); var allConstructors = new List<IConstructorDef>(); foreach (ConstructorInfo c in clazz.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { var constructorAnnotatedInjectable = null != c.GetCustomAttribute<InjectAttribute>(); bool constructorInjectable = constructorAnnotatedInjectable; ConstructorDefImpl constructorDef = CreateConstructorDef(c, constructorAnnotatedInjectable); if (constructorInjectable) { // if (injectableConstructors.Contains(constructorDef)) if (constructorDef.IsInList(injectableConstructors)) { var e = new ClassHierarchyException( "Ambiguous boundConstructors detected in class " + clazz + ": " + constructorDef + " differs from some other" + " constructor only " + "by parameter order."); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } else { injectableConstructors.Add(constructorDef); } } allConstructors.Add(constructorDef); } string defaultImplementation = null; DefaultImplementationAttribute defaultImpl = clazz.GetCustomAttribute<DefaultImplementationAttribute>(); if (null != defaultImpl) { Type defaultImplementationClazz = defaultImpl.Value; if (defaultImplementationClazz == null) { defaultImplementation = defaultImpl.Name; } else { if (!ReflectionUtilities.IsAssignableFromIgnoreGeneric(clazz, defaultImplementationClazz)) { var e = new ClassHierarchyException(clazz + " declares its default implementation to be non-subclass " + defaultImplementationClazz); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } defaultImplementation = ReflectionUtilities.GetAssemblyQualifiedName(defaultImplementationClazz); } } else { defaultImplementation = null; } return new ClassNodeImpl(parent, simpleName, fullName, unit, true, isAssignableFromExternalConstructor, injectableConstructors, allConstructors, defaultImplementation); }
// private static void assertIsSubclassOf(Class<?> named_parameter, Class<?> default_class, Type argClass) { private static void AssertIsSubclassOf(Type namedparameter, Type defaultclass, Type argClass) { bool isSubclass = false; string argClassName = ReflectionUtilities.GetAssemblyQualifiedName(argClass); foreach (Type t in ReflectionUtilities.ClassAndAncestors(defaultclass)) { if (argClassName.Equals(ReflectionUtilities.GetAssemblyQualifiedName(t))) { isSubclass = true; } } if (!isSubclass) { var e = new ClassHierarchyException(namedparameter + " defines a default class " + ReflectionUtilities.GetName(defaultclass) + " with a type that does not extend of its target's type " + argClass); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } }
public static INamedParameterNode CreateNamedParameterNode(INode parent, Type clazz, Type argClass) { Type setRawArgType = ReflectionUtilities.GetInterfaceTarget(typeof(ISet<>), argClass); bool isSet = setRawArgType != null; if (isSet) { argClass = setRawArgType; } Type listRawArgType = ReflectionUtilities.GetInterfaceTargetForType(typeof(IList<>), argClass); bool isList = listRawArgType != null; if (isList) { argClass = listRawArgType; } string simpleName = ReflectionUtilities.GetName(clazz); string fullName = ReflectionUtilities.GetAssemblyQualifiedName(clazz); string fullArgName = ReflectionUtilities.GetAssemblyQualifiedName(argClass); string simpleArgName = ReflectionUtilities.GetName(argClass); NamedParameterAttribute namedParameter = clazz.GetCustomAttribute<NamedParameterAttribute>(); if (namedParameter == null) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Got name without named parameter post-validation!"), LOGGER); } bool hasStringDefault, hasClassDefault, hasStringSetDefault, hasClassSetDefault; int default_count = 0; if (namedParameter.DefaultValue == null || namedParameter.DefaultValue.Equals(NamedParameterAttribute.ReefUninitializedValue)) { hasStringDefault = false; } else { hasStringDefault = true; default_count++; } if (namedParameter.DefaultClass != null /*Void.class*/) { hasClassDefault = true; default_count++; } else { hasClassDefault = false; } if (namedParameter.DefaultValues != null && namedParameter.DefaultValues.Length > 0) { hasStringSetDefault = true; default_count++; } else { hasStringSetDefault = false; } if (namedParameter.DefaultClasses != null && namedParameter.DefaultClasses.Length > 0) { hasClassSetDefault = true; default_count++; } else { hasClassSetDefault = false; } if (default_count > 1) { var e = new ClassHierarchyException("Named parameter " + fullName + " defines more than one of default_value, default_class, default_values and default_classes"); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } string[] defaultInstanceAsStrings = new string[] { }; if (default_count == 0) { defaultInstanceAsStrings = new String[] { }; } else if (hasClassDefault) { Type default_class = namedParameter.DefaultClass; AssertIsSubclassOf(clazz, default_class, argClass); defaultInstanceAsStrings = new String[] { ReflectionUtilities.GetAssemblyQualifiedName(default_class) }; } else if (hasStringDefault) { // Don't know if the string is a class or literal here, so don't bother validating. defaultInstanceAsStrings = new String[] { namedParameter.DefaultValue }; } else if (hasClassSetDefault) { Type[] clzs = namedParameter.DefaultClasses; defaultInstanceAsStrings = new String[clzs.Length]; for (int i = 0; i < clzs.Length; i++) { AssertIsSubclassOf(clazz, clzs[i], argClass); defaultInstanceAsStrings[i] = ReflectionUtilities.GetAssemblyQualifiedName(clzs[i]); } } else if (hasStringSetDefault) { defaultInstanceAsStrings = namedParameter.DefaultValues; } else { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(), LOGGER); } string documentation = namedParameter.Documentation; string shortName = namedParameter.ShortName; if (namedParameter.ShortName != null && namedParameter.ShortName.Length == 0) { shortName = null; } return new NamedParameterNodeImpl(parent, simpleName, fullName, fullArgName, simpleArgName, isSet, isList, documentation, shortName, defaultInstanceAsStrings, namedParameter.Alias, namedParameter.AliasLanguage); }
public object ParseDefaultValue(INamedParameterNode name) { string[] vals = name.GetDefaultInstanceAsStrings(); object[] ret = new object[vals.Length]; for (int i = 0; i < vals.Length; i++) { string val = vals[i]; try { ret[i] = Parse(name, val); } catch (ParseException e) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER); var ex = new ClassHierarchyException("Could not parse default value " + val, e); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } } if (name.IsSet()) { return new HashSet<object>(ret.ToList<object>()); } if (name.IsList()) { return new List<object>(ret.ToList<object>()); } if (ret.Length == 0) { return null; } if (ret.Length == 1) { return ret[0]; } var ec = new IllegalStateException("Multiple defaults for non-set named parameter! " + name.GetFullName()); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ec, LOGGER); return null; // this line would be never reached as Throw will throw an exception }
public INode BuildPathToNode(Type type) { INode parent = GetParentNode(type); Type argType = ReflectionUtilities.GetNamedParameterTargetOrNull(type); if (argType == null) { return NodeFactory.CreateClassNode(parent, type); } INamedParameterNode np = NodeFactory.CreateNamedParameterNode(parent, type, argType); if (Parameterparser.CanParse(ReflectionUtilities.GetAssemblyQualifiedName(argType))) { if (type.GetCustomAttribute<NamedParameterAttribute>().DefaultClass != null) { var e = new ClassHierarchyException("Named parameter " + ReflectionUtilities.GetAssemblyQualifiedName(type) + " defines default implementation for parsable type " + ReflectionUtilities.GetAssemblyQualifiedName(argType)); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } } if (!string.IsNullOrEmpty(np.GetAlias())) { IDictionary<string, string> mapping = null; _aliasLookupTable.TryGetValue(np.GetAliasLanguage().ToString(), out mapping); if (null == mapping) { mapping = new Dictionary<string, string>(); _aliasLookupTable.Add(np.GetAliasLanguage().ToString(), mapping); } try { mapping.Add(np.GetAlias(), np.GetFullName()); } catch (Exception) { var e = new TangApplicationException(string.Format(CultureInfo.CurrentCulture, "Duplicated alias {0} on named parameter {1}.", np.GetAlias(), np.GetFullName())); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } } string shortName = np.GetShortName(); if (shortName != null && !shortName.Equals(string.Empty)) { INamedParameterNode oldNode = null; shortNames.TryGetValue(shortName, out oldNode); if (oldNode != null) { if (oldNode.GetFullName().Equals(np.GetFullName())) { var ex = new IllegalStateException("Tried to double bind " + oldNode.GetFullName() + " to short name " + shortName); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } var e = new ClassHierarchyException("Named parameters " + oldNode.GetFullName() + " and " + np.GetFullName() + " have the same short name: " + shortName); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } shortNames.Add(shortName, np); } return np; }
public INode RegisterType(Type type) { if (ReflectionUtilities.IsAnonymousType(type)) { // DevNote: Kinda hacky way to indicate the no-op case. return rootNode; } INode n = GetAlreadyBoundNode(type); if (n != null) { return n; } if (type.BaseType != null) { RegisterType(type.BaseType); } foreach (Type interf in type.GetInterfaces()) { RegisterType(ReflectionUtilities.EnsureInterfaceType(interf)); } Type enclosingClass = type.DeclaringType; // this.GetEnclosingClass(type); if (enclosingClass != null) { RegisterType(enclosingClass); } INode node = RegisterClass(type); foreach (Type inner in type.GetNestedTypes()) { RegisterType(inner); } IClassNode classNode = node as ClassNodeImpl; if (classNode != null) { foreach (IConstructorDef constructorDef in classNode.GetInjectableConstructors()) { foreach (IConstructorArg constructorArg in constructorDef.GetArgs()) { if (constructorArg.Gettype() == null) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException("not type in arg"), LOGGER); } RegisterType(constructorArg.Gettype()); // Gettype returns param's Type.fullname if (constructorArg.GetNamedParameterName() != null) { var pn = RegisterType(constructorArg.GetNamedParameterName()); if (!(pn is INamedParameterNode)) { string message = string.Format(CultureInfo.CurrentCulture, "The class {0}, used in the constructor of {1}, should not be defined as a NamedParameter.", constructorArg.GetNamedParameterName(), constructorDef.GetClassName()); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException(message), LOGGER); } INamedParameterNode np = (INamedParameterNode)RegisterType(constructorArg.GetNamedParameterName()); try { if (np.IsSet() || np.IsList()) { // throw new NotImplementedException(); } else { if (!ReflectionUtilities.IsCoercable(ClassForName(constructorArg.Gettype()), ClassForName(np.GetFullArgName()))) { var e = new ClassHierarchyException( "Named parameter type mismatch in " + classNode.GetFullName() + ". Constructor expects a " + constructorArg.Gettype() + " but " + np.GetName() + " is a " + np.GetFullArgName()); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } } } catch (TypeLoadException e) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER); var ex = new ClassHierarchyException("Constructor refers to unknown class " + constructorArg.GetType(), e); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } } } } } else { INamedParameterNode npNode = node as INamedParameterNode; if (npNode != null) { RegisterType(npNode.GetFullArgName()); } } return node; }
public INode BuildPathToNode(Type type) { INode parent = GetParentNode(type); Type argType = ReflectionUtilities.GetNamedParameterTargetOrNull(type); if (argType == null) { return NodeFactory.CreateClassNode(parent, type); } INamedParameterNode np = NodeFactory.CreateNamedParameterNode(parent, type, argType); if(Parameterparser.CanParse(ReflectionUtilities.GetAssemblyQualifiedName(argType))) { if(type.GetCustomAttribute<NamedParameterAttribute>().DefaultClass != null) { var e = new ClassHierarchyException("Named parameter " + ReflectionUtilities.GetAssemblyQualifiedName(type) + " defines default implementation for parsable type " + ReflectionUtilities.GetAssemblyQualifiedName(argType)); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } } string shortName = np.GetShortName(); if (shortName != null && !shortName.Equals("")) { INamedParameterNode oldNode = null; shortNames.TryGetValue(shortName, out oldNode); if (oldNode != null) { if (oldNode.GetFullName().Equals(np.GetFullName())) { var ex = new IllegalStateException("Tried to double bind " + oldNode.GetFullName() + " to short name " + shortName); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } var e = new ClassHierarchyException("Named parameters " + oldNode.GetFullName() + " and " + np.GetFullName() + " have the same short name: " + shortName); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } shortNames.Add(shortName, np); } return np; }
/// <summary> /// Gets the named parameter target or null. /// </summary> /// <param name="type">The type.</param> /// <returns></returns> /// <exception cref="ClassHierarchyException">Named parameter + GetName(type) + implements /// + multiple interfaces. It is only allowed to implement Name</exception> public static Type GetNamedParameterTargetOrNull(Type type) { var npAnnotation = type.GetCustomAttribute<NamedParameterAttribute>(); if (npAnnotation != null) { Type[] intfs = type.GetInterfaces(); if (intfs.Length > 1) { var ex = new ClassHierarchyException("Named parameter " + GetName(type) + " implements " + "multiple interfaces. It is only allowed to implement Name<T>"); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } else if (intfs.Length == 0 || !IsName(intfs[0])) { var ex = new ClassHierarchyException("Found illegal [NamedParameter " + GetName(type) + " does not implement Name<T>"); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } Type[] args = intfs[0].GetGenericArguments(); if (args.Length > 1) { var ex = new ClassHierarchyException("Found illegal [NamedParameter " + GetName(type) + " that has more than one arguments"); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } if (args.Length == 0) { var ex = new ClassHierarchyException("Found illegal [NamedParameter " + GetName(type) + " that has no argument"); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } if (HasConstructor(type) || HasInjectableConstructor(type)) { var ex = new ClassHierarchyException("Named parameter " + GetName(type) + " has " + (HasInjectableConstructor(type) ? "an injectable" : "a") + " constructor. " + " Named parameters must not declare any constructors."); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } return args[0]; } if (ImplementName(type)) //Implement Name<> but no [NamedParameter] attribute { var ex = new ClassHierarchyException("Named parameter " + GetName(type) + " is missing its [NamedParameter] attribute."); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); } return null; }
public static void ProcessConfigData(IConfigurationBuilder conf, IList<KeyValuePair<string, string>> settings) { foreach (KeyValuePair<string, string> kv in settings) { try { conf.Bind(kv.Key, kv.Value); } catch (BindException ex) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(ex, Level.Error, LOGGER); var e = new BindException("Failed to process configuration tuple: [" + kv.Key + "=" + kv.Value + "]", ex); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } catch (ClassHierarchyException ex) { Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(ex, Level.Error, LOGGER); var e = new ClassHierarchyException("Failed to process configuration tuple: [" + kv.Key + "=" + kv.Value + "]", ex); Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER); } } }