/// <summary> /// Activate the options that were previously set with calls to properties. /// <see cref="Renderer"/> of type <see cref="IObjectRenderer"/> is taken from Properties["renderer"] if present. /// <see cref="Fetcher"/> of type <see cref="IRawLayout"/> is taken from Properties["fetcher"] if present /// <see cref="IArrangement"/> is taken from Properties["arrangement"] and from <i>option</i>. /// Converters to be used in arrangements are taken from Properties["converters"], an array of <see cref="ConverterInfo"/>. /// Members are arranged using <see cref="SetUp"/> /// </summary> /// <remarks> /// <para> /// This allows an object to defer activation of its options until all /// options have been set. This is required for components which have /// related options that remain ambiguous until all are set. /// </para> /// <para> /// If a component implements this interface then this method must be called /// after its properties have been set before the component can be used. /// </para> /// <para> /// Please note that properties are only supported with log4net 1.2.11 and above. /// </para> /// </remarks> public virtual void ActivateOptions() { #if LOG4NET_1_2_10_COMPATIBLE var renderer = null as IObjectRenderer; var fetcher = null as IRawLayout; var decorators = null as IEnumerable <IDecorator>; var converters = null as ConverterInfo[]; var arrangement = null as IArrangement; #else var renderer = Properties["renderer"] as IObjectRenderer; var fetcher = Properties["fetcher"] as IRawLayout; var decorators = Properties["decorators"] as IEnumerable <IDecorator>; var converters = Properties["converters"] as IEnumerable <ConverterInfo>; var arrangement = Properties["arrangement"] as IArrangement; #endif SetUp(arrangement, converters, fetcher, renderer, decorators); if (!String.IsNullOrEmpty(Option)) { var convertersArray = converters == null ? null : Enumerable.ToArray(converters); var optarrangement = ArrangementConverter.GetArrangement(Option, convertersArray); Arrange(optarrangement, converters); } }
/// <summary> /// Activate the options that were previously set with calls to properties. /// </summary> /// <remarks> /// <para> /// This allows an object to defer activation of its options until all /// options have been set. This is required for components which have /// related options that remain ambiguous until all are set. /// </para> /// <para> /// If a component implements this interface then this method must be called /// after its properties have been set before the component can be used. /// </para> /// <para> /// The strange constructor call to this method is suspended using /// <see cref="m_constructed"/>. /// </para> /// </remarks> public override void ActivateOptions() { if (!m_constructed) { return; } // pass control to parent in case we do not get a serializer :o[ base.ActivateOptions(); // just to get those converters var parser = CreatePatternParser(String.Empty); // Extract discovered converters var converters = Enumerable.ToArray( Enumerable.Cast <ConverterInfo>( parser.PatternConverters.Values ) ); var arrangement = new MultipleArrangement(); if (m_arrangement.Arrangements.Count != 0) { arrangement.AddArrangement(m_arrangement); } var patternArrangement = ArrangementConverter.GetArrangement(ConversionPattern, converters); if (patternArrangement != null) { arrangement.AddArrangement(patternArrangement); } if (arrangement.Arrangements.Count == 0) { // cater for bare defaults arrangement.AddArrangement(new DefaultArrangement()); } var serconv = SerializingConverter; if (serconv == null) { var name = SerializerName ?? DefaultSerializerName; var info = (parser.PatternConverters.ContainsKey(name) ? parser.PatternConverters[name] as ConverterInfo : null ) ?? CreateSerializingConverterInfo(name, typeof(JsonPatternConverter)); SerializingConverter = serconv = CreateSerializingConverter(info); } if (serconv != null) { SetUpSerializingConverter(serconv, converters, arrangement, m_fetcher, m_renderer, m_decorators.ToArray()); } }
/// <summary> /// Parse the Arrangement string and use the new arrangement instance. /// </summary> /// <param name="members">Members to be arranged</param> /// <param name="converters">inherited converters, can be null</param> public override void Arrange(IList <IMember> members, ConverterInfo[] converters) { var arrangement = ArrangementConverter.GetArrangement(Arrangement, converters); if (arrangement != null) { arrangement.Arrange(members, converters); } }
/// <summary> /// Simply call each and every one of the <see cref="Arrangements"/> /// </summary> /// <param name="members">Members to be arranged</param> /// <param name="converters">inherited converters, can be null</param> public override void Arrange(IList <IMember> members, ConverterInfo[] converters) { if (members == null) { throw new ArgumentNullException("memebers"); } var optarrangement = ArrangementConverter.GetArrangement(Option, converters); if (optarrangement != null) { optarrangement.Arrange(members, converters); } foreach (var arrangement in Arrangements) { if (arrangement == null) { continue; } arrangement.Arrange(members, converters); } }
/// <summary> /// When configured by XML or by <see cref="ArrangementConverter"/> in general, /// the <see cref="Option"/> is tried to figure out the <see cref="IRawLayout"/> to use. /// </summary> /// <remarks> /// It can be a <see cref="PatternString" />, then the option will be stringified. /// It can be a <see cref="string"/>, then <see cref="ArrangementConverter.GetArrangement"/> will be attempted. /// It can be an <see cref="IArrangement"/>, then it will be used to arrange a new <see cref="RawArrangedLayout"/> /// It can be another <see cref="IMember" />, then if Name was not set yet it will be adopted. /// It can be a <see cref="ConverterInfo" />, then a new RawCallLayout will be set up around it. /// It can be a <see cref="PatternParser" />, then a new RawCallLayout will be set up around it. /// </remarks> public void ActivateOptions() { if (Option == null) { Option = GetLayout(Name); return; } if (Option is PatternString) { var ps = (PatternString)Option; Option = ps.Format(); } if (Option is string) { // try to parse an arrangement var arrangement = ArrangementConverter.GetArrangement(Option as string, Converters); if (arrangement != null) { Option = arrangement; } } if (Option is string) { // try to find a layout var layout = GetLayout(Option as string); if (layout != null) { Option = layout; } } if (Option is ConverterInfo) { Option = new RawCallLayout((ConverterInfo)Option); } if (Option is PatternConverter) { Option = new RawCallLayout(Name, (PatternConverter)Option); } if (Option is IOptionHandler) { // this simplifies calls in ArrangementConverter a lot ((IOptionHandler)Option).ActivateOptions(); } if (Option is ILayout) { var layout = (ILayout)Option; var playout = Option as PatternLayout; if (playout != null && Converters != null) { foreach (var conv in Converters) { playout.AddConverter(conv); } } Option = new Layout2RawLayoutAdapter((ILayout)Option); } else if (Option is IMember) { var optionMember = (IMember)Option; if (String.IsNullOrEmpty(Name)) { Name = optionMember.Name; } Option = optionMember.Layout; } else if (Option is IArrangement) { var optionArrangemet = (IArrangement)Option; var l = new RawArrangedLayout(); optionArrangemet.Arrange(l.Members, Converters); Option = l; } if (Option is IOptionHandler) { // do it again if object changed ((IOptionHandler)Option).ActivateOptions(); } }