started ObjectDefinitionParserHelper and ObjectsNamespaceParser refactoring towards Spring/J 2.5 codebase to better support new extension projects

This commit is contained in:
eeichinger
2009-02-26 17:38:15 +00:00
parent e422882b2f
commit ad046ac936
7 changed files with 510 additions and 187 deletions

View File

@@ -105,7 +105,7 @@ namespace Spring.Objects.Factory.Xml
/// and was called to process the root node.
/// </p>
/// </remarks>
public IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext)
public virtual IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext)
{
AbstractObjectDefinition definition = ParseInternal(element, parserContext);

View File

@@ -153,27 +153,101 @@ namespace Spring.Objects.Factory.Xml
/// in case an error happens during parsing and registering object definitions
/// </exception>
protected virtual void ParseObjectDefinitions(XmlElement root, ObjectDefinitionParserHelper helper)
{
foreach (XmlNode node in root.ChildNodes)
{
if (helper.IsDefaultNamespace(root.NamespaceURI))
{
foreach (XmlNode node in root.ChildNodes)
{
if (node.NodeType != XmlNodeType.Element) continue;
try
{
XmlElement element = (XmlElement)node;
if (helper.IsDefaultNamespace(element.NamespaceURI))
{
ParseDefaultElement(element, helper);
}
else
{
helper.ParseCustomElement(element);
}
}
catch (ObjectDefinitionStoreException)
{
throw;
}
catch (Exception ex)
{
helper.ReaderContext.ReportException(node, null, "Failed parsing element", ex);
}
}
}
else
{
helper.ParseCustomElement(root);
}
}
private void ParseDefaultElement(XmlElement element, ObjectDefinitionParserHelper helper)
{
if (element.LocalName == ObjectDefinitionConstants.ImportElement)
{
ImportObjectDefinitionResource(element);
}
else if (element.LocalName == ObjectDefinitionConstants.AliasElement)
{
ParseAlias(element, helper.ReaderContext.Registry);
}
else if (element.LocalName == ObjectDefinitionConstants.ObjectElement)
{
ProcessObjectDefinition(element, helper);
}
}
/// <summary>
/// Process an alias element.
/// </summary>
protected virtual void ProcessAlias(XmlElement element)
{
this.ParseAlias(element, this.ReaderContext.Registry);
}
/// <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);
#region Instrumentation
if (log.IsDebugEnabled)
{
log.Debug(string.Format(CultureInfo.InvariantCulture, "Registering object definition with id '{0}'.", bdHolder.ObjectName));
}
#endregion
ObjectDefinitionReaderUtils.RegisterObjectDefinition(bdHolder, ReaderContext.Registry);
// TODO: Send registration event.
// ReaderContext.FireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
catch (ObjectDefinitionStoreException)
{
throw;
}
catch (Exception ex)
{
if (node.NodeType == XmlNodeType.Element)
{
XmlElement element = (XmlElement) node;
try
{
INamespaceParser parser = GetNamespaceParser(element, helper);
ParserContext parserContext = new ParserContext(helper.ReaderContext, helper);
parser.ParseElement(element, parserContext);
}
catch( ObjectDefinitionStoreException )
{
throw;
}
catch (Exception ex)
{
helper.ReaderContext.ReportException(node, null, "Failed parsing element", ex);
}
}
throw new ObjectDefinitionStoreException(
string.Format("Failed parsing object definition '{0}'", element.OuterXml), ex);
}
}
@@ -233,37 +307,7 @@ namespace Spring.Objects.Factory.Xml
/// <seealso cref="Spring.Objects.Factory.Support.ObjectDefinitionReaderUtils.RegisterObjectDefinition"/>
protected virtual void RegisterObjectDefinition(XmlElement element, ObjectDefinitionParserHelper helper)
{
ObjectDefinitionHolder holder = null;
try
{
INamespaceParser parser = GetNamespaceParser(element, helper);
//holder = ParseObjectDefinition(element, parserContext);
//holder = helper.ParseObjectDefinitionElement(element);
if (holder == null)
{
return;
}
}
catch (Exception ex)
{
throw new ObjectDefinitionStoreException(
string.Format("Failed parsing object definition '{0}'", element.OuterXml), ex);
}
#region Instrumentation
if (log.IsDebugEnabled)
{
log.Debug(
string.Format(
CultureInfo.InvariantCulture,
"Registering object definition with id '{0}'.", holder.ObjectName));
}
#endregion
ObjectDefinitionReaderUtils.RegisterObjectDefinition(holder, ReaderContext.Registry);
ProcessObjectDefinition(element, helper);
}
/// <summary>
@@ -313,20 +357,20 @@ namespace Spring.Objects.Factory.Xml
return helper;
}
private INamespaceParser GetNamespaceParser(XmlElement element, ObjectDefinitionParserHelper helper)
{
INamespaceParser parser = NamespaceParserRegistry.GetParser(element.NamespaceURI);
if (parser == null)
{
helper.ReaderContext.ReportException(element, null, GetNoParserForNamespaceMessage(element.NamespaceURI));
}
return parser;
}
private string GetNoParserForNamespaceMessage(string namespaceURI)
{
return "There is no parser registered for namespace '" + namespaceURI + "'";
}
// private INamespaceParser GetNamespaceParser(XmlElement element, ObjectDefinitionParserHelper helper)
// {
// INamespaceParser parser = NamespaceParserRegistry.GetParser(element.NamespaceURI);
// if (parser == null)
// {
// helper.ReaderContext.ReportException(element, null, GetNoParserForNamespaceMessage(element.NamespaceURI));
// }
// return parser;
// }
//
// private string GetNoParserForNamespaceMessage(string namespaceURI)
// {
// return "There is no parser registered for namespace '" + namespaceURI + "'";
// }
#endregion
}

