You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@reef.apache.org by we...@apache.org on 2015/01/29 21:43:00 UTC
[16/31] incubator-reef git commit: [REEF-97] Add the REEF.NET code
base
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/AbstractNode.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/AbstractNode.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/AbstractNode.cs
new file mode 100644
index 0000000..a88e7d2
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/AbstractNode.cs
@@ -0,0 +1,131 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class AbstractNode : INode
+ {
+ /// It is from Type.FullName. This name is used as Name in a Node.
+ /// It is not unique for a generic type with different type of arguments.
+ /// It is used for toString or debug info as AssemblyQualifiedName is really long
+ private String name;
+
+ /// It is from Type.AssemblyQualifiedName. THis name is used as full name in a Node
+ /// It is unique for a generic type with different type of arguments.
+ private String fullName; //it comes from
+
+ //parent node in the class hierarchy
+ private INode parent;
+
+ //children in the class hierarchy
+ protected IDictionary<String, INode> children = new MonotonicTreeMap<string, INode>();
+
+ public AbstractNode(INode parent, String name, String fullName)
+ {
+ this.parent = parent;
+ this.name = name;
+ this.fullName = fullName;
+ if (parent != null)
+ {
+ parent.Add(this);
+ }
+ }
+
+ public ICollection<INode> GetChildren()
+ {
+ return children.Values;
+ }
+
+ public bool Contains(String key)
+ {
+ return children.ContainsKey(key);
+ }
+
+ public INode Get(String key)
+ {
+ INode val;
+ if (children.TryGetValue(key, out val))
+ {
+ return val;
+ }
+ return null;
+ }
+
+ public virtual void Add(INode n)
+ {
+ children.Add(n.GetFullName(), n);
+ }
+
+ public string GetFullName()
+ {
+ return fullName;
+ }
+
+ public string GetName()
+ {
+ return name;
+ }
+
+ public INode GetParent()
+ {
+ return parent;
+ }
+
+ public override bool Equals(Object o)
+ {
+ if(o == null) return false;
+ if(o == this) return true;
+
+ AbstractNode n = (AbstractNode) o;
+ bool parentsEqual;
+ if (n.parent == this.parent) {
+ parentsEqual = true;
+ } else if (n.parent == null) {
+ parentsEqual = false;
+ } else if (this.parent == null) {
+ parentsEqual = false;
+ } else {
+ parentsEqual = n.parent.Equals(this.parent);
+ }
+ if (!parentsEqual) {
+ return false;
+ }
+ return fullName.Equals(n.fullName);
+ }
+
+ public override int GetHashCode()
+ {
+ return fullName.GetHashCode();
+ }
+
+ public override String ToString()
+ {
+ return "[" + this.GetType().FullName + " '" + fullName + "']";
+ }
+
+ public int CompareTo(INode n)
+ {
+ return fullName.CompareTo(n.GetFullName());
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassHierarchyImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassHierarchyImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassHierarchyImpl.cs
new file mode 100644
index 0000000..3f9f16e
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassHierarchyImpl.cs
@@ -0,0 +1,526 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Annotations;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class ClassHierarchyImpl : ICsClassHierarchy
+ {
+ private static readonly Logger LOGGER = Logger.GetLogger(typeof (ClassHierarchyImpl));
+ private INode rootNode;
+ private MonotonicTreeMap<String, INamedParameterNode> shortNames = new MonotonicTreeMap<String, INamedParameterNode>();
+ private IList<string> assemblies;
+ private AssemblyLoader loader = null;
+
+ public ParameterParser Parameterparser = new ParameterParser();
+
+ public ClassHierarchyImpl(String file) : this(new string[] { file }, new Type[0])
+ {
+ }
+
+ public ClassHierarchyImpl(string[] assemblies) : this(assemblies, new Type[0])
+ {
+ }
+
+ //parameterParsers are classes that extends from IExternalConstructor
+ public ClassHierarchyImpl(string[] assemblies, Type[] parameterParsers)
+ {
+ this.assemblies = assemblies;
+ rootNode = NodeFactory.CreateRootPackageNode();
+ loader = new AssemblyLoader(assemblies);
+
+ foreach (Type p in parameterParsers) //p must be extend from IExternalConstructor
+ {
+ try
+ {
+ Parameterparser.AddParser(p);
+ }
+ catch (BindException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException("Could not register parameter parsers", e), LOGGER);
+ }
+ }
+
+ foreach (var a in loader.Assemblies)
+ {
+ foreach (var t in a.GetTypes())
+ {
+ RegisterType(t);
+ }
+ }
+ }
+
+ public INode RegisterType(string assemblyQualifiedName)
+ {
+ Type type = this.loader.GetType(assemblyQualifiedName);
+ if (type != null)
+ {
+ return RegisterType(type);
+ }
+ return null;
+ }
+
+ public INode RegisterType(Type type)
+ {
+ if (ReflectionUtilities.IsAnnonymousType(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)
+ {
+ 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;
+ }
+
+ private INode RegisterClass(Type type)
+ {
+ INode node = GetAlreadyBoundNode(type);
+ if (node != null)
+ {
+ return node;
+ }
+
+ node = BuildPathToNode(type);
+ IClassNode classNode = node as IClassNode;
+ if (classNode != null)
+ {
+ Type baseType = type.BaseType;
+ if (baseType != null)
+ {
+ IClassNode n = (IClassNode) GetAlreadyBoundNode(baseType);
+ if (n != null)
+ {
+ n.PutImpl(classNode);
+ }
+ else
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Error in finding Node for BaseType"), LOGGER);
+ }
+ }
+
+ foreach (Type interf in ReflectionUtilities.GetInterfaces(type, false))
+ {
+ IClassNode n = (IClassNode)GetAlreadyBoundNode(ReflectionUtilities.EnsureInterfaceType(interf));
+ if (n != null)
+ {
+ n.PutImpl(classNode);
+ }
+ else
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Error in finding Node for Interface"), LOGGER);
+ }
+ }
+ }
+ 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;
+ }
+
+ //return Type T if type implements Name<T>, null otherwise
+ //e.g. [NamedParameter(typeof(System.String), "Number of seconds to sleep", "10", "sec")]
+ //class Seconds : Name<Int32> { }
+ //return Int32
+
+ //TODO add error handlings
+ public Type GetNamedParameterTargetOrNull(Type type)
+ {
+ var npAnnotation = type.GetCustomAttribute<NamedParameterAttribute>();
+ if (npAnnotation != null)
+ {
+ Type[] intfs = type.GetInterfaces();
+ if (intfs.Length == 1)
+ {
+ if (intfs[0].Name.Equals(GetNameOfNameInterface()))
+ {
+ Type[] args = intfs[0].GetGenericArguments();
+ if (args.Length == 1)
+ {
+ return args[0];
+ }
+ }
+ }
+
+ }
+ return null;
+ }
+
+ private INode GetAlreadyBoundNode(Type t)
+ {
+ //get outclass names including itsself
+ string[] outerClassNames = ReflectionUtilities.GetEnclosingClassNames(t);
+
+ INode current = rootNode;
+ for (int i = 0; i < outerClassNames.Length; i++)
+ {
+ current = current.Get(outerClassNames[i]);
+ if (current == null)
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j <= i; j++)
+ {
+ sb.Append(outerClassNames[j]);
+ if (j != i)
+ {
+ sb.Append(".");
+ }
+ }
+ return null;
+ //throw new NameResolutionException(t.FullName, sb.ToString());
+ }
+
+ }
+ return current;
+ }
+
+ //starting from the root, get child for each eclosing class excluding the type itsself
+ //all enclosing classes should be already in the hierarchy
+ //Type B2 = asm.GetType(@"Org.Apache.Reef.Tang.Examples.B+B1+B2");
+ //string[] pathB2 = ClassNameParser.GetEnclosingClassShortNames(B2);
+ //Assert.AreEqual(pathB2[0], "B");
+ //Assert.AreEqual(pathB2[1], "B1");
+ //Assert.AreEqual(pathB2[2], "B2");
+ //return INode for B1
+ private INode GetParentNode(Type type)
+ {
+ INode current = rootNode;
+ string[] enclosingPath = ReflectionUtilities.GetEnclosingClassNames(type);
+ for (int i = 0; i < enclosingPath.Length - 1; i++)
+ {
+ current = current.Get(enclosingPath[i]);
+ }
+ return current;
+ }
+
+ private string GetNameOfNameInterface()
+ {
+ var tn = typeof(Name<int>);
+ return tn.Name;
+ }
+
+ public INode GetNode(string fullName)
+ {
+ Type t = loader.GetType(fullName);
+
+ if (t == null)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new NameResolutionException(fullName, fullName), LOGGER);
+ }
+
+ return this.GetNode(t);
+ }
+
+ public INode GetNode(Type type)
+ {
+ this.RegisterType(type);
+ return GetAlreadyBoundNode(type);
+ }
+
+ public INode GetNamespace()
+ {
+ return rootNode;
+ }
+
+ public bool IsImplementation(IClassNode inter, IClassNode impl)
+ {
+ return impl.IsImplementationOf(inter);
+ }
+
+ public IClassHierarchy Merge(IClassHierarchy ch)
+ {
+ if (this == ch) { return this; }
+
+ if (!(ch is ClassHierarchyImpl))
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new NotSupportedException("Can't merge java and non-java class hierarchies yet!"), LOGGER);
+ }
+
+ if(this.assemblies.Count == 0)
+ {
+ return ch;
+ }
+
+ ClassHierarchyImpl chi = (ClassHierarchyImpl)ch;
+ MonotonicHashSet<string> otherJars = new MonotonicHashSet<string>();
+ otherJars.AddAll(chi.assemblies);
+ MonotonicHashSet<string> myJars = new MonotonicHashSet<string>();
+ myJars.AddAll(this.assemblies);
+ if(myJars.ContainsAll(otherJars))
+ {
+ return this;
+ }
+ if (otherJars.ContainsAll(myJars))
+ {
+ return ch;
+ }
+ myJars.AddAll(otherJars);
+ return new ClassHierarchyImpl(myJars.ToArray());
+ }
+
+ public object Parse(INamedParameterNode np, string value)
+ {
+ IClassNode iface = null;
+ try
+ {
+ iface = (IClassNode)GetNode(np.GetFullArgName());
+ }
+ catch(NameResolutionException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ var ex = new IllegalStateException("Could not parse validated named parameter argument type. NamedParameter is " + np.GetFullName() + " argument type is " + np.GetFullArgName(), e);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ Type clazz;
+ String fullName;
+ try
+ {
+ clazz = (Type)ClassForName(iface.GetFullName());
+ fullName = null;
+ }
+ catch(TypeLoadException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Warning, LOGGER);
+ clazz = null;
+ fullName = iface.GetFullName();
+ }
+
+ object result = null;
+ if (clazz != null)
+ {
+ result = Parameterparser.Parse(clazz, value);
+ }
+ else
+ {
+ result = Parameterparser.Parse(fullName, value);
+ }
+
+ if (result == null)
+ {
+ try
+ {
+ INode impl = GetNode(value);
+ if (impl is IClassNode)
+ {
+ if (IsImplementation(iface, (IClassNode) impl))
+ {
+ return impl;
+ }
+ }
+ var ex =
+ new ParseException(
+ "Name<" + iface.GetFullName() + "> " + np.GetFullName() + " cannot take non-subclass " +
+ impl.GetFullName());
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ catch (NameResolutionException ec)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(ec, Level.Error, LOGGER);
+ var ex =
+ new ParseException(
+ "Name<" + iface.GetFullName() + "> " + np.GetFullName() + " cannot take non-class " + value,
+ ec);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ }
+ return result;
+ }
+
+ 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 Type ClassForName(string name)
+ {
+ return this.GetType(name);
+ }
+
+ public Type GetType(string name)
+ {
+ return this.loader.GetType(name);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassNodeImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassNodeImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassNodeImpl.cs
new file mode 100644
index 0000000..27a57b9
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassNodeImpl.cs
@@ -0,0 +1,157 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class ClassNodeImpl : AbstractNode, IClassNode
+ {
+ private static readonly Logger LOGGER = Logger.GetLogger(typeof(ClassNodeImpl));
+
+ private readonly bool injectable;
+ private readonly bool unit;
+ private readonly bool externalConstructor;
+ private readonly IList<IConstructorDef> injectableConstructors;
+ private readonly IList<IConstructorDef> allConstructors;
+ private readonly MonotonicSet<IClassNode> knownImpls;
+ private readonly String defaultImpl;
+
+ public ClassNodeImpl(INode parent, String simpleName, String fullName,
+ bool unit, bool injectable, bool externalConstructor,
+ IList<IConstructorDef> injectableConstructors,
+ IList<IConstructorDef> allConstructors,
+ String defaultImplementation)
+ : base(parent, simpleName, fullName)
+ {
+
+ this.unit = unit;
+ this.injectable = injectable;
+ this.externalConstructor = externalConstructor;
+ this.injectableConstructors = injectableConstructors;
+ this.allConstructors = allConstructors;
+ this.knownImpls = new MonotonicSet<IClassNode>();
+ this.defaultImpl = defaultImplementation;
+ }
+
+ public IList<IConstructorDef> GetInjectableConstructors()
+ {
+ return injectableConstructors;
+ }
+
+ public IList<IConstructorDef> GetAllConstructors()
+ {
+ return allConstructors;
+ }
+
+ public bool IsInjectionCandidate()
+ {
+ return injectable;
+ }
+
+ public bool IsExternalConstructor()
+ {
+ return externalConstructor;
+ }
+
+ public override String ToString()
+ {
+ StringBuilder sb = new StringBuilder(base.ToString() + ": ");
+ if (GetInjectableConstructors() != null)
+ {
+ foreach (IConstructorDef c in GetInjectableConstructors())
+ {
+ sb.Append(c.ToString() + ", ");
+ }
+ }
+ else
+ {
+ sb.Append("OBJECT BUILD IN PROGRESS! BAD NEWS!");
+ }
+ return sb.ToString();
+ }
+
+ public IConstructorDef GetConstructorDef(IList<IClassNode> paramTypes)
+ {
+ if (!IsInjectionCandidate())
+ {
+ var e = new BindException("Cannot @Inject non-static member/local class: "
+ + GetFullName());
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+ }
+ foreach (IConstructorDef c in GetAllConstructors())
+ {
+ if (c.TakesParameters(paramTypes))
+ {
+ return c;
+ }
+ }
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new BindException("Could not find requested constructor for class " + GetFullName()), LOGGER);
+ return null; // this line would not be reached as Thrwo throws an exception
+ }
+
+ public void PutImpl(IClassNode impl)
+ {
+ knownImpls.Add(impl);
+ }
+
+ public ISet<IClassNode> GetKnownImplementations()
+ {
+ return new MonotonicSet<IClassNode>(knownImpls);
+ }
+
+ public bool IsUnit()
+ {
+ return unit;
+ }
+
+ public bool IsImplementationOf(IClassNode inter)
+ {
+ List<IClassNode> worklist = new List<IClassNode>();
+ if (this.Equals(inter))
+ {
+ return true;
+ }
+ worklist.Add(inter);
+ while (worklist.Count != 0)
+ {
+ IClassNode cn = worklist[worklist.Count - 1];
+ worklist.RemoveAt(worklist.Count - 1);
+ ISet<IClassNode> impls = cn.GetKnownImplementations();
+ if (impls.Contains(this))
+ {
+ return true;
+ }
+ worklist.AddRange(impls);
+ }
+ return false;
+ }
+
+ public String GetDefaultImplementation()
+ {
+ return defaultImpl;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorArgImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorArgImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorArgImpl.cs
new file mode 100644
index 0000000..31e4103
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorArgImpl.cs
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class ConstructorArgImpl : IConstructorArg
+ {
+ private readonly String type;
+ private readonly String name;
+ private readonly bool isInjectionFuture;
+
+ public ConstructorArgImpl(String type, String namedParameterName, bool isInjectionFuture)
+ {
+ if (type == null)
+ {
+ ;
+ }
+ this.type = type;
+ this.name = namedParameterName;
+
+ //if (name != null && name.Contains(','))
+ // throw new ApplicationException("Name contains comma : " + name);
+ this.isInjectionFuture = isInjectionFuture;
+ }
+
+ public string GetName()
+ {
+ return name == null ? type : name;
+ }
+
+ public string GetNamedParameterName()
+ {
+ return name;
+ }
+
+ public string Gettype()
+ {
+ return type;
+ }
+
+ public bool IsInjectionFuture()
+ {
+ return isInjectionFuture;
+ }
+
+ public override String ToString()
+ {
+ return name == null ? type : type + " " + name;
+ }
+
+ public override int GetHashCode()
+ {
+ return 0;
+ }
+
+ public override bool Equals(Object o)
+ {
+ ConstructorArgImpl arg = (ConstructorArgImpl)o;
+ if (!type.Equals(arg.type))
+ {
+ return false;
+ }
+ if (name == null && arg.name == null)
+ {
+ return true;
+ }
+ if (name == null && arg.name != null)
+ {
+ return false;
+ }
+ if (name != null && arg.name == null)
+ {
+ return false;
+ }
+ return name.Equals(arg.name);
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorDefImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorDefImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorDefImpl.cs
new file mode 100644
index 0000000..4e72da7
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorDefImpl.cs
@@ -0,0 +1,203 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class ConstructorDefImpl : IConstructorDef
+ {
+ private static readonly Logger LOGGER = Logger.GetLogger(typeof(ConstructorDefImpl));
+
+ private readonly IList<IConstructorArg> args = new List<IConstructorArg>();
+ private readonly String className;
+
+ 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 IList<IConstructorArg> GetArgs()
+ {
+ return args;
+ }
+
+ public String GetClassName()
+ {
+ return className;
+ }
+
+ private String Join(String sep, Object[] vals)
+ {
+ if (vals.Length != 0)
+ {
+ StringBuilder sb = new StringBuilder(vals[0].ToString());
+ for (int i = 1; i < vals.Length; i++)
+ {
+ sb.Append(sep + vals[i]);
+ }
+ return sb.ToString();
+ }
+ else
+ {
+ return "";
+ }
+ }
+
+ public override String ToString()
+ {
+ StringBuilder sb = new StringBuilder(className);
+ sb.Append("(");
+ sb.Append(Join(",", args.ToArray()));
+ sb.Append(")");
+ return sb.ToString();
+ }
+
+ // 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 bool TakesParameters(IList<IClassNode> paramTypes)
+ {
+ if (paramTypes.Count != args.Count)
+ {
+ return false;
+ }
+
+ int i = 0;
+ foreach (INode t in paramTypes)
+ {
+ string s;
+ if (t is INamedParameterNode)
+ {
+ s = ((INamedParameterNode)paramTypes[i]).GetFullArgName();
+ }
+ else
+ {
+ s = paramTypes[i].GetFullName();
+ }
+ if (!args[i].Gettype().Equals(s))
+ {
+ return false;
+ }
+ else
+ {
+ i++;
+ }
+
+ }
+ return true;
+ }
+
+ public override bool Equals(Object o)
+ {
+ return EqualsIgnoreOrder((IConstructorDef)o);
+ }
+
+ public override int GetHashCode()
+ {
+ return 0;
+ }
+
+ //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;
+ }
+
+ public int CompareTo(object obj)
+ {
+ IConstructorDef o = (IConstructorDef)obj;
+ return ToString().CompareTo(o.ToString());
+ }
+
+ public bool IsInList(IList<IConstructorDef> list )
+ {
+ foreach (IConstructorDef def in list)
+ {
+ if (CompareTo(def) == 0)
+ {
+ return true;
+ }
+
+ }
+ return false;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NamedParameterNodeImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NamedParameterNodeImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NamedParameterNodeImpl.cs
new file mode 100644
index 0000000..3bdc868
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NamedParameterNodeImpl.cs
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class NamedParameterNodeImpl : AbstractNode, INamedParameterNode
+ {
+ private readonly String fullArgName;
+ private readonly String simpleArgName;
+ private readonly String documentation;
+ private readonly String shortName;
+ private readonly String[] defaultInstanceAsStrings;
+ private readonly bool isSet;
+ private readonly bool isList;
+
+ public NamedParameterNodeImpl(INode parent, String simpleName,
+ String fullName, String fullArgName, String simpleArgName, bool isSet, bool isList,
+ String documentation, String shortName, String[] defaultInstanceAsStrings)
+ : base(parent, simpleName, fullName)
+ {
+ this.fullArgName = fullArgName;
+ this.simpleArgName = simpleArgName;
+ this.isSet = isSet;
+ this.isList = isList;
+ this.documentation = documentation;
+ this.shortName = shortName;
+ this.defaultInstanceAsStrings = defaultInstanceAsStrings;
+ }
+
+ public override String ToString()
+ {
+ return GetSimpleArgName() + " " + GetName();
+ }
+
+ public String GetSimpleArgName()
+ {
+ return simpleArgName;
+ }
+
+ public String GetFullArgName()
+ {
+ return fullArgName;
+ }
+
+ public String GetDocumentation()
+ {
+ return documentation;
+ }
+
+ public String GetShortName()
+ {
+ return shortName;
+ }
+
+ public String[] GetDefaultInstanceAsStrings()
+ {
+ return defaultInstanceAsStrings;
+ }
+
+ public bool IsSet()
+ {
+ return isSet;
+ }
+
+ public bool IsList()
+ {
+ return isList;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NodeFactory.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NodeFactory.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NodeFactory.cs
new file mode 100644
index 0000000..474f2d5
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NodeFactory.cs
@@ -0,0 +1,315 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Annotations;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Interface;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class NodeFactory
+ {
+ private static readonly Logger LOGGER = Logger.GetLogger(typeof(NodeFactory));
+
+ public static IPackageNode CreateRootPackageNode()
+ {
+ return new PackageNodeImpl();
+ }
+
+ 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);
+ }
+
+ //TODO
+ private static ConstructorDefImpl CreateConstructorDef(ConstructorInfo constructor, bool injectable)
+ {
+ var parameters = constructor.GetParameters();
+
+ IConstructorArg[] args = new ConstructorArgImpl[parameters.Length];
+
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ //TODO for getInterfaceTarget() call
+ Type type = parameters[i].ParameterType;
+ type = ReflectionUtilities.EnsureInterfaceType(type);
+ //if (type.IsGenericType && type.FullName == null)
+ //{
+ // type = type.GetGenericTypeDefinition();
+ //}
+ bool isFuture;
+
+ if(ReflectionUtilities.IsAssignableFromIgnoreGeneric(typeof(IInjectionFuture<>), type))
+ {
+ type = ReflectionUtilities.GetInterfaceTarget(typeof(IInjectionFuture<>), type);
+ isFuture = true;
+ }
+ else
+ {
+ isFuture = false;
+ }
+
+ ParameterAttribute named = parameters[i].GetCustomAttribute<ParameterAttribute>();
+ if (named != null && !injectable)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ClassHierarchyException(constructor + " is not injectable, but it has an @Parameter annotation."), LOGGER);
+ }
+
+ if (type == null)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Exception"), LOGGER);
+ }
+
+ string typename = ReflectionUtilities.GetAssemblyQualifiedName(type);
+ if (typename == null)
+ {
+ typename = type.Name;
+ }
+ args[i] = new ConstructorArgImpl(typename, named == null ? null : ReflectionUtilities.GetAssemblyQualifiedName(named.Value), isFuture);
+ }
+ return new ConstructorDefImpl(ReflectionUtilities.GetAssemblyQualifiedName(constructor.DeclaringType), args, injectable);
+ }
+
+ 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.default_value().isEmpty()) { //QUESTION: difference from below?
+ if (namedParameter.DefaultValue != null && namedParameter.DefaultValue.Length > 0)
+ {
+ hasStringDefault = true;
+ default_count++;
+ }
+ else
+ {
+ hasStringDefault = false;
+ }
+
+ 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);
+ }
+
+ // 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);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/PackageNodeImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/PackageNodeImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/PackageNodeImpl.cs
new file mode 100644
index 0000000..7516493
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/PackageNodeImpl.cs
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class PackageNodeImpl : AbstractNode, IPackageNode
+ {
+ public PackageNodeImpl(INode parent, String name, String fullName) :
+ base(parent, name, fullName)
+ {
+ }
+
+ public PackageNodeImpl()
+ : base(null, "", "[root node]")
+ {
+ }
+
+ /**
+ * Unlike normal nodes, the root node needs to take the package name of its
+ * children into account. Therefore, we use the full name as the key when
+ * we insert nodes into the root.
+ */
+ public override void Add(INode n) {
+ if (children.Count == 289)
+ {
+ Console.WriteLine("Test");
+ }
+ children.Add(n.GetFullName(), n);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ParameterParser.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ParameterParser.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ParameterParser.cs
new file mode 100644
index 0000000..840e447
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ParameterParser.cs
@@ -0,0 +1,199 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class ParameterParser
+ {
+ private static readonly Logger LOGGER = Logger.GetLogger(typeof(ParameterParser));
+
+ MonotonicTreeMap<String, ConstructorInfo> parsers = new MonotonicTreeMap<String, ConstructorInfo>();
+
+ //ec: ACons, tc: A
+ public void AddParser(Type ec)
+ {
+ Type tc = (Type)ReflectionUtilities.GetInterfaceTarget(typeof(IExternalConstructor<>), ec);
+ AddParser(tc, ec);
+ }
+
+ //TODO
+ //public <T, U extends T> void AddParser(Class<U> clazz, Class<? extends ExternalConstructor<T>> ec) throws BindException {
+ //public void AddParser<T, U, V>(GenericType<U> clazz, GenericType<V> ec)
+ // where U : T
+ // where V: IExternalConstructor<T>
+ //{
+
+ //clazz: A, ec: ACons
+ private void AddParser(Type clazz, Type ec)
+ {
+ ConstructorInfo c = ec.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string) }, null);
+
+ if (c == null)
+ {
+ var e = new BindException("Constructor " + ReflectionUtilities.GetAssemblyQualifiedName(ec) + "(String) does not exist!");
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+ }
+
+ //c.setAccessible(true); //set as public
+ parsers.Add(ReflectionUtilities.GetAssemblyQualifiedName(clazz), c);
+ }
+
+
+ public void MergeIn(ParameterParser p)
+ {
+ foreach (string s in p.parsers.Keys)
+ {
+ if (!parsers.ContainsKey(s))
+ {
+ ConstructorInfo ci;
+ p.parsers.TryGetValue(s, out ci);
+ parsers.Add(s, ci);
+ }
+ else
+ {
+ ConstructorInfo oldC;
+ ConstructorInfo newC;
+ parsers.TryGetValue(s, out oldC);
+ p.parsers.TryGetValue(s, out newC);
+ if (!oldC.Equals(newC))
+ {
+ var e = new ArgumentException(
+ "Conflict detected when merging parameter parsers! To parse " + s
+ + " I have a: " + ReflectionUtilities.GetAssemblyQualifiedName(oldC.DeclaringType)
+ + " the other instance has a: " + ReflectionUtilities.GetAssemblyQualifiedName(newC.DeclaringType));
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+ }
+ }
+ }
+ }
+
+ //(Integer, "3") return object of new Integer(3)
+ public object Parse(Type c, String s)
+ {
+ Type d = ReflectionUtilities.BoxClass(c);
+ foreach (Type e in ReflectionUtilities.ClassAndAncestors(d)) // get all the super classes of Integer for example
+ {
+ string name = ReflectionUtilities.GetAssemblyQualifiedName(e);
+ if (parsers.ContainsKey(name))
+ {
+ object ret = Parse(name, s);
+ if (c.IsAssignableFrom(ret.GetType())) //check if ret can be cast as c
+ {
+ return ret;
+ }
+ else
+ {
+ var ex = new InvalidCastException("Cannot cast from " + ret.GetType() + " to " + c);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ }
+ }
+ return Parse(d.Name, s);
+ }
+
+ //name: "Integer", value: "12"
+ public object Parse(string name, string value)
+ {
+ if (parsers.ContainsKey(name))
+ {
+ try
+ {
+ ConstructorInfo c = null;
+ parsers.TryGetValue(name, out c);
+ var o = c.Invoke(new object[] { value });
+ var m = o.GetType().GetMethod("NewInstance", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+ return m.Invoke(o, new object[] {});
+ }
+ catch (TargetInvocationException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException("Error invoking constructor for " + name, e), LOGGER);
+ }
+ }
+ else if (name.Equals(typeof(string).Name))
+ {
+ return (object)value;
+ }
+ if (name.Equals(typeof(Byte).Name))
+ {
+ return (object)(Byte)Byte.Parse(value);
+ }
+ if (name.Equals(typeof(Char).Name))
+ {
+ return (object)(Char)value[0];
+ }
+ if (name.Equals(typeof(short).Name))
+ {
+ return (System.Int16)System.Int16.Parse(value);
+ }
+ if (name.Equals(typeof(int).Name))
+ {
+ return (object)(Int32)Int32.Parse(value);
+ }
+ if (name.Equals(typeof(long).Name))
+ {
+ return (object)(Int64)Int64.Parse(value);
+ }
+ if (name.Equals(typeof(float).Name))
+ {
+ return (object)(Single)Single.Parse(value);
+ }
+ if (name.Equals(typeof(Double).Name))
+ {
+ return (object)(Double)Double.Parse(value);
+ }
+ if (name.Equals(typeof(Boolean).Name))
+ {
+ return (object)(Boolean)Boolean.Parse(value);
+ }
+ if (name.Equals(typeof(byte[]).Name))
+ {
+ byte[] bytes = new byte[value.Length * sizeof(char)];
+ System.Buffer.BlockCopy(value.ToCharArray(), 0, bytes, 0, bytes.Length);
+ return bytes;
+ }
+ return null;
+ }
+
+ private static readonly ISet<string> BUILTIN_NAMES = new HashSet<string>(new string[]
+ {
+ typeof(string).AssemblyQualifiedName,
+ typeof(Byte).AssemblyQualifiedName,
+ typeof(char).AssemblyQualifiedName,
+ typeof(short).AssemblyQualifiedName,
+ typeof(Int32).AssemblyQualifiedName,
+ typeof(long).AssemblyQualifiedName,
+ typeof(float).AssemblyQualifiedName,
+ typeof(double).AssemblyQualifiedName,
+ typeof(bool).AssemblyQualifiedName
+ } );
+
+ public bool CanParse(string name)
+ {
+ return parsers.ContainsKey(name) || BUILTIN_NAMES.Contains(name);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationBuilderImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationBuilderImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationBuilderImpl.cs
new file mode 100644
index 0000000..cd2aa30
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationBuilderImpl.cs
@@ -0,0 +1,364 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class ConfigurationBuilderImpl : IConfigurationBuilder
+ {
+ public IClassHierarchy ClassHierarchy;
+
+ public readonly IDictionary<IClassNode, IClassNode> BoundImpls = new MonotonicTreeMap<IClassNode, IClassNode>();
+ public readonly IDictionary<IClassNode, IClassNode> BoundConstructors = new MonotonicTreeMap<IClassNode, IClassNode>();
+ public readonly IDictionary<INamedParameterNode, String> NamedParameters = new MonotonicTreeMap<INamedParameterNode, String>();
+ public readonly IDictionary<IClassNode, IConstructorDef> LegacyConstructors = new MonotonicTreeMap<IClassNode, IConstructorDef>();
+ public readonly MonotonicMultiMap<INamedParameterNode, object> BoundSetEntries = new MonotonicMultiMap<INamedParameterNode, object>();
+ public readonly IDictionary<INamedParameterNode, IList<object>> BoundLists = new MonotonicTreeMap<INamedParameterNode, IList<object>>();
+
+ public readonly static string INIT = "<init>";
+
+ private static readonly Logger LOGGER = Logger.GetLogger(typeof(ConfigurationBuilderImpl));
+
+ protected ConfigurationBuilderImpl()
+ {
+ this.ClassHierarchy = TangFactory.GetTang().GetDefaultClassHierarchy();
+ }
+
+ public ConfigurationBuilderImpl(IClassHierarchy classHierarchy)
+ {
+ this.ClassHierarchy = classHierarchy;
+ }
+
+ protected ConfigurationBuilderImpl(string[] assemblies, IConfiguration[] confs, Type[] parsers)
+ {
+ this.ClassHierarchy = TangFactory.GetTang().GetDefaultClassHierarchy(assemblies, parsers);
+ foreach (IConfiguration tc in confs)
+ {
+ AddConfiguration(((ConfigurationImpl) tc));
+ }
+ }
+
+ public ConfigurationBuilderImpl(ConfigurationBuilderImpl t)
+ {
+ this.ClassHierarchy = t.GetClassHierarchy();
+ try {
+ AddConfiguration(t.GetClassHierarchy(), t);
+ }
+ catch (BindException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Could not copy builder", e), LOGGER);
+ }
+ }
+
+ protected ConfigurationBuilderImpl(string[] assemblies) : this(assemblies, new IConfiguration[0], new Type[0])
+ {
+ }
+
+ protected ConfigurationBuilderImpl(IConfiguration[] confs) : this(new string[0], confs, new Type[0])
+ {
+ }
+
+ public void AddConfiguration(IConfiguration conf)
+ {
+ AddConfiguration(conf.GetClassHierarchy(), ((ConfigurationImpl)conf).Builder);
+ }
+
+ 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);
+ }
+ }
+
+ public IClassHierarchy GetClassHierarchy()
+ {
+ return this.ClassHierarchy;
+ }
+
+ public void RegisterLegacyConstructor(IClassNode cn, IList<IClassNode> args)
+ {
+ LegacyConstructors.Add(cn, cn.GetConstructorDef(args));
+ }
+
+ public void RegisterLegacyConstructor(string s, IList<string> args)
+ {
+ IClassNode cn = (IClassNode) this.ClassHierarchy.GetNode(s);
+ IList<IClassNode> cnArgs = new List<IClassNode>();
+ for (int i = 0; i < args.Count; i++)
+ {
+ cnArgs.Add((IClassNode)ClassHierarchy.GetNode(args[i]));
+ }
+ RegisterLegacyConstructor(cn, cnArgs);
+ }
+
+ public void RegisterLegacyConstructor(IClassNode c, IList<IConstructorArg> args)
+ {
+ string[] cn = new string[args.Count];
+
+ for (int i = 0; i < args.Count; i++)
+ {
+ cn[i] = args[i].Gettype();
+ }
+ RegisterLegacyConstructor(c.GetFullName(), cn);
+ }
+
+ public IConfiguration Build()
+ {
+ return new ConfigurationImpl(new ConfigurationBuilderImpl(this));
+ }
+
+ public void Bind(string key, string value)
+ {
+ INode n = this.ClassHierarchy.GetNode(key);
+ if (n is INamedParameterNode)
+ {
+ BindParameter((INamedParameterNode)n, value);
+ }
+ else if (n is IClassNode)
+ {
+ INode m = this.ClassHierarchy.GetNode(value);
+ Bind((IClassNode)n, (IClassNode)m);
+ }
+ else
+ {
+ var ex = new IllegalStateException(string.Format("getNode() returned {0} which is neither a ClassNode nor a NamedParameterNode", n));
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ }
+
+ public void Bind(Types.INode key, Types.INode value)
+ {
+ if (key is INamedParameterNode)
+ {
+ BindParameter((INamedParameterNode)key, value.GetFullName());
+ }
+ else if (key is IClassNode)
+ {
+ IClassNode k = (IClassNode)key;
+ if (value is IClassNode)
+ {
+ IClassNode val = (IClassNode)value;
+ if (val.IsExternalConstructor() && !k.IsExternalConstructor())
+ {
+ BindConstructor(k, (IClassNode) val);
+ }
+ else
+ {
+ BindImplementation(k, (IClassNode)val);
+ }
+ }
+ }
+ }
+
+ public void BindParameter(INamedParameterNode name, String value)
+ {
+ /* Parse and discard value; this is just for type checking, skip for now*/
+ if (this.ClassHierarchy is ICsClassHierarchy)
+ {
+ ((ICsClassHierarchy)ClassHierarchy).Parse(name, value);
+ }
+
+ if(name.IsSet())
+ {
+ BindSetEntry((INamedParameterNode)name, value);
+ }
+ else
+ {
+ NamedParameters.Add(name, value);
+ }
+ }
+
+ public void BindImplementation(IClassNode n, IClassNode m)
+ {
+ if (this.ClassHierarchy.IsImplementation(n, m))
+ {
+ BoundImpls.Add(n, m);
+ }
+ else
+ {
+ var ex = new ArgumentException(string.Format("Class {0} does not extend {1}.", m, n));
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ }
+
+ public void BindSetEntry(String iface, String impl)
+ {
+ BoundSetEntries.Add((INamedParameterNode)this.ClassHierarchy.GetNode(iface), impl);
+ }
+
+ public void BindSetEntry(String iface, INode impl)
+ {
+ BoundSetEntries.Add((INamedParameterNode)ClassHierarchy.GetNode(iface), impl);
+ }
+
+ public void BindSetEntry(INamedParameterNode iface, String impl)
+ {
+ BoundSetEntries.Add(iface, impl);
+ }
+
+ public void BindSetEntry(INamedParameterNode iface, INode impl)
+ {
+ BoundSetEntries.Add(iface, impl);
+ }
+
+ public void BindList(INamedParameterNode iface, IList<INode> impl)
+ {
+ IList<object> l = new List<object>();
+ foreach (var n in impl)
+ {
+ l.Add((object)n);
+ }
+ BoundLists.Add(iface, l);
+ }
+
+ public void BindList(INamedParameterNode iface, IList<string> impl)
+ {
+ IList<object> l = new List<object>();
+ foreach (var n in impl)
+ {
+ l.Add((object)n);
+ }
+ BoundLists.Add(iface, l);
+ }
+
+ public void BindList(string iface, IList<INode> impl)
+ {
+ BindList((INamedParameterNode)ClassHierarchy.GetNode(iface), impl);
+ }
+
+ public void BindList(string iface, IList<string> impl)
+ {
+ BindList((INamedParameterNode)ClassHierarchy.GetNode(iface), impl);
+ }
+
+ public void BindConstructor(Types.IClassNode k, Types.IClassNode v)
+ {
+ BoundConstructors.Add(k, v);
+ }
+
+ public string ClassPrettyDefaultString(string longName)
+ {
+ INamedParameterNode param = (INamedParameterNode) this.ClassHierarchy.GetNode(longName);
+ return param.GetSimpleArgName() + "=" + Join(",", param.GetDefaultInstanceAsStrings());
+ }
+
+ private String Join(string sep, string[] s)
+ {
+ if (s.Length == 0)
+ {
+ return null;
+ }
+ else
+ {
+ StringBuilder sb = new StringBuilder(s[0]);
+ for (int i = 1; i < s.Length; i++)
+ {
+ sb.Append(sep);
+ sb.Append(s[i]);
+ }
+ return sb.ToString();
+ }
+ }
+
+ public string ClassPrettyDescriptionString(string fullName)
+ {
+ INamedParameterNode param = (INamedParameterNode) this.ClassHierarchy.GetNode(fullName);
+ return param.GetDocumentation() + "\n" + param.GetFullName();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationImpl.cs
new file mode 100644
index 0000000..17739e8
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationImpl.cs
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class ConfigurationImpl : IConfiguration
+ {
+ public readonly ConfigurationBuilderImpl Builder;
+
+ public ConfigurationImpl(ConfigurationBuilderImpl builder)
+ {
+ Builder = builder;
+ }
+
+ public IClassHierarchy GetClassHierarchy()
+ {
+ return Builder.ClassHierarchy;
+ }
+
+ public IConfigurationBuilder newBuilder()
+ {
+ return ((ConfigurationImpl)Builder.Build()).Builder;
+ }
+
+ public ICollection<IClassNode> GetBoundImplementations()
+ {
+ return Builder.BoundImpls.Keys;
+ }
+
+ public IClassNode GetBoundImplementation(IClassNode cn)
+ {
+ IClassNode v;
+
+ Builder.BoundImpls.TryGetValue(cn, out v);
+
+ return v;
+ }
+
+ public ICollection<IClassNode> GetBoundConstructors()
+ {
+ return Builder.BoundConstructors.Keys;
+ }
+
+ public IClassNode GetBoundConstructor(IClassNode cn)
+ {
+ IClassNode v;
+
+ Builder.BoundConstructors.TryGetValue(cn, out v);
+
+ return v;
+ }
+
+ public ICollection<INamedParameterNode> GetNamedParameters()
+ {
+ return Builder.NamedParameters.Keys;
+ }
+
+ public string GetNamedParameter(INamedParameterNode np)
+ {
+ string v = null;
+ Builder.NamedParameters.TryGetValue(np, out v);
+
+ return v;
+ }
+
+ public IConstructorDef GetLegacyConstructor(IClassNode cn)
+ {
+ IConstructorDef v;
+
+ Builder.LegacyConstructors.TryGetValue(cn, out v);
+
+ return v;
+ }
+
+ public ICollection<IClassNode> GetLegacyConstructors()
+ {
+ return Builder.LegacyConstructors.Keys;
+ }
+
+ public ISet<Object> GetBoundSet(INamedParameterNode np)
+ {
+ return Builder.BoundSetEntries.GetValuesForKey(np);
+ }
+
+ public IEnumerator<KeyValuePair<INamedParameterNode, object>> GetBoundSets()
+ {
+ return Builder.BoundSetEntries.GetEnumerator();
+ }
+
+ public IDictionary<INamedParameterNode, IList<object>> GetBoundList()
+ {
+ return Builder.BoundLists;
+ }
+
+ public IList<object> GetBoundList(INamedParameterNode np)
+ {
+ IList<object> list;
+ Builder.BoundLists.TryGetValue(np, out list);
+ return list;
+ }
+ }
+}
\ No newline at end of file