removed HttpContext deps
further Spring/J syncs (introduced INamespaceParserResolver (just internal yet)) fixed ParserContext.ContainingObjectDefinition handling fixed SPRNET-1211
This commit is contained in:
@@ -17,6 +17,8 @@ Spring.Core
|
||||
<v:action ...>
|
||||
<v:validator ...>
|
||||
|
||||
2. XmlReaderContext constructor now requires an IObjectDefinitionFactory to be specified. Thus XmlReaderContext.ObjectDefinitionFactory
|
||||
is read only now.
|
||||
|
||||
Changes (1.1.2 to 1.2 RC1 or greater)
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ namespace Spring.Context.Support
|
||||
protected virtual void LoadObjectDefinitions(DefaultListableObjectFactory objectFactory)
|
||||
{
|
||||
//Create a new XmlObjectDefinitionReader for the given ObjectFactory
|
||||
XmlObjectDefinitionReader objectDefinitionReader = new XmlObjectDefinitionReader(objectFactory);
|
||||
XmlObjectDefinitionReader objectDefinitionReader = CreateXmlObjectDefinitionReader(objectFactory);
|
||||
|
||||
// Configure the bean definition reader with this context's
|
||||
// resource loading environment.
|
||||
@@ -236,6 +236,16 @@ namespace Spring.Context.Support
|
||||
// then proceed with actually loading the object definitions.
|
||||
InitObjectDefinitionReader(objectDefinitionReader);
|
||||
LoadObjectDefinitions(objectDefinitionReader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new reader instance for importing object definitions into the specified <paramref name="objectFactory"/>.
|
||||
/// </summary>
|
||||
/// <param name="objectFactory">the <see cref="DefaultListableObjectFactory"/> to be associated with the reader</param>
|
||||
/// <returns>a new <see cref="XmlObjectDefinitionReader"/> instance.</returns>
|
||||
protected virtual XmlObjectDefinitionReader CreateXmlObjectDefinitionReader(DefaultListableObjectFactory objectFactory)
|
||||
{
|
||||
return new XmlObjectDefinitionReader(objectFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -251,6 +251,16 @@ namespace Spring.Context.Support
|
||||
public void RegisterAlias(string name, string theAlias)
|
||||
{
|
||||
objectFactory.RegisterAlias(name, theAlias);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given object name is already in use within this factory,
|
||||
/// i.e. whether there is a local object or alias registered under this name or
|
||||
/// an inner object created with this name.
|
||||
/// </summary>
|
||||
public bool IsObjectNameInUse(string objectName)
|
||||
{
|
||||
return objectFactory.IsObjectNameInUse(objectName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -232,7 +232,7 @@ namespace Spring.Objects.Factory.Support
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
|
||||
log.Debug("Loaded " + loadCount + " object definitions from location [" + location + "]");
|
||||
}
|
||||
return loadCount;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,12 @@ namespace Spring.Objects.Factory.Support
|
||||
/// <author>Rick Evans (.NET)</author>
|
||||
public interface IObjectDefinitionRegistry
|
||||
{
|
||||
/// <summary>
|
||||
/// Determine whether the given object name is already in use within this registry,
|
||||
/// i.e. whether there is a local object or alias registered under this name.
|
||||
/// </summary>
|
||||
bool IsObjectNameInUse(string objectName);
|
||||
|
||||
/// <summary>
|
||||
/// Return the number of objects defined in the registry.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation of the <see cref="INamespaceParserResolver"/> interface.
|
||||
/// Resolves namespace URIs to implementation types based on mappings.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <seealso cref="INamespaceParser"/>
|
||||
/// <seealso cref="DefaultObjectDefinitionDocumentReader"/>
|
||||
internal class DefaultNamespaceHandlerResolver : INamespaceParserResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolve the namespace URI and return the corresponding <see cref="INamespaceParser"/>
|
||||
/// implementation.
|
||||
/// </summary>
|
||||
/// <param name="namespaceUri">the namespace URI to get the matching parser for.</param>
|
||||
/// <returns>the matching parser or <c>null</c></returns>
|
||||
public INamespaceParser Resolve(string namespaceUri)
|
||||
{
|
||||
return NamespaceParserRegistry.GetParser(namespaceUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,8 +352,7 @@ namespace Spring.Objects.Factory.Xml
|
||||
/// <returns>a new <see cref="ObjectDefinitionParserHelper"/> instance</returns>
|
||||
protected virtual ObjectDefinitionParserHelper CreateHelper(XmlReaderContext readerContext, XmlElement root)
|
||||
{
|
||||
ObjectDefinitionParserHelper helper = new ObjectDefinitionParserHelper(readerContext);
|
||||
helper.InitDefaults(root);
|
||||
ObjectDefinitionParserHelper helper = new ObjectDefinitionParserHelper(readerContext, root);
|
||||
return helper;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Strategy interface for parsing XML object definitions.
|
||||
/// Strategy interface for parsing XML object definitions. Equivalent to Spring/Java's <c>NamespaceHandler</c> interface.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
@@ -38,7 +38,7 @@ namespace Spring.Objects.Factory.Xml
|
||||
/// for actually parsing a DOM document or
|
||||
/// <see cref="System.Xml.XmlElement"/> fragment.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// </remarks>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Rick Evans (.NET)</author>
|
||||
/// <author>Sandu Turcan (.NET)</author>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// Used by <see cref="DefaultObjectDefinitionDocumentReader"/> to locate
|
||||
/// <see cref="INamespaceParser"/> implementations for a particular namespace URI.
|
||||
/// </summary>
|
||||
/// <remarks>TODO (EE): clarify naming of INamespaceParser (SPR/NET) vs. INamespaceHandler (SPR/Java), thus internal for now</remarks>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <seealso cref="XmlObjectDefinitionReader.NamespaceParserResolver"/>
|
||||
/// <seealso cref="XmlObjectDefinitionReader.CreateDefaultNamespaceParserResolver"/>
|
||||
/// <seealso cref="XmlReaderContext.NamespaceParserResolver"/>
|
||||
internal interface INamespaceParserResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// Lookup a <see cref="INamespaceParser"/> for the given namespace URI.
|
||||
/// </summary>
|
||||
/// <param name="namespaceUri">the namespace URI</param>
|
||||
/// <returns>the located namespace handler or <c>null</c></returns>
|
||||
INamespaceParser Resolve(string namespaceUri);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#region License
|
||||
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2007 the original author or authors.
|
||||
*
|
||||
@@ -14,163 +14,182 @@
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
using Common.Logging;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// Stateful class used to parse XML object definitions.
|
||||
/// </summary>
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using Common.Logging;
|
||||
using Spring.Collections;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// Stateful class used to parse XML object definitions.
|
||||
/// </summary>
|
||||
/// <remarks>Not all parsing code has been refactored into this class. See
|
||||
/// BeanDefinitionParserDelegate in Java for how this class should evolve.</remarks>
|
||||
/// <author>Rob Harrop</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
public class ObjectDefinitionParserHelper
|
||||
{
|
||||
|
||||
#region Fields
|
||||
/// <summary>
|
||||
/// The shared <see cref="Common.Logging.ILog"/> instance for this class (and derived classes).
|
||||
/// </summary>
|
||||
protected static readonly ILog log =
|
||||
LogManager.GetLogger(typeof(ObjectDefinitionParserHelper));
|
||||
|
||||
private DocumentDefaultsDefinition defaults;
|
||||
|
||||
private XmlReaderContext readerContext;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ObjectDefinitionParserHelper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="readerContext">The reader context.</param>
|
||||
public ObjectDefinitionParserHelper(XmlReaderContext readerContext)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(readerContext, "readerContext");
|
||||
this.readerContext = readerContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the defaults definition object, or <code>null</code> if the
|
||||
/// default have not yet been initialized.
|
||||
/// </summary>
|
||||
/// <value>The defaults.</value>
|
||||
public DocumentDefaultsDefinition Defaults
|
||||
{
|
||||
get { return defaults; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reader context.
|
||||
/// </summary>
|
||||
/// <value>The reader context.</value>
|
||||
public XmlReaderContext ReaderContext
|
||||
{
|
||||
get { return readerContext; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default lazy-init, dependency check, and autowire settings.
|
||||
/// </summary>
|
||||
/// <param name="root">The root element</param>
|
||||
public void InitDefaults(XmlElement root)
|
||||
{
|
||||
DocumentDefaultsDefinition ddd = new DocumentDefaultsDefinition();
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug("Loading object definitions...");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
ddd.LazyInit = GetAttributeValue(root, ObjectDefinitionConstants.DefaultLazyInitAttribute);
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug(
|
||||
string.Format(
|
||||
"Default lazy init '{0}'.",
|
||||
ddd.LazyInit));
|
||||
}
|
||||
|
||||
/// BeanDefinitionParserDelegate in Java for how this class should evolve.</remarks>
|
||||
/// <author>Rob Harrop</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
public class ObjectDefinitionParserHelper
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// The shared <see cref="Common.Logging.ILog"/> instance for this class (and derived classes).
|
||||
/// </summary>
|
||||
protected readonly ILog log;
|
||||
|
||||
private DocumentDefaultsDefinition defaults;
|
||||
|
||||
private readonly XmlReaderContext readerContext;
|
||||
|
||||
private readonly ObjectsNamespaceParser objectsNamespaceParser;
|
||||
|
||||
private readonly ISet usedNames = new HashedSet();
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ObjectDefinitionParserHelper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="readerContext">The reader context.</param>
|
||||
public ObjectDefinitionParserHelper(XmlReaderContext readerContext)
|
||||
:this(readerContext, null)
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ObjectDefinitionParserHelper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="readerContext">The reader context.</param>
|
||||
/// <param name="root">The root element of the definition document to parse</param>
|
||||
public ObjectDefinitionParserHelper(XmlReaderContext readerContext, XmlElement root)
|
||||
{
|
||||
log = LogManager.GetLogger(this.GetType());
|
||||
this.readerContext = readerContext;
|
||||
this.objectsNamespaceParser = (ObjectsNamespaceParser) readerContext.NamespaceParserResolver.Resolve(ObjectsNamespaceParser.Namespace);
|
||||
if (root != null)
|
||||
{
|
||||
InitDefaults(root);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the defaults definition object, or <code>null</code> if the
|
||||
/// default have not yet been initialized.
|
||||
/// </summary>
|
||||
/// <value>The defaults.</value>
|
||||
public DocumentDefaultsDefinition Defaults
|
||||
{
|
||||
get { return defaults; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reader context.
|
||||
/// </summary>
|
||||
/// <value>The reader context.</value>
|
||||
public XmlReaderContext ReaderContext
|
||||
{
|
||||
get { return readerContext; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default lazy-init, dependency check, and autowire settings.
|
||||
/// </summary>
|
||||
/// <param name="root">The root element</param>
|
||||
public void InitDefaults(XmlElement root)
|
||||
{
|
||||
DocumentDefaultsDefinition ddd = new DocumentDefaultsDefinition();
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug("Loading object definitions...");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
ddd.DependencyCheck = GetAttributeValue(root, ObjectDefinitionConstants.DefaultDependencyCheckAttribute);
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug(
|
||||
string.Format(
|
||||
"Default dependency check '{0}'.",
|
||||
ddd.DependencyCheck));
|
||||
}
|
||||
|
||||
ddd.LazyInit = GetAttributeValue(root, ObjectDefinitionConstants.DefaultLazyInitAttribute);
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug(
|
||||
string.Format(
|
||||
"Default lazy init '{0}'.",
|
||||
ddd.LazyInit));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
ddd.Autowire = GetAttributeValue(root, ObjectDefinitionConstants.DefaultAutowireAttribute);
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug(
|
||||
string.Format(
|
||||
"Default autowire '{0}'.",
|
||||
ddd.Autowire));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
defaults = ddd;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the Spring object namespace is equal to the the specified namespace URI.
|
||||
/// </summary>
|
||||
/// <param name="namespaceUri">The namespace URI.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if is the default Spring namespace; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsDefaultNamespace(string namespaceUri)
|
||||
{
|
||||
return
|
||||
(!StringUtils.HasLength(namespaceUri) || ObjectsNamespaceParser.Namespace.Equals(namespaceUri));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Decorates the object definition if required.
|
||||
/// </summary>
|
||||
/// <param name="element">The element.</param>
|
||||
/// <param name="holder">The holder.</param>
|
||||
/// <returns></returns>
|
||||
public ObjectDefinitionHolder DecorateObjectDefinitionIfRequired(XmlElement element, ObjectDefinitionHolder holder)
|
||||
{
|
||||
|
||||
//TODO decoration processing.
|
||||
return holder;
|
||||
ddd.DependencyCheck = GetAttributeValue(root, ObjectDefinitionConstants.DefaultDependencyCheckAttribute);
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug(
|
||||
string.Format(
|
||||
"Default dependency check '{0}'.",
|
||||
ddd.DependencyCheck));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
ddd.Autowire = GetAttributeValue(root, ObjectDefinitionConstants.DefaultAutowireAttribute);
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug(
|
||||
string.Format(
|
||||
"Default autowire '{0}'.",
|
||||
ddd.Autowire));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
defaults = ddd;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the Spring object namespace is equal to the the specified namespace URI.
|
||||
/// </summary>
|
||||
/// <param name="namespaceUri">The namespace URI.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if is the default Spring namespace; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsDefaultNamespace(string namespaceUri)
|
||||
{
|
||||
return
|
||||
(!StringUtils.HasLength(namespaceUri) || ObjectsNamespaceParser.Namespace.Equals(namespaceUri));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Decorates the object definition if required.
|
||||
/// </summary>
|
||||
/// <param name="element">The element.</param>
|
||||
/// <param name="holder">The holder.</param>
|
||||
/// <returns></returns>
|
||||
public ObjectDefinitionHolder DecorateObjectDefinitionIfRequired(XmlElement element, ObjectDefinitionHolder holder)
|
||||
{
|
||||
|
||||
//TODO decoration processing.
|
||||
return holder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -194,7 +213,7 @@ namespace Spring.Objects.Factory.Xml
|
||||
/// as the canonical name, registering all others as aliases.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public ObjectDefinitionHolder ParseObjectDefinitionElement(XmlElement element)
|
||||
public ObjectDefinitionHolder ParseObjectDefinitionElement(XmlElement element)
|
||||
{
|
||||
return ParseObjectDefinitionElement(element, null);
|
||||
}
|
||||
@@ -221,11 +240,8 @@ namespace Spring.Objects.Factory.Xml
|
||||
/// as the canonical name, registering all others as aliases.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public ObjectDefinitionHolder ParseObjectDefinitionElement(XmlElement element, IObjectDefinition containingDefinition)
|
||||
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();
|
||||
@@ -238,13 +254,26 @@ namespace Spring.Objects.Factory.Xml
|
||||
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);
|
||||
if (aliases.Count > 0)
|
||||
{
|
||||
objectName = (string) 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(",", (string[]) aliases.ToArray(typeof(string)))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
objectName = PostProcessObjectNameAndAliases(objectName, aliases, element, containingDefinition);
|
||||
|
||||
if (containingDefinition == null)
|
||||
{
|
||||
CheckNameUniqueness(objectName, aliases, element);
|
||||
}
|
||||
|
||||
ParserContext parserContext = new ParserContext(this, containingDefinition);
|
||||
IConfigurableObjectDefinition definition = parser.ParseObjectDefinitionElement(element, objectName, parserContext);
|
||||
IConfigurableObjectDefinition definition = objectsNamespaceParser.ParseObjectDefinitionElement(element, objectName, parserContext);
|
||||
if (definition != null)
|
||||
{
|
||||
if (StringUtils.IsNullOrEmpty(objectName))
|
||||
@@ -252,11 +281,20 @@ namespace Spring.Objects.Factory.Xml
|
||||
if (containingDefinition != null)
|
||||
{
|
||||
objectName =
|
||||
ObjectDefinitionReaderUtils.GenerateObjectName(definition, parserContext.Registry, true);
|
||||
ObjectDefinitionReaderUtils.GenerateObjectName(definition, readerContext.Registry, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
objectName = ObjectDefinitionReaderUtils.GenerateObjectName(definition, parserContext.Registry);
|
||||
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
|
||||
@@ -264,17 +302,76 @@ namespace Spring.Objects.Factory.Xml
|
||||
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));
|
||||
"Neither XML '{0}' nor '{1}' specified - using generated object name [{2}]",
|
||||
ObjectDefinitionConstants.IdAttribute, ObjectDefinitionConstants.NameAttribute, objectName));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
string[] aliasesArray = (string[])aliases.ToArray(typeof(string));
|
||||
return new ObjectDefinitionHolder(definition, objectName, aliasesArray);
|
||||
return CreateObjectDefinitionHolder(element, definition, objectName, aliasesArray);
|
||||
}
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an <see cref="ObjectDefinitionHolder"/> instance from the given <paramref name="definition"/> and <paramref name="objectName"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method may be used as a last resort to post-process an object definition before it gets added to the registry.
|
||||
/// </remarks>
|
||||
protected virtual ObjectDefinitionHolder CreateObjectDefinitionHolder(XmlElement element, IConfigurableObjectDefinition definition, string objectName, string[] aliasesArray)
|
||||
{
|
||||
return new ObjectDefinitionHolder(definition, objectName, aliasesArray);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows deriving classes to post process the name and aliases for the current element. By default
|
||||
/// does nothing and returns the unmodified <paramref name="objectName"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The <paramref name="aliases"/> list passed in may be modified by an implementation of this method to reflect special needs.
|
||||
/// </remarks>
|
||||
/// <param name="objectName">the object name obtained by the default algorithm from 'id' and 'name' attributes so far.</param>
|
||||
/// <param name="aliases">the object aliases obtained by the default algorithm from 'name' attribute so far.</param>
|
||||
/// <param name="element">the currently processed element.</param>
|
||||
/// <param name="containingDefinition">the containing object definition, may be <c>null</c></param>
|
||||
/// <returns>the new object name to be used.</returns>
|
||||
protected virtual string PostProcessObjectNameAndAliases(string objectName, ArrayList aliases, XmlElement element, IObjectDefinition containingDefinition)
|
||||
{
|
||||
if (!StringUtils.HasText(objectName) && aliases.Count == 0)
|
||||
{
|
||||
string result = this.objectsNamespaceParser.CalculateId(element, aliases);
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return objectName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate that the specified object name and aliases have not been used already.
|
||||
/// </summary>
|
||||
protected virtual void CheckNameUniqueness(string objectName, ArrayList aliases, XmlElement element)
|
||||
{
|
||||
string foundName = null;
|
||||
|
||||
if (StringUtils.HasText(objectName) && this.usedNames.Contains(objectName))
|
||||
{
|
||||
foundName = objectName;
|
||||
}
|
||||
if (foundName == null)
|
||||
{
|
||||
foundName = (string) CollectionUtils.FindFirstMatch(this.usedNames, aliases);
|
||||
}
|
||||
if(foundName != null)
|
||||
{
|
||||
Error("Object name '" + foundName + "' is already used in this file", element);
|
||||
}
|
||||
|
||||
this.usedNames.Add(objectName);
|
||||
this.usedNames.AddAll(aliases);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -321,37 +418,37 @@ namespace Spring.Objects.Factory.Xml
|
||||
return StringUtils.Split(
|
||||
value, ObjectDefinitionConstants.ObjectNameDelimiters, true, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the string represents a 'true' boolean value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if is 'true' string value; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsTrueStringValue(string value)
|
||||
{
|
||||
return ObjectDefinitionConstants.TrueValue.Equals(value.ToLower(CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience method to create a builder for a root object definition.
|
||||
/// </summary>
|
||||
/// <param name="objectTypeName">Name of the object type.</param>
|
||||
/// <returns>A builder for a root object definition.</returns>
|
||||
public ObjectDefinitionBuilder CreateRootObjectDefinitionBuilder(string objectTypeName)
|
||||
{
|
||||
return ObjectDefinitionBuilder.RootObjectDefinition(this.readerContext.ObjectDefinitionFactory, objectTypeName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience method to create a builder for a root object definition.
|
||||
/// </summary>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <returns>a builder for a root object definition</returns>
|
||||
public ObjectDefinitionBuilder CreateRootObjectDefinitionBuilder(Type objectType)
|
||||
{
|
||||
return ObjectDefinitionBuilder.RootObjectDefinition(this.readerContext.ObjectDefinitionFactory, objectType);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the string represents a 'true' boolean value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if is 'true' string value; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsTrueStringValue(string value)
|
||||
{
|
||||
return ObjectDefinitionConstants.TrueValue.Equals(value.ToLower(CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience method to create a builder for a root object definition.
|
||||
/// </summary>
|
||||
/// <param name="objectTypeName">Name of the object type.</param>
|
||||
/// <returns>A builder for a root object definition.</returns>
|
||||
public ObjectDefinitionBuilder CreateRootObjectDefinitionBuilder(string objectTypeName)
|
||||
{
|
||||
return ObjectDefinitionBuilder.RootObjectDefinition(this.readerContext.ObjectDefinitionFactory, objectTypeName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience method to create a builder for a root object definition.
|
||||
/// </summary>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <returns>a builder for a root object definition</returns>
|
||||
public ObjectDefinitionBuilder CreateRootObjectDefinitionBuilder(Type objectType)
|
||||
{
|
||||
return ObjectDefinitionBuilder.RootObjectDefinition(this.readerContext.ObjectDefinitionFactory, objectType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -385,14 +482,14 @@ namespace Spring.Objects.Factory.Xml
|
||||
return element.GetAttribute(attributeName);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Report a parser error.
|
||||
/// </summary>
|
||||
protected virtual void Error(string message, XmlElement element)
|
||||
protected virtual void Error(string message, XmlElement element)
|
||||
{
|
||||
this.ReaderContext.ReportFatalException(element, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,54 +384,7 @@ namespace Spring.Objects.Factory.Xml
|
||||
[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);
|
||||
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 = CalculateId(element, aliases);
|
||||
}
|
||||
|
||||
|
||||
IConfigurableObjectDefinition definition = ParseObjectDefinitionElement(element, objectName, parserContext);
|
||||
if (definition != null)
|
||||
{
|
||||
if (StringUtils.IsNullOrEmpty(objectName))
|
||||
{
|
||||
if (nestedDefinition)
|
||||
{
|
||||
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;
|
||||
return parserContext.ParserHelper.ParseObjectDefinitionElement(element, parserContext.ContainingObjectDefinition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -453,32 +406,10 @@ namespace Spring.Objects.Factory.Xml
|
||||
/// <returns>
|
||||
/// A calculated object definition id.
|
||||
/// </returns>
|
||||
[Obsolete("This method will be dropped, override ObjectDefinitionParserHelper.PostProcessObjectNameAndAliases instead", false)]
|
||||
protected internal virtual string CalculateId(XmlElement element, ArrayList aliases)
|
||||
{
|
||||
string id = null;
|
||||
if (aliases.Count > 0)
|
||||
{
|
||||
string firstAlias = aliases[0] as string;
|
||||
aliases.RemoveAt(0);
|
||||
id = firstAlias;
|
||||
}
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
foreach (string alias in aliases)
|
||||
{
|
||||
buffer.Append(alias).Append(",");
|
||||
}
|
||||
log.Debug(string.Format("No XML 'id' specified - using '{0}' as the id and '{1}' as aliases.",
|
||||
id, buffer.ToString()));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
return id;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -514,12 +445,12 @@ namespace Spring.Objects.Factory.Xml
|
||||
= parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition(
|
||||
typeName, parent, parserContext.ReaderContext.Reader.Domain);
|
||||
|
||||
ParserContext childParserContext = new ParserContext(parserContext.ParserHelper, od);
|
||||
|
||||
MutablePropertyValues pvs = ParsePropertyElements(id, element, parserContext);
|
||||
ConstructorArgumentValues arguments
|
||||
= ParseConstructorArgSubElements(id, element, parserContext);
|
||||
EventValues events = ParseEventHandlerSubElements(id, element, parserContext);
|
||||
MethodOverrides methodOverrides = ParseMethodOverrideSubElements(id, element, parserContext);
|
||||
MutablePropertyValues pvs = ParsePropertyElements(id, element, childParserContext);
|
||||
ConstructorArgumentValues arguments = ParseConstructorArgSubElements(id, element, childParserContext);
|
||||
EventValues events = ParseEventHandlerSubElements(id, element, childParserContext);
|
||||
MethodOverrides methodOverrides = ParseMethodOverrideSubElements(id, element, childParserContext);
|
||||
|
||||
bool isPage = StringUtils.HasText(typeName) && typeName != null && typeName.ToLower().EndsWith(".aspx");
|
||||
if (!isPage)
|
||||
@@ -540,13 +471,13 @@ namespace Spring.Objects.Factory.Xml
|
||||
string dependencyCheck = GetAttributeValue(element, ObjectDefinitionConstants.DependencyCheckAttribute);
|
||||
if (ObjectDefinitionConstants.DefaultValue.Equals(dependencyCheck))
|
||||
{
|
||||
dependencyCheck = parserContext.ParserHelper.Defaults.DependencyCheck;
|
||||
dependencyCheck = childParserContext.ParserHelper.Defaults.DependencyCheck;
|
||||
}
|
||||
od.DependencyCheck = GetDependencyCheck(dependencyCheck);
|
||||
string autowire = GetAttributeValue(element, ObjectDefinitionConstants.AutowireAttribute);
|
||||
if (ObjectDefinitionConstants.DefaultValue.Equals(autowire))
|
||||
{
|
||||
autowire = parserContext.ParserHelper.Defaults.Autowire;
|
||||
autowire = childParserContext.ParserHelper.Defaults.Autowire;
|
||||
}
|
||||
od.AutowireMode = GetAutowireMode(autowire);
|
||||
string initMethodName = GetAttributeValue(element, ObjectDefinitionConstants.InitMethodAttribute);
|
||||
@@ -567,12 +498,12 @@ namespace Spring.Objects.Factory.Xml
|
||||
if (ObjectDefinitionConstants.DefaultValue.Equals(lazyInit) && od.IsSingleton)
|
||||
{
|
||||
// just apply default to singletons, as lazy-init has no meaning for prototypes...
|
||||
lazyInit = parserContext.ParserHelper.Defaults.LazyInit;
|
||||
lazyInit = childParserContext.ParserHelper.Defaults.LazyInit;
|
||||
}
|
||||
od.IsLazyInit = IsTrueStringValue(lazyInit);
|
||||
|
||||
// try to get the line info
|
||||
string resourceDescription = parserContext.ParserHelper.ReaderContext.Resource.Description;
|
||||
string resourceDescription = childParserContext.ParserHelper.ReaderContext.Resource.Description;
|
||||
if (StringUtils.HasText(resourceDescription))
|
||||
{
|
||||
int line = ConfigurationUtils.GetLineNumber(element);
|
||||
@@ -940,7 +871,7 @@ namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
case ObjectDefinitionConstants.ObjectElement:
|
||||
{
|
||||
return ParseObjectDefinitionElement(element, parserContext, true);
|
||||
return parserContext.ParserHelper.ParseObjectDefinitionElement(element, parserContext.ContainingObjectDefinition);
|
||||
}
|
||||
case ObjectDefinitionConstants.RefElement:
|
||||
{
|
||||
@@ -986,35 +917,38 @@ namespace Spring.Objects.Factory.Xml
|
||||
"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,
|
||||
"Unknown subelement of <property>: <" + element.Name + ">");
|
||||
return parserContext.ParserHelper.ParseCustomElement(element, parserContext.ContainingObjectDefinition);
|
||||
|
||||
// parserContext.ParserHelper.parse
|
||||
// // it may match another Parser
|
||||
// INamespaceParser otherParser = parserContext. (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,
|
||||
// "Unknown subelement of <property>: <" + element.Name + ">");
|
||||
}
|
||||
|
||||
private static INamespaceParser GetParser(string nspace)
|
||||
{
|
||||
// finds the configuration parser for the given namespace
|
||||
try
|
||||
{
|
||||
return NamespaceParserRegistry.GetParser(nspace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// The parser for the given namespace is not found
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// private static INamespaceParser GetParser(string nspace)
|
||||
// {
|
||||
// // finds the configuration parser for the given namespace
|
||||
// try
|
||||
// {
|
||||
// return NamespaceParserRegistry.GetParser(nspace);
|
||||
// }
|
||||
// catch (Exception)
|
||||
// {
|
||||
// // The parser for the given namespace is not found
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
private static object ParseIdReference(XmlElement element, ObjectDefinitionParserHelper parserHelper, string name)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#region License
|
||||
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
@@ -14,56 +14,57 @@
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using Spring.Core.IO;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// Object definition reader for Spring's default XML object definition format.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Typically applied to a
|
||||
/// <see cref="Spring.Objects.Factory.Support.DefaultListableObjectFactory"/> instance.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This class registers each object definition with the given object factory superclass,
|
||||
/// and relies on the latter's implementation of the
|
||||
/// <see cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry"/> interface.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// It supports singletons, prototypes, and references to either of these kinds of object.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Rick Evans (.NET)</author>
|
||||
public class XmlObjectDefinitionReader : AbstractObjectDefinitionReader
|
||||
{
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using Spring.Core.IO;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// Object definition reader for Spring's default XML object definition format.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Typically applied to a
|
||||
/// <see cref="Spring.Objects.Factory.Support.DefaultListableObjectFactory"/> instance.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This class registers each object definition with the given object factory superclass,
|
||||
/// and relies on the latter's implementation of the
|
||||
/// <see cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry"/> interface.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// It supports singletons, prototypes, and references to either of these kinds of object.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Rick Evans (.NET)</author>
|
||||
public class XmlObjectDefinitionReader : AbstractObjectDefinitionReader
|
||||
{
|
||||
#region Utility Classes
|
||||
|
||||
/// <summary>
|
||||
/// For retrying the parse process
|
||||
/// </summary>
|
||||
private class RetryParseException : Exception
|
||||
/// </summary>
|
||||
private class RetryParseException : Exception
|
||||
{
|
||||
public RetryParseException()
|
||||
{}
|
||||
}
|
||||
|
||||
{ }
|
||||
}
|
||||
|
||||
#if !NET_2_0
|
||||
private class ValidationEventHandlerWrapper
|
||||
{
|
||||
@@ -85,208 +86,266 @@ namespace Spring.Objects.Factory.Xml
|
||||
_owner.HandleValidation(_sender,args);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
[NonSerialized]
|
||||
private XmlResolver resolver;
|
||||
|
||||
private Type documentReaderType = typeof (DefaultObjectDefinitionDocumentReader);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Objects.Factory.Xml.XmlObjectDefinitionReader"/> class.
|
||||
/// </summary>
|
||||
/// <param name="registry">
|
||||
/// The <see cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry"/>
|
||||
/// instance that this reader works on.
|
||||
/// </param>
|
||||
public XmlObjectDefinitionReader(IObjectDefinitionRegistry registry)
|
||||
: this(registry, new XmlUrlResolver())
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Objects.Factory.Xml.XmlObjectDefinitionReader"/> class.
|
||||
/// </summary>
|
||||
/// <param name="registry">
|
||||
/// The <see cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry"/>
|
||||
/// instance that this reader works on.
|
||||
/// </param>
|
||||
/// <param name="resolver">
|
||||
/// The <see cref="System.Xml.XmlResolver"/>to be used for parsing.
|
||||
/// </param>
|
||||
public XmlObjectDefinitionReader(IObjectDefinitionRegistry registry, XmlResolver resolver) : base(registry)
|
||||
{
|
||||
Resolver = resolver;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="System.Xml.XmlResolver"/>to be used for parsing.
|
||||
/// </summary>
|
||||
public XmlResolver Resolver
|
||||
{
|
||||
get { return resolver; }
|
||||
set { resolver = value; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the IObjectDefinitionDocumentReader implementation to use, responsible for
|
||||
/// the actual reading of the XML object definition document.stype of the document reader.
|
||||
/// </summary>
|
||||
/// <value>The type of the document reader.</value>
|
||||
public Type DocumentReaderType
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value == null || !typeof(IObjectDefinitionDocumentReader).IsAssignableFrom(value))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"DocumentReaderType must be an implementation of the IObjectDefinitionReader interface.");
|
||||
}
|
||||
documentReaderType = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Load object definitions from the supplied XML <paramref name="resource"/>.
|
||||
/// </summary>
|
||||
/// <param name="resource">
|
||||
/// The XML resource for the object definitions that are to be loaded.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The number of object definitions that were loaded.
|
||||
/// </returns>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In the case of loading or parsing errors.
|
||||
/// </exception>
|
||||
public override int LoadObjectDefinitions(IResource resource)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException
|
||||
("Resource cannot be null: expected an XML resource.");
|
||||
}
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug("Loading XML object definitions from " + resource);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
try
|
||||
{
|
||||
Stream stream = resource.InputStream;
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException(
|
||||
"InputStream is null from Resource = [" + resource + "]");
|
||||
}
|
||||
try
|
||||
{
|
||||
return DoLoadObjectDefinitions(stream, resource);
|
||||
}
|
||||
finally
|
||||
{
|
||||
#region Close stream
|
||||
try
|
||||
{
|
||||
stream.Close();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsWarnEnabled)
|
||||
{
|
||||
log.Warn("Could not close stream.", ex);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException(
|
||||
"IOException parsing XML document from " + resource.Description, ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actually load object definitions from the specified XML file.
|
||||
/// </summary>
|
||||
/// <param name="stream">The input stream to read from.</param>
|
||||
/// <param name="resource">The resource for the XML data.</param>
|
||||
/// <returns></returns>
|
||||
protected virtual int DoLoadObjectDefinitions(Stream stream, IResource resource)
|
||||
{
|
||||
try
|
||||
{
|
||||
// create local copy of data
|
||||
byte[] xmlData = IOUtils.ToByteArray( stream );
|
||||
|
||||
#region Fields
|
||||
|
||||
[NonSerialized]
|
||||
private XmlResolver resolver;
|
||||
|
||||
private Type documentReaderType;
|
||||
private INamespaceParserResolver namespaceParserResolver;
|
||||
private IObjectDefinitionFactory objectDefinitionFactory;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Objects.Factory.Xml.XmlObjectDefinitionReader"/> class.
|
||||
/// </summary>
|
||||
/// <param name="registry">
|
||||
/// The <see cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry"/>
|
||||
/// instance that this reader works on.
|
||||
/// </param>
|
||||
public XmlObjectDefinitionReader(IObjectDefinitionRegistry registry)
|
||||
: this(registry, new XmlUrlResolver())
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Objects.Factory.Xml.XmlObjectDefinitionReader"/> class.
|
||||
/// </summary>
|
||||
/// <param name="registry">
|
||||
/// The <see cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry"/>
|
||||
/// instance that this reader works on.
|
||||
/// </param>
|
||||
/// <param name="resolver">
|
||||
/// The <see cref="System.Xml.XmlResolver"/>to be used for parsing.
|
||||
/// </param>
|
||||
public XmlObjectDefinitionReader(IObjectDefinitionRegistry registry, XmlResolver resolver)
|
||||
: this(registry, resolver, new DefaultObjectDefinitionFactory())
|
||||
{
|
||||
Resolver = resolver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Objects.Factory.Xml.XmlObjectDefinitionReader"/> class.
|
||||
/// </summary>
|
||||
/// <param name="registry">
|
||||
/// The <see cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry"/>
|
||||
/// instance that this reader works on.
|
||||
/// </param>
|
||||
/// <param name="resolver">
|
||||
/// The <see cref="System.Xml.XmlResolver"/>to be used for parsing.
|
||||
/// </param>
|
||||
/// <param name="objectDefinitionFactory">the <see cref="IObjectDefinitionFactory"/> to use for creating new <see cref="IObjectDefinition"/>s</param>
|
||||
protected XmlObjectDefinitionReader(IObjectDefinitionRegistry registry, XmlResolver resolver, IObjectDefinitionFactory objectDefinitionFactory)
|
||||
: base(registry)
|
||||
{
|
||||
Resolver = resolver;
|
||||
this.objectDefinitionFactory = objectDefinitionFactory;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="System.Xml.XmlResolver"/>to be used for parsing.
|
||||
/// </summary>
|
||||
public XmlResolver Resolver
|
||||
{
|
||||
get { return resolver; }
|
||||
set { resolver = value; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the IObjectDefinitionDocumentReader implementation to use, responsible for
|
||||
/// the actual reading of the XML object definition document.stype of the document reader.
|
||||
/// </summary>
|
||||
/// <value>The type of the document reader.</value>
|
||||
public Type DocumentReaderType
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value == null || !typeof(IObjectDefinitionDocumentReader).IsAssignableFrom(value))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"DocumentReaderType must be an implementation of the IObjectDefinitionReader interface.");
|
||||
}
|
||||
documentReaderType = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify a <see cref="INamespaceParserResolver"/> to use. If none is specified a default
|
||||
/// instance will be created by <see cref="CreateDefaultNamespaceParserResolver"/>
|
||||
/// </summary>
|
||||
internal INamespaceParserResolver NamespaceParserResolver
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.namespaceParserResolver == null)
|
||||
{
|
||||
this.namespaceParserResolver = CreateDefaultNamespaceParserResolver();
|
||||
}
|
||||
return this.namespaceParserResolver;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (this.namespaceParserResolver != null)
|
||||
{
|
||||
throw new InvalidOperationException("NamespaceParserResolver is already set");
|
||||
}
|
||||
this.namespaceParserResolver = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify a <see cref="IObjectDefinitionFactory"/> for creating instances of <see cref="AbstractObjectDefinition"/>.
|
||||
/// </summary>
|
||||
protected IObjectDefinitionFactory ObjectDefinitionFactory
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.objectDefinitionFactory;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Load object definitions from the supplied XML <paramref name="resource"/>.
|
||||
/// </summary>
|
||||
/// <param name="resource">
|
||||
/// The XML resource for the object definitions that are to be loaded.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The number of object definitions that were loaded.
|
||||
/// </returns>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In the case of loading or parsing errors.
|
||||
/// </exception>
|
||||
public override int LoadObjectDefinitions(IResource resource)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException
|
||||
("Resource cannot be null: expected an XML resource.");
|
||||
}
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug("Loading XML object definitions from " + resource);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
try
|
||||
{
|
||||
Stream stream = resource.InputStream;
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException(
|
||||
"InputStream is null from Resource = [" + resource + "]");
|
||||
}
|
||||
try
|
||||
{
|
||||
return DoLoadObjectDefinitions(stream, resource);
|
||||
}
|
||||
finally
|
||||
{
|
||||
#region Close stream
|
||||
try
|
||||
{
|
||||
stream.Close();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsWarnEnabled)
|
||||
{
|
||||
log.Warn("Could not close stream.", ex);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException(
|
||||
"IOException parsing XML document from " + resource.Description, ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actually load object definitions from the specified XML file.
|
||||
/// </summary>
|
||||
/// <param name="stream">The input stream to read from.</param>
|
||||
/// <param name="resource">The resource for the XML data.</param>
|
||||
/// <returns></returns>
|
||||
protected virtual int DoLoadObjectDefinitions(Stream stream, IResource resource)
|
||||
{
|
||||
try
|
||||
{
|
||||
// create local copy of data
|
||||
byte[] xmlData = IOUtils.ToByteArray(stream);
|
||||
|
||||
XmlDocument doc;
|
||||
// loop until no unregistered, wellknown namespaces left
|
||||
while(true)
|
||||
while (true)
|
||||
{
|
||||
XmlReader reader = null;
|
||||
try
|
||||
{
|
||||
MemoryStream xmlDataStream = new MemoryStream(xmlData);
|
||||
reader = CreateValidatingReader(xmlDataStream);
|
||||
doc = new ConfigXmlDocument();
|
||||
doc.Load(reader);
|
||||
break;
|
||||
reader = CreateValidatingReader(xmlDataStream);
|
||||
doc = new ConfigXmlDocument();
|
||||
doc.Load(reader);
|
||||
break;
|
||||
}
|
||||
catch(RetryParseException)
|
||||
catch (RetryParseException)
|
||||
{
|
||||
if (reader != null) reader.Close();
|
||||
if (reader != null)
|
||||
reader.Close();
|
||||
}
|
||||
}
|
||||
return RegisterObjectDefinitions(doc, resource);
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException(resource.Description,
|
||||
"Line " + ex.LineNumber + " in XML document from " +
|
||||
resource + " is not well formed. " + ex.Message, ex);
|
||||
}
|
||||
catch (XmlSchemaException ex)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException(resource.Description,
|
||||
"Line " + ex.LineNumber + " in XML document from " +
|
||||
resource + " violates the schema. " + ex.Message, ex);
|
||||
}
|
||||
catch(ObjectDefinitionStoreException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException("Unexpected exception parsing XML document from " + resource.Description + "Inner exception message= " + ex.Message, ex);
|
||||
}
|
||||
return RegisterObjectDefinitions(doc, resource);
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException(resource.Description,
|
||||
"Line " + ex.LineNumber + " in XML document from " +
|
||||
resource + " is not well formed. " + ex.Message, ex);
|
||||
}
|
||||
catch (XmlSchemaException ex)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException(resource.Description,
|
||||
"Line " + ex.LineNumber + " in XML document from " +
|
||||
resource + " violates the schema. " + ex.Message, ex);
|
||||
}
|
||||
catch (ObjectDefinitionStoreException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException("Unexpected exception parsing XML document from " + resource.Description + "Inner exception message= " + ex.Message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private XmlReader CreateValidatingReader(MemoryStream stream)
|
||||
@@ -297,7 +356,7 @@ namespace Spring.Objects.Factory.Xml
|
||||
reader = XmlUtils.CreateReader(stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
#if !NET_2_0
|
||||
// only because 1.0/1.1 don't pass the sender into the handler callback...
|
||||
ValidationEventHandlerWrapper validationEventHandlerWrapper = new ValidationEventHandlerWrapper(this);
|
||||
@@ -305,116 +364,134 @@ namespace Spring.Objects.Factory.Xml
|
||||
new ValidationEventHandler(validationEventHandlerWrapper.HandleValidation));
|
||||
validationEventHandlerWrapper.Reader = reader;
|
||||
#else
|
||||
reader = XmlUtils.CreateValidatingReader(stream, Resolver, NamespaceParserRegistry.GetSchemas(), HandleValidation);
|
||||
#endif
|
||||
}
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug("Using the following XmlReader implementation : " + reader.GetType());
|
||||
reader = XmlUtils.CreateValidatingReader(stream, Resolver, NamespaceParserRegistry.GetSchemas(), HandleValidation);
|
||||
#endif
|
||||
}
|
||||
return reader;
|
||||
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug("Using the following XmlReader implementation : " + reader.GetType());
|
||||
}
|
||||
return reader;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation callback for a validating XML reader.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="args">Any data pertinent to the event.</param>
|
||||
private void HandleValidation(object sender, ValidationEventArgs args)
|
||||
{
|
||||
if (args.Severity == XmlSeverityType.Error)
|
||||
{
|
||||
XmlSchemaException ex = args.Exception;
|
||||
XmlReader xmlReader = (XmlReader) sender;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation callback for a validating XML reader.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="args">Any data pertinent to the event.</param>
|
||||
private void HandleValidation(object sender, ValidationEventArgs args)
|
||||
{
|
||||
if (args.Severity == XmlSeverityType.Error)
|
||||
{
|
||||
XmlSchemaException ex = args.Exception;
|
||||
XmlReader xmlReader = (XmlReader)sender;
|
||||
if (!NamespaceParserRegistry.GetSchemas().Contains(xmlReader.NamespaceURI)
|
||||
#if NET_2_0
|
||||
&& ex is XmlSchemaValidationException
|
||||
&& ex is XmlSchemaValidationException
|
||||
#endif
|
||||
)
|
||||
)
|
||||
{
|
||||
// try wellknown parsers
|
||||
bool registered = NamespaceParserRegistry.RegisterWellknownNamespaceParserType(xmlReader.NamespaceURI);
|
||||
if (registered)
|
||||
{
|
||||
{
|
||||
throw new RetryParseException();
|
||||
}
|
||||
}
|
||||
}
|
||||
#if !NET_2_0
|
||||
// ignore validation errors for well-known 'xml' namespace. This seems to be a bug in net 1.0 + 1.1
|
||||
if (ex.Message.IndexOf("http://www.w3.org/XML/1998/namespace:") > -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
throw ex;
|
||||
}
|
||||
else
|
||||
{
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsWarnEnabled)
|
||||
{
|
||||
log.Warn(
|
||||
"Ignored XML validation warning: " + args.Message,
|
||||
args.Exception);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the object definitions contained in the given DOM document.
|
||||
/// </summary>
|
||||
/// <param name="doc">The DOM document.</param>
|
||||
/// <param name="resource">
|
||||
/// The original resource from where the <see cref="System.Xml.XmlDocument"/>
|
||||
/// was read.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The number of object definitions that were registered.
|
||||
/// </returns>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of parsing errors.
|
||||
/// </exception>
|
||||
public int RegisterObjectDefinitions(
|
||||
XmlDocument doc, IResource resource)
|
||||
{
|
||||
IObjectDefinitionDocumentReader documentReader = CreateObjectDefinitionDocumentReader();
|
||||
|
||||
//TODO make void return and get object count from registry.
|
||||
int countBefore = Registry.ObjectDefinitionCount;
|
||||
documentReader.RegisterObjectDefinitions(doc, CreateReaderContext(resource));
|
||||
return Registry.ObjectDefinitionCount - countBefore;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the <see cref="IObjectDefinitionDocumentReader"/> to use for actually
|
||||
/// reading object definitions from an XML document.
|
||||
/// </summary>
|
||||
/// <remarks>Default implementation instantiates the specified 'documentReaderType'.</remarks>
|
||||
/// <returns></returns>
|
||||
protected virtual IObjectDefinitionDocumentReader CreateObjectDefinitionDocumentReader()
|
||||
{
|
||||
return (IObjectDefinitionDocumentReader) ObjectUtils.InstantiateType(documentReaderType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the <see cref="XmlReaderContext"/> to be passed along
|
||||
/// during the object definition reading process.
|
||||
/// </summary>
|
||||
/// <param name="resource">The underlying <see cref="IResource"/> that is currently processed.</param>
|
||||
/// <returns>A new <see cref="XmlReaderContext"/></returns>
|
||||
protected virtual XmlReaderContext CreateReaderContext(IResource resource)
|
||||
{
|
||||
return new XmlReaderContext(resource, this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
||||
throw ex;
|
||||
}
|
||||
else
|
||||
{
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsWarnEnabled)
|
||||
{
|
||||
log.Warn(
|
||||
"Ignored XML validation warning: " + args.Message,
|
||||
args.Exception);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the object definitions contained in the given DOM document.
|
||||
/// </summary>
|
||||
/// <param name="doc">The DOM document.</param>
|
||||
/// <param name="resource">
|
||||
/// The original resource from where the <see cref="System.Xml.XmlDocument"/>
|
||||
/// was read.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The number of object definitions that were registered.
|
||||
/// </returns>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of parsing errors.
|
||||
/// </exception>
|
||||
public int RegisterObjectDefinitions(
|
||||
XmlDocument doc, IResource resource)
|
||||
{
|
||||
IObjectDefinitionDocumentReader documentReader = CreateObjectDefinitionDocumentReader();
|
||||
|
||||
//TODO make void return and get object count from registry.
|
||||
int countBefore = Registry.ObjectDefinitionCount;
|
||||
XmlReaderContext readerContext = CreateReaderContext(resource);
|
||||
readerContext.NamespaceParserResolver = this.NamespaceParserResolver;
|
||||
documentReader.RegisterObjectDefinitions(doc, readerContext);
|
||||
return Registry.ObjectDefinitionCount - countBefore;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the <see cref="IObjectDefinitionDocumentReader"/> to use for actually
|
||||
/// reading object definitions from an XML document.
|
||||
/// </summary>
|
||||
/// <remarks>Default implementation instantiates the specified <see cref="DocumentReaderType"/>
|
||||
/// or <see cref="DefaultObjectDefinitionDocumentReader"/> if no reader type is specified.</remarks>
|
||||
/// <returns></returns>
|
||||
protected virtual IObjectDefinitionDocumentReader CreateObjectDefinitionDocumentReader()
|
||||
{
|
||||
if (documentReaderType == null)
|
||||
{
|
||||
return new DefaultObjectDefinitionDocumentReader();
|
||||
}
|
||||
return (IObjectDefinitionDocumentReader)ObjectUtils.InstantiateType(documentReaderType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the <see cref="XmlReaderContext"/> to be passed along
|
||||
/// during the object definition reading process.
|
||||
/// </summary>
|
||||
/// <param name="resource">The underlying <see cref="IResource"/> that is currently processed.</param>
|
||||
/// <returns>A new <see cref="XmlReaderContext"/></returns>
|
||||
protected virtual XmlReaderContext CreateReaderContext(IResource resource)
|
||||
{
|
||||
return new XmlReaderContext(resource, this, this.objectDefinitionFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="INamespaceParserResolver"/> instance for handling custom namespaces.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// TODO (EE): make protected virtual, see remarks on <see cref="INamespaceParserResolver"/>
|
||||
/// </remarks>
|
||||
private INamespaceParserResolver CreateDefaultNamespaceParserResolver()
|
||||
{
|
||||
return new DefaultNamespaceHandlerResolver();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,18 +29,14 @@ using Spring.Util;
|
||||
namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension of <see cref="ReaderContext"/> specific to use with an
|
||||
/// XmlObjectDefinitionReader.
|
||||
/// Extension of <see cref="ReaderContext"/> specific to use with an XmlObjectDefinitionReader.
|
||||
/// Provides access to <see cref="NamespaceParserResolver"/> configured in <see cref="XmlObjectDefinitionReader"/>
|
||||
/// </summary>
|
||||
/// <remarks>In future will contain access to IXmlParserRegistry</remarks>
|
||||
public class XmlReaderContext : ReaderContext
|
||||
{
|
||||
|
||||
//TODO: Should have a ref to NamespaceParserRegistry, i.e. NamespaceHandlerResolver here....
|
||||
|
||||
private IObjectDefinitionReader reader;
|
||||
|
||||
private IObjectDefinitionFactory objectDefinitionFactory = new DefaultObjectDefinitionFactory();
|
||||
private readonly IObjectDefinitionReader reader;
|
||||
private readonly IObjectDefinitionFactory objectDefinitionFactory;
|
||||
private INamespaceParserResolver namespaceParserResolver;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum length of any XML fragment displayed in the error message
|
||||
@@ -54,18 +50,32 @@ namespace Spring.Objects.Factory.Xml
|
||||
/// </remarks>
|
||||
private const int MaxXmlErrorFragmentLength = 255;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="XmlReaderContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="resource">The resource.</param>
|
||||
/// <param name="reader">The reader.</param>
|
||||
public XmlReaderContext(IResource resource, IObjectDefinitionReader reader)
|
||||
: this(resource, reader, new DefaultObjectDefinitionFactory())
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="XmlReaderContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="resource">The resource.</param>
|
||||
/// <param name="reader">The reader.</param>
|
||||
public XmlReaderContext(IResource resource, IObjectDefinitionReader reader) : base(resource)
|
||||
/// <param name="objectDefinitionFactory">The factory to use for creating new <see cref="IObjectDefinition"/> instances.</param>
|
||||
internal XmlReaderContext(IResource resource, IObjectDefinitionReader reader, IObjectDefinitionFactory objectDefinitionFactory)
|
||||
: base(resource)
|
||||
{
|
||||
this.reader = reader;
|
||||
|
||||
if (reader is XmlObjectDefinitionReader)
|
||||
{
|
||||
this.namespaceParserResolver = ((XmlObjectDefinitionReader) reader).NamespaceParserResolver;
|
||||
}
|
||||
this.objectDefinitionFactory = objectDefinitionFactory;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reader.
|
||||
/// </summary>
|
||||
@@ -96,7 +106,6 @@ namespace Spring.Objects.Factory.Xml
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the object definition factory.
|
||||
/// </summary>
|
||||
@@ -104,10 +113,16 @@ namespace Spring.Objects.Factory.Xml
|
||||
public IObjectDefinitionFactory ObjectDefinitionFactory
|
||||
{
|
||||
get { return objectDefinitionFactory; }
|
||||
set { objectDefinitionFactory = value; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the <see cref="INamespaceParserResolver"/> instance to lookup parsers for custom namespaces.
|
||||
/// </summary>
|
||||
internal INamespaceParserResolver NamespaceParserResolver
|
||||
{
|
||||
get { return namespaceParserResolver; }
|
||||
set { namespaceParserResolver = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the name of the object.
|
||||
|
||||
@@ -600,6 +600,8 @@
|
||||
<Compile Include="Objects\Factory\Xml\AbstractObjectDefinitionParser.cs" />
|
||||
<Compile Include="Objects\Factory\Xml\AbstractSimpleObjectDefinitionParser.cs" />
|
||||
<Compile Include="Objects\Factory\Xml\AbstractSingleObjectDefinitionParser.cs" />
|
||||
<Compile Include="Objects\Factory\Xml\DefaultNamespaceHandlerResolver.cs" />
|
||||
<Compile Include="Objects\Factory\Xml\INamespaceParserResolver.cs" />
|
||||
<Compile Include="Objects\Factory\Xml\NamespaceParserAttribute.cs" />
|
||||
<Compile Include="Objects\Factory\Xml\ObjectFactorySectionHandler.cs" />
|
||||
<Compile Include="Objects\Factory\Xml\DocumentDefaultsDefinition.cs" />
|
||||
|
||||
@@ -72,9 +72,10 @@ namespace Spring.Util
|
||||
/// <returns><see lang="true"/> if the element is in the collection, <see lang="false"/> otherwise.</returns>
|
||||
public static bool Contains(ICollection collection, Object element)
|
||||
{
|
||||
// TODO (EE): does not match Spring/J behavior. Change to IEnumerable and enumerable may be null
|
||||
if (collection == null)
|
||||
{
|
||||
throw new ArgumentNullException("Collection cannot be null.");
|
||||
throw new ArgumentNullException("collection", "Collection cannot be null.");
|
||||
}
|
||||
MethodInfo method;
|
||||
method = collection.GetType().GetMethod("contains", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
|
||||
@@ -92,17 +93,32 @@ namespace Spring.Util
|
||||
/// <param name="element">The object to add to the collection.</param>
|
||||
public static void Add(ICollection collection, object element)
|
||||
{
|
||||
if (collection == null)
|
||||
Add((IEnumerable)collection, element);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified <paramref name="element"/> to the specified <paramref name="enumerable"/> .
|
||||
/// </summary>
|
||||
/// <param name="enumerable">The enumerable to add the element to.</param>
|
||||
/// <param name="element">The object to add to the collection.</param>
|
||||
public static void Add(IEnumerable enumerable, object element)
|
||||
{
|
||||
if (enumerable == null)
|
||||
{
|
||||
throw new ArgumentNullException("Collection cannot be null.");
|
||||
throw new ArgumentNullException("enumerable", "Collection cannot be null.");
|
||||
}
|
||||
if (enumerable is IList)
|
||||
{
|
||||
((IList)enumerable).Add(element);
|
||||
return;
|
||||
}
|
||||
MethodInfo method;
|
||||
method = collection.GetType().GetMethod("add", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
|
||||
method = enumerable.GetType().GetMethod("add", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
|
||||
if (null == method)
|
||||
{
|
||||
throw new InvalidOperationException("Collection type " + collection.GetType() + " does not implement a Add() method.");
|
||||
throw new InvalidOperationException("Enumerable type " + enumerable.GetType() + " does not implement a Add() method.");
|
||||
}
|
||||
method.Invoke(collection, new Object[] { element });
|
||||
method.Invoke(enumerable, new Object[] { element });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -113,9 +129,13 @@ namespace Spring.Util
|
||||
/// <returns>true if the target collection contains all the elements of the specified collection.</returns>
|
||||
public static bool ContainsAll(ICollection targetCollection, ICollection sourceCollection)
|
||||
{
|
||||
if (targetCollection == null || sourceCollection == null)
|
||||
if (targetCollection == null)
|
||||
{
|
||||
throw new ArgumentNullException("Collection cannot be null.");
|
||||
throw new ArgumentNullException("targetCollection", "Collection cannot be null.");
|
||||
}
|
||||
if (sourceCollection == null)
|
||||
{
|
||||
throw new ArgumentNullException("sourceCollection", "Collection cannot be null.");
|
||||
}
|
||||
if (sourceCollection.Count == 0 && targetCollection.Count > 1)
|
||||
return true;
|
||||
@@ -213,6 +233,47 @@ namespace Spring.Util
|
||||
return array;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first element contained in both, <paramref name="source"/> and <paramref name="candidates"/>.
|
||||
/// </summary>
|
||||
/// <remarks>The implementation assumes that <paramref name="candidates"/> <<< <paramref name="source"/></remarks>
|
||||
/// <param name="source">the source enumerable. may be <c>null</c></param>
|
||||
/// <param name="candidates">the list of candidates to match against <paramref name="source"/> elements. may be <c>null</c></param>
|
||||
/// <returns>the first element found in both enumerables or <c>null</c></returns>
|
||||
public static object FindFirstMatch(IEnumerable source, IEnumerable candidates)
|
||||
{
|
||||
if (IsEmpty(source) || IsEmpty(candidates))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
IList candidateList = candidates as IList;
|
||||
if (candidateList == null)
|
||||
{
|
||||
if (candidates is ICollection)
|
||||
{
|
||||
candidateList = new ArrayList((ICollection)candidates);
|
||||
}
|
||||
else
|
||||
{
|
||||
candidateList = new ArrayList();
|
||||
foreach (object el in candidates)
|
||||
{
|
||||
candidateList.Add(el);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (object sourceElement in source)
|
||||
{
|
||||
if (candidateList.Contains(sourceElement))
|
||||
{
|
||||
return sourceElement;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a value of the given type in the given collection.
|
||||
/// </summary>
|
||||
@@ -268,6 +329,31 @@ namespace Spring.Util
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified collection is null or empty.
|
||||
/// </summary>
|
||||
/// <param name="enumerable">The collection to check.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified collection is empty or null; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public static bool IsEmpty(IEnumerable enumerable)
|
||||
{
|
||||
if (enumerable == null)
|
||||
return true;
|
||||
|
||||
if (enumerable is ICollection)
|
||||
{
|
||||
return (0 == ((ICollection)enumerable).Count);
|
||||
}
|
||||
|
||||
IEnumerator it = enumerable.GetEnumerator();
|
||||
if (!it.MoveNext())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified collection is null or empty.
|
||||
/// </summary>
|
||||
@@ -337,11 +423,11 @@ namespace Spring.Util
|
||||
|
||||
ehancedInput.Sort(Entry.GetComparer(comparer));
|
||||
|
||||
for (int i = 0; i < ehancedInput.Count; i++ )
|
||||
for (int i = 0; i < ehancedInput.Count; i++)
|
||||
{
|
||||
ehancedInput[i] = ((Entry) ehancedInput[i]).Value;
|
||||
ehancedInput[i] = ((Entry)ehancedInput[i]).Value;
|
||||
}
|
||||
|
||||
|
||||
return ehancedInput;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,15 @@ namespace Spring.Validation.Config
|
||||
string parent = GetAttributeValue(element, ObjectDefinitionConstants.ParentAttribute);
|
||||
|
||||
string name = "validator: " + (StringUtils.HasText(id) ? id : this.definitionCount.ToString());
|
||||
|
||||
MutablePropertyValues properties = new MutablePropertyValues();
|
||||
IConfigurableObjectDefinition od
|
||||
= parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition(
|
||||
typeName, parent, parserContext.ReaderContext.Reader.Domain);
|
||||
|
||||
od.PropertyValues = properties;
|
||||
od.IsSingleton = true;
|
||||
od.IsLazyInit = true;
|
||||
|
||||
ParseAttributeIntoProperty(element, ValidatorDefinitionConstants.TestAttribute, properties, "Test");
|
||||
ParseAttributeIntoProperty(element, ValidatorDefinitionConstants.WhenAttribute, properties, "When");
|
||||
@@ -141,6 +149,7 @@ namespace Spring.Validation.Config
|
||||
|
||||
ManagedList nestedValidators = new ManagedList();
|
||||
ManagedList actions = new ManagedList();
|
||||
ParserContext childParserContext = new ParserContext(parserContext.ParserHelper, od);
|
||||
foreach (XmlNode node in element.ChildNodes)
|
||||
{
|
||||
XmlElement child = node as XmlElement;
|
||||
@@ -150,19 +159,19 @@ namespace Spring.Validation.Config
|
||||
{
|
||||
case ValidatorDefinitionConstants.PropertyElement:
|
||||
string propertyName = GetAttributeValue(child, ValidatorDefinitionConstants.PropertyNameAttribute);
|
||||
properties.Add(propertyName, base.ParsePropertyValue(child, name, parserContext));
|
||||
properties.Add(propertyName, base.ParsePropertyValue(child, name, childParserContext));
|
||||
break;
|
||||
case ValidatorDefinitionConstants.MessageElement:
|
||||
actions.Add(ParseErrorMessageAction(child, parserContext));
|
||||
actions.Add(ParseErrorMessageAction(child, childParserContext));
|
||||
break;
|
||||
case ValidatorDefinitionConstants.ActionElement:
|
||||
actions.Add(ParseGenericAction(child, parserContext));
|
||||
actions.Add(ParseGenericAction(child, childParserContext));
|
||||
break;
|
||||
case ValidatorDefinitionConstants.ReferenceElement:
|
||||
nestedValidators.Add(ParseValidatorReference(child, parserContext));
|
||||
nestedValidators.Add(ParseValidatorReference(child, childParserContext));
|
||||
break;
|
||||
default:
|
||||
nestedValidators.Add(ParseAndRegisterValidator(child, parserContext));
|
||||
nestedValidators.Add(ParseAndRegisterValidator(child, childParserContext));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -176,14 +185,6 @@ namespace Spring.Validation.Config
|
||||
properties.Add("Actions", actions);
|
||||
}
|
||||
|
||||
IConfigurableObjectDefinition od
|
||||
= parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition(
|
||||
typeName, parent, parserContext.ReaderContext.Reader.Domain);
|
||||
|
||||
od.PropertyValues = properties;
|
||||
od.IsSingleton = true;
|
||||
od.IsLazyInit = true;
|
||||
|
||||
return od;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Xml;
|
||||
using Common.Logging;
|
||||
using Spring.Collections;
|
||||
using Spring.Objects;
|
||||
@@ -106,10 +107,7 @@ namespace Spring.Context.Support
|
||||
|
||||
// remember creation info for debug output
|
||||
this._constructionTimeStamp = DateTime.Now;
|
||||
if (HttpContext.Current != null)
|
||||
{
|
||||
this._constructionUrl = HttpContext.Current.Request.RawUrl;
|
||||
}
|
||||
this._constructionUrl = VirtualEnvironment.CurrentVirtualPathAndQuery;
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug("created instance " + this.ToString());
|
||||
@@ -217,7 +215,7 @@ namespace Spring.Context.Support
|
||||
{
|
||||
get
|
||||
{
|
||||
string requestUrl = HttpContext.Current.Request.FilePath;
|
||||
string requestUrl = VirtualEnvironment.CurrentVirtualFilePath;
|
||||
return GetContextInternal(requestUrl);
|
||||
}
|
||||
}
|
||||
@@ -351,7 +349,7 @@ namespace Spring.Context.Support
|
||||
/// <param name="objectDefinitionReader">Reader to initialize.</param>
|
||||
protected override void InitObjectDefinitionReader(XmlObjectDefinitionReader objectDefinitionReader)
|
||||
{
|
||||
NamespaceParserRegistry.RegisterParser(typeof(WebObjectsNamespaceParser));
|
||||
// NamespaceParserRegistry.RegisterParser(typeof(WebObjectsNamespaceParser));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -369,6 +367,16 @@ namespace Spring.Context.Support
|
||||
/// </summary>
|
||||
/// <returns>Web object factory to use.</returns>
|
||||
protected override DefaultListableObjectFactory CreateObjectFactory()
|
||||
{
|
||||
string contextPath = GetContextPathWithTrailingSlash();
|
||||
return new WebObjectFactory(contextPath, this.CaseSensitive, GetInternalParentObjectFactory());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the application-relative virtual path of this context (without leading '~'!).
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string GetContextPathWithTrailingSlash()
|
||||
{
|
||||
string contextPath = this.Name;
|
||||
if (contextPath == DefaultRootContextName)
|
||||
@@ -379,7 +387,16 @@ namespace Spring.Context.Support
|
||||
{
|
||||
contextPath = contextPath + "/";
|
||||
}
|
||||
return new WebObjectFactory(contextPath, this.CaseSensitive, GetInternalParentObjectFactory());
|
||||
return contextPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a reader instance capable of handling web objects (Pages,Controls) for importing o
|
||||
/// bject definitions into the specified <paramref name="objectFactory"/>.
|
||||
/// </summary>
|
||||
protected override XmlObjectDefinitionReader CreateXmlObjectDefinitionReader(DefaultListableObjectFactory objectFactory)
|
||||
{
|
||||
return new WebObjectDefinitionReader(GetContextPathWithTrailingSlash(), objectFactory, new XmlUrlResolver());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
using Spring.Core;
|
||||
@@ -97,27 +98,22 @@ namespace Spring.DataBinding
|
||||
/// </param>
|
||||
public override void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, IDictionary variables)
|
||||
{
|
||||
HttpRequest request;
|
||||
if (HttpContext.Current == null || (HttpContext.Current.Request) == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot perform Request data binding without a valid HTTP request.");
|
||||
}
|
||||
request = HttpContext.Current.Request;
|
||||
NameValueCollection parameters = VirtualEnvironment.RequestParams;
|
||||
IList targetList = targetExpression.GetValue(target) as IList;
|
||||
if (targetList == null)
|
||||
{
|
||||
throw new ArgumentException("Target property has to be initialized to an instance of IList interface.");
|
||||
}
|
||||
|
||||
if (request.Params.GetValues(requestParams[0]) != null)
|
||||
if (parameters.GetValues(requestParams[0]) != null)
|
||||
{
|
||||
int valueCount = request.Params.GetValues(requestParams[0]).Length;
|
||||
int valueCount = parameters.GetValues(requestParams[0]).Length;
|
||||
for (int i = 0; i < valueCount; i++)
|
||||
{
|
||||
IDictionary vars = new Hashtable();
|
||||
foreach (string paramName in requestParams)
|
||||
{
|
||||
vars[paramName] = request.Params.GetValues(paramName)[i];
|
||||
vars[paramName] = parameters.GetValues(paramName)[i];
|
||||
}
|
||||
|
||||
object targetItem;
|
||||
|
||||
@@ -58,7 +58,8 @@ namespace Spring.Objects.Factory.Support
|
||||
/// The <see cref="Spring.Objects.MutablePropertyValues"/> to be applied to
|
||||
/// a new instance of the object.
|
||||
/// </param>
|
||||
public ChildWebObjectDefinition(string parentName, Type type, ConstructorArgumentValues arguments, MutablePropertyValues properties) : base(parentName, type, arguments, properties)
|
||||
public ChildWebObjectDefinition(string parentName, Type type, ConstructorArgumentValues arguments, MutablePropertyValues properties)
|
||||
: base(parentName, type, arguments, properties)
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
@@ -76,7 +77,8 @@ namespace Spring.Objects.Factory.Support
|
||||
/// The <see cref="Spring.Objects.MutablePropertyValues"/> to be applied to
|
||||
/// a new instance of the object.
|
||||
/// </param>
|
||||
public ChildWebObjectDefinition(string parentName, string typeName, ConstructorArgumentValues arguments, MutablePropertyValues properties) : base(parentName, typeName, arguments, properties)
|
||||
public ChildWebObjectDefinition(string parentName, string typeName, ConstructorArgumentValues arguments, MutablePropertyValues properties)
|
||||
: base(parentName, typeName, arguments, properties)
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
@@ -93,7 +95,7 @@ namespace Spring.Objects.Factory.Support
|
||||
public ChildWebObjectDefinition(string parentName, string pageName, MutablePropertyValues properties)
|
||||
: base(parentName, WebObjectUtils.GetPageType(pageName), null, properties)
|
||||
{
|
||||
_pageName = WebUtils.CombineVirtualPaths(HttpContext.Current.Request.CurrentExecutionFilePath, pageName);
|
||||
_pageName = WebUtils.CombineVirtualPaths(VirtualEnvironment.CurrentExecutionFilePath, pageName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spring.Objects.Factory.Support
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
internal interface IWebObjectNameGenerator
|
||||
{
|
||||
string CreatePageDefinitionName(string virtualPath);
|
||||
string CreateControlDefinitionName(string virtualPath);
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@ namespace Spring.Objects.Factory.Support
|
||||
MutablePropertyValues properties)
|
||||
: base(WebObjectUtils.GetPageType(pageName), null, properties)
|
||||
{
|
||||
_pageName = WebUtils.CombineVirtualPaths(HttpContext.Current.Request.CurrentExecutionFilePath, pageName);
|
||||
_pageName = WebUtils.CombineVirtualPaths(VirtualEnvironment.CurrentExecutionFilePath, pageName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -127,6 +127,14 @@ namespace Spring.Objects.Factory.Support
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns the virtual path this object factory is associated with.
|
||||
/// </summary>
|
||||
public string ContextPath
|
||||
{
|
||||
get { return contextPath; }
|
||||
}
|
||||
|
||||
#region Convenience accessors for Http* objects
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -27,9 +27,11 @@ using System.Web.UI;
|
||||
#endif
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
//using System.Web;
|
||||
using Common.Logging;
|
||||
using Spring.Util;
|
||||
using IHttpHandler = System.Web.IHttpHandler;
|
||||
using HttpException = System.Web.HttpException;
|
||||
|
||||
namespace Spring.Objects.Factory.Support
|
||||
{
|
||||
@@ -91,16 +93,16 @@ namespace Spring.Objects.Factory.Support
|
||||
s_log.Debug( "creating page instance '" + pageUrl + "'" );
|
||||
}
|
||||
|
||||
HttpContext ctx = HttpContext.Current;
|
||||
if (ctx == null)
|
||||
{
|
||||
throw new ObjectCreationException(
|
||||
"Unable to instantiate page. HttpContext is not defined." );
|
||||
}
|
||||
IHttpHandler page = null;
|
||||
// HttpContext ctx = HttpContext.Current;
|
||||
// if (ctx == null)
|
||||
// {
|
||||
// throw new ObjectCreationException(
|
||||
// "Unable to instantiate page. HttpContext is not defined." );
|
||||
// }
|
||||
IHttpHandler page;
|
||||
try
|
||||
{
|
||||
page = CreateHandler( ctx, pageUrl );
|
||||
page = CreateHandler( pageUrl );
|
||||
}
|
||||
catch (HttpException httpEx)
|
||||
{
|
||||
@@ -132,25 +134,26 @@ namespace Spring.Objects.Factory.Support
|
||||
/// <summary>
|
||||
/// Creates the raw handler instance without any exception handling
|
||||
/// </summary>
|
||||
/// <param name="ctx"></param>
|
||||
/// <param name="pageUrl"></param>
|
||||
/// <returns></returns>
|
||||
internal static IHttpHandler CreateHandler( HttpContext ctx, string pageUrl )
|
||||
internal static IHttpHandler CreateHandler( string pageUrl )
|
||||
{
|
||||
IHttpHandler page;
|
||||
#if NET_1_1
|
||||
string physicalPath = ctx.Server.MapPath(pageUrl);
|
||||
s_log.Debug(string.Format("constructing page virtual path '{0}' from physical file '{1}'", pageUrl, physicalPath));
|
||||
page = PageParser.GetCompiledPageInstance(pageUrl, physicalPath, ctx);
|
||||
#else
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths( ctx.Request.CurrentExecutionFilePath, pageUrl );
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug( "page vpath is " + rootedVPath );
|
||||
}
|
||||
|
||||
page = BuildManager.CreateInstanceFromVirtualPath( rootedVPath, typeof( IHttpHandler ) ) as IHttpHandler;
|
||||
#endif
|
||||
// HttpContext ctx = HttpContext.Current;
|
||||
//#if NET_1_1
|
||||
// string physicalPath = ctx.Server.MapPath(pageUrl);
|
||||
// s_log.Debug(string.Format("constructing page virtual path '{0}' from physical file '{1}'", pageUrl, physicalPath));
|
||||
// page = PageParser.GetCompiledPageInstance(pageUrl, physicalPath, ctx);
|
||||
//#else
|
||||
// string rootedVPath = WebUtils.CombineVirtualPaths( ctx.Request.CurrentExecutionFilePath, pageUrl );
|
||||
// if (s_log.IsDebugEnabled)
|
||||
// {
|
||||
// s_log.Debug( "page vpath is " + rootedVPath );
|
||||
// }
|
||||
//
|
||||
// page = BuildManager.CreateInstanceFromVirtualPath( rootedVPath, typeof( IHttpHandler ) ) as IHttpHandler;
|
||||
//#endif
|
||||
page = VirtualEnvironment.CreateInstanceFromVirtualPath(pageUrl, typeof (IHttpHandler)) as IHttpHandler;
|
||||
return page;
|
||||
}
|
||||
|
||||
@@ -188,11 +191,11 @@ namespace Spring.Objects.Factory.Support
|
||||
{
|
||||
AssertUtils.ArgumentHasText( pageUrl, "pageUrl" );
|
||||
|
||||
HttpContext ctx = HttpContext.Current;
|
||||
if (ctx == null)
|
||||
{
|
||||
throw new ObjectCreationException( "Unable to get page type. HttpContext is not defined." );
|
||||
}
|
||||
// HttpContext ctx = HttpContext.Current;
|
||||
// if (ctx == null)
|
||||
// {
|
||||
// throw new ObjectCreationException( "Unable to get page type. HttpContext is not defined." );
|
||||
// }
|
||||
|
||||
try
|
||||
{
|
||||
@@ -209,10 +212,10 @@ namespace Spring.Objects.Factory.Support
|
||||
|
||||
/// <summary>
|
||||
/// Calls the underlying ASP.NET infrastructure to obtain the compiled page type
|
||||
/// relative to the current <see cref="HttpRequest.CurrentExecutionFilePath"/>.
|
||||
/// relative to the current <see cref="System.Web.HttpRequest.CurrentExecutionFilePath"/>.
|
||||
/// </summary>
|
||||
/// <param name="pageUrl">
|
||||
/// The filename of the ASPX page relative to the current <see cref="HttpRequest.CurrentExecutionFilePath"/>
|
||||
/// The filename of the ASPX page relative to the current <see cref="System.Web.HttpRequest.CurrentExecutionFilePath"/>
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The <see cref="System.Type"/> of the ASPX page
|
||||
@@ -225,18 +228,18 @@ namespace Spring.Objects.Factory.Support
|
||||
s_log.Debug( "getting page type for " + pageUrl );
|
||||
}
|
||||
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths( HttpContext.Current.Request.CurrentExecutionFilePath, pageUrl );
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths( VirtualEnvironment.CurrentExecutionFilePath, pageUrl );
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug( "page vpath is " + rootedVPath );
|
||||
}
|
||||
|
||||
Type pageType = null;
|
||||
#if NET_2_0
|
||||
pageType = BuildManager.GetCompiledType( rootedVPath ); // requires rooted virtual path!
|
||||
#else
|
||||
pageType = CreatePageInstance(pageUrl).GetType();
|
||||
#endif
|
||||
Type pageType = VirtualEnvironment.GetCompiledType(rootedVPath);
|
||||
//#if NET_2_0
|
||||
// pageType = BuildManager.GetCompiledType( rootedVPath ); // requires rooted virtual path!
|
||||
//#else
|
||||
// pageType = CreatePageInstance(pageUrl).GetType();
|
||||
//#endif
|
||||
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
@@ -257,27 +260,28 @@ namespace Spring.Objects.Factory.Support
|
||||
s_log.Debug( "getting control type for " + controlName );
|
||||
}
|
||||
|
||||
HttpContext ctx = HttpContext.Current;
|
||||
if (ctx == null)
|
||||
{
|
||||
throw new ObjectCreationException( "Unable to get control type. HttpContext is not defined." );
|
||||
}
|
||||
// HttpContext ctx = HttpContext.Current;
|
||||
// if (ctx == null)
|
||||
// {
|
||||
// throw new ObjectCreationException( "Unable to get control type. HttpContext is not defined." );
|
||||
// }
|
||||
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths( ctx.Request.CurrentExecutionFilePath, controlName );
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths( VirtualEnvironment.CurrentExecutionFilePath, controlName );
|
||||
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug( "control vpath is " + rootedVPath );
|
||||
}
|
||||
|
||||
Type controlType = null;
|
||||
Type controlType;
|
||||
try
|
||||
{
|
||||
#if NET_2_0
|
||||
controlType = BuildManager.GetCompiledType( rootedVPath ); // requires rooted virtual path!
|
||||
#else
|
||||
controlType = (Type) miGetCompiledUserControlType.Invoke(null, new object[] { rootedVPath, null, ctx });
|
||||
#endif
|
||||
//#if NET_2_0
|
||||
// controlType = BuildManager.GetCompiledType( rootedVPath ); // requires rooted virtual path!
|
||||
//#else
|
||||
// controlType = (Type) miGetCompiledUserControlType.Invoke(null, new object[] { rootedVPath, null, ctx });
|
||||
//#endif
|
||||
controlType = VirtualEnvironment.GetCompiledType(rootedVPath);
|
||||
}
|
||||
catch (HttpException httpEx)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see cref="DefaultObjectDefinitionDocumentReader"/> capable of handling web objects (Pages,Controls).
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
internal class WebObjectDefinitionDocumentReader : DefaultObjectDefinitionDocumentReader
|
||||
{
|
||||
private readonly IWebObjectNameGenerator webObjectNameGenerator;
|
||||
|
||||
public WebObjectDefinitionDocumentReader(IWebObjectNameGenerator webObjectNameGenerator)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(webObjectNameGenerator, "webObjectNameGenerator");
|
||||
this.webObjectNameGenerator = webObjectNameGenerator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="WebObjectDefinitionParserHelper"/> instance for the given
|
||||
/// <paramref name="readerContext"/> and <paramref name="root"/> element.
|
||||
/// </summary>
|
||||
protected override ObjectDefinitionParserHelper CreateHelper(XmlReaderContext readerContext, System.Xml.XmlElement root)
|
||||
{
|
||||
return new WebObjectDefinitionParserHelper(webObjectNameGenerator, readerContext, root);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Xml;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see cref="ObjectDefinitionParserHelper"/> capable of handling web objects (Pages,Controls)
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
internal class WebObjectDefinitionParserHelper : ObjectDefinitionParserHelper
|
||||
{
|
||||
private readonly IWebObjectNameGenerator webObjectNameGenerator;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WebObjectDefinitionParserHelper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="webObjectNameGenerator">used for generating object definition names from web object types (page, control)</param>
|
||||
/// <param name="readerContext">The reader context.</param>
|
||||
/// <param name="root">The root element of the xml document to parse</param>
|
||||
public WebObjectDefinitionParserHelper(IWebObjectNameGenerator webObjectNameGenerator, XmlReaderContext readerContext, XmlElement root)
|
||||
: base(readerContext, root)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(webObjectNameGenerator, "webObjectNameGenerator");
|
||||
this.webObjectNameGenerator = webObjectNameGenerator;
|
||||
}
|
||||
|
||||
protected override string PostProcessObjectNameAndAliases(string objectName, System.Collections.ArrayList aliases, XmlElement element, IObjectDefinition containingDefinition)
|
||||
{
|
||||
string url = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute);
|
||||
string strTypeName = url.ToLower();
|
||||
if (strTypeName.EndsWith(".aspx"))
|
||||
{
|
||||
if (!StringUtils.HasText(objectName))
|
||||
{
|
||||
objectName = webObjectNameGenerator.CreatePageDefinitionName(url);
|
||||
}
|
||||
|
||||
// adjust aliases if necessary
|
||||
for (int ai = 0; ai < aliases.Count; ai++)
|
||||
{
|
||||
string alias = (string)aliases[ai];
|
||||
if (alias != null && alias.Length > 0 && alias[0] == '~')
|
||||
{
|
||||
aliases[ai] = "/" + alias.Substring(1).TrimStart('/', '\\');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strTypeName.EndsWith(".ascx") || strTypeName.EndsWith(".master"))
|
||||
{
|
||||
if (!StringUtils.HasText(objectName))
|
||||
{
|
||||
objectName = webObjectNameGenerator.CreateControlDefinitionName(url);
|
||||
}
|
||||
}
|
||||
|
||||
return objectName;
|
||||
}
|
||||
|
||||
protected override ObjectDefinitionHolder CreateObjectDefinitionHolder(XmlElement element, IConfigurableObjectDefinition definition, string objectName, string[] aliasesArray)
|
||||
{
|
||||
IWebObjectDefinition webDefinition = definition as IWebObjectDefinition;
|
||||
|
||||
if (webDefinition != null)
|
||||
{
|
||||
webDefinition.Scope = GetScope(element.GetAttribute(ObjectDefinitionConstants.ScopeAttribute));
|
||||
|
||||
// force request and session scoped objects to be lazily initialized...
|
||||
if (webDefinition.Scope != ObjectScope.Application)
|
||||
{
|
||||
definition.IsLazyInit = true;
|
||||
}
|
||||
|
||||
string typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute);
|
||||
if (typeName.EndsWith(".ascx") || typeName.EndsWith(".master"))
|
||||
{
|
||||
definition.IsAbstract = true;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectDefinitionHolder holder = base.CreateObjectDefinitionHolder(element, definition, objectName, aliasesArray);
|
||||
return holder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scope out of the supplied <paramref name="value"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// If the supplied <paramref name="value"/> is invalid
|
||||
/// (i.e. it does not resolve to one of the
|
||||
/// <see cref="Spring.Objects.Factory.Support.ObjectScope"/> values),
|
||||
/// then the return value of this method call will be
|
||||
/// <see cref="Spring.Objects.Factory.Support.ObjectScope.Default"/>;
|
||||
/// no exception will be raised (although the value of the invalid
|
||||
/// scope <paramref name="value"/> will be logged).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="value">The string containing the scope name.</param>
|
||||
/// <returns>The scope.</returns>
|
||||
/// <seealso cref="Spring.Objects.Factory.Support.ObjectScope"/>
|
||||
private ObjectScope GetScope(string value)
|
||||
{
|
||||
ObjectScope scope = ObjectScope.Default;
|
||||
if (StringUtils.HasText(value))
|
||||
{
|
||||
try
|
||||
{
|
||||
scope = (ObjectScope)Enum.Parse(typeof(ObjectScope), value, true);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug(string.Format("Error while parsing object scope : '{0}' is an invalid value.",
|
||||
value), ex);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System.Web;
|
||||
using System.Xml;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Objects.Factory.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see cref="XmlObjectDefinitionReader"/> capable of handling web object definitions (Pages, Controls)
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class WebObjectDefinitionReader : XmlObjectDefinitionReader, IWebObjectNameGenerator
|
||||
{
|
||||
private readonly string contextVirtualPath;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Objects.Factory.Xml.XmlObjectDefinitionReader"/> class.
|
||||
/// </summary>
|
||||
/// <param name="contextVirtualPath">the (rooted) virtual path to resolve relative virtual paths.</param>
|
||||
/// <param name="registry">
|
||||
/// The <see cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry"/>
|
||||
/// instance that this reader works on.
|
||||
/// </param>
|
||||
/// <param name="resolver">the <see cref="XmlResolver"/> to use for resolving entities.</param>
|
||||
public WebObjectDefinitionReader(string contextVirtualPath, IObjectDefinitionRegistry registry, XmlResolver resolver)
|
||||
: base(registry, resolver, new WebObjectDefinitionFactory())
|
||||
{
|
||||
this.contextVirtualPath = contextVirtualPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the <see cref="IObjectDefinitionDocumentReader"/> to use for actually
|
||||
/// reading object definitions from an XML document.
|
||||
/// </summary>
|
||||
protected override IObjectDefinitionDocumentReader CreateObjectDefinitionDocumentReader()
|
||||
{
|
||||
return new WebObjectDefinitionDocumentReader(this);
|
||||
}
|
||||
|
||||
string IWebObjectNameGenerator.CreatePageDefinitionName(string virtualPath)
|
||||
{
|
||||
return CreatePageDefinitionName(virtualPath);
|
||||
}
|
||||
|
||||
string IWebObjectNameGenerator.CreateControlDefinitionName(string virtualPath)
|
||||
{
|
||||
return CreateControlDefinitionName(virtualPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an object definition name for the given control path
|
||||
/// </summary>
|
||||
protected virtual string CreateControlDefinitionName(string virtualPath)
|
||||
{
|
||||
string objectName;
|
||||
objectName = WebObjectUtils.GetControlType(virtualPath).FullName;
|
||||
return objectName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an object definition name for the given page path
|
||||
/// </summary>
|
||||
protected virtual string CreatePageDefinitionName(string url)
|
||||
{
|
||||
string objectName;
|
||||
objectName = WebUtils.CombineVirtualPaths(VirtualEnvironment.CurrentExecutionFilePath, url);
|
||||
string appPath = VirtualEnvironment.ApplicationVirtualPath;
|
||||
if (objectName.ToLower().StartsWith(appPath.ToLower()))
|
||||
{
|
||||
objectName = objectName.Substring(appPath.Length-1);
|
||||
}
|
||||
|
||||
// System.Web.UI.Page page = (System.Web.UI.Page)WebObjectUtils.CreatePageInstance(url);
|
||||
//#if NET_2_0
|
||||
// objectName = page.AppRelativeVirtualPath.Substring(1);
|
||||
//#else
|
||||
// string appPath = HttpContext.Current.Request.ApplicationPath.TrimEnd('\\', '/');
|
||||
// objectName = page.TemplateSourceDirectory.TrimEnd('\\','/') + "/" + WebUtils.GetPageName(url) + ".aspx";
|
||||
// if (objectName.ToLower().StartsWith(appPath.ToLower()))
|
||||
// {
|
||||
// objectName = objectName.Substring(appPath.Length);
|
||||
// }
|
||||
//#endif
|
||||
return objectName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ namespace Spring.Objects.Factory.Xml
|
||||
/// <see cref="ObjectsNamespaceParser"/>
|
||||
public class WebObjectsNamespaceParser : ObjectsNamespaceParser
|
||||
{
|
||||
private IObjectDefinitionFactory objectDefinitionFactory;
|
||||
// private IObjectDefinitionFactory objectDefinitionFactory;
|
||||
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
@@ -58,148 +58,148 @@ namespace Spring.Objects.Factory.Xml
|
||||
/// </summary>
|
||||
public WebObjectsNamespaceParser()
|
||||
{
|
||||
objectDefinitionFactory = new WebObjectDefinitionFactory();
|
||||
// objectDefinitionFactory = new WebObjectDefinitionFactory();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Parses an object definition and set various web related properties
|
||||
/// if the definition is an <see cref="RootWebObjectDefinition"/>.
|
||||
/// </summary>
|
||||
/// <param name="element">The object definition element.</param>
|
||||
/// <param name="id">The id / name of the object definition.</param>
|
||||
/// <param name="parserContext">the parser helper</param>
|
||||
/// <returns>The object (definition).</returns>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The <i>'various web related properties'</i> currently includes the
|
||||
/// intended scope of the object.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <see cref="Spring.Objects.Factory.Support.ObjectScope"/>
|
||||
/// <see cref="Spring.Objects.Factory.Support.IWebObjectDefinition"/>
|
||||
protected override IConfigurableObjectDefinition ParseObjectDefinitionElement(
|
||||
XmlElement element, string id, ParserContext parserContext)
|
||||
{
|
||||
parserContext.ReaderContext.ObjectDefinitionFactory = objectDefinitionFactory;
|
||||
IConfigurableObjectDefinition definition = base.ParseObjectDefinitionElement(element, id, parserContext);
|
||||
IWebObjectDefinition webDefinition = definition as IWebObjectDefinition;
|
||||
|
||||
if (webDefinition != null)
|
||||
{
|
||||
webDefinition.Scope = GetScope(element.GetAttribute(ObjectDefinitionConstants.ScopeAttribute));
|
||||
// /// <summary>
|
||||
// /// Parses an object definition and set various web related properties
|
||||
// /// if the definition is an <see cref="RootWebObjectDefinition"/>.
|
||||
// /// </summary>
|
||||
// /// <param name="element">The object definition element.</param>
|
||||
// /// <param name="id">The id / name of the object definition.</param>
|
||||
// /// <param name="parserContext">the parser helper</param>
|
||||
// /// <returns>The object (definition).</returns>
|
||||
// /// <remarks>
|
||||
// /// <p>
|
||||
// /// The <i>'various web related properties'</i> currently includes the
|
||||
// /// intended scope of the object.
|
||||
// /// </p>
|
||||
// /// </remarks>
|
||||
// /// <see cref="Spring.Objects.Factory.Support.ObjectScope"/>
|
||||
// /// <see cref="Spring.Objects.Factory.Support.IWebObjectDefinition"/>
|
||||
// protected override IConfigurableObjectDefinition ParseObjectDefinitionElement(
|
||||
// XmlElement element, string id, ParserContext parserContext)
|
||||
// {
|
||||
// IConfigurableObjectDefinition definition = base.ParseObjectDefinitionElement(element, id, parserContext);
|
||||
// IWebObjectDefinition webDefinition = definition as IWebObjectDefinition;
|
||||
//
|
||||
// if (webDefinition != null)
|
||||
// {
|
||||
// webDefinition.Scope = GetScope(element.GetAttribute(ObjectDefinitionConstants.ScopeAttribute));
|
||||
//
|
||||
// // force request and session scoped objects to be lazily initialized...
|
||||
// if (webDefinition.Scope != ObjectScope.Application)
|
||||
// {
|
||||
// definition.IsLazyInit = true;
|
||||
// }
|
||||
//
|
||||
// string typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute);
|
||||
// if (typeName.EndsWith(".ascx") || typeName.EndsWith(".master"))
|
||||
// {
|
||||
// definition.IsAbstract = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return definition;
|
||||
// }
|
||||
|
||||
// force request and session scoped objects to be lazily initialized...
|
||||
if (webDefinition.Scope != ObjectScope.Application)
|
||||
{
|
||||
definition.IsLazyInit = true;
|
||||
}
|
||||
|
||||
string typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute);
|
||||
if (typeName.EndsWith(".ascx") || typeName.EndsWith(".master"))
|
||||
{
|
||||
definition.IsAbstract = true;
|
||||
}
|
||||
}
|
||||
|
||||
return definition;
|
||||
}
|
||||
// /// <summary>
|
||||
// /// Calculates an id for an object definition.
|
||||
// /// </summary>
|
||||
// /// <param name="element">
|
||||
// /// The element containing the object definition.
|
||||
// /// </param>
|
||||
// /// <param name="aliases">
|
||||
// /// The list of names defined for the object; may be <see lang="null"/>
|
||||
// /// or even empty.
|
||||
// /// </param>
|
||||
// /// <returns>
|
||||
// /// A calculated object definition id.
|
||||
// /// </returns>
|
||||
// /// <seealso cref="ObjectsNamespaceParser.CalculateId"/>.
|
||||
// protected override string CalculateId(XmlElement element, ArrayList aliases)
|
||||
// {
|
||||
// return null;
|
||||
// string id = null;
|
||||
// string strTypeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute).ToLower();
|
||||
// if (strTypeName.EndsWith(".aspx"))
|
||||
// {
|
||||
// string url = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute);
|
||||
// //id = WebUtils.GetPageName(url);
|
||||
// //Type pageType = WebUtils.GetPageType(url);
|
||||
// System.Web.UI.Page page = (System.Web.UI.Page)WebObjectUtils.CreatePageInstance(url);
|
||||
//#if NET_2_0
|
||||
// id = page.AppRelativeVirtualPath.Substring(1);
|
||||
//#else
|
||||
// string appPath = HttpContext.Current.Request.ApplicationPath.TrimEnd('\\', '/');
|
||||
// id = page.TemplateSourceDirectory.TrimEnd('\\','/') + "/" + WebUtils.GetPageName(url) + ".aspx";
|
||||
// if (id.ToLower().StartsWith(appPath.ToLower()))
|
||||
// {
|
||||
// id = id.Substring(appPath.Length);
|
||||
// }
|
||||
//#endif
|
||||
// for(int ai=0;ai<aliases.Count;ai++)
|
||||
// {
|
||||
// string alias = (string)aliases[ai];
|
||||
// if (alias != null && alias.Length>0 && alias[0]=='~')
|
||||
// {
|
||||
// aliases[ai] = "/"+alias.Substring(1).TrimStart('/','\\');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if (strTypeName.EndsWith(".ascx") || strTypeName.EndsWith(".master"))
|
||||
// {
|
||||
// id = WebObjectUtils.GetControlType(strTypeName).FullName;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// id = base.CalculateId(element, aliases);
|
||||
// }
|
||||
// return id;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Calculates an id for an object definition.
|
||||
/// </summary>
|
||||
/// <param name="element">
|
||||
/// The element containing the object definition.
|
||||
/// </param>
|
||||
/// <param name="aliases">
|
||||
/// The list of names defined for the object; may be <see lang="null"/>
|
||||
/// or even empty.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A calculated object definition id.
|
||||
/// </returns>
|
||||
/// <seealso cref="ObjectsNamespaceParser.CalculateId"/>.
|
||||
protected override string CalculateId(XmlElement element, ArrayList aliases)
|
||||
{
|
||||
string id = null;
|
||||
string strTypeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute).ToLower();
|
||||
if (strTypeName.EndsWith(".aspx"))
|
||||
{
|
||||
string url = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute);
|
||||
//id = WebUtils.GetPageName(url);
|
||||
//Type pageType = WebUtils.GetPageType(url);
|
||||
System.Web.UI.Page page = (System.Web.UI.Page)WebObjectUtils.CreatePageInstance(url);
|
||||
#if NET_2_0
|
||||
id = page.AppRelativeVirtualPath.Substring(1);
|
||||
#else
|
||||
string appPath = HttpContext.Current.Request.ApplicationPath.TrimEnd('\\', '/');
|
||||
id = page.TemplateSourceDirectory.TrimEnd('\\','/') + "/" + WebUtils.GetPageName(url) + ".aspx";
|
||||
if (id.ToLower().StartsWith(appPath.ToLower()))
|
||||
{
|
||||
id = id.Substring(appPath.Length);
|
||||
}
|
||||
#endif
|
||||
for(int ai=0;ai<aliases.Count;ai++)
|
||||
{
|
||||
string alias = (string)aliases[ai];
|
||||
if (StringUtils.HasText(alias) && alias[0]=='~')
|
||||
{
|
||||
aliases[ai] = "/"+alias.Substring(1).TrimStart('/','\\');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strTypeName.EndsWith(".ascx") || strTypeName.EndsWith(".master"))
|
||||
{
|
||||
id = WebObjectUtils.GetControlType(strTypeName).FullName;
|
||||
}
|
||||
else
|
||||
{
|
||||
id = base.CalculateId(element, aliases);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scope out of the supplied <paramref name="value"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// If the supplied <paramref name="value"/> is invalid
|
||||
/// (i.e. it does not resolve to one of the
|
||||
/// <see cref="Spring.Objects.Factory.Support.ObjectScope"/> values),
|
||||
/// then the return value of this method call will be
|
||||
/// <see cref="Spring.Objects.Factory.Support.ObjectScope.Default"/>;
|
||||
/// no exception will be raised (although the value of the invalid
|
||||
/// scope <paramref name="value"/> will be logged).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="value">The string containing the scope name.</param>
|
||||
/// <returns>The scope.</returns>
|
||||
/// <seealso cref="Spring.Objects.Factory.Support.ObjectScope"/>
|
||||
private ObjectScope GetScope(string value)
|
||||
{
|
||||
ObjectScope scope = ObjectScope.Default;
|
||||
if (StringUtils.HasText(value))
|
||||
{
|
||||
try
|
||||
{
|
||||
scope = (ObjectScope) Enum.Parse(typeof(ObjectScope), value, true);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug(string.Format("Error while parsing object scope : '{0}' is an invalid value.",
|
||||
value), ex);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
// /// <summary>
|
||||
// /// Gets the scope out of the supplied <paramref name="value"/>.
|
||||
// /// </summary>
|
||||
// /// <remarks>
|
||||
// /// <p>
|
||||
// /// If the supplied <paramref name="value"/> is invalid
|
||||
// /// (i.e. it does not resolve to one of the
|
||||
// /// <see cref="Spring.Objects.Factory.Support.ObjectScope"/> values),
|
||||
// /// then the return value of this method call will be
|
||||
// /// <see cref="Spring.Objects.Factory.Support.ObjectScope.Default"/>;
|
||||
// /// no exception will be raised (although the value of the invalid
|
||||
// /// scope <paramref name="value"/> will be logged).
|
||||
// /// </p>
|
||||
// /// </remarks>
|
||||
// /// <param name="value">The string containing the scope name.</param>
|
||||
// /// <returns>The scope.</returns>
|
||||
// /// <seealso cref="Spring.Objects.Factory.Support.ObjectScope"/>
|
||||
// private ObjectScope GetScope(string value)
|
||||
// {
|
||||
// ObjectScope scope = ObjectScope.Default;
|
||||
// if (StringUtils.HasText(value))
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// scope = (ObjectScope) Enum.Parse(typeof(ObjectScope), value, true);
|
||||
// }
|
||||
// catch (ArgumentException ex)
|
||||
// {
|
||||
// #region Instrumentation
|
||||
//
|
||||
// if (log.IsDebugEnabled)
|
||||
// {
|
||||
// log.Debug(string.Format("Error while parsing object scope : '{0}' is an invalid value.",
|
||||
// value), ex);
|
||||
// }
|
||||
//
|
||||
// #endregion
|
||||
// }
|
||||
// }
|
||||
// return scope;
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,10 @@
|
||||
<Compile Include="Globalization\AspNetResourceCache.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Objects\Factory\Support\IWebObjectNameGenerator.cs" />
|
||||
<Compile Include="Objects\Factory\Xml\WebObjectDefinitionDocumentReader.cs" />
|
||||
<Compile Include="Objects\Factory\Xml\WebObjectDefinitionParserHelper.cs" />
|
||||
<Compile Include="Objects\Factory\Xml\WebObjectDefinitionReader.cs" />
|
||||
<Compile Include="Util\ISessionState.cs" />
|
||||
<Compile Include="Util\SecurityCritical.cs" />
|
||||
<Compile Include="Web\Support\DefaultHandlerFactory.cs" />
|
||||
|
||||
@@ -49,34 +49,60 @@ namespace Spring.Util
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class HttpContextSwitch : IDisposable
|
||||
{
|
||||
private HttpContext savedContext;
|
||||
private string originalUrl;
|
||||
private readonly IDisposable rewriteContext;
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(HttpContextSwitch));
|
||||
|
||||
// /// <summary>
|
||||
// /// Performs an immediate call to <see cref="HttpContext.RewritePath(string)"/>
|
||||
// /// </summary>
|
||||
// /// <param name="virtualDirectory">a directory path (without trailing filename!)</param>
|
||||
// public HttpContextSwitch( string virtualDirectory )
|
||||
// {
|
||||
// HttpContext currentContext = HttpContext.Current;
|
||||
// if (currentContext == null) return; // no webrequest
|
||||
//
|
||||
// virtualDirectory = WebUtils.GetVirtualDirectory(virtualDirectory);
|
||||
// string currentFileDirectory = WebUtils.GetVirtualDirectory(currentContext.Request.FilePath);
|
||||
// // only switch path if necessary
|
||||
// if (string.Compare( virtualDirectory, currentFileDirectory, true ) != 0)
|
||||
// {
|
||||
// savedContext = currentContext;
|
||||
// originalUrl = savedContext.Request.Url.PathAndQuery;
|
||||
// string newPath = virtualDirectory + "currentcontext.dummy";
|
||||
//#if NET_2_0
|
||||
// savedContext.RewritePath( newPath, false );
|
||||
//#else
|
||||
// savedContext.RewritePath( newPath );
|
||||
//#endif
|
||||
// if (log.IsDebugEnabled) log.Debug("rewriting path from " + originalUrl + " to " + newPath + " results in " + savedContext.Request.FilePath);
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Performs an immediate call to <see cref="HttpContext.RewritePath(string)"/>
|
||||
/// </summary>
|
||||
/// <param name="virtualDirectory">a directory path (without trailing filename!)</param>
|
||||
public HttpContextSwitch( string virtualDirectory )
|
||||
public HttpContextSwitch(string virtualDirectory)
|
||||
{
|
||||
HttpContext currentContext = HttpContext.Current;
|
||||
if (currentContext == null) return; // no webrequest
|
||||
rewriteContext = VirtualEnvironment.RewritePath(virtualDirectory, false);
|
||||
|
||||
virtualDirectory = WebUtils.GetVirtualDirectory(virtualDirectory);
|
||||
string currentFileDirectory = WebUtils.GetVirtualDirectory(currentContext.Request.FilePath);
|
||||
// only switch path if necessary
|
||||
if (string.Compare( virtualDirectory, currentFileDirectory, true ) != 0)
|
||||
{
|
||||
savedContext = currentContext;
|
||||
originalUrl = savedContext.Request.Url.PathAndQuery;
|
||||
string newPath = virtualDirectory + "currentcontext.dummy";
|
||||
#if NET_2_0
|
||||
savedContext.RewritePath( newPath, false );
|
||||
#else
|
||||
savedContext.RewritePath( newPath );
|
||||
#endif
|
||||
if (log.IsDebugEnabled) log.Debug("rewriting path from " + originalUrl + " to " + newPath + " results in " + savedContext.Request.FilePath);
|
||||
}
|
||||
// string currentFileDirectory = WebUtils.GetVirtualDirectory(VirtualEnvironment.CurrentVirtualFilePath);
|
||||
// // only switch path if necessary
|
||||
// if (string.Compare(virtualDirectory, currentFileDirectory, true) != 0)
|
||||
// {
|
||||
// originalUrl = VirtualEnvironment.CurrentVirtualPathAndQuery;
|
||||
// string newPath = virtualDirectory + "currentcontext.dummy";
|
||||
// VirtualEnvironment.RewritePath(newPath, false);
|
||||
//
|
||||
// #region Instrumentation
|
||||
//
|
||||
// if (log.IsDebugEnabled)
|
||||
// {
|
||||
// log.Debug("rewriting path from " + originalUrl + " to " + newPath + " results in " + VirtualEnvironment.CurrentVirtualFilePath);
|
||||
// }
|
||||
//
|
||||
// #endregion
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -84,17 +110,45 @@ namespace Spring.Util
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (savedContext != null)
|
||||
{
|
||||
if (log.IsDebugEnabled) log.Debug("restoring original path from " + savedContext.Request.FilePath + " back to " + originalUrl);
|
||||
HttpContext context = savedContext;
|
||||
savedContext = null;
|
||||
#if NET_2_0
|
||||
context.RewritePath( originalUrl, false );
|
||||
#else
|
||||
context.RewritePath( originalUrl );
|
||||
#endif
|
||||
}
|
||||
rewriteContext.Dispose();
|
||||
// if (rewriteContext != null)
|
||||
// {
|
||||
// VirtualEnvironment.RewritePath(originalUrl, false);
|
||||
//
|
||||
// #region Instrumentation
|
||||
//
|
||||
// if (log.IsDebugEnabled)
|
||||
// {
|
||||
// log.Debug("restoring original path from " + VirtualEnvironment.CurrentVirtualFilePath + " back to " + originalUrl);
|
||||
// }
|
||||
//
|
||||
// #endregion
|
||||
// }
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// Restores original path if necessary
|
||||
// /// </summary>
|
||||
// public void Dispose()
|
||||
// {
|
||||
// if (originalUrl != null)
|
||||
// {
|
||||
// HttpContext context = HttpContext.Current;
|
||||
//#if NET_2_0
|
||||
// context.RewritePath( originalUrl, false );
|
||||
//#else
|
||||
// context.RewritePath( originalUrl );
|
||||
//#endif
|
||||
//
|
||||
// #region Instrumentation
|
||||
//
|
||||
// if (log.IsDebugEnabled)
|
||||
// {
|
||||
// log.Debug("restoring original path from " + context.Request.FilePath + " back to " + originalUrl);
|
||||
// }
|
||||
//
|
||||
// #endregion
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
@@ -64,17 +65,40 @@ namespace Spring.Util
|
||||
/// </remarks>
|
||||
string CurrentExecutionFilePath { get; }
|
||||
/// <summary>
|
||||
/// The query parameters
|
||||
/// </summary>
|
||||
NameValueCollection QueryString { get; }
|
||||
/// <summary>
|
||||
/// Maps a virtual path to it's physical location
|
||||
/// </summary>
|
||||
string MapPath( string virtualPath );
|
||||
/// <summary>
|
||||
/// Rewrites the <see cref="CurrentVirtualPath"/>, thus also affecting <see cref="MapPath"/>
|
||||
/// </summary>
|
||||
IDisposable RewritePath(string newVirtualPath, bool rebaseClientPath);
|
||||
/// <summary>
|
||||
/// Returns the current Session's variable dictionary
|
||||
/// </summary>
|
||||
ISessionState Session { get; }
|
||||
/// <summary>
|
||||
/// Returns the current Request's variable dictionary
|
||||
/// Returns the current Request's variable dictionary <see cref="HttpContext.Items"/>
|
||||
/// </summary>
|
||||
IDictionary RequestVariables { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Request's parameter dictionary <see cref="HttpRequest.Params"/>
|
||||
/// </summary>
|
||||
NameValueCollection RequestParams { get; }
|
||||
/// <summary>
|
||||
/// Get the compiled type for the given virtual path
|
||||
/// </summary>
|
||||
/// <param name="absoluteVirtualPath">the absolute (=rooted) virtual path</param>
|
||||
/// <returns></returns>
|
||||
Type GetCompiledType(string absoluteVirtualPath);
|
||||
/// <summary>
|
||||
/// Creates an instance from the given virtual path
|
||||
/// </summary>
|
||||
/// <param name="absoluteVirtualPath">the absolute (=rooted) virtual path</param>
|
||||
/// <param name="requiredBaseType">the required base type </param>
|
||||
object CreateInstanceFromVirtualPath(string absoluteVirtualPath, Type requiredBaseType);
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,15 @@
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
using System.Web.Compilation;
|
||||
using System.Web.SessionState;
|
||||
using System.Web.UI;
|
||||
using Common.Logging;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -229,6 +234,75 @@ namespace Spring.Util
|
||||
|
||||
#endregion //HttpSessionState Adapter
|
||||
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof (HttpRuntimeEnvironment));
|
||||
|
||||
#if NET_1_1
|
||||
// Required method for resolving control types
|
||||
private static MethodInfo miGetCompiledUserControlType = null;
|
||||
|
||||
static HttpRuntimeEnvironment()
|
||||
{
|
||||
Type tUserControlParser = typeof(System.Web.UI.UserControl).Assembly.GetType("System.Web.UI.UserControlParser");
|
||||
miGetCompiledUserControlType = tUserControlParser.GetMethod("GetCompiledUserControlType", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
}
|
||||
#endif
|
||||
private class RewriteContext : IDisposable
|
||||
{
|
||||
private string originalPath;
|
||||
private bool rebaseClientPath;
|
||||
private HttpContext ctx;
|
||||
|
||||
public RewriteContext(string virtualDirectory, bool rebaseClientPath)
|
||||
{
|
||||
ctx = HttpContext.Current;
|
||||
if (ctx == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.rebaseClientPath = rebaseClientPath;
|
||||
|
||||
string newVirtualPath = WebUtils.GetVirtualDirectory(virtualDirectory);
|
||||
string currentFileDirectory = WebUtils.GetVirtualDirectory(ctx.Request.FilePath);
|
||||
// only switch path if necessary
|
||||
if (string.Compare(newVirtualPath, currentFileDirectory, true) != 0)
|
||||
{
|
||||
originalPath = ctx.Request.Url.PathAndQuery;
|
||||
string newPath = newVirtualPath + "currentcontext.dummy";
|
||||
#if NET_1_1
|
||||
ctx.RewritePath(newPath);
|
||||
#else
|
||||
ctx.RewritePath(newPath, rebaseClientPath);
|
||||
#endif
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug("rewriting path from " + currentFileDirectory + " to " + newPath + " results in " + ctx.Request.FilePath);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (originalPath != null)
|
||||
{
|
||||
if (log.IsDebugEnabled)
|
||||
{
|
||||
log.Debug("restoring path from " + ctx.Request.FilePath + " back to " + originalPath);
|
||||
}
|
||||
#if NET_1_1
|
||||
ctx.RewritePath(originalPath);
|
||||
#else
|
||||
ctx.RewritePath(originalPath, rebaseClientPath);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ApplicationVirtualPath
|
||||
{
|
||||
get
|
||||
@@ -254,6 +328,11 @@ namespace Spring.Util
|
||||
get { return HttpContext.Current.Request.CurrentExecutionFilePath; }
|
||||
}
|
||||
|
||||
public NameValueCollection QueryString
|
||||
{
|
||||
get { return HttpContext.Current.Request.QueryString; }
|
||||
}
|
||||
|
||||
public string MapPath(string virtualPath)
|
||||
{
|
||||
HttpContext ctx = HttpContext.Current;
|
||||
@@ -261,8 +340,9 @@ namespace Spring.Util
|
||||
{
|
||||
return ctx.Request.MapPath(virtualPath);
|
||||
}
|
||||
#if NET_2_0
|
||||
|
||||
#if NET_1_1
|
||||
throw new ArgumentException("can't map context relative path outside a context");
|
||||
#else
|
||||
if (VirtualPathUtility.IsAbsolute(virtualPath) && virtualPath.StartsWith(HttpRuntime.AppDomainAppVirtualPath))
|
||||
{
|
||||
virtualPath = VirtualPathUtility.ToAppRelative(virtualPath);
|
||||
@@ -273,8 +353,13 @@ namespace Spring.Util
|
||||
string physicalPath = Path.Combine(HttpRuntime.AppDomainAppPath, virtualPath);
|
||||
return physicalPath;
|
||||
}
|
||||
return virtualPath;
|
||||
#endif
|
||||
throw new ArgumentException("can't map context relative path outside a context");
|
||||
}
|
||||
|
||||
public IDisposable RewritePath(string virtualDirectory, bool rebaseClientPath)
|
||||
{
|
||||
return new RewriteContext(virtualDirectory, rebaseClientPath);
|
||||
}
|
||||
|
||||
public ISessionState Session
|
||||
@@ -286,6 +371,49 @@ namespace Spring.Util
|
||||
{
|
||||
get { return HttpContext.Current.Items; }
|
||||
}
|
||||
|
||||
public NameValueCollection RequestParams
|
||||
{
|
||||
get { return HttpContext.Current.Request.Params; }
|
||||
}
|
||||
|
||||
public Type GetCompiledType(string virtualPath)
|
||||
{
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths(CurrentExecutionFilePath, virtualPath);
|
||||
|
||||
Type type = null;
|
||||
#if NET_1_1
|
||||
if (virtualPath.EndsWith(".aspx"))
|
||||
{
|
||||
type = CreateInstanceFromVirtualPath(virtualPath, typeof(Page)).GetType();
|
||||
}
|
||||
else if (virtualPath.EndsWith(".ascx"))
|
||||
{
|
||||
type = (Type)miGetCompiledUserControlType.Invoke(null, new object[] { rootedVPath, null, HttpContext.Current });
|
||||
}
|
||||
#else
|
||||
type = BuildManager.GetCompiledType(rootedVPath); // requires rooted virtual path!
|
||||
#endif
|
||||
return type;
|
||||
}
|
||||
|
||||
public object CreateInstanceFromVirtualPath(string virtualPath, Type requiredBaseType)
|
||||
{
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths(CurrentExecutionFilePath, virtualPath);
|
||||
object result;
|
||||
#if NET_1_1
|
||||
HttpContext ctx = HttpContext.Current;
|
||||
string physicalPath = ctx.Server.MapPath(rootedVPath);
|
||||
result = PageParser.GetCompiledPageInstance(virtualPath, physicalPath, ctx);
|
||||
#else
|
||||
result = BuildManager.CreateInstanceFromVirtualPath(rootedVPath, requiredBaseType);
|
||||
#endif
|
||||
if (!requiredBaseType.IsAssignableFrom(result.GetType()))
|
||||
{
|
||||
throw new HttpException(string.Format("Type '{0}' from virtual path '{1}' does not inherit from '{2}'", result.GetType(), rootedVPath, requiredBaseType));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -306,6 +434,22 @@ namespace Spring.Util
|
||||
get { return instance.CurrentVirtualPath; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The virtual (rooted) path of the current Request including <see cref="HttpRequest.PathInfo"/>
|
||||
/// </summary>
|
||||
public static string CurrentVirtualPathAndQuery
|
||||
{
|
||||
get
|
||||
{
|
||||
string result = CurrentVirtualPath;
|
||||
if (QueryString.Count > 0)
|
||||
{
|
||||
result = result + "?" + QueryString.ToString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The virtual (rooted) path of the current Request without trailing <see cref="HttpRequest.PathInfo"/>
|
||||
/// </summary>
|
||||
@@ -322,6 +466,30 @@ namespace Spring.Util
|
||||
get { return instance.CurrentExecutionFilePath; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The query parameters
|
||||
/// </summary>
|
||||
public static NameValueCollection QueryString
|
||||
{
|
||||
get { return instance.QueryString; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Request's variable dictionary (<see cref="HttpContext.Items"/>)
|
||||
/// </summary>
|
||||
public static IDictionary RequestVariables
|
||||
{
|
||||
get { return instance.RequestVariables; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Request's parameter dictionary (<see cref="HttpRequest.Params"/>)
|
||||
/// </summary>
|
||||
public static NameValueCollection RequestParams
|
||||
{
|
||||
get { return instance.RequestParams; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a virtual path to it's physical location
|
||||
/// </summary>
|
||||
@@ -330,6 +498,32 @@ namespace Spring.Util
|
||||
return instance.MapPath(virtualPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rewrites the <see cref="CurrentVirtualPath"/>, thus also affecting <see cref="MapPath"/>
|
||||
/// </summary>
|
||||
public static IDisposable RewritePath(string newVirtualPath, bool rebaseClientPath)
|
||||
{
|
||||
return instance.RewritePath(newVirtualPath, rebaseClientPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an instance of the specified file.
|
||||
/// </summary>
|
||||
public static object CreateInstanceFromVirtualPath(string virtualPath, Type requiredBaseType)
|
||||
{
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths(instance.CurrentExecutionFilePath, virtualPath);
|
||||
return instance.CreateInstanceFromVirtualPath(rootedVPath, requiredBaseType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an the compiled type of the specified file.
|
||||
/// </summary>
|
||||
public static Type GetCompiledType(string virtualPath)
|
||||
{
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths(instance.CurrentExecutionFilePath, virtualPath);
|
||||
return instance.GetCompiledType(rootedVPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Receives EndRequest-event from an <see cref="HttpApplication"/> instance
|
||||
/// and dispatches it to all handlers registered with this module.
|
||||
|
||||
@@ -318,7 +318,7 @@ namespace Spring.Web.Support
|
||||
return handler;
|
||||
}
|
||||
#else
|
||||
private static readonly IDynamicField fControls = SafeField.CreateFrom(GetField("_controls"));
|
||||
private static readonly IDynamicField fControls = new SafeField(GetField("_controls"));
|
||||
|
||||
private ControlCollection GetChildControlCollection()
|
||||
{
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace Spring.Web.Support
|
||||
}
|
||||
else
|
||||
{
|
||||
handler = WebObjectUtils.CreateHandler(context, rawUrl);
|
||||
handler = WebObjectUtils.CreateHandler(rawUrl);
|
||||
// let WebSupportModule handle configuration
|
||||
handler = WebSupportModule.ConfigureHandler(context, handler, appContext, rawUrl, false);
|
||||
}
|
||||
|
||||
@@ -1784,7 +1784,8 @@ namespace Spring.Objects.Factory.Xml
|
||||
</objects>";
|
||||
stream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
|
||||
IObjectFactory factory = new XmlObjectFactory(new InputStreamResource(stream, string.Empty));
|
||||
factory.GetObject("foo");
|
||||
ITestObject to = (ITestObject) factory.GetObject("foo");
|
||||
Assert.IsNotNull( to.Spouse );
|
||||
}
|
||||
|
||||
[Test(Description="SPR-1313")]
|
||||
|
||||
@@ -803,6 +803,7 @@
|
||||
<Content Include="Data\Spring\Objects\Factory\Xml\collections.xml" />
|
||||
<Content Include="Data\Spring\Objects\Factory\Xml\constructor-arg.xml" />
|
||||
<Content Include="Data\Spring\Objects\Factory\Xml\array-autowire.xml" />
|
||||
<Content Include="Data\Spring\Objects\Factory\Xml\objectNameGeneration.xml" />
|
||||
<Content Include="Data\Spring\Objects\Factory\Xml\simple-constructor-arg.xml" />
|
||||
<Content Include="Data\Spring\Objects\Factory\Xml\expressions.xml" />
|
||||
<Content Include="Data\Spring\Objects\Factory\Xml\default-autowire.xml" />
|
||||
|
||||
@@ -404,5 +404,23 @@ namespace Spring.Util
|
||||
|
||||
return ((int)dex.Key).CompareTo(dey.Key);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindFirstMatchReturnsNullIfAnyInputIsEmpty()
|
||||
{
|
||||
Assert.IsNull( CollectionUtils.FindFirstMatch(null, null) );
|
||||
Assert.IsNull( CollectionUtils.FindFirstMatch(new string[0], new string[0]));
|
||||
Assert.IsNull( CollectionUtils.FindFirstMatch(null, new string[] { "x" }));
|
||||
Assert.IsNull( CollectionUtils.FindFirstMatch(new string[] { "x" }, null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindFirstMatchReturnsFirstMatch()
|
||||
{
|
||||
ArrayList source = new ArrayList();
|
||||
string[] candidates = new string[] { "G", "B", "H" };
|
||||
source.AddRange( new string[] { "A", "B", "C" } );
|
||||
Assert.AreEqual( "B" , CollectionUtils.FindFirstMatch(source, candidates));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,11 @@ namespace Spring.Validation
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsObjectNameInUse(string objectName)
|
||||
{
|
||||
return this.objects[objectName] != null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,7 +39,7 @@ namespace Spring.Core.IO
|
||||
[TestFixtureSetUp]
|
||||
public void SetUpFixture()
|
||||
{
|
||||
testVirtualEnvironment = new VirtualEnvironmentMock("/some.request", "somepathinfo", "/", true);
|
||||
testVirtualEnvironment = new VirtualEnvironmentMock("/some.request", "somepathinfo", null, "/", true);
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Spring.Objects.Factory.Support
|
||||
|
||||
// we need to create WOF within a valid HttpContext environment 'cause we will
|
||||
// make use of 'request' and 'session' scope.
|
||||
using (new VirtualEnvironmentMock("/somedir/some.file", null, "/", true))
|
||||
using (new VirtualEnvironmentMock("/somedir/some.file", null, null, "/", true))
|
||||
{
|
||||
wof = new WebObjectFactory("/somedir/", false);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Spring.Objects.Factory.Support
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
[TestFixture]
|
||||
public class WebObjectUtilsTests
|
||||
{
|
||||
[Test]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void GetPageTypeWithNullPageName()
|
||||
{
|
||||
WebObjectUtils.GetPageType(null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void GetPageTypeWithEmptyStringPageName()
|
||||
{
|
||||
WebObjectUtils.GetPageType(string.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void GetPageTypeWithWhitespacedPageName()
|
||||
{
|
||||
WebObjectUtils.GetPageType(" ");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(ObjectCreationException))]
|
||||
public void CreatePageInstanceWhenNotRunningInServerContext()
|
||||
{
|
||||
WebObjectUtils.CreatePageInstance("foo.aspx");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Xml;
|
||||
using NUnit.Framework;
|
||||
using Spring.Collections;
|
||||
using Spring.Core.IO;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.TestSupport;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Objects.Factory
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
[TestFixture]
|
||||
public class WebObjectDefinitionReaderTests
|
||||
{
|
||||
public class TestWebObjectDefinitionReader : WebObjectDefinitionReader
|
||||
{
|
||||
public TestWebObjectDefinitionReader(string contextVirtualPath, IObjectDefinitionRegistry registry, XmlResolver resolver)
|
||||
: base(contextVirtualPath, registry, resolver)
|
||||
{}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ControlDefinitionsGetMarkedAbstract()
|
||||
{
|
||||
const string CONTEXTPATH = "/ContextPath/";
|
||||
const string xml =
|
||||
@"<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<objects xmlns='http://www.springframework.net'>
|
||||
<object type='MyControl.ascx' />
|
||||
</objects>";
|
||||
|
||||
WebObjectFactory objectFactory = new WebObjectFactory(CONTEXTPATH, false);
|
||||
TestWebObjectDefinitionReader reader = new TestWebObjectDefinitionReader(objectFactory.ContextPath, objectFactory, new XmlUrlResolver());
|
||||
|
||||
using (VirtualEnvironmentMock env = new VirtualEnvironmentMock(CONTEXTPATH + "test.aspx", null, null, CONTEXTPATH, true))
|
||||
{
|
||||
env.VirtualPath2ArtifactsTable[CONTEXTPATH + "MyControl.ascx"] = typeof(Spring.Web.UI.UserControl);
|
||||
|
||||
reader.LoadObjectDefinitions(new StringResource(xml));
|
||||
}
|
||||
|
||||
Assert.IsTrue(objectFactory.ContainsObjectDefinition("Spring.Web.UI.UserControl"));
|
||||
Assert.IsTrue(objectFactory.GetObjectDefinition("Spring.Web.UI.UserControl").IsAbstract);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParsesPagePathIntoObjectNameIfNeitherIdNorNameAttributeSpecified()
|
||||
{
|
||||
const string CONTEXTPATH = "/ContextPath/";
|
||||
|
||||
const string xml =
|
||||
@"<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<objects xmlns='http://www.springframework.net'>
|
||||
<object type='MyPage.aspx' />
|
||||
<object type='~/MyControl.ascx' />
|
||||
</objects>";
|
||||
|
||||
WebObjectFactory objectFactory = new WebObjectFactory(CONTEXTPATH, false);
|
||||
TestWebObjectDefinitionReader reader = new TestWebObjectDefinitionReader(objectFactory.ContextPath, objectFactory, new XmlUrlResolver());
|
||||
|
||||
using (VirtualEnvironmentMock env = new VirtualEnvironmentMock(CONTEXTPATH + "test.aspx", null, null, CONTEXTPATH, true))
|
||||
{
|
||||
env.VirtualPath2ArtifactsTable[CONTEXTPATH + "MyPage.aspx"] = typeof (Spring.Web.UI.Page);
|
||||
env.VirtualPath2ArtifactsTable[CONTEXTPATH + "MyControl.ascx"] = typeof (Spring.Web.UI.UserControl);
|
||||
|
||||
reader.LoadObjectDefinitions(new StringResource(xml));
|
||||
}
|
||||
|
||||
Assert.IsTrue(objectFactory.ContainsObjectDefinition("/MyPage.aspx"));
|
||||
Assert.AreEqual(typeof(Spring.Web.UI.Page), objectFactory.GetType("/MyPage.aspx"));
|
||||
Assert.IsTrue(objectFactory.ContainsObjectDefinition("Spring.Web.UI.UserControl"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DoesNotGenerateObjectNameIfIdAttributeSpecified()
|
||||
{
|
||||
const string CONTEXTPATH = "/ContextPath/";
|
||||
const string xml =
|
||||
@"<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<objects xmlns='http://www.springframework.net'>
|
||||
<object id='mypage' type='MyPage.aspx' />
|
||||
<object id='mycontrol' type='MyControl.ascx' />
|
||||
</objects>";
|
||||
|
||||
WebObjectFactory objectFactory = new WebObjectFactory(CONTEXTPATH, false);
|
||||
TestWebObjectDefinitionReader reader = new TestWebObjectDefinitionReader(objectFactory.ContextPath, objectFactory, new XmlUrlResolver());
|
||||
|
||||
using (VirtualEnvironmentMock env = new VirtualEnvironmentMock(CONTEXTPATH + "test.aspx", null, null, CONTEXTPATH, true))
|
||||
{
|
||||
env.VirtualPath2ArtifactsTable[CONTEXTPATH + "MyPage.aspx"] = typeof (Spring.Web.UI.Page);
|
||||
env.VirtualPath2ArtifactsTable[CONTEXTPATH + "MyControl.ascx"] = typeof (Spring.Web.UI.UserControl);
|
||||
|
||||
reader.LoadObjectDefinitions(new StringResource(xml));
|
||||
}
|
||||
|
||||
Assert.IsTrue(objectFactory.ContainsObjectDefinition("mypage"));
|
||||
Assert.AreEqual(typeof(Spring.Web.UI.Page), objectFactory.GetType("mypage"));
|
||||
Assert.IsTrue(objectFactory.ContainsObjectDefinition("mycontrol"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DoesNotGenerateObjectNameIfNameAttributeSpecified()
|
||||
{
|
||||
const string CONTEXTPATH = "/ContextPath/";
|
||||
const string xml =
|
||||
@"<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<objects xmlns='http://www.springframework.net'>
|
||||
<object name='mypage' type='MyPage.aspx' />
|
||||
<object name='mycontrol' type='MyControl.ascx' />
|
||||
</objects>";
|
||||
|
||||
WebObjectFactory objectFactory = new WebObjectFactory(CONTEXTPATH, false);
|
||||
TestWebObjectDefinitionReader reader = new TestWebObjectDefinitionReader(objectFactory.ContextPath, objectFactory, new XmlUrlResolver());
|
||||
|
||||
using (VirtualEnvironmentMock env = new VirtualEnvironmentMock(CONTEXTPATH + "test.aspx", null, null, CONTEXTPATH, true))
|
||||
{
|
||||
env.VirtualPath2ArtifactsTable[CONTEXTPATH + "MyPage.aspx"] = typeof(Spring.Web.UI.Page);
|
||||
env.VirtualPath2ArtifactsTable[CONTEXTPATH + "MyControl.ascx"] = typeof(Spring.Web.UI.UserControl);
|
||||
|
||||
reader.LoadObjectDefinitions(new StringResource(xml));
|
||||
}
|
||||
|
||||
Assert.IsTrue(objectFactory.ContainsObjectDefinition("mypage"));
|
||||
Assert.AreEqual(typeof(Spring.Web.UI.Page), objectFactory.GetType("mypage"));
|
||||
Assert.IsTrue(objectFactory.ContainsObjectDefinition("mycontrol"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DoesNotGenerateObjectNameIfIdAndNameAttributeSpecified()
|
||||
{
|
||||
const string CONTEXTPATH = "/";
|
||||
const string xml =
|
||||
@"<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<objects xmlns='http://www.springframework.net'>
|
||||
<object id='mypage' name='mypageAlias' type='~/MyPage.aspx' />
|
||||
<object id='mycontrol' name='mycontrolAlias' type='~/MyControl.ascx' />
|
||||
</objects>";
|
||||
|
||||
WebObjectFactory objectFactory = new WebObjectFactory(CONTEXTPATH, false);
|
||||
TestWebObjectDefinitionReader reader = new TestWebObjectDefinitionReader(objectFactory.ContextPath, objectFactory, new XmlUrlResolver());
|
||||
|
||||
using (VirtualEnvironmentMock env = new VirtualEnvironmentMock(CONTEXTPATH + "test.aspx", null, null, CONTEXTPATH, true))
|
||||
{
|
||||
env.VirtualPath2ArtifactsTable[CONTEXTPATH + "MyPage.aspx"] = typeof(Spring.Web.UI.Page);
|
||||
env.VirtualPath2ArtifactsTable[CONTEXTPATH + "MyControl.ascx"] = typeof(Spring.Web.UI.UserControl);
|
||||
|
||||
reader.LoadObjectDefinitions(new StringResource(xml));
|
||||
}
|
||||
|
||||
Assert.IsTrue(objectFactory.ContainsObjectDefinition("mypage"));
|
||||
Assert.IsTrue(objectFactory.ContainsObject("mypageAlias"));
|
||||
Assert.IsTrue(objectFactory.ContainsObjectDefinition("mycontrol"));
|
||||
Assert.IsTrue(objectFactory.ContainsObject("mycontrolAlias"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,6 +104,8 @@
|
||||
<Compile Include="Objects\Factory\Support\WebObjectFactoryTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Objects\Factory\Support\WebObjectUtilsTests.cs" />
|
||||
<Compile Include="Objects\Factory\Xml\WebObjectDefinitionReaderTests.cs" />
|
||||
<Compile Include="TestSupport\NUnitAdapter.cs" />
|
||||
<Compile Include="TestSupport\SessionMock.cs" />
|
||||
<Compile Include="TestSupport\TestPage.cs">
|
||||
|
||||
@@ -2,6 +2,9 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using Spring.Collections;
|
||||
using Spring.Util;
|
||||
|
||||
@@ -15,20 +18,30 @@ namespace Spring.TestSupport
|
||||
{
|
||||
private readonly IVirtualEnvironment _prevEnvironment;
|
||||
|
||||
private readonly string _currentVirtualFilePath;
|
||||
private readonly string _pathInfo;
|
||||
private string _currentVirtualFilePath;
|
||||
private string _pathInfo;
|
||||
private HttpValueCollection _query;
|
||||
private string _currentExecutionFilePath;
|
||||
private readonly string _applicationVirtualPath;
|
||||
private ISessionState _session = new SessionMock();
|
||||
private IDictionary _requestVariables = new CaseInsensitiveHashtable(); //CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
private NameValueCollection requestParams = new NameValueCollection();
|
||||
private IDictionary virtualPath2ArtifactsTable = new CaseInsensitiveHashtable();
|
||||
|
||||
public VirtualEnvironmentMock(string currentVirtualFilePath, string pathInfo, string applicationVirtualPath, bool autoInitialize)
|
||||
public VirtualEnvironmentMock(string currentVirtualFilePath, string pathInfo, string queryText, string applicationVirtualPath, bool autoInitialize)
|
||||
{
|
||||
_currentVirtualFilePath = currentVirtualFilePath;
|
||||
_currentExecutionFilePath = currentVirtualFilePath;
|
||||
_pathInfo = (pathInfo == null || pathInfo.Length == 0) ? "" : "/" + pathInfo.TrimStart('/'); // prevent null string and ensure '/' prefixed
|
||||
_query = new HttpValueCollection(queryText);
|
||||
_applicationVirtualPath = "/" + ("" + applicationVirtualPath).Trim('/');
|
||||
if (!_applicationVirtualPath.EndsWith("/")) _applicationVirtualPath = _applicationVirtualPath + "/";
|
||||
|
||||
// if (!_currentVirtualFilePath.StartsWith(_applicationVirtualPath))
|
||||
// {
|
||||
// throw new ArgumentException("currentVirtualFilePath must begin with applicationVirtualPath");
|
||||
// }
|
||||
|
||||
_prevEnvironment = VirtualEnvironment.SetInstance(this);
|
||||
if (autoInitialize)
|
||||
{
|
||||
@@ -36,6 +49,11 @@ namespace Spring.TestSupport
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary VirtualPath2ArtifactsTable
|
||||
{
|
||||
get { return virtualPath2ArtifactsTable; }
|
||||
}
|
||||
|
||||
public string ApplicationVirtualPath
|
||||
{
|
||||
get { return _applicationVirtualPath; }
|
||||
@@ -43,9 +61,19 @@ namespace Spring.TestSupport
|
||||
|
||||
public string CurrentVirtualPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentVirtualFilePath + _pathInfo;
|
||||
get { return _currentVirtualFilePath + _pathInfo; }
|
||||
}
|
||||
|
||||
public string CurrentVirtualPathAndQuery
|
||||
{
|
||||
get
|
||||
{
|
||||
string result = _currentVirtualFilePath + _pathInfo;
|
||||
if (_query.Count > 0)
|
||||
{
|
||||
result = result + "?" + _query.ToString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,14 +88,58 @@ namespace Spring.TestSupport
|
||||
set { this._currentExecutionFilePath = value; }
|
||||
}
|
||||
|
||||
public NameValueCollection QueryString
|
||||
{
|
||||
get { return _query; }
|
||||
}
|
||||
|
||||
public string MapPath(string virtualPath)
|
||||
{
|
||||
string basePath = Path.GetDirectoryName(new Uri(GetType().Assembly.CodeBase).LocalPath);
|
||||
string resultPath = WebUtils.CreateAbsolutePath(this.ApplicationVirtualPath, virtualPath);
|
||||
string resultPath = WebUtils.CreateAbsolutePath(this.CurrentVirtualFilePath, virtualPath);
|
||||
resultPath = basePath.TrimEnd('\\') + "\\" + resultPath.Replace('/', '\\').TrimStart('\\');
|
||||
return resultPath;
|
||||
}
|
||||
|
||||
public IDisposable RewritePath(string newVirtualPath, bool rebaseClientPath)
|
||||
{
|
||||
IDisposable ctx = new RewriteContext(CurrentVirtualPathAndQuery, false, this);
|
||||
|
||||
int index = newVirtualPath.IndexOf('?');
|
||||
if (index >= 0)
|
||||
{
|
||||
string newQueryString = (index < (newVirtualPath.Length - 1)) ? newVirtualPath.Substring(index + 1) : string.Empty;
|
||||
_query = new HttpValueCollection(newQueryString);
|
||||
newVirtualPath = newVirtualPath.Substring(0, index);
|
||||
}
|
||||
|
||||
_currentVirtualFilePath = newVirtualPath;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
public Type GetCompiledType(string virtualPath)
|
||||
{
|
||||
object o = virtualPath2ArtifactsTable[virtualPath];
|
||||
if (o == null)
|
||||
throw new FileNotFoundException(virtualPath);
|
||||
else if (o is Type)
|
||||
return (Type) o;
|
||||
else
|
||||
return o.GetType();
|
||||
}
|
||||
|
||||
public object CreateInstanceFromVirtualPath(string virtualPath, Type requiredBaseType)
|
||||
{
|
||||
object o = virtualPath2ArtifactsTable[virtualPath];
|
||||
if (o == null)
|
||||
throw new FileNotFoundException(virtualPath);
|
||||
else if (o is Type)
|
||||
return Activator.CreateInstance((Type)o);
|
||||
else
|
||||
return o;
|
||||
}
|
||||
|
||||
public ISessionState Session
|
||||
{
|
||||
get { return _session; }
|
||||
@@ -80,9 +152,152 @@ namespace Spring.TestSupport
|
||||
set { _requestVariables = value; }
|
||||
}
|
||||
|
||||
public NameValueCollection RequestParams
|
||||
{
|
||||
get { return requestParams; }
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
VirtualEnvironment.SetInstance(_prevEnvironment);
|
||||
}
|
||||
|
||||
private class RewriteContext : IDisposable
|
||||
{
|
||||
private string originalPath;
|
||||
private bool rebaseClientPath;
|
||||
private VirtualEnvironmentMock runtime;
|
||||
|
||||
public RewriteContext(string originalPath, bool rebaseClientPath, VirtualEnvironmentMock runtime)
|
||||
{
|
||||
this.originalPath = originalPath;
|
||||
this.rebaseClientPath = rebaseClientPath;
|
||||
this.runtime = runtime;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (originalPath != null)
|
||||
{
|
||||
this.runtime.RewritePath(originalPath, rebaseClientPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class HttpValueCollection : NameValueCollection
|
||||
{
|
||||
public HttpValueCollection(string queryText)
|
||||
{
|
||||
FillFromString(queryText, false, Encoding.UTF8);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(true);
|
||||
}
|
||||
|
||||
private void FillFromString(string s, bool urlencoded, Encoding encoding)
|
||||
{
|
||||
int num = (s != null) ? s.Length : 0;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
int startIndex = i;
|
||||
int num4 = -1;
|
||||
while (i < num)
|
||||
{
|
||||
char ch = s[i];
|
||||
if (ch == '=')
|
||||
{
|
||||
if (num4 < 0)
|
||||
{
|
||||
num4 = i;
|
||||
}
|
||||
}
|
||||
else if (ch == '&')
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
string str = null;
|
||||
string str2 = null;
|
||||
if (num4 >= 0)
|
||||
{
|
||||
str = s.Substring(startIndex, num4 - startIndex);
|
||||
str2 = s.Substring(num4 + 1, (i - num4) - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
str2 = s.Substring(startIndex, i - startIndex);
|
||||
}
|
||||
if (urlencoded)
|
||||
{
|
||||
base.Add(HttpUtility.UrlDecode(str, encoding), HttpUtility.UrlDecode(str2, encoding));
|
||||
}
|
||||
else
|
||||
{
|
||||
base.Add(str, str2);
|
||||
}
|
||||
if ((i == (num - 1)) && (s[i] == '&'))
|
||||
{
|
||||
base.Add(null, string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual string ToString(bool urlencoded)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int count = this.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string str3;
|
||||
string key = this.GetKey(i);
|
||||
if (urlencoded)
|
||||
{
|
||||
key = HttpUtility.UrlEncodeUnicode(key);
|
||||
}
|
||||
string str2 = ((key != null) && (key.Length > 0)) ? (key + "=") : "";
|
||||
ArrayList list = (ArrayList)base.BaseGet(i);
|
||||
int num3 = (list != null) ? list.Count : 0;
|
||||
if (i > 0)
|
||||
{
|
||||
builder.Append('&');
|
||||
}
|
||||
if (num3 == 1)
|
||||
{
|
||||
builder.Append(str2);
|
||||
str3 = (string)list[0];
|
||||
if (urlencoded)
|
||||
{
|
||||
str3 = HttpUtility.UrlEncodeUnicode(str3);
|
||||
}
|
||||
builder.Append(str3);
|
||||
}
|
||||
else if (num3 == 0)
|
||||
{
|
||||
builder.Append(str2);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < num3; j++)
|
||||
{
|
||||
if (j > 0)
|
||||
{
|
||||
builder.Append('&');
|
||||
}
|
||||
builder.Append(str2);
|
||||
str3 = (string)list[j];
|
||||
if (urlencoded)
|
||||
{
|
||||
str3 = HttpUtility.UrlEncodeUnicode(str3);
|
||||
}
|
||||
builder.Append(str3);
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,34 +39,6 @@ namespace Spring.Util
|
||||
{
|
||||
private const string ExpectedPageName = "foo";
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof (ArgumentNullException))]
|
||||
public void GetPageTypeWithNullPageName()
|
||||
{
|
||||
WebObjectUtils.GetPageType(null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof (ArgumentNullException))]
|
||||
public void GetPageTypeWithEmptyStringPageName()
|
||||
{
|
||||
WebObjectUtils.GetPageType(string.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof (ArgumentNullException))]
|
||||
public void GetPageTypeWithWhitespacedPageName()
|
||||
{
|
||||
WebObjectUtils.GetPageType(" ");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof (ObjectCreationException))]
|
||||
public void CreatePageInstanceWhenNotRunningInServerContext()
|
||||
{
|
||||
WebObjectUtils.CreatePageInstance("foo.aspx");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof (ArgumentNullException))]
|
||||
public void GetPageNameWithNullUrl()
|
||||
@@ -180,7 +152,7 @@ namespace Spring.Util
|
||||
public void CombineVirtualPathsInRootWeb()
|
||||
{
|
||||
// emulate root website context
|
||||
using( new VirtualEnvironmentMock("/somedir/some.file", null, "/", true) )
|
||||
using( new VirtualEnvironmentMock("/somedir/some.file", null, null, "/", true) )
|
||||
{
|
||||
CombineVirtualPathsSuite( "/" );
|
||||
}
|
||||
@@ -190,7 +162,7 @@ namespace Spring.Util
|
||||
public void CombineVirtualPathsInChildWeb()
|
||||
{
|
||||
// emulate child website context
|
||||
using( new VirtualEnvironmentMock("/somedir/some.file", null, "/myapp", true) )
|
||||
using( new VirtualEnvironmentMock("/somedir/some.file", null, null, "/myapp", true) )
|
||||
{
|
||||
CombineVirtualPathsSuite( "/myapp/" );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user