http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/c1b5200f/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/Configurations.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/Configurations.cs b/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/Configurations.cs new file mode 100644 index 0000000..1c27d21 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/Configurations.cs @@ -0,0 +1,56 @@ +/** + * 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 Org.Apache.REEF.Tang.Implementations.Tang; +using Org.Apache.REEF.Tang.Interface; +using Org.Apache.REEF.Tang.Protobuf; + +namespace Org.Apache.REEF.Tang.Implementations.Configuration +{ + public class Configurations + { + public static IConfiguration Merge(params IConfiguration[] configurations) + { + return TangFactory.GetTang().NewConfigurationBuilder(configurations).Build(); + } + + public static IConfiguration MergeDeserializedConfs(params IConfiguration[] configurations) + { + IClassHierarchy ch; + + if (configurations != null && configurations.Length > 0) + { + ch = configurations[0].GetClassHierarchy(); + } + else + { + ch = new ProtocolBufferClassHierarchy(); + } + + IConfigurationBuilder cb = TangFactory.GetTang().NewConfigurationBuilder(ch); + + foreach (IConfiguration tc in configurations) + { + cb.AddConfiguration(((ConfigurationImpl)tc)); + } + + return cb.Build(); + } + } +}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/c1b5200f/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/CsConfigurationBuilderImpl.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/CsConfigurationBuilderImpl.cs b/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/CsConfigurationBuilderImpl.cs new file mode 100644 index 0000000..db9b042 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/CsConfigurationBuilderImpl.cs @@ -0,0 +1,489 @@ +/** + * 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; +using System.Collections.Generic; +using System.Globalization; +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.Configuration +{ + public class CsConfigurationBuilderImpl : ConfigurationBuilderImpl, ICsInternalConfigurationBuilder + { + private static readonly Logger LOGGER = Logger.GetLogger(typeof(CsConfigurationBuilderImpl)); + + #region Constructors + public CsConfigurationBuilderImpl(string[] assemblies, IConfiguration[] confs, Type[] parsers) : base(assemblies,confs,parsers) + { + } + + public CsConfigurationBuilderImpl(IConfiguration[] confs) : base(confs) + { + } + + public CsConfigurationBuilderImpl(CsConfigurationBuilderImpl impl) : base(impl) + { + } + + public CsConfigurationBuilderImpl(ICsClassHierarchy classHierarchy) + : base(classHierarchy) + { + } + + public CsConfigurationBuilderImpl(string[] assemblies) + : base(assemblies) + { + } + #endregion Constructors + + #region ICsConfigurationBuilder + /// <summary> + /// Builds this instance. + /// </summary> + /// <returns></returns> + public CsConfigurationImpl build() + { + return new CsConfigurationImpl(new CsConfigurationBuilderImpl(this)); + } + + /// <summary> + /// Binds a string to a named parameter. + /// </summary> + /// <param name="name">The name.</param> + /// <param name="value">The value.</param> + /// <returns></returns> + /// <exception cref="BindException">Detected type mismatch when setting named parameter + name + /// + Expected NamedParameterNode, but namespace contains a + np</exception> + public ICsConfigurationBuilder BindNamedParameter(Type name, string value) + { + if (value == null) + { + var ex = new IllegalStateException(string.Format(CultureInfo.CurrentCulture, "The value null set to the named parameter {0} is illegel.", name)); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + INode np = GetNode(name); + if (np is INamedParameterNode) + { + BindParameter((INamedParameterNode)np, value); + } + else + { + var ex = new BindException( + "Detected type mismatch when setting named parameter " + name + + " Expected NamedParameterNode, but namespace contains a " + np); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + return this; + } + + /// <summary> + /// Binds the class impl as the implementation of the interface iface + /// </summary> + /// <param name="iface">The iface.</param> + /// <param name="impl">The impl.</param> + /// <returns></returns> + public ICsConfigurationBuilder BindImplementation(Type iface, Type impl) + { + INode cn = GetNode(iface); + INode dn = GetNode(impl); + if (!(cn is IClassNode)) + { + var ex = new BindException( + "bindImplementation passed interface that resolved to " + cn + + " expected a ClassNode<?>"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + if (!(dn is IClassNode)) + { + var ex = new BindException( + "bindImplementation passed implementation that resolved to " + dn + + " expected a ClassNode<?>"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + BindImplementation((IClassNode)cn, (IClassNode)dn); + return this; + } + + /// <summary> + /// Binds the implementation to the interface + /// </summary> + /// <typeparam name="U"></typeparam> + /// <typeparam name="T"></typeparam> + /// <param name="iface">The iface.</param> + /// <param name="impl">The impl.</param> + /// <returns></returns> + public ICsConfigurationBuilder BindImplementation<U, T>(GenericType<U> iface, GenericType<T> impl) + where T : U + { + return BindImplementation(typeof(U), typeof(T)); + } + + /// <summary> + /// Binds a value to a named parameter. + /// </summary> + /// <typeparam name="U"></typeparam> + /// <typeparam name="T"></typeparam> + /// <param name="name">The name.</param> + /// <param name="value">The value.</param> + /// <returns></returns> + public ICsConfigurationBuilder BindNamedParameter<U, T>(GenericType<U> name, string value) + where U : Name<T> + { + return BindNamedParameter(typeof(U), value); + } + + /// <summary> + /// Binds an implementaion to a named parameter. + /// </summary> + /// <typeparam name="U"></typeparam> + /// <typeparam name="V"></typeparam> + /// <typeparam name="T"></typeparam> + /// <param name="iface">The iface.</param> + /// <param name="impl">The impl.</param> + /// <returns></returns> + public ICsConfigurationBuilder BindNamedParameter<U, V, T>(GenericType<U> iface, GenericType<V> impl) + where U : Name<T> + where V : T + { + return ((ICsInternalConfigurationBuilder)this).BindNamedParameter(typeof(U), typeof(V)); + } + + /// <summary> + /// Binds an external constructor. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <typeparam name="U"></typeparam> + /// <param name="c">The c.</param> + /// <param name="v">The v.</param> + /// <returns></returns> + public ICsConfigurationBuilder BindConstructor<T, U>(GenericType<T> c, GenericType<U> v) + where U : IExternalConstructor<T> + { + return ((ICsInternalConfigurationBuilder)this).BindConstructor(typeof(T), typeof(U)); + } + + //public <T> void bindSetEntry(Class<? extends Name<Set<T>>> iface, String value) throws BindException; + /// <summary> + /// Binds a string value to a named parameter of ISet. + /// </summary> + /// <typeparam name="U"></typeparam> + /// <typeparam name="T"></typeparam> + /// <param name="iface">The iface.</param> + /// <param name="value">The value.</param> + /// <returns></returns> + public ICsConfigurationBuilder BindSetEntry<U, T>(GenericType<U> iface, string value) + where U : Name<ISet<T>> + { + return ((ICsInternalConfigurationBuilder)this).BindSetEntry(typeof(U), value); + } + + //public <T> void bindSetEntry(Class<? extends Name<Set<T>>> iface, Class<? extends T> impl) throws BindException; + /// <summary> + /// Binds an implementaion of T to a named parameter of ISet of T. + /// </summary> + /// <typeparam name="U"></typeparam> + /// <typeparam name="V"></typeparam> + /// <typeparam name="T"></typeparam> + /// <param name="iface">The iface.</param> + /// <param name="impl">The impl.</param> + /// <returns></returns> + public ICsConfigurationBuilder BindSetEntry<U, V, T>(GenericType<U> iface, GenericType<V> impl) + where U : Name<ISet<T>> + where V : T + { + return ((ICsInternalConfigurationBuilder)this).BindSetEntry(typeof(U), typeof(V)); + } + + public ICsConfigurationBuilder BindList<U, V, T>(GenericType<U> iface, IList<GenericType<V>> impl) + where U : Name<IList<T>> + where V : T + { + IList<Type> implTypes = new List<Type>(); + foreach (var item in impl) + { + implTypes.Add(item.TypeT); + } + return ((ICsInternalConfigurationBuilder)this).BindList(typeof(U), implTypes); + } + + public ICsConfigurationBuilder BindList<U, T>(GenericType<U> iface, IList<string> impl) + where U : Name<IList<T>> + { + return ((ICsInternalConfigurationBuilder)this).BindList(typeof(U), impl); + } + + public ICsConfigurationBuilder BindList(Type iface, IList<Type> implList) + { + INode n = GetNode(iface); + IList<INode> result = new List<INode>(); + + if (!(n is INamedParameterNode)) + { + var ex = new BindException("BindList got an interface that resolved to " + n + "; expected a NamedParameter"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + + Type listType = ReflectionUtilities.GetInterfaceTarget(typeof(Name<>), iface); + if (!ReflectionUtilities.IsGenericTypeof(typeof(IList<>), listType)) + { + var ex = new BindException("BindList got a NamedParameter that takes a " + listType + "; expected List<...>"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + + if (implList != null && implList.Count > 0) + { + Type valType = ReflectionUtilities.GetInterfaceTarget(typeof(IList<>), listType); + + foreach (var item in implList) + { + if (!valType.IsAssignableFrom((Type)item)) + { + var ex = + new BindException("BindList got implementation " + item + + " that is incompatible with expected type " + valType); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + result.Add(GetNode(item)); + } + } + + BindList((INamedParameterNode)n, result); + return this; + } + #endregion ICsConfigurationBuilder + + #region ICsInternalConfigurationBuilder + /// <summary> + /// Bind named parameters, implementations or external constructors, depending + /// on the types of the classes passed in. + /// </summary> + /// <param name="iface">The iface.</param> + /// <param name="impl">The impl.</param> + /// <returns></returns> + ICsInternalConfigurationBuilder ICsInternalConfigurationBuilder.Bind(Type iface, Type impl) + { + Bind(GetNode(iface), GetNode(impl)); + return this; + } + + /// <summary> + /// Binds an implementation for a named parameter. + /// </summary> + /// <param name="iface">The iface.</param> + /// <param name="impl">The impl.</param> + /// <returns></returns> + /// <exception cref="BindException">Type mismatch when setting named parameter + ifaceN + /// + Expected NamedParameterNode</exception> + ICsInternalConfigurationBuilder ICsInternalConfigurationBuilder.BindNamedParameter(Type iface, Type impl) + { + INode ifaceN = GetNode(iface); + INode implN = GetNode(impl); + if (!(ifaceN is INamedParameterNode)) + { + var ex = new BindException("Type mismatch when setting named parameter " + ifaceN + + " Expected NamedParameterNode"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + Bind(ifaceN, implN); + return this; + } + + //public <T> void bindSetEntry(Class<? extends Name<Set<T>>> iface, String value) throws BindException; + /// <summary> + /// Binds a string value to to a named parameter of ISet entry + /// </summary> + /// <param name="iface">The iface.</param> + /// <param name="value">The value.</param> + /// <returns></returns> + /// <exception cref="BindException">BindSetEntry got an interface that resolved to + n + ; expected a NamedParameter</exception> + ICsInternalConfigurationBuilder ICsInternalConfigurationBuilder.BindSetEntry(Type iface, string value) + { + INode n = GetNode(iface); + + if (!(n is INamedParameterNode)) + { + var ex = new BindException("BindSetEntry got an interface that resolved to " + n + "; expected a NamedParameter"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + Type setType = ReflectionUtilities.GetInterfaceTarget(typeof(Name<>), iface); + + //check if setType is ISet + if (ReflectionUtilities.GetInterfaceTarget(typeof(ISet<>), setType) == null) + { + var ex = new BindException("BindSetEntry got a NamedParameter that takes a " + setType + "; expected Set<...>"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + // Type valType = ReflectionUtilities.getInterfaceTarget(Set.class, setType); + BindSetEntry((INamedParameterNode)n, value); + return this; + } + + //public <T> void bindSetEntry(Class<? extends Name<Set<T>>> iface, Class<? extends T> impl) throws BindException; + /// <summary> + /// Binds an implementaion to a named parameter of ISset entry. + /// </summary> + /// <param name="iface">The iface.</param> + /// <param name="impl">The impl.</param> + /// <returns></returns> + /// <exception cref="BindException">BindSetEntry got an interface that resolved to + n + ; expected a NamedParameter</exception> + ICsInternalConfigurationBuilder ICsInternalConfigurationBuilder.BindSetEntry(Type iface, Type impl) + { + INode n = GetNode(iface); + INode m = GetNode(impl); + + if (!(n is INamedParameterNode)) + { + var ex = new BindException("BindSetEntry got an interface that resolved to " + n + "; expected a NamedParameter"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + Type setType = ReflectionUtilities.GetInterfaceTarget(typeof(Name<>), iface); + + //if (!ReflectionUtilities.GetRawClass(setType).Equals(typeof(ISet<>))) + if (!ReflectionUtilities.IsGenericTypeof(typeof(ISet<>), setType)) + { + var ex = new BindException("BindSetEntry got a NamedParameter that takes a " + setType + "; expected Set<...>"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + + Type valType = ReflectionUtilities.GetInterfaceTarget(typeof(ISet<>), setType); + + if (!valType.IsAssignableFrom(impl)) + //if (!ReflectionUtilities.GetRawClass(valType).IsAssignableFrom(impl)) + { + var ex = new BindException("BindSetEntry got implementation " + impl + " that is incompatible with expected type " + valType); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + + BindSetEntry((INamedParameterNode)n, m); + return this; + } + + ICsInternalConfigurationBuilder ICsInternalConfigurationBuilder.BindList(Type iface, IList<string> implList) + { + INode n = GetNode(iface); + + if (!(n is INamedParameterNode)) + { + var ex = new BindException("BindList got an interface that resolved to " + n + "; expected a NamedParameter"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + + Type listType = ReflectionUtilities.GetInterfaceTarget(typeof(Name<>), iface); + if (!ReflectionUtilities.IsGenericTypeof(typeof(IList<>), listType)) + { + var ex = new BindException("BindList got a NamedParameter that takes a " + listType + "; expected List<...>"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + + BindList((INamedParameterNode)n, implList); + return this; + } + + //public <T> void bindConstructor(Class<T> c, Class<? extends ExternalConstructor<? extends T>> v) throws BindException; + /// <summary> + /// Binds an external constructor. + /// </summary> + /// <param name="c">The c.</param> + /// <param name="v">The v.</param> + /// <returns></returns> + /// <exception cref="BindException">BindConstructor got class that resolved to + n + ; expected ClassNode</exception> + ICsInternalConfigurationBuilder ICsInternalConfigurationBuilder.BindConstructor(Type c, Type v) + { + INode n = GetNode(c); + INode m = GetNode(v); + + if (!(n is IClassNode)) + { + var ex = new BindException("BindConstructor got class that resolved to " + n + "; expected ClassNode"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + if (!(m is IClassNode)) + { + var ex = new BindException("BindConstructor got class that resolved to " + m + "; expected ClassNode"); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + BindConstructor((IClassNode)n, (IClassNode)m); + return this; + } + #endregion ICsInternalConfigurationBuilder + + #region extension methods + + public ICsConfigurationBuilder BindNamedParam<TName, TType>(string str) where TName : Name<TType> + { + return BindNamedParameter<TName, TType>(GenericType<TName>.Class, str); + } + + public ICsConfigurationBuilder BindStringNamedParam<T>(string str) where T : Name<string> + { + return BindNamedParameter<T, string>(GenericType<T>.Class, str); + } + + public ICsConfigurationBuilder BindIntNamedParam<T>(string str) where T : Name<int> + { + return BindNamedParameter<T, int>(GenericType<T>.Class, str); + } + + public ICsConfigurationBuilder BindNamedParameter<U, V, T>() + where U : Name<T> + where V : T + { + return BindNamedParameter<U, V, T>(GenericType<U>.Class, GenericType<V>.Class); + } + + public ICsConfigurationBuilder BindSetEntry<T1, T2, T3>() + where T1 : Name<ISet<T3>> + where T2 : T3 + { + return BindSetEntry<T1, T2, T3>(GenericType<T1>.Class, GenericType<T2>.Class); + } + + public ICsConfigurationBuilder BindSetEntry<U, T>(string value) where U : Name<ISet<T>> + { + return BindSetEntry<U, T>(GenericType<U>.Class, value); + } + + public ICsConfigurationBuilder BindImplementation<T1, T2>() where T2 : T1 + { + return BindImplementation(GenericType<T1>.Class, GenericType<T2>.Class); + } + + public ICsConfigurationBuilder BindList<U, T>(IList<string> impl) where U : Name<IList<T>> + { + return BindList<U, T>(GenericType<U>.Class, impl); + } + + public ICsConfigurationBuilder BindConstructor<T, U>() where U : IExternalConstructor<T> + { + return BindConstructor<T, U>(GenericType<T>.Class, GenericType<U>.Class); + } + + #endregion extension methods + + private INode GetNode(Type c) + { + return ((ICsClassHierarchy)ClassHierarchy).GetNode(c); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/c1b5200f/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/CsConfigurationImpl.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/CsConfigurationImpl.cs b/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/CsConfigurationImpl.cs new file mode 100644 index 0000000..c72206a --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Tang/Implementations/Configuration/CsConfigurationImpl.cs @@ -0,0 +1,34 @@ +/** + * 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 System.Threading.Tasks; +using Org.Apache.REEF.Tang.Interface; + +namespace Org.Apache.REEF.Tang.Implementations.Configuration +{ + public class CsConfigurationImpl : ConfigurationImpl + { + public CsConfigurationImpl(CsConfigurationBuilderImpl builder) : base(builder) + { + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/c1b5200f/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/Constructor.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/Constructor.cs b/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/Constructor.cs new file mode 100644 index 0000000..fbce0d0 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/Constructor.cs @@ -0,0 +1,217 @@ +/** + * 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; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using Org.Apache.REEF.Utilities.Logging; +using Org.Apache.REEF.Tang.Types; + +namespace Org.Apache.REEF.Tang.Implementations.InjectionPlan +{ + //Base case for an injection plan. A plan for a class. + public class Constructor : InjectionPlan + { + private static readonly Logger LOGGER = Logger.GetLogger(typeof(Constructor)); + + IConstructorDef constructor; //which constructor to use + InjectionPlan[] args; //constructor arguments in which we already got injectionPlan for each (nested cases) + int numAlternatives; + bool isAmbiguous; + bool isInjectable; + + public InjectionPlan[] GetArgs() + { + return args; + } + + public new ICollection<InjectionPlan> GetChildren() + { + return new ReadOnlyCollection<InjectionPlan>(this.args.OfType<InjectionPlan>().ToList()); + } + + public IConstructorDef GetConstructorDef() + { + return constructor; + } + + 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; + } + + public new IClassNode GetNode() + { + return (IClassNode) node; + } + + public override int GetNumAlternatives() + { + return numAlternatives; + } + + public override bool IsAmbiguous() + { + return isAmbiguous; + } + + public override bool IsInjectable() + { + return isInjectable; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder("new " + GetNode().GetName() + '('); + if (args.Length > 0) + { + sb.Append(args[0]); + for (int i = 1; i < args.Length; i++) + { + sb.Append(", " + args[i]); + } + } + sb.Append(')'); + return sb.ToString(); + } + + private String ShallowArgString(InjectionPlan arg) + { + if (arg is Constructor || arg is Subplan) + { + return arg.GetType().Name + ": " + arg.GetNode().GetName(); + } + else + { + return arg.ToShallowString(); + } + } + + public override string ToShallowString() + { + StringBuilder sb = new StringBuilder("new " + GetNode().GetName() + '('); + if (args.Length > 0) + { + sb.Append(ShallowArgString(args[0])); + for (int i = 1; i < args.Length; i++) + { + sb.Append(", " + ShallowArgString(args[i])); + } + } + sb.Append(')'); + return sb.ToString(); + } + + public override string ToAmbiguousInjectString() + { + + if (!isAmbiguous) + { + var ex = new ArgumentException(GetNode().GetFullName() + " is NOT ambiguous."); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + + StringBuilder sb = new StringBuilder(GetNode().GetFullName() + " has ambiguous arguments: [ "); + + foreach (InjectionPlan plan in args) + { + if (plan.IsAmbiguous()) + { + sb.Append(plan.ToAmbiguousInjectString()); + } + } + + sb.Append(']'); + return sb.ToString(); + } + + public override string ToInfeasibleInjectString() + { + IList<InjectionPlan> leaves = new List<InjectionPlan>(); + + foreach (InjectionPlan ip in args) + { + if (!ip.IsFeasible()) + { + if (ip.IsInfeasibleLeaf()) + { + leaves.Add(ip); + } else + { + return ip.ToInfeasibleInjectString(); + } + } + } + + if (leaves.Count == 0) + { + var ex = new ArgumentException(GetNode().GetFullName() + " has NO infeasible leaves."); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + } + + if (leaves.Count == 1) + { + return GetNode().GetFullName() + " missing argument " + leaves[0].GetNode().GetFullName(); + } + else + { + StringBuilder sb = new StringBuilder(GetNode().GetFullName() + " missing arguments: [ "); + foreach (InjectionPlan leaf in leaves) + { + sb.Append(leaf.GetNode().GetFullName() + ' '); + } + sb.Append(']'); + return sb.ToString(); + } + } + + public override bool IsInfeasibleLeaf() + { + return false; + } + + //public override bool HasFutureDependency() + //{ + // foreach (InjectionPlan p in args) + // { + // if(p.HasFutureDependency()) + // { + // return true; + // } + // } + // return false; + //} + } +} http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/c1b5200f/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/CsInstance.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/CsInstance.cs b/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/CsInstance.cs new file mode 100644 index 0000000..5db415b --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/CsInstance.cs @@ -0,0 +1,90 @@ +/** + * 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 System.Threading.Tasks; +using Org.Apache.REEF.Utilities.Logging; +using Org.Apache.REEF.Tang.Types; + +namespace Org.Apache.REEF.Tang.Implementations.InjectionPlan +{ + public class CsInstance : InjectionPlan + { + public readonly object instance; + private static readonly Logger LOGGER = Logger.GetLogger(typeof(CsInstance)); + + public CsInstance(INode name, object instance) : base(name) + { + this.instance = instance; + } + public override int GetNumAlternatives() + { + return instance == null ? 0 : 1; + } + + public override string ToString() + { + return GetNode() + " = " + instance; + } + + public override bool IsAmbiguous() + { + return false; + } + + public override bool IsInjectable() + { + return instance != null; + } + + public string GetInstanceAsString() + { + return instance.ToString(); + } + + //public override bool HasFutureDependency() + //{ + // return false; + //} + + public override string ToAmbiguousInjectString() + { + var ex = new ArgumentException("toAmbiguousInjectString called on CsInstance!" + this.ToString()); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + return null; + } + + public override string ToInfeasibleInjectString() + { + return GetNode() + " is not bound."; + } + + public override bool IsInfeasibleLeaf() + { + return true; + } + + public override string ToShallowString() + { + return ToString(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/c1b5200f/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionFuture.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionFuture.cs b/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionFuture.cs new file mode 100644 index 0000000..cfe4e40 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionFuture.cs @@ -0,0 +1,100 @@ +/** + * 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.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.Util; + +namespace Org.Apache.REEF.Tang.Implementations.InjectionPlan +{ + + public interface IInjectionFuture<out T> + { + T Get(); + } + + public class InjectionFutureImpl<T> : IInjectionFuture<T> + { + protected readonly InjectorImpl injector; + private readonly Type iface; //entend from T + private readonly T instance; + + //public InjectionFuture() + //{ + // injector = null; + // iface = null; + // instance = null; + //} + + public InjectionFutureImpl(IInjector injector, Type iface) + { + this.injector = (InjectorImpl)injector; + this.iface = iface; + this.instance = default(T); + } + + public InjectionFutureImpl(T instance) + { + this.injector = null; + this.iface = null; + this.instance = instance; + } + + //public bool Cancel(bool mayInterruptIfRunning) + //{ + // return false; + //} + + //public bool IsCancelled() + //{ + // return false; + //} + + //public bool IsDone() + //{ + // return true; + //} + + public T Get() + { + if (instance != null) return instance; + lock(injector) + { + T t; + if (ReflectionUtilities.IsAssignableFromIgnoreGeneric(typeof(Name<>), iface)) + { + t = (T)injector.GetNamedInstance(iface); + } + else + { + t = (T)injector.GetInstance(iface); + } + Aspect a = injector.GetAspect(); + if(a != null) + { + a.InjectionFutureInstantiated(this, t); + } + return t; + } + } + + } +} http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/c1b5200f/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionFuturePlan.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionFuturePlan.cs b/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionFuturePlan.cs new file mode 100644 index 0000000..6d27c44 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionFuturePlan.cs @@ -0,0 +1,73 @@ +/** + * 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.Utilities.Logging; +using Org.Apache.REEF.Tang.Types; + +namespace Org.Apache.REEF.Tang.Implementations.InjectionPlan +{ + public class InjectionFuturePlan : InjectionPlan + { + private static readonly Logger LOGGER = Logger.GetLogger(typeof(InjectionFuturePlan)); + + public InjectionFuturePlan(INode name) : base (name) + { + } + + public override int GetNumAlternatives() + { + return 1; + } + + public override bool IsAmbiguous() + { + return false; + } + + public override bool IsInjectable() + { + return true; + } + + //public override bool HasFutureDependency() + //{ + // return true; + //} + + public override string ToAmbiguousInjectString() + { + throw new NotSupportedException("InjectionFuturePlan cannot be ambiguous!"); + } + + public override string ToInfeasibleInjectString() + { + throw new NotSupportedException("InjectionFuturePlan is always feasible!"); + } + + public override bool IsInfeasibleLeaf() + { + return false; + } + + public override string ToShallowString() + { + return "InjectionFuture<"+GetNode().GetFullName()+">"; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/c1b5200f/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionPlan.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionPlan.cs b/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionPlan.cs new file mode 100644 index 0000000..8ed459f --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Tang/Implementations/InjectionPlan/InjectionPlan.cs @@ -0,0 +1,222 @@ +/** + * 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.Text; +using Org.Apache.REEF.Utilities.Logging; +using Org.Apache.REEF.Tang.Types; + +namespace Org.Apache.REEF.Tang.Implementations.InjectionPlan +{ + //contains the data for injecting a Node such as which Constructor to use, what are the arguments + public abstract class InjectionPlan : ITraversable<InjectionPlan> + { + protected INode node; + + private static readonly Logger LOGGER = Logger.GetLogger(typeof(InjectionPlan)); + + public InjectionPlan(INode node) + { + this.node = node; + } + + public INode GetNode() + { + return node; + } + + /// <summary> + /// Get child elements of the injection plan tree. By default, returns an empty list. + /// </summary> + /// <returns>An empty list</returns> + public ICollection<InjectionPlan> GetChildren() + { + return new List<InjectionPlan>(); + } + + public abstract int GetNumAlternatives(); + + public bool IsFeasible() + { + return GetNumAlternatives() > 0; + } + + abstract public bool IsAmbiguous(); + + abstract public bool IsInjectable(); + + //abstract public bool HasFutureDependency(); + + protected void pad(StringBuilder sb, int n) + { + for (int i = 0; i < n; i++) + { + sb.Append(" "); + } + } + + private static void Newline(StringBuilder pretty, int indent) + { + pretty.Append('\n'); + for (int j = 0; j < indent * 2; j++) + { + pretty.Append(' '); + } + } + + public String ToPrettyString() + { + String ugly = node.GetFullName() + ":\n" + ToString(); + StringBuilder pretty = new StringBuilder(); + int currentIndent = 1; + for (int i = 0; i < ugly.Length; i++) + { + char c = ugly[i]; + if (c == '(') + { + if (ugly[i + 1] == ')') + { + pretty.Append("()"); + i++; + } + else + { + Newline(pretty, currentIndent); + currentIndent++; + pretty.Append(c); + pretty.Append(' '); + } + } + else if (c == '[') + { + if (ugly[i + 1] == ']') + { + pretty.Append("[]"); + i++; + } + else + { + Newline(pretty, currentIndent); + currentIndent++; + pretty.Append(c); + pretty.Append(' '); + } + } + else if (c == ')' || c == ']') + { + currentIndent--; + Newline(pretty, currentIndent); + pretty.Append(c); + } + else if (c == '|') + { + Newline(pretty, currentIndent); + pretty.Append(c); + } + else if (c == ',') + { + currentIndent--; + Newline(pretty, currentIndent); + pretty.Append(c); + currentIndent++; + } + else + { + pretty.Append(c); + } + } + return pretty.ToString(); + } + + public string ToCantInjectString() + { + if (!IsFeasible()) + { + return ToInfeasibleInjectString(); + } + if (IsAmbiguous()) + { + return ToAmbiguousInjectString(); + } + var ex = new ArgumentException( + "toCantInjectString() called on injectable constructor:" + + this.ToPrettyString()); + Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER); + return null; + } + + public abstract string ToAmbiguousInjectString(); + + public abstract string ToInfeasibleInjectString(); + + public abstract bool IsInfeasibleLeaf(); + + public abstract string ToShallowString(); + + } + + public class BuildingInjectionPlan : InjectionPlan + { + + public BuildingInjectionPlan(INode node) + : base(node) + { + } + + public override int GetNumAlternatives() + { + throw new NotSupportedException(); + } + + public override bool IsAmbiguous() + { + throw new NotSupportedException(); + } + + public override bool IsInjectable() + { + throw new NotSupportedException(); + } + + //public override bool HasFutureDependency() + //{ + // throw new NotSupportedException(); + //} + + public override string ToAmbiguousInjectString() + { + throw new NotSupportedException(); + } + + public override string ToInfeasibleInjectString() + { + throw new NotSupportedException(); + } + + public override bool IsInfeasibleLeaf() + { + throw new NotSupportedException(); + } + + public override string ToShallowString() + { + throw new NotSupportedException(); + } + } +}
