/* * Copyright 2003-2004 The Apache Software Foundation * Licensed 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. */ namespace Apache.Avalon.Composition.Model.Default { using System; using Apache.Avalon.Framework; using Apache.Avalon.Composition.Data; using Apache.Avalon.Meta; /// Default implementation of a the context entry constructor model. /// /// /// Avalon Development Team /// /// $Revision: 1.2 $ $Date: 2004/02/29 18:07:17 $ /// public class DefaultConstructorModel : DefaultEntryModel { //============================================================== // static //============================================================== //============================================================== // immutable state //============================================================== //UPGRADE_NOTE: Final was removed from the declaration of 'm_directive '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' private ConstructorDirective m_directive; //UPGRADE_NOTE: Final was removed from the declaration of 'm_descriptor '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' private EntryDescriptor m_descriptor; //UPGRADE_NOTE: Final was removed from the declaration of 'm_context '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' private IComponentContext m_context; //UPGRADE_NOTE: Final was removed from the declaration of 'm_map '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' private System.Collections.IDictionary m_map; //============================================================== // mutable state //============================================================== private System.Object m_value; //============================================================== // constructor //============================================================== /// Creation of a new context entry import model. /// /// /// the context entry descriptor /// /// the context entry directive /// /// the containment context /// /// a map of available context entries /// public DefaultConstructorModel(EntryDescriptor descriptor, ConstructorDirective directive, IComponentContext context, System.Collections.IDictionary map):base(descriptor) { if (directive == null) { throw new System.ArgumentNullException("directive"); } if (context == null) { throw new System.ArgumentNullException("context"); } m_descriptor = descriptor; m_directive = directive; m_context = context; m_map = map; Validate(); } private void Validate() { String descriptorClassName = m_descriptor.Type.FullName; String directiveClassName = m_directive.Classname; validatePair(descriptorClassName, directiveClassName); Parameter[] params_Renamed = m_directive.Parameters; // // TODO: // wizz through and validate all of the parameter declarations // and make sure that constructors exist that match the sub-parameter // delcarations // } private void validatePair(String descriptorClass, String directiveClass) { String key = m_descriptor.Key; System.Type target = null; try { target = Type.GetType(descriptorClass); } catch (System.Exception) { String error = "constructor.descriptor.unknown.error " + key + " " + descriptorClass; throw new ModelException(error); } System.Type source = null; try { source = Type.GetType(directiveClass); } catch (System.Exception) { String error = "constructor.directive.unknown.error" + " " + key + " " + directiveClass; throw new ModelException(error); } if (!target.IsAssignableFrom(source)) { String error = "constructor.invalid-model.error" + " " + key + " " + descriptorClass + " " + directiveClass; throw new ModelException(error); } } //============================================================== // IEntryModel //============================================================== /// Return the context entry value. /// /// /// the context entry value /// public override System.Object Value { get { if (m_value != null) { return m_value; } String target = m_descriptor.Key; System.Object object_Renamed = null; try { String typename = m_directive.Classname; String argument = m_directive.Argument; Parameter[] params_Renamed = m_directive.Parameters; System.Type type = getParameterClass(typename); object_Renamed = GetValue(type, argument, params_Renamed); } //UPGRADE_NOTE: Exception 'java.lang.Throwable' was converted to 'System.Exception' which has different behavior. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1100"' catch (System.Exception e) { //UPGRADE_NOTE: Final was removed from the declaration of 'error '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' String error = "Cannot establish a constructed context entry for the key " + target + " due to a runtime failure."; throw new ModelException(error, e); } if (!m_descriptor.Volatile) { m_value = object_Renamed; } return object_Renamed; } } /// Return the context entry value. /// /// /// the context entry value /// public virtual System.Object GetValue(Parameter p) { //UPGRADE_ISSUE: Class 'java.lang.ClassLoader' was not converted. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1000_javalangClassLoader"' String typename = p.Classname; String argument = p.Argument; Parameter[] params_Renamed = p.Parameters; System.Type type = getParameterClass(typename); return GetValue(type, argument, params_Renamed); } /// Return the derived parameter value. /// the classloader to use /// /// the constructor class /// /// a single string constructor argument /// /// an alternative sequence of arguments /// /// the value /// /// ModelException if the parameter value cannot be resolved /// public virtual System.Object GetValue(System.Type type, String argument, Parameter[] parameters) { // // if the parameter contains a text argument then check if its a reference // to a map entry (in the form"${}" ), otherwise its a simple constructor // case with a single string paremeter // if (parameters.Length == 0) { if ((System.Object) argument == null) { return getNullArgumentConstructorValue(type); } else { return getSingleArgumentConstructorValue( type, argument); } } else { return GetMultiArgumentConstructorValue(type, parameters); } } private System.Object GetMultiArgumentConstructorValue(System.Type type, Parameter[] parameters) { // // getting here means we are dealing with 0..n types parameter constructor where the // parameters are defined by the nested parameter definitions // if (parameters.Length == 0) { try { return Activator.CreateInstance(type); } catch (System.UnauthorizedAccessException e) { String error = "Cannot access null constructor for the class: '" + type.FullName + "'."; throw new ModelException(error, e); } catch (System.Exception e) { String error = "Unable to instantiate instance of class: " + type.FullName; throw new ModelException(error, e); } } else { System.Type[] params_Renamed = new System.Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { String typename = parameters[i].Classname; try { params_Renamed[i] = Type.GetType(typename); } catch (System.Exception e) { String error = "Unable to resolve sub-parameter class: " + typename + " for the parameter " + type.FullName; throw new ModelException(error, e); } } System.Object[] values = new System.Object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { Parameter p = parameters[i]; String typename = p.Classname; try { values[i] = GetValue(p); } catch (System.Exception e) { String error = "Unable to instantiate sub-parameter for value: " + typename + " inside the parameter " + type.FullName; throw new ModelException(error, e); } } System.Reflection.ConstructorInfo constructor = null; try { constructor = type.GetConstructor(params_Renamed); } catch (System.MethodAccessException e) { String error = "Supplied parameters for " + type.FullName + " do not match the available class constructors."; throw new ModelException(error, e); } try { return constructor.Invoke(values); } catch (System.UnauthorizedAccessException e) { String error = "Cannot access multi-parameter constructor for the class: '" + type.FullName + "'."; throw new ModelException(error, e); } catch (System.Exception e) { String error = "Unable to instantiate an instance of a multi-parameter constructor for class: '" + type.FullName + "'."; throw new ModelException(error, e); } } } private System.Object getNullArgumentConstructorValue(System.Type type) { try { //UPGRADE_TODO: Method 'java.lang.Class.newInstance' was converted to 'SupportClass.CreateNewInstance' which has a different behavior. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1073"' //UPGRADE_WARNING: Method 'java.lang.Class.newInstance' was converted to 'SupportClass.CreateNewInstance' which may throw an exception. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1101"' return Activator.CreateInstance(type); } //UPGRADE_NOTE: Exception 'java.lang.InstantiationException' was converted to 'System.Exception' which has different behavior. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1100"' catch (System.Exception e) { //UPGRADE_NOTE: Final was removed from the declaration of 'error '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' String error = "Unable to instantiate instance of class: " + type.FullName; throw new ModelException(error, e); } } //UPGRADE_ISSUE: Class 'java.lang.ClassLoader' was not converted. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1000_javalangClassLoader"' private System.Object getSingleArgumentConstructorValue(System.Type type, String argument) { if (argument.StartsWith("${")) { if (argument.EndsWith("}")) { //UPGRADE_NOTE: Final was removed from the declaration of 'key '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' String key = argument.Substring(2, (argument.Length - 1) - (2)); System.Object value_Renamed = null; try { return m_context.Resolve(key); } catch (ContextException) { //UPGRADE_TODO: Method 'java.util.Map.get' was converted to 'System.Collections.IDictionary.Item' which has a different behavior. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1073_javautilMapget_javalangObject"' value_Renamed = m_map[key]; if (value_Renamed != null) { return value_Renamed; } else { //UPGRADE_NOTE: Final was removed from the declaration of 'error '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' String error = "Unresolvable primative context value: '" + key + "'."; throw new ModelException(error); } } } else { //UPGRADE_NOTE: Final was removed from the declaration of 'error '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' String error = "Illegal format for context reference: '" + argument + "'."; throw new ModelException(error); } } else { // // the argument is a simple type that takes a single String value // as a constructor argument // try { //UPGRADE_NOTE: Final was removed from the declaration of 'params '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' System.Type[] params_Renamed = new System.Type[]{typeof(String)}; System.Reflection.ConstructorInfo constructor = type.GetConstructor(params_Renamed); //UPGRADE_NOTE: Final was removed from the declaration of 'values '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' System.Object[] values = new System.Object[]{argument}; //UPGRADE_ISSUE: Method 'java.lang.reflect.Constructor.newInstance' was not converted. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1000_javalangreflectConstructornewInstance_javalangObject[]"' return constructor.Invoke(values); } catch (System.MethodAccessException) { //UPGRADE_NOTE: Final was removed from the declaration of 'error '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' String error = "Class: '" + type.FullName + "' does not implement a single string argument constructor."; throw new ModelException(error); } //UPGRADE_NOTE: Exception 'java.lang.InstantiationException' was converted to 'System.Exception' which has different behavior. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1100"' catch (System.Exception e) { //UPGRADE_NOTE: Final was removed from the declaration of 'error '. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1003"' String error = "Unable to instantiate instance of class: " + type.FullName + " with the single argument: '" + argument + "'"; throw new ModelException(error, e); } } } /// Return the typename of the parameter implementation to use. /// the classloader to use /// /// the parameter class /// /// ModelException if the parameter class cannot be resolved /// //UPGRADE_ISSUE: Class 'java.lang.ClassLoader' was not converted. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1000_javalangClassLoader"' internal virtual System.Type getParameterClass(String typename) { try { //UPGRADE_ISSUE: Method 'java.lang.ClassLoader.loadClass' was not converted. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1000_javalangClassLoader"' return Type.GetType(typename); } //UPGRADE_NOTE: Exception 'java.lang.ClassNotFoundException' was converted to 'System.Exception' which has different behavior. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1100"' catch (System.Exception e) { if (typename.Equals("int")) { return typeof(int); } else if (typename.Equals("short")) { return typeof(short); } else if (typename.Equals("long")) { return typeof(long); } else if (typename.Equals("sbyte")) { return typeof(sbyte); } else if (typename.Equals("double")) { return typeof(double); } else if (typename.Equals("sbyte")) { return typeof(sbyte); } else if (typename.Equals("float")) { return typeof(float); } else if (typename.Equals("char")) { return typeof(char); } else if (typename.Equals("bool")) { return typeof(bool); } else { throw new ModelException("Could not locate the parameter implemetation for class: '" + typename + "'.", e); } } } } }