|
From: <fab...@us...> - 2008-10-10 19:19:47
|
Revision: 3835
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3835&view=rev
Author: fabiomaulo
Date: 2008-10-10 19:19:40 +0000 (Fri, 10 Oct 2008)
Log Message:
-----------
Few test passed
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Mapping/Property.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate/Properties/PropertyAccessorFactory.cs
trunk/nhibernate/src/NHibernate/Type/NullableType.cs
trunk/nhibernate/src/NHibernate.Test/EntityModeTest/Xml/Accessors/XmlAccessorFixture.cs
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Properties/XmlAccessor.cs
Modified: trunk/nhibernate/src/NHibernate/Mapping/Property.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/Property.cs 2008-10-10 16:29:37 UTC (rev 3834)
+++ trunk/nhibernate/src/NHibernate/Mapping/Property.cs 2008-10-10 19:19:40 UTC (rev 3835)
@@ -187,6 +187,11 @@
get { return PropertyAccessorFactory.GetPropertyAccessor(PropertyAccessorName); }
}
+ public virtual string GetAccessorPropertyName(EntityMode mode)
+ {
+ return mode == EntityMode.Xml ? nodeName : Name;
+ }
+
public virtual bool IsBasicPropertyAccessor
{
// NH Different behavior : see IPropertyAccessor.CanAccessThroughReflectionOptimizer (ref. NH-1304)
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2008-10-10 16:29:37 UTC (rev 3834)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2008-10-10 19:19:40 UTC (rev 3835)
@@ -1109,6 +1109,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Util\XmlHelper.cs" />
+ <Compile Include="Properties\XmlAccessor.cs" />
<EmbeddedResource Include="nhibernate-configuration.xsd">
<SubType>Designer</SubType>
</EmbeddedResource>
Modified: trunk/nhibernate/src/NHibernate/Properties/PropertyAccessorFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/PropertyAccessorFactory.cs 2008-10-10 16:29:37 UTC (rev 3834)
+++ trunk/nhibernate/src/NHibernate/Properties/PropertyAccessorFactory.cs 2008-10-10 19:19:40 UTC (rev 3835)
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
+using NHibernate.Type;
using NHibernate.Util;
+using NHibernate.Engine;
namespace NHibernate.Properties
{
@@ -213,11 +215,20 @@
return GetPocoPropertyAccessor(property.PropertyAccessorName);
case EntityMode.Map:
return DynamicMapPropertyAccessor;
+ case EntityMode.Xml:
+ return GetXmlPropertyAccessor(property.GetAccessorPropertyName(modeToUse), property.Type, null);
default:
throw new MappingException("Unknown entity mode [" + mode + "]");
}
}
+ private static IPropertyAccessor GetXmlPropertyAccessor(string nodeName, IType type, ISessionFactoryImplementor factory)
+ {
+ //TODO: need some caching scheme? really comes down to decision
+ // regarding amount of state (if any) kept on PropertyAccessors
+ return new XmlAccessor(nodeName, type, factory);
+ }
+
private static IPropertyAccessor GetPocoPropertyAccessor(string accessorName)
{
string accName = string.IsNullOrEmpty(accessorName) ? DefaultAccessorName : accessorName;
Added: trunk/nhibernate/src/NHibernate/Properties/XmlAccessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/XmlAccessor.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Properties/XmlAccessor.cs 2008-10-10 19:19:40 UTC (rev 3835)
@@ -0,0 +1,425 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Xml;
+using NHibernate.Engine;
+using NHibernate.Type;
+
+namespace NHibernate.Properties
+{
+ /// <summary>
+ /// Responsible for accessing property values represented as a XmlElement
+ /// or XmlAttribute.
+ /// </summary>
+ public class XmlAccessor : IPropertyAccessor
+ {
+ private readonly ISessionFactoryImplementor factory;
+ private readonly string nodeName;
+ private readonly IType propertyType;
+
+ public XmlAccessor(string nodeName, IType propertyType, ISessionFactoryImplementor factory)
+ {
+ this.factory = factory;
+ this.nodeName = nodeName;
+ this.propertyType = propertyType;
+ }
+
+ #region Implementation of IPropertyAccessor
+
+ public IGetter GetGetter(System.Type theClass, string propertyName)
+ {
+ if (nodeName == null)
+ {
+ throw new MappingException("no node name for property: " + propertyName);
+ }
+ if (".".Equals(nodeName))
+ {
+ return new TextGetter(propertyType, factory);
+ }
+ else if (nodeName.IndexOf('/') > -1)
+ {
+ return new ElementAttributeGetter(nodeName, propertyType, factory);
+ }
+ else if (nodeName.IndexOf('@') > -1)
+ {
+ return new AttributeGetter(nodeName, propertyType, factory);
+ }
+ else
+ {
+ return new ElementGetter(nodeName, propertyType, factory);
+ }
+ }
+
+ public ISetter GetSetter(System.Type theClass, string propertyName)
+ {
+ if (nodeName == null)
+ {
+ throw new MappingException("no node name for property: " + propertyName);
+ }
+ if (".".Equals(nodeName))
+ {
+ return new TextSetter(propertyType);
+ }
+ else if (nodeName.IndexOf('/') > -1)
+ {
+ return new ElementAttributeSetter(nodeName, propertyType);
+ }
+ else if (nodeName.IndexOf('@') > -1)
+ {
+ return new AttributeSetter(nodeName, propertyType);
+ }
+ else
+ {
+ return new ElementSetter(nodeName, propertyType);
+ }
+ }
+
+ public bool CanAccessThroughReflectionOptimizer
+ {
+ get { return true; }
+ }
+
+ #endregion
+
+ #region Nested type: AttributeGetter
+
+ /// <summary> For nodes like <tt>"@bar"</tt></summary>
+ [Serializable]
+ public class AttributeGetter : XmlGetter
+ {
+ private readonly string attributeName;
+
+ public AttributeGetter(string name, IType propertyType, ISessionFactoryImplementor factory)
+ : base(propertyType, factory)
+ {
+ attributeName = name.Substring(1);
+ }
+
+ public override object Get(object owner)
+ {
+ var ownerElement = (XmlNode) owner;
+ XmlNode attribute = ownerElement.Attributes[attributeName];
+ return attribute == null ? null : propertyType.FromXMLNode(attribute, factory);
+ }
+ }
+
+ #endregion
+
+ #region Nested type: AttributeSetter
+
+ /// <summary> For nodes like <tt>"@bar"</tt></summary>
+ [Serializable]
+ public class AttributeSetter : XmlSetter
+ {
+ private readonly string attributeName;
+
+ public AttributeSetter(string name, IType propertyType) : base(propertyType)
+ {
+ attributeName = name.Substring(1);
+ }
+
+ public override void Set(object target, object value)
+ {
+ var owner = (XmlElement) target;
+ XmlAttribute attribute = owner.Attributes[attributeName];
+ if (value == null)
+ {
+ if (attribute != null)
+ {
+ owner.Attributes.Remove(attribute);
+ }
+ }
+ else
+ {
+ if (attribute == null)
+ {
+ owner.SetAttribute(attributeName, "null");
+ attribute = owner.Attributes[attributeName];
+ }
+ propertyType.SetToXMLNode(attribute, value, null);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Nested type: ElementAttributeGetter
+
+ /// <summary> For nodes like <tt>"foo/@bar"</tt></summary>
+ [Serializable]
+ public class ElementAttributeGetter : XmlGetter
+ {
+ private readonly string attributeName;
+ private readonly string elementName;
+
+ public ElementAttributeGetter(string name, IType propertyType, ISessionFactoryImplementor factory)
+ : base(propertyType, factory)
+ {
+ elementName = name.Substring(0, (name.IndexOf('/')));
+ attributeName = name.Substring(name.IndexOf('/') + 2);
+ }
+
+ public override object Get(object owner)
+ {
+ var ownerElement = (XmlNode) owner;
+
+ XmlNode element = ownerElement[elementName];
+
+ if (element == null)
+ {
+ return null;
+ }
+ else
+ {
+ XmlAttribute attribute = element.Attributes[attributeName];
+ if (attribute == null)
+ {
+ return null;
+ }
+ else
+ {
+ return propertyType.FromXMLNode(attribute, factory);
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ #region Nested type: ElementAttributeSetter
+
+ /// <summary> For nodes like <tt>"foo/@bar"</tt></summary>
+ [Serializable]
+ public class ElementAttributeSetter : XmlSetter
+ {
+ private readonly string attributeName;
+ private readonly string elementName;
+
+ public ElementAttributeSetter(string name, IType propertyType) : base(propertyType)
+ {
+ elementName = name.Substring(0, name.IndexOf('/'));
+ attributeName = name.Substring(name.IndexOf('/') + 2);
+ }
+
+ public override void Set(object target, object value)
+ {
+ var owner = (XmlElement) target;
+ XmlElement element = owner[elementName];
+ if (value == null)
+ {
+ if (element != null)
+ {
+ owner.RemoveChild(element);
+ }
+ }
+ else
+ {
+ XmlAttribute attribute;
+ if (element == null)
+ {
+ element = owner.OwnerDocument.CreateElement(elementName);
+ owner.AppendChild(element);
+ attribute = null;
+ }
+ else
+ {
+ attribute = element.Attributes[attributeName];
+ }
+
+ if (attribute == null)
+ {
+ element.SetAttribute(attributeName, "null");
+ attribute = element.Attributes[attributeName];
+ }
+ propertyType.SetToXMLNode(attribute, value, null);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Nested type: ElementGetter
+
+ /// <summary> For nodes like <tt>"foo"</tt></summary>
+ [Serializable]
+ public class ElementGetter : XmlGetter
+ {
+ private readonly string elementName;
+
+ public ElementGetter(string name, IType propertyType, ISessionFactoryImplementor factory)
+ : base(propertyType, factory)
+ {
+ elementName = name;
+ }
+
+ public override object Get(object owner)
+ {
+ var ownerElement = (XmlNode) owner;
+ XmlNode element = ownerElement[elementName];
+ return element == null ? null : propertyType.FromXMLNode(element, factory);
+ }
+ }
+
+ #endregion
+
+ #region Nested type: ElementSetter
+
+ /// <summary> For nodes like <tt>"foo"</tt></summary>
+ [Serializable]
+ public class ElementSetter : XmlSetter
+ {
+ private readonly string elementName;
+
+ public ElementSetter(string name, IType propertyType) : base(propertyType)
+ {
+ elementName = name;
+ }
+
+ public override void Set(object target, object value)
+ {
+ if (value != CollectionType.UnfetchedCollection)
+ {
+ var owner = (XmlElement) target;
+ XmlElement existing = owner[elementName];
+ if (existing != null)
+ {
+ owner.RemoveChild(existing);
+ }
+ if (value != null)
+ {
+ XmlElement element = owner.OwnerDocument.CreateElement(elementName);
+ owner.AppendChild(element);
+ propertyType.SetToXMLNode(element, value, null);
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ #region Nested type: TextGetter
+
+ /// <summary> For nodes like <tt>"."</tt></summary>
+ [Serializable]
+ public class TextGetter : XmlGetter
+ {
+ public TextGetter(IType propertyType, ISessionFactoryImplementor factory) : base(propertyType, factory) {}
+
+ public override object Get(object owner)
+ {
+ var ownerElement = (XmlNode) owner;
+ return propertyType.FromXMLNode(ownerElement, factory);
+ }
+ }
+
+ #endregion
+
+ #region Nested type: TextSetter
+
+ /// <summary> For nodes like <tt>"."</tt></summary>
+ [Serializable]
+ public class TextSetter : XmlSetter
+ {
+ public TextSetter(IType propertyType) : base(propertyType) {}
+
+ public override void Set(object target, object value)
+ {
+ var owner = (XmlNode) target;
+ if (!propertyType.IsXMLElement)
+ {
+ //kinda ugly, but needed for collections with a "." node mapping
+ if (value == null)
+ {
+ owner.InnerText = ""; //is this ok?
+ }
+ else
+ {
+ propertyType.SetToXMLNode(owner, value, null);
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ #region Nested type: XmlGetter
+
+ /// <summary> Defines the strategy for getting property values out of a dom4j Node.</summary>
+ [Serializable]
+ public abstract class XmlGetter : IGetter
+ {
+ protected ISessionFactoryImplementor factory;
+ protected IType propertyType;
+
+ internal XmlGetter(IType propertyType, ISessionFactoryImplementor factory)
+ {
+ this.propertyType = propertyType;
+ this.factory = factory;
+ }
+
+ #region IGetter Members
+
+ /// <summary> Get the declared type</summary>
+ public virtual System.Type ReturnType
+ {
+ get { return typeof (object); }
+ }
+
+ /// <summary> Optional operation (return null)</summary>
+ public virtual string PropertyName
+ {
+ get { return null; }
+ }
+
+ /// <summary> Optional operation (return null)</summary>
+ public virtual MethodInfo Method
+ {
+ get { return null; }
+ }
+
+ public virtual object GetForInsert(object owner, IDictionary mergeMap, ISessionImplementor session)
+ {
+ return Get(owner);
+ }
+
+ public abstract object Get(object target);
+
+ #endregion
+ }
+
+ #endregion
+
+ #region Nested type: XmlSetter
+
+ [Serializable]
+ public abstract class XmlSetter : ISetter
+ {
+ protected internal IType propertyType;
+
+ internal XmlSetter(IType propertyType)
+ {
+ this.propertyType = propertyType;
+ }
+
+ #region ISetter Members
+
+ /// <summary> Optional operation (return null)</summary>
+ public virtual string PropertyName
+ {
+ get { return null; }
+ }
+
+ /// <summary> Optional operation (return null)</summary>
+ public virtual MethodInfo Method
+ {
+ get { return null; }
+ }
+
+ public abstract void Set(object target, object value);
+
+ #endregion
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
Property changes on: trunk/nhibernate/src/NHibernate/Properties/XmlAccessor.cs
___________________________________________________________________
Added: svn:mergeinfo
+
Modified: trunk/nhibernate/src/NHibernate/Type/NullableType.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Type/NullableType.cs 2008-10-10 16:29:37 UTC (rev 3834)
+++ trunk/nhibernate/src/NHibernate/Type/NullableType.cs 2008-10-10 19:19:40 UTC (rev 3835)
@@ -345,12 +345,12 @@
public override object FromXMLNode(XmlNode xml, IMapping factory)
{
- return FromXMLString(xml.Value, factory);
+ return FromXMLString(xml.InnerText, factory);
}
public override void SetToXMLNode(XmlNode xml, object value, ISessionFactoryImplementor factory)
{
- xml.Value = ToXMLString(value, factory);
+ xml.InnerText = ToXMLString(value, factory);
}
public string ToXMLString(object value, ISessionFactoryImplementor pc)
Modified: trunk/nhibernate/src/NHibernate.Test/EntityModeTest/Xml/Accessors/XmlAccessorFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/EntityModeTest/Xml/Accessors/XmlAccessorFixture.cs 2008-10-10 16:29:37 UTC (rev 3834)
+++ trunk/nhibernate/src/NHibernate.Test/EntityModeTest/Xml/Accessors/XmlAccessorFixture.cs 2008-10-10 19:19:40 UTC (rev 3835)
@@ -1,3 +1,4 @@
+using System;
using System.Xml;
using NHibernate.Mapping;
using NHibernate.Properties;
@@ -6,7 +7,7 @@
namespace NHibernate.Test.EntityModeTest.Xml.Accessors
{
- [TestFixture, Ignore("Not supported yet.")]
+ [TestFixture]
public class XmlAccessorFixture
{
public static XmlElement dom = GenerateTestElement();
@@ -77,6 +78,7 @@
nameSetter.Set(root, "NHForge");
accountIdSetter.Set(root, 456L);
+ Console.WriteLine(dom.OuterXml);
//Assert.That(new NodeComparator().Compare(dom, root) == 0);
}
@@ -107,7 +109,7 @@
Assert.That(name, Is.EqualTo("NHForge"));
}
- [Test]
+ [Test, Ignore("Not supported yet.")]
public void StringTextExtraction()
{
Property property = GenerateTextProperty();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|