Postat la
27-Feb-2009
ora
06:48 pm
de
[Chetroesu]
Incercand sa convertesc un cod Java la cod .NET, m-am lovit de problema implementarii unui modul care sa faca ceea ce face digester-ul java. Am inceput sa caut pe internet si dupa ceva timp am gasit o librarie care aparent putea face ceea ce aveam eu nevoie.
NDigester este implementarea .NET a pachetului Jakarta Commons-Digester. Pe baza unor fisiere XML de configurare, NDigester ofera posibilitatea initializarii de obiecte in cadrul aplicatiei pe baza configurarilor XML.
NDigester se poate descarca de la adresa: http://sourceforge.net/projects/ndigester/
L-am descarcat si am incercat sa-l folosesc. M-am lovit de cateva incompatibilitati. Cum am rezolvat incompatibilitatile? Am refacut fisierele XML care functionau in Java, conform cerintelor NDigester astfel:
1. In cadrul regulei object-create-rule am schimbat classname cu typeName
Exemplu:
<object-create-rule classname="ro.atypIQ.LL.xml.MyObjectXML" />
se transforma in
<object-create-rule typeName="ro.atypIQ.LL.xml.MyObjectXML, MyAssembly" />
Nota: typeName va contine numele assembly-ului unde se gasesc resursele.
2. Am schimbat regula call-method-rule cu property-setter-rule, iar in cadrul regulei am schimbat methodname cu propertyName, iar paramcount dispare
Exemplu:
<call-method-rule pattern="name" methodname="setName" paramcount="0" />
se transforma in
<property-setter-rule pattern="name" propertyName="Name"/>
3. Am schimbat regula alias cu set-property-rule, iar in cadrul regulei am schimbat attr-name cu value si prop-name cu name.
Exemplu:
<alias attr-name="name" prop-name="name" />
se transforma in
<set-property-rule name="Name" value="name" />
4. Am schimbat regula bean-property-setter-rule cu property-setter-rule.
Exemplu:
<bean-property-setter-rule pattern="name" propertyName="name" />
se transforma in
<property-setter-rule pattern="name" propertyName="Name" />
Atentie: Vor trebui redenumite si numele de functii si de proprietati acolo unde este cazul.
Pana acum totul a decurs ok, cu o singura exceptie. Se pare ca NDigester are un bug. Rezolvarea mea presupune modificarea functiei OnBegin() din clasa SetPropertyRule.cs.
Functia originala:
public override void OnBegin()
{
// determine actual 'name' and 'value'
string actualName = null;
string actualValue = null;
for(int i=0; istring name = digester.Attributes.GetKey(i);
string value = digester.Attributes[i];
if(name == this.name)
{
actualName = value;
}
else if(name == this.value)
{
actualValue = value;
}
}
// populate object's property
object top = digester.Peek();
PropertyInfo prop = top.GetType().GetProperty(actualName, BindingFlags.Public | BindingFlags.Instance);
prop.SetValue(top, Convert.ChangeType(actualValue, prop.PropertyType), null);
}
Functia modificata:
public override void OnBegin()
{
//determine actual 'name' and 'value'
string actualName = null;
string actualValue = null;
for(int i=0; istring name = digester.Attributes.GetKey(i);
string value = digester.Attributes[i];
if(name == this.value)
{
actualName = this.name;
actualValue = value;
}
}
if (actualName == null || actualName.Equals(""))
return;
// populate object's property
object top = digester.Peek();
PropertyInfo prop = top.GetType().GetProperty(actualName, BindingFlags.Public | BindingFlags.Instance);
prop.SetValue(top, Convert.ChangeType(actualValue, prop.PropertyType), null);
}
Acum, totul functioneaza perfect!