View File

@@ -19,6 +19,7 @@
#endregion
using System;
using System.Collections;
using System.Globalization;
using System.Xml;
using Common.Logging;
@@ -170,8 +171,156 @@ namespace Spring.Objects.Factory.Xml
//TODO decoration processing.
return holder;
}
}
/// <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>
/// <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)
{
return ParseObjectDefinitionElement(element, null);
}
/// <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)
{
// TODO: move code from ObjectsNamespaceParser into this class to eliminate ONP
ObjectsNamespaceParser parser = (ObjectsNamespaceParser) NamespaceParserRegistry.GetParser(ObjectsNamespaceParser.Namespace);
string id = GetAttributeValue(element, ObjectDefinitionConstants.IdAttribute);
string nameAttr = GetAttributeValue(element, ObjectDefinitionConstants.NameAttribute);
ArrayList aliases = new ArrayList();
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))
{
// TODO (EE): pass parserContext to CalculateId as well (resolving relative Urls in WebApps is parserContext-dependent) (EE)
objectName = parser.CalculateId(element, aliases);
}
ParserContext parserContext = new ParserContext(this, containingDefinition);
IConfigurableObjectDefinition definition = parser.ParseObjectDefinitionElement(element, objectName, parserContext);
if (definition != null)
{
if (StringUtils.IsNullOrEmpty(objectName))
{
if (containingDefinition != null)
{
objectName =
ObjectDefinitionReaderUtils.GenerateObjectName(definition, parserContext.Registry, true);
}
else
{
objectName = ObjectDefinitionReaderUtils.GenerateObjectName(definition, parserContext.Registry);
}
#region Instrumentation
if (log.IsDebugEnabled)
{
log.Debug(string.Format(
"Neither XML '{0}' nor '{1}' specified - using object " +
"class name [{2}] as the id.",
id, ObjectDefinitionConstants.IdAttribute, ObjectDefinitionConstants.NameAttribute));
}
#endregion
}
string[] aliasesArray = (string[])aliases.ToArray(typeof(string));
return new ObjectDefinitionHolder(definition, objectName, aliasesArray);
}
return null;
}
/// <summary>
/// Parses an element in a custom namespace.
/// </summary>
/// <param name="ele"></param>
/// <returns>the parsed object definition or null if not supported by the corresponding parser.</returns>
public IObjectDefinition ParseCustomElement(XmlElement ele)
{
return ParseCustomElement(ele, null);
}
/// <summary>
/// Parses an element in a custom namespace.
/// </summary>
/// <param name="ele"></param>
/// <param name="containingDefinition">if a nested element, the containing object definition</param>
/// <returns>the parsed object definition or null if not supported by the corresponding parser.</returns>
public IObjectDefinition ParseCustomElement(XmlElement ele, IObjectDefinition containingDefinition)
{
String namespaceUri = ele.NamespaceURI;
INamespaceParser handler = NamespaceParserRegistry.GetParser(namespaceUri);
if (handler == null)
{
Error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
return handler.ParseElement(ele, new ParserContext(this, containingDefinition));
}
/// <summary>
/// Given a string containing delimited object names, returns
/// a string array split on the object name delimeter.
/// </summary>
/// <param name="value">
/// The string containing delimited object names.
/// </param>
/// <returns>
/// A string array split on the object name delimeter.
/// </returns>
/// <seealso cref="ObjectDefinitionConstants.ObjectNameDelimiters"/>
private string[] GetObjectNames(string value)
{
return StringUtils.Split(
value, ObjectDefinitionConstants.ObjectNameDelimiters, true, true);
}
/// <summary>
/// Determines whether the string represents a 'true' boolean value.
@@ -237,5 +386,13 @@ namespace Spring.Objects.Factory.Xml
}
return defaultValue;
}
/// <summary>
/// Report a parser error.
/// </summary>
protected virtual void Error(string message, XmlElement element)
{
this.ReaderContext.ReportFatalException(element, message);
}
}
}

