/// <summary> /// Process the object element /// </summary> protected virtual void ProcessObjectDefinition(XmlElement element, ObjectDefinitionParserHelper helper) { // TODO: add event handling try { ObjectDefinitionHolder bdHolder = helper.ParseObjectDefinitionElement(element); if (bdHolder == null) { return; } bdHolder = helper.DecorateObjectDefinitionIfRequired(element, bdHolder); if (log.IsEnabled(LogLevel.Debug)) { log.LogDebug(string.Format(CultureInfo.InvariantCulture, "Registering object definition with id '{0}'.", bdHolder.ObjectName)); } ObjectDefinitionReaderUtils.RegisterObjectDefinition(bdHolder, ReaderContext.Registry); // TODO: Send registration event. // ReaderContext.FireComponentRegistered(new BeanComponentDefinition(bdHolder)); } catch (ObjectDefinitionStoreException) { throw; } catch (Exception ex) { throw new ObjectDefinitionStoreException( $"Failed parsing object definition '{element.OuterXml}'", ex); } }
/** * Register an error channel in the given ObjectDefinitionRegistry if not yet present. * The bean name for which this is checking is defined by the constant * {@link IntegrationContextUtils#ERROR_CHANNEL_BEAN_NAME}. */ private void RegisterErrorChannelIfNecessary(IObjectDefinitionRegistry registry) { if (!registry.ContainsObjectDefinition(IntegrationContextUtils.ErrorChannelObjectName)) { if (logger.IsInfoEnabled) { logger.Info("No bean named '" + IntegrationContextUtils.ErrorChannelObjectName + "' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created."); } RootObjectDefinition errorChannelDef = new RootObjectDefinition(); errorChannelDef.ObjectTypeName = IntegrationNamespaceUtils.BASE_PACKAGE + ".Channel.PublishSubscribeChannel"; ObjectDefinitionHolder errorChannelHolder = new ObjectDefinitionHolder(errorChannelDef, IntegrationContextUtils.ErrorChannelObjectName); ObjectDefinitionReaderUtils.RegisterObjectDefinition(errorChannelHolder, registry); ObjectDefinitionBuilder loggingHandlerBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(IntegrationNamespaceUtils.HANDLER_PACKAGE + ".LoggingHandler"); string loggingHandlerObjectName = ObjectDefinitionReaderUtils.GenerateObjectName(loggingHandlerBuilder.ObjectDefinition, registry); loggingHandlerBuilder.AddConstructorArg("ERROR"); ObjectDefinitionHolder loggingHandlerHolder = new ObjectDefinitionHolder(loggingHandlerBuilder.ObjectDefinition, loggingHandlerObjectName); ObjectDefinitionReaderUtils.RegisterObjectDefinition(loggingHandlerHolder, registry); ObjectDefinitionBuilder loggingEndpointBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(IntegrationNamespaceUtils.ENDPOINT_PACKAGE + ".EventDrivenConsumer"); loggingEndpointBuilder.AddConstructorArgReference(IntegrationContextUtils.ErrorChannelObjectName); loggingEndpointBuilder.AddConstructorArgReference(loggingHandlerObjectName); string loggingEndpointObjectName = ObjectDefinitionReaderUtils.GenerateObjectName(loggingEndpointBuilder.ObjectDefinition, registry); ObjectDefinitionHolder loggingEndpointHolder = new ObjectDefinitionHolder(loggingEndpointBuilder.ObjectDefinition, loggingEndpointObjectName); ObjectDefinitionReaderUtils.RegisterObjectDefinition(loggingEndpointHolder, registry); } }
/// <summary>The parse inner object definition.</summary> /// <param name="element">The element.</param> /// <param name="parserContext">The parser context.</param> /// <returns>The Spring.Objects.Factory.Config.IObjectDefinition.</returns> public static IObjectDefinition ParseInnerObjectDefinition(XmlElement element, ParserContext parserContext) { // parses out inner object definition for concrete implementation if defined var childElements = element.GetElementsByTagName("object"); IObjectDefinition innerComponentDefinition = null; IConfigurableObjectDefinition inDef = null; if (childElements != null && childElements.Count == 1) { var objectElement = childElements[0] as XmlElement; // var odDelegate = parserContext.GetDelegate(); var odHolder = parserContext.ParserHelper.ParseObjectDefinitionElement(objectElement); // odHolder = odDelegate.DecorateObjectDefinitionIfRequired(objectElement, odHolder); inDef = odHolder.ObjectDefinition as IConfigurableObjectDefinition; var objectName = ObjectDefinitionReaderUtils.GenerateObjectName(inDef, parserContext.Registry); // innerComponentDefinition = new ObjectComponentDefinition(inDef, objectName); parserContext.Registry.RegisterObjectDefinition(objectName, inDef); } var aRef = element.GetAttribute(REF_ATTRIBUTE); AssertUtils.IsTrue( !(!string.IsNullOrWhiteSpace(aRef) && inDef != null), "Ambiguous definition. Inner object " + (inDef == null ? string.Empty : inDef.ObjectTypeName) + " declaration and \"ref\" " + aRef + " are not allowed together." ); return(inDef); }
/// <summary> /// Parse the specified element and register any resulting /// IObjectDefinitions with the IObjectDefinitionRegistry that is /// embedded in the supplied ParserContext. /// </summary> /// <param name="element">The element to be parsed into one or more IObjectDefinitions</param> /// <param name="parserContext">The object encapsulating the current state of the parsing /// process.</param> /// <returns> /// The primary IObjectDefinition (can be null as explained above) /// </returns> /// <remarks> /// Implementations should return the primary IObjectDefinition /// that results from the parse phase if they wish to used nested /// inside (for example) a <code><property></code> tag. /// <para>Implementations may return null if they will not /// be used in a nested scenario. /// </para> /// </remarks> public override IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) { ParseElementCalled = true; ObjectDefinitionHolder holder = ParseTestObjectDefinition(element, parserContext); ObjectDefinitionReaderUtils.RegisterObjectDefinition(holder, parserContext.Registry); return(null); }
/// <see cref="INamespaceParser"/> public override IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) { string name = element.GetAttribute(ObjectDefinitionConstants.IdAttribute); IConfigurableObjectDefinition templateDefinition = ParseTemplateDefinition(element, parserContext); if (!StringUtils.HasText(name)) { name = ObjectDefinitionReaderUtils.GenerateObjectName(templateDefinition, parserContext.Registry); } parserContext.Registry.RegisterObjectDefinition(name, templateDefinition); return(null); }
private void RegisterDefaultConfiguringObjectFactoryPostProcessorIfNecessary(ParserContext parserContext) { if (!parserContext.Registry.IsObjectNameInUse(DEFAULT_CONFIGURING_POSTPROCESSOR_OBJECT_NAME)) { ObjectDefinitionBuilder builder = ObjectDefinitionBuilder.GenericObjectDefinition(IntegrationNamespaceUtils.CONFIG_XML_PACKAGE + "." + DEFAULT_CONFIGURING_POSTPROCESSOR_SIMPLE_CLASS_NAME); ObjectDefinitionHolder holder = new ObjectDefinitionHolder(builder.ObjectDefinition, DEFAULT_CONFIGURING_POSTPROCESSOR_OBJECT_NAME); ObjectDefinitionReaderUtils.RegisterObjectDefinition(holder, parserContext.Registry); } }
private void RegisterNullChannel(IObjectDefinitionRegistry registry) { if (registry.IsObjectNameInUse(IntegrationContextUtils.NullChannelObjectName)) { throw new IllegalStateException("The object name '" + IntegrationContextUtils.NullChannelObjectName + "' is reserved."); } RootObjectDefinition nullChannelDef = new RootObjectDefinition(); nullChannelDef.ObjectTypeName = IntegrationNamespaceUtils.BASE_PACKAGE + ".Channel.NullChannel"; ObjectDefinitionHolder nullChannelHolder = new ObjectDefinitionHolder(nullChannelDef, IntegrationContextUtils.NullChannelObjectName); ObjectDefinitionReaderUtils.RegisterObjectDefinition(nullChannelHolder, registry); }
private static string CreateDirectChannel(XmlElement element, ParserContext parserContext) { string channelId = element.GetAttribute("id"); if (!StringUtils.HasText(channelId)) { parserContext.ReaderContext.ReportException(element, "channel", "The channel-adapter's 'id' attribute is required when no 'channel' " + "reference has been provided, because that 'id' would be used for the created channel."); } ObjectDefinitionBuilder channelBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(IntegrationNamespaceUtils.CHANNEL_PACKAGE + ".DirectChannel"); ObjectDefinitionHolder holder = new ObjectDefinitionHolder(channelBuilder.ObjectDefinition, channelId); ObjectDefinitionReaderUtils.RegisterObjectDefinition(holder, parserContext.Registry); return(channelId); }
protected override AbstractObjectDefinition ParseInternal(XmlElement element, ParserContext parserContext) { ObjectDefinitionBuilder handlerBuilder = ParseHandler(element, parserContext); IntegrationNamespaceUtils.SetReferenceIfAttributeDefined(handlerBuilder, element, "output-channel"); IntegrationNamespaceUtils.SetValueIfAttributeDefined(handlerBuilder, element, "order"); AbstractObjectDefinition handlerBeanDefinition = handlerBuilder.ObjectDefinition; string inputChannelAttributeName = InputChannelAttributeName; if (!element.HasAttribute(inputChannelAttributeName)) { if (!parserContext.IsNested) { parserContext.ReaderContext.ReportException(element, element.Name, "The '" + inputChannelAttributeName + "' attribute is required for top-level endpoint elements."); } return(handlerBeanDefinition); } ObjectDefinitionBuilder builder = ObjectDefinitionBuilder.GenericObjectDefinition(IntegrationNamespaceUtils.CONFIG_PACKAGE + ".ConsumerEndpointFactoryObject"); string handlerBeanName = parserContext.ReaderContext.RegisterWithGeneratedName(handlerBeanDefinition); builder.AddConstructorArgReference(handlerBeanName); string inputChannelName = element.GetAttribute(inputChannelAttributeName); if (!parserContext.Registry.ContainsObjectDefinition(inputChannelName)) { ObjectDefinitionBuilder channelDef = ObjectDefinitionBuilder.GenericObjectDefinition(IntegrationNamespaceUtils.CHANNEL_PACKAGE + ".DirectChannel"); ObjectDefinitionHolder holder = new ObjectDefinitionHolder(channelDef.ObjectDefinition, inputChannelName); ObjectDefinitionReaderUtils.RegisterObjectDefinition(holder, parserContext.Registry); } builder.AddPropertyValue("inputChannelName", inputChannelName); XmlElement pollerElement = DomUtils.GetChildElementByTagName(element, "poller"); if (pollerElement != null) { IntegrationNamespaceUtils.ConfigurePollerMetadata(pollerElement, builder, parserContext); } IntegrationNamespaceUtils.SetValueIfAttributeDefined(builder, element, "auto-startup"); return(builder.ObjectDefinition); }
private void LoadObjectDefinitionForConfigurationClassIfNecessary(ConfigurationClass configClass) { if (configClass.ObjectName != null) { // a Object definition already exists for this configuration class -> nothing to do return; } // no Object definition exists yet -> this must be an imported configuration class ([Import]). GenericObjectDefinition configObjectDef = new GenericObjectDefinition(); String className = configClass.ConfigurationClassType.Name; configObjectDef.ObjectTypeName = className; configObjectDef.ObjectType = configClass.ConfigurationClassType; if (CheckConfigurationClassCandidate(configClass.ConfigurationClassType)) { String configObjectName = ObjectDefinitionReaderUtils.RegisterWithGeneratedName(configObjectDef, _registry); configClass.ObjectName = configObjectName; Logger.LogDebug($"Registered object definition for imported [Configuration] class {configObjectName}"); } }
/// <summary> /// Register a TaskScheduler in the given <see cref="IObjectDefinitionFactory"/> if not yet present. /// The object name for which this is checking is defined by the constant <see cref="IntegrationContextUtils.TaskSchedulerObjectName"/> /// </summary> /// <param name="registry">the <see cref="IObjectDefinitionFactory"/></param> private void RegisterTaskSchedulerIfNecessary(IObjectDefinitionRegistry registry) { if (!registry.ContainsObjectDefinition(IntegrationContextUtils.TaskSchedulerObjectName)) { if (logger.IsInfoEnabled) { logger.Info("No object named '" + IntegrationContextUtils.TaskSchedulerObjectName + "' has been explicitly defined. Therefore, a default SimpleTaskScheduler will be created."); } IExecutor taskExecutor = IntegrationContextUtils.CreateThreadPoolTaskExecutor(2, 100, 0, "task-scheduler-"); ObjectDefinitionBuilder schedulerBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(IntegrationNamespaceUtils.SCHEDULING_PACKAGE + ".SimpleTaskScheduler"); schedulerBuilder.AddConstructorArg(taskExecutor); ObjectDefinitionBuilder errorHandlerBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(IntegrationNamespaceUtils.CHANNEL_PACKAGE + ".MessagePublishingErrorHandler"); errorHandlerBuilder.AddPropertyReference("defaultErrorChannel", IntegrationContextUtils.ErrorChannelObjectName); string errorHandlerBeanName = ObjectDefinitionReaderUtils.GenerateObjectName(errorHandlerBuilder.ObjectDefinition, registry); ObjectDefinitionHolder errorHandlerHolder = new ObjectDefinitionHolder(errorHandlerBuilder.ObjectDefinition, errorHandlerBeanName); ObjectDefinitionReaderUtils.RegisterObjectDefinition(errorHandlerHolder, registry); schedulerBuilder.AddPropertyReference("errorHandler", errorHandlerBeanName); ObjectDefinitionHolder schedulerHolder = new ObjectDefinitionHolder(schedulerBuilder.ObjectDefinition, IntegrationContextUtils.TaskSchedulerObjectName); ObjectDefinitionReaderUtils.RegisterObjectDefinition(schedulerHolder, registry); } }
/// <summary> /// Applies attributes to the proxy class. /// </summary> /// <param name="typeBuilder">The type builder to use.</param> /// <param name="targetType">The proxied class.</param> /// <see cref="IProxyTypeBuilder.ProxyTargetAttributes"/> /// <see cref="IProxyTypeBuilder.TypeAttributes"/> protected override void ApplyTypeAttributes(TypeBuilder typeBuilder, Type targetType) { foreach (object attr in GetTypeAttributes(targetType)) { if (attr is CustomAttributeBuilder) { typeBuilder.SetCustomAttribute((CustomAttributeBuilder)attr); } else if (attr is CustomAttributeData) { typeBuilder.SetCustomAttribute( ReflectionUtils.CreateCustomAttribute((CustomAttributeData)attr)); } else if (attr is Attribute) { typeBuilder.SetCustomAttribute( ReflectionUtils.CreateCustomAttribute((Attribute)attr)); } else if (attr is IObjectDefinition) { RootObjectDefinition objectDefinition = (RootObjectDefinition)attr; //TODO check that object definition is for an Attribute type. //Change object definition so it can be instantiated and make prototype scope. objectDefinition.IsAbstract = false; objectDefinition.IsSingleton = false; string objectName = ObjectDefinitionReaderUtils.GenerateObjectName(objectDefinition, objectFactory); objectFactory.RegisterObjectDefinition(objectName, objectDefinition); //find constructor and constructor arg values to create this attribute. ConstructorResolver constructorResolver = new ConstructorResolver(objectFactory, objectFactory, new SimpleInstantiationStrategy(), new ObjectDefinitionValueResolver(objectFactory)); ConstructorInstantiationInfo ci = constructorResolver.GetConstructorInstantiationInfo(objectName, objectDefinition, null, null); if (objectDefinition.PropertyValues.PropertyValues.Count == 0) { CustomAttributeBuilder cab = new CustomAttributeBuilder(ci.ConstructorInfo, ci.ArgInstances); typeBuilder.SetCustomAttribute(cab); } else { object attributeInstance = objectFactory.GetObject(objectName); IObjectWrapper wrappedAttributeInstance = new ObjectWrapper(attributeInstance); PropertyInfo[] namedProperties = wrappedAttributeInstance.GetPropertyInfos(); object[] propertyValues = new object[namedProperties.Length]; for (int i = 0; i < namedProperties.Length; i++) { propertyValues[i] = wrappedAttributeInstance.GetPropertyValue(namedProperties[i].Name); } CustomAttributeBuilder cab = new CustomAttributeBuilder(ci.ConstructorInfo, ci.ArgInstances, namedProperties, propertyValues); typeBuilder.SetCustomAttribute(cab); } } } }
/// <summary> /// Parse a standard object definition into a /// <see cref="Spring.Objects.Factory.Config.ObjectDefinitionHolder"/>, /// including object name and aliases. /// </summary> /// <param name="element">The element containing the object definition.</param> /// <param name="containingDefinition">The containing object definition if <paramref name="element"/> is a nested element.</param> /// <returns> /// The parsed object definition wrapped within an /// <see cref="Spring.Objects.Factory.Config.ObjectDefinitionHolder"/> /// instance. /// </returns> /// <remarks> /// <para> /// Object elements specify their canonical name via the "id" attribute /// and their aliases as a delimited "name" attribute. /// </para> /// <para> /// If no "id" is specified, uses the first name in the "name" attribute /// as the canonical name, registering all others as aliases. /// </para> /// </remarks> public ObjectDefinitionHolder ParseObjectDefinitionElement(XmlElement element, IObjectDefinition containingDefinition) { string id = GetAttributeValue(element, ObjectDefinitionConstants.IdAttribute); string nameAttr = GetAttributeValue(element, ObjectDefinitionConstants.NameAttribute); List <string> aliases = new List <string>(); if (StringUtils.HasText(nameAttr)) { aliases.AddRange(GetObjectNames(nameAttr)); } // if we ain't got an id, check if object is page definition or assign any existing (first) alias... string objectName = id; if (StringUtils.IsNullOrEmpty(objectName)) { if (aliases.Count > 0) { objectName = aliases[0]; aliases.RemoveAt(0); if (log.IsDebugEnabled) { log.Debug(string.Format("No XML 'id' specified using '{0}' as object name and '{1}' as aliases", objectName, string.Join(",", aliases.ToArray()))); } } } objectName = PostProcessObjectNameAndAliases(objectName, aliases, element, containingDefinition); if (containingDefinition == null) { CheckNameUniqueness(objectName, aliases, element); } ParserContext parserContext = new ParserContext(this, containingDefinition); IConfigurableObjectDefinition definition = objectsNamespaceParser.ParseObjectDefinitionElement(element, objectName, parserContext); if (definition != null) { if (StringUtils.IsNullOrEmpty(objectName)) { if (containingDefinition != null) { objectName = ObjectDefinitionReaderUtils.GenerateObjectName(definition, readerContext.Registry, true); } else { objectName = readerContext.GenerateObjectName(definition); // Register an alias for the plain object type name, if possible. string objectTypeName = definition.ObjectTypeName; if (objectTypeName != null && objectName.StartsWith(objectTypeName) && objectName.Length > objectTypeName.Length && !readerContext.Registry.IsObjectNameInUse(objectTypeName)) { aliases.Add(objectTypeName); } } #region Instrumentation if (log.IsDebugEnabled) { log.Debug(string.Format( "Neither XML '{0}' nor '{1}' specified - using generated object name [{2}]", ObjectDefinitionConstants.IdAttribute, ObjectDefinitionConstants.NameAttribute, objectName)); } #endregion } return(CreateObjectDefinitionHolder(element, definition, objectName, aliases)); } return(null); }
/// <summary> /// Registers the supplied <see cref="ObjectDefinitionHolder"/> with the supplied /// <see cref="IObjectDefinitionRegistry"/>. /// </summary> /// <remarks>Subclasses can override this method to control whether or not the supplied /// <see cref="ObjectDefinitionHolder"/> is actually even registered, or to /// register even more objects. /// <para> /// The default implementation registers the supplied <see cref="ObjectDefinitionHolder"/> /// with the supplied <see cref="ObjectDefinitionHolder"/> only if the <code>IsNested</code> /// parameter is <code>false</code>, because one typically does not want inner objects /// to be registered as top level objects. /// </para> /// </remarks> /// /// <param name="definition">The object definition to be registered.</param> /// <param name="registry">The registry that the bean is to be registered with.</param> protected virtual void RegisterObjectDefinition(ObjectDefinitionHolder definition, IObjectDefinitionRegistry registry) { ObjectDefinitionReaderUtils.RegisterObjectDefinition(definition, registry); }