View File

@@ -61,11 +61,12 @@ namespace Spring.Objects.Factory.Xml
[
NamespaceParser(
Namespace = "http://www.springframework.net",
SchemaLocationAssemblyHint = typeof(ObjectsNamespaceParser),
SchemaLocation = "/Spring.Objects.Factory.Xml/spring-objects-1.1.xsd"
)
SchemaLocationAssemblyHint = typeof(ObjectsNamespaceParser),
SchemaLocation = "/Spring.Objects.Factory.Xml/spring-objects-1.1.xsd"
)
]
public class ObjectsNamespaceParser : INamespaceParser
// [Obsolete("ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
public class ObjectsNamespaceParser : AbstractObjectDefinitionParser, INamespaceParser
{
/// <summary>
/// The namespace URI for the standard Spring.NET object definition schema.
@@ -87,11 +88,32 @@ namespace Spring.Objects.Factory.Xml
/// <remarks>This is a NoOp</remarks>
public void Init()
{
}
#endregion
/// <summary>
/// Parse the specified XmlElement and register the resulting
/// ObjectDefinitions with the <see cref="ParserContext.Registry"/> IObjectDefinitionRegistry
/// embedded in the supplied <see cref="ParserContext"/>
/// </summary>
/// <param name="element">The element to be parsed.</param>
/// <param name="parserContext">TThe object encapsulating the current state of the parsing process.
/// Provides access to a IObjectDefinitionRegistry</param>
/// <returns>The primary object definition.</returns>
/// <remarks>
/// <p>
/// This method is never invoked if the parser is namespace aware
/// and was called to process the root node.
/// </p>
/// </remarks>
[Obsolete("not used anymore - ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
public override IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext)
{
// TODO (EE): overridden just to stay binary compatible between 1.2.0 and 1.2.1
return base.ParseElement(element, parserContext);
}
/// <summary>
/// Parse the specified element and register any resulting
@@ -112,9 +134,8 @@ namespace Spring.Objects.Factory.Xml
/// be used in a nested scenario.
/// </para>
/// </remarks>
public virtual IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext)
protected override AbstractObjectDefinition ParseInternal(XmlElement element, ParserContext parserContext)
{
if (element.LocalName == ObjectDefinitionConstants.ImportElement)
{
ImportObjectDefinitionResource(element, parserContext);
@@ -125,9 +146,14 @@ namespace Spring.Objects.Factory.Xml
}
else if (element.LocalName == ObjectDefinitionConstants.ObjectElement)
{
RegisterObjectDefinition(element, parserContext);
// atm this will call back into this ns parsers
ObjectDefinitionHolder odh = parserContext.ParserHelper.ParseObjectDefinitionElement(element);
if (odh != null)
{
return odh.ObjectDefinition as AbstractObjectDefinition;
}
}
return null;
}
@@ -152,6 +178,7 @@ namespace Spring.Objects.Factory.Xml
/// or simply the original object definition if no decoration is required. A null value is strickly
/// speaking invalid, but will leniently treated like the case where the original object definition
/// gets returned.</returns>
[Obsolete("not used anymore - ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
public ObjectDefinitionHolder Decorate(XmlNode node, ObjectDefinitionHolder definition,
ParserContext parserContext)
{
@@ -161,7 +188,7 @@ namespace Spring.Objects.Factory.Xml
private void ParseAlias(XmlElement aliasElement, IObjectDefinitionRegistry registry)
{
string name = GetAttributeValue(aliasElement, ObjectDefinitionConstants.NameAttribute);
string alias = GetAttributeValue(aliasElement, ObjectDefinitionConstants.AliasAttribute);
string alias = GetAttributeValue(aliasElement, ObjectDefinitionConstants.AliasAttribute);
registry.RegisterAlias(name, alias);
}
@@ -174,6 +201,7 @@ namespace Spring.Objects.Factory.Xml
/// <exception cref="Spring.Objects.Factory.ObjectDefinitionStoreException">
/// If the resource could not be imported.
/// </exception>
[Obsolete("not used anymore - ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
protected virtual void ImportObjectDefinitionResource(XmlElement resource, ParserContext parserContext)
{
string location = GetAttributeValue(resource, ObjectDefinitionConstants.ImportResourceAttribute);
@@ -201,7 +229,7 @@ namespace Spring.Objects.Factory.Xml
location), ex);
}
}
/// <summary>Parses an event listener definition.</summary>
/// <param name="name">
@@ -249,22 +277,21 @@ namespace Spring.Objects.Factory.Xml
case ObjectDefinitionConstants.TypeAttribute:
// we're wiring up to a static event exposed on a Type (class)
myHandler.Source = parserContext.ReaderContext.Reader.Domain == null ?
(object) sourceAtt.Value :
(object)sourceAtt.Value :
(object)TypeResolutionUtils.ResolveType(sourceAtt.Value);
break;
}
events.AddHandler(myHandler);
}
/// <summary>
/// Parse an object definition and register it with the object factory..
/// </summary>
/// <param name="element">The element containing the object definition.</param>
/// <param name="parserContext">The parser context.</param>
/// <seealso cref="Spring.Objects.Factory.Support.ObjectDefinitionReaderUtils.RegisterObjectDefinition"/>
protected void RegisterObjectDefinition(XmlElement element, ParserContext parserContext)
[Obsolete("not used anymore - ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
protected ObjectDefinitionHolder ParseObjectDefinition(XmlElement element, ParserContext parserContext)
{
ObjectDefinitionHolder holder = null;
try
@@ -272,16 +299,16 @@ namespace Spring.Objects.Factory.Xml
holder = ParseObjectDefinitionElement(element, parserContext, false);
if (holder == null)
{
return;
return null;
}
}
catch(ObjectDefinitionStoreException)
catch (ObjectDefinitionStoreException)
{
throw;
}
catch (Exception ex)
{
//throw new ObjectDefinitionStoreException(string.Format("Failed parsing object definition '{0}'", element.OuterXml), ex);
//throw new ObjectDefinitionStoreException(string.Format("Failed parsing object definition '{0}'", element.OuterXml), ex);
parserContext.ReaderContext.ReportException(element, null, null, ex);
}
@@ -300,7 +327,33 @@ namespace Spring.Objects.Factory.Xml
#endregion
return holder;
}
/// <summary>
/// Parse an object definition and register it with the object factory..
/// </summary>
/// <param name="element">The element containing the object definition.</param>
/// <param name="parserContext">The parser context.</param>
/// <seealso cref="Spring.Objects.Factory.Support.ObjectDefinitionReaderUtils.RegisterObjectDefinition"/>
[Obsolete("not used anymore - ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
protected ObjectDefinitionHolder ParseAndRegisterObjectDefinition(XmlElement element, ParserContext parserContext)
{
ObjectDefinitionHolder holder = ParseObjectDefinition(element, parserContext);
ObjectDefinitionReaderUtils.RegisterObjectDefinition(holder, parserContext.ReaderContext.Registry);
return holder;
}
/// <summary>
/// Parse an object definition and register it with the object factory..
/// </summary>
/// <param name="element">The element containing the object definition.</param>
/// <param name="parserContext">The parser context.</param>
/// <seealso cref="Spring.Objects.Factory.Support.ObjectDefinitionReaderUtils.RegisterObjectDefinition"/>
[Obsolete("not used anymore - ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
protected void RegisterObjectDefinition(XmlElement element, ParserContext parserContext)
{
ParseAndRegisterObjectDefinition(element, parserContext);
}
@@ -328,6 +381,7 @@ namespace Spring.Objects.Factory.Xml
/// as the canonical name, registering all others as aliases.
/// </p>
/// </remarks>
[Obsolete("not used anymore - ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
protected ObjectDefinitionHolder ParseObjectDefinitionElement(XmlElement element, ParserContext parserContext, bool nestedDefinition)
{
string id = GetAttributeValue(element, ObjectDefinitionConstants.IdAttribute);
@@ -345,7 +399,7 @@ namespace Spring.Objects.Factory.Xml
// TODO (EE): pass parserContext to CalculateId as well (resolving relative Urls in WebApps is parserContext-dependent) (EE)
objectName = CalculateId(element, aliases);
}
IConfigurableObjectDefinition definition = ParseObjectDefinitionElement(element, objectName, parserContext);
if (definition != null)
@@ -374,7 +428,7 @@ namespace Spring.Objects.Factory.Xml
#endregion
}
string[] aliasesArray = (string[]) aliases.ToArray(typeof (string));
string[] aliasesArray = (string[])aliases.ToArray(typeof(string));
return new ObjectDefinitionHolder(definition, objectName, aliasesArray);
}
return null;
@@ -399,7 +453,7 @@ namespace Spring.Objects.Factory.Xml
/// <returns>
/// A calculated object definition id.
/// </returns>
protected virtual string CalculateId(XmlElement element, ArrayList aliases)
protected internal virtual string CalculateId(XmlElement element, ArrayList aliases)
{
string id = null;
if (aliases.Count > 0)
@@ -434,7 +488,8 @@ namespace Spring.Objects.Factory.Xml
/// <param name="id">The id of the object definition.</param>
/// <param name="parserContext">parsing state holder</param>
/// <returns>The object (definition).</returns>
protected virtual IConfigurableObjectDefinition ParseObjectDefinitionElement(
// [Obsolete("not used anymore - ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
protected internal virtual IConfigurableObjectDefinition ParseObjectDefinitionElement(
XmlElement element, string id, ParserContext parserContext)
{
string typeName = null;
@@ -466,7 +521,7 @@ namespace Spring.Objects.Factory.Xml
EventValues events = ParseEventHandlerSubElements(id, element, parserContext);
MethodOverrides methodOverrides = ParseMethodOverrideSubElements(id, element, parserContext);
bool isPage = StringUtils.HasText(typeName) && typeName!= null && typeName.ToLower().EndsWith(".aspx");
bool isPage = StringUtils.HasText(typeName) && typeName != null && typeName.ToLower().EndsWith(".aspx");
if (!isPage)
{
od.ConstructorArgumentValues = arguments;
@@ -620,7 +675,7 @@ namespace Spring.Objects.Factory.Xml
ReplacedMethodOverride theOverride = new ReplacedMethodOverride(methodName, targetReplacerObjectName);
foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.ReplacedMethodArgumentTypeElement))
{
XmlElement argElement = (XmlElement) node;
XmlElement argElement = (XmlElement)node;
string match = GetAttributeValue(argElement, ObjectDefinitionConstants.ReplacedMethodArgumentTypeMatchAttribute);
if (StringUtils.IsNullOrEmpty(match))
{
@@ -683,7 +738,7 @@ namespace Spring.Objects.Factory.Xml
MutablePropertyValues properties = new MutablePropertyValues();
foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.PropertyElement))
{
ParsePropertyElement(name, properties, (XmlElement) node, parserContext);
ParsePropertyElement(name, properties, (XmlElement)node, parserContext);
}
return properties;
}
@@ -834,7 +889,7 @@ namespace Spring.Objects.Factory.Xml
{
return new ExpressionHolder(inlineExpressionAtt.Value);
}
// should only have one element child: value, ref, collection...
XmlNodeList nodes = element.ChildNodes;
XmlElement valueRefOrCollectionElement = null;
@@ -879,58 +934,68 @@ namespace Spring.Objects.Factory.Xml
protected virtual object ParsePropertySubElement(
XmlElement element, string name, ParserContext parserContext)
{
if (element.Name.Equals(ObjectDefinitionConstants.ObjectElement))
if (element.NamespaceURI == Namespace)
{
return ParseObjectDefinitionElement(element, parserContext, true);
}
else if (element.Name.Equals(ObjectDefinitionConstants.RefElement))
{
return ParseReference(element, parserContext.ParserHelper, name);
}
else if (element.Name.Equals(ObjectDefinitionConstants.IdRefElement))
{
return ParseIdReference(element, parserContext.ParserHelper, name);
}
else if (element.Name.Equals(ObjectDefinitionConstants.ListElement))
{
return ParseListElement(element, name, parserContext);
}
else if (element.Name.Equals(ObjectDefinitionConstants.SetElement))
{
return ParseSetElement(element, name, parserContext);
}
else if (element.Name.Equals(ObjectDefinitionConstants.DictionaryElement))
{
return ParseDictionaryElement(element, name, parserContext);
}
else if (element.Name.Equals(ObjectDefinitionConstants.NameValuesElement))
{
return ParseNameValueCollectionElement(element, name);
}
else if (element.Name.Equals(ObjectDefinitionConstants.ValueElement))
{
return ParseValueElement(element, name);
}
else if (element.Name.Equals(ObjectDefinitionConstants.ExpressionElement))
{
return ParseExpressionElement(element, name, parserContext);
}
else if (element.Name.Equals(ObjectDefinitionConstants.NullElement))
{
// it's a distinguished null value...
return null;
}
else
{
// it may match another Parser
INamespaceParser otherParser = GetParser(element.NamespaceURI);
if (otherParser != null)
switch(element.LocalName)
{
// The other parser uses nestings tags and thus returns the definition
// of the parsed object.
return otherParser.ParseElement(element, new ParserContext(parserContext.ReaderContext, parserContext.ParserHelper));
case ObjectDefinitionConstants.ObjectElement:
{
return ParseObjectDefinitionElement(element, parserContext, true);
}
case ObjectDefinitionConstants.RefElement:
{
return ParseReference(element, parserContext.ParserHelper, name);
}
case ObjectDefinitionConstants.IdRefElement:
{
return ParseIdReference(element, parserContext.ParserHelper, name);
}
case ObjectDefinitionConstants.ListElement:
{
return ParseListElement(element, name, parserContext);
}
case ObjectDefinitionConstants.SetElement:
{
return ParseSetElement(element, name, parserContext);
}
case ObjectDefinitionConstants.DictionaryElement:
{
return ParseDictionaryElement(element, name, parserContext);
}
case ObjectDefinitionConstants.NameValuesElement:
{
return ParseNameValueCollectionElement(element, name);
}
case ObjectDefinitionConstants.ValueElement:
{
return ParseValueElement(element, name);
}
case ObjectDefinitionConstants.ExpressionElement:
{
return ParseExpressionElement(element, name, parserContext);
}
case ObjectDefinitionConstants.NullElement:
{
// it's a distinguished null value...
return null;
}
default:
throw new ObjectDefinitionStoreException(
parserContext.ReaderContext.Resource,
name,
"Unknown subelement of <property>: <" + element.Name + ">");
}
}
// it may match another Parser
INamespaceParser otherParser = GetParser(element.NamespaceURI);
if (otherParser != null)
{
// The other parser uses nestings tags and thus returns the definition
// of the parsed object.
return otherParser.ParseElement(element, new ParserContext(parserContext.ParserHelper));
}
throw new ObjectDefinitionStoreException(
parserContext.ReaderContext.Resource,
name,
@@ -950,7 +1015,7 @@ namespace Spring.Objects.Factory.Xml
return null;
}
}
private static object ParseIdReference(XmlElement element, ObjectDefinitionParserHelper parserHelper, string name)
{
// a generic reference to any name of any object
@@ -1046,7 +1111,7 @@ namespace Spring.Objects.Factory.Xml
{
list.ElementTypeName = elementTypeName;
}
foreach (XmlNode node in element.ChildNodes)
{
XmlElement ele = node as XmlElement;
@@ -1153,7 +1218,7 @@ namespace Spring.Objects.Factory.Xml
ObjectDefinitionConstants.DictionaryKeyRefShortcutAttribute,
ObjectDefinitionConstants.EntryElement));
}
XmlElement keyElement = (XmlElement) keyNode;
XmlElement keyElement = (XmlElement)keyNode;
XmlNodeList keyNodes = keyElement.GetElementsByTagName("*");
if (keyNodes == null || keyNodes.Count == 0)
{
@@ -1236,6 +1301,7 @@ namespace Spring.Objects.Factory.Xml
/// <paramref name="element"/> with the supplied
/// <paramref name="childElementName"/>.
/// </returns>
[Obsolete("not used anymore - ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
protected XmlNodeList SelectNodes(XmlElement element, string childElementName)
{
XmlNamespaceManager nsManager = new XmlNamespaceManager(new NameTable());
@@ -1263,6 +1329,7 @@ namespace Spring.Objects.Factory.Xml
/// <paramref name="element"/> with the supplied
/// <paramref name="childElementName"/>.
/// </returns>
[Obsolete("not used anymore - ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
protected XmlNode SelectSingleNode(XmlElement element, string childElementName)
{
XmlNamespaceManager nsManager = new XmlNamespaceManager(new NameTable());
@@ -1301,7 +1368,7 @@ namespace Spring.Objects.Factory.Xml
}
else
{
nvc.Add(key,value);
nvc.Add(key, value);
}
}
return nvc;
@@ -1351,7 +1418,7 @@ namespace Spring.Objects.Factory.Xml
{
try
{
code = (DependencyCheckingMode) Enum.Parse(
code = (DependencyCheckingMode)Enum.Parse(
typeof(DependencyCheckingMode), value, true);
}
catch (ArgumentException ex)
@@ -1393,7 +1460,7 @@ namespace Spring.Objects.Factory.Xml
{
try
{
mode = (AutoWiringMode) Enum.Parse(
mode = (AutoWiringMode)Enum.Parse(
typeof(AutoWiringMode), value, true);
}
catch (ArgumentException ex)
@@ -1440,37 +1507,37 @@ namespace Spring.Objects.Factory.Xml
return StringUtils.HasText(element.Prefix) ? element.Prefix : "spring";
}
/// <summary>
/// Returns the value of the element's attribute or <c>null</c>, if the attribute is not specified.
/// </summary>
/// <remarks>
/// This is a helper for bypassing the behavior of <see cref="XmlElement.GetAttribute(string)"/>
/// to return <see cref="string.Empty"/> if the attribute does not exist.
/// </remarks>
protected static string GetAttributeValue(XmlElement element, string attributeName)
{
if (element.HasAttribute(attributeName))
{
return element.GetAttribute(attributeName);
}
return null;
}
/// <summary>
/// Returns the value of the element's attribute or <paramref name="defaultValue"/>,
/// if the attribute is not specified.
/// </summary>
/// <remarks>
/// This is a helper for bypassing the behavior of <see cref="XmlElement.GetAttribute(string)"/>
/// to return <see cref="string.Empty"/> if the attribute does not exist.
/// </remarks>
protected static string GetAttributeValue(XmlElement element, string attributeName, string defaultValue)
{
if (element.HasAttribute(attributeName))
{
return element.GetAttribute(attributeName);
}
return defaultValue;
}
// /// <summary>
// /// Returns the value of the element's attribute or <c>null</c>, if the attribute is not specified.
// /// </summary>
// /// <remarks>
// /// This is a helper for bypassing the behavior of <see cref="XmlElement.GetAttribute(string)"/>
// /// to return <see cref="string.Empty"/> if the attribute does not exist.
// /// </remarks>
// protected static string GetAttributeValue(XmlElement element, string attributeName)
// {
// if (element.HasAttribute(attributeName))
// {
// return element.GetAttribute(attributeName);
// }
// return null;
// }
//
// /// <summary>
// /// Returns the value of the element's attribute or <paramref name="defaultValue"/>,
// /// if the attribute is not specified.
// /// </summary>
// /// <remarks>
// /// This is a helper for bypassing the behavior of <see cref="XmlElement.GetAttribute(string)"/>
// /// to return <see cref="string.Empty"/> if the attribute does not exist.
// /// </remarks>
// protected static string GetAttributeValue(XmlElement element, string attributeName, string defaultValue)
// {
// if (element.HasAttribute(attributeName))
// {
// return element.GetAttribute(attributeName);
// }
// return defaultValue;
// }
}
}

View File

@@ -18,6 +18,7 @@
#endregion
using System;
using System.Collections;
using Spring.Objects.Factory.Config;
using Spring.Objects.Factory.Support;
@@ -30,20 +31,43 @@ namespace Spring.Objects.Factory.Xml
/// </summary>
public class ParserContext
{
private XmlReaderContext readerContext;
private readonly XmlReaderContext readerContext;
private ObjectDefinitionParserHelper parserHelper;
private readonly ObjectDefinitionParserHelper parserHelper;
private IObjectDefinition containingObjectDefinition;
private Stack containingComponents = new Stack();
private readonly IObjectDefinition containingObjectDefinition;
// private Stack containingComponents = new Stack();
/// <summary>
/// Initializes a new instance of the <see cref="ParserContext"/> class.
/// </summary>
/// <param name="readerContext">The reader context.</param>
/// <param name="parserHelper">The parser helper.</param>
public ParserContext(ObjectDefinitionParserHelper parserHelper)
{
this.readerContext = parserHelper.ReaderContext;
this.parserHelper = parserHelper;
}
/// <summary>
/// Initializes a new instance of the <see cref="ParserContext"/> class.
/// </summary>
/// <param name="parserHelper">The parser helper.</param>
/// <param name="containingObjectDefinition">The containing object definition.</param>
public ParserContext(ObjectDefinitionParserHelper parserHelper, IObjectDefinition containingObjectDefinition)
{
this.readerContext = parserHelper.ReaderContext;
this.parserHelper = parserHelper;
this.containingObjectDefinition = containingObjectDefinition;
}
/// <summary>
/// Initializes a new instance of the <see cref="ParserContext"/> class.
/// </summary>
/// <param name="readerContext">The reader context.</param>
/// <param name="parserHelper">The parser helper.</param>
[Obsolete("consider using ParserContext(ObjectDefinitionParserHelper) instead", false)]
public ParserContext(XmlReaderContext readerContext, ObjectDefinitionParserHelper parserHelper)
{
this.readerContext = readerContext;
@@ -56,7 +80,8 @@ namespace Spring.Objects.Factory.Xml
/// </summary>
/// <param name="readerContext">The reader context.</param>
/// <param name="parserHelper">The parser helper.</param>
/// <param name="containingObjectDefinition">The containing object definition.</param>
/// <param name="containingObjectDefinition">The containing object definition.</param>
[Obsolete("consider using ParserContext(ObjectDefinitionParserHelper, IObjectDefinition) instead", false)]
public ParserContext(XmlReaderContext readerContext, ObjectDefinitionParserHelper parserHelper, IObjectDefinition containingObjectDefinition)
{
this.readerContext = readerContext;

View File

@@ -98,6 +98,7 @@ namespace Spring.Validation.Config
/// be used in a nested scenario.
/// </para>
/// </remarks>
[Obsolete("not used anymore - ObjectsNamespaceParser will be dropped with 2.x, use ObjectDefinitionParserHelper instead", false)]
public override IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext)
{
if (!element.HasAttribute("id"))

View File

@@ -246,5 +246,34 @@ namespace Spring.Objects.Factory.Xml
</objects>
"));
}
[Test]
public void ParsesNonDefaultNamespace()
{
try
{
NamespaceParserRegistry.Reset();
DefaultListableObjectFactory of = new DefaultListableObjectFactory();
XmlObjectDefinitionReader reader = new XmlObjectDefinitionReader(of);
reader.LoadObjectDefinitions(new StringResource(
@"<?xml version='1.0' encoding='UTF-8' ?>
<core:objects xmlns:core='http://www.springframework.net'>
<core:object id='test2' type='Spring.Objects.TestObject, Spring.Core.Tests'>
<core:property name='Sibling'>
<core:object type='Spring.Objects.TestObject, Spring.Core.Tests' />
</core:property>
</core:object>
</core:objects>
"));
TestObject test2 = (TestObject) of.GetObject("test2");
Assert.AreEqual(typeof(TestObject), test2.GetType());
Assert.IsNotNull(test2.Sibling);
}
finally
{
NamespaceParserRegistry.Reset();
}
}
}
}