Re: [configuration] XPathExpressionEngine Variable Interpolation
finally got a chance to look into this. oliver, the extra information at the end of your message was the hint that helped. indeed i was relying on the original dot-notation within my configuration files so when i switched to xpath it was unable to interpolate those. in my case, i have a large number of configuration files, all of which use the standard dot-notation for interpolating values. however, i came across a case where the use of xpath would access select resources in a more economical manner. for me to go back and convert all my interpolated values to use xpath slash-notation would be too difficult --- both code and configuration would be touched. it seems that if one is using interpolation then you can either use either the standard expression engine or the xpath expression engine but not both. thanks for the clarification. On Sun, Jan 23, 2011 at 8:15 AM, Oliver Heger wrote: > Am 23.01.2011 00:57, schrieb NJuk Njuk: > > i've been using Commons Configuration on a particular project for several >> years. until lately i have been using the DefaultExpressionEngine --- or >> at >> least i believe i have since i've never called setExpressionEngine(). my >> configuration is specified by a set of xml files, some of which use >> variable >> interpolation (via ${} syntax) to define property values. >> >> i recently had a case where the use of XPATH would be helpful in obtaining >> certain configuration values. when i switched the expression engine to >> XPathExpressionEngine, i was able to locate the necessary configuration >> properties but their values resulted in the non-interpolated string. if i >> use the DefaultExpressionEngine, the values are properly interpolated. >> >> am i wrong in assuming that XPathExpressionEngine should transparently >> variable interpolation like DefaultExpressionEngine does? i saw no >> mention >> of this, one way or the other, in the Commons Configuration documentation. >> >> thanks in advance for any guidance. >> >> > You are right, interpolation should work the same way for the > XPathExpressionEngine as for the default one. > > Would it be possible to post a code fragment and an example configuration > file so that we can reproduce the problem? > > What might be the cause for your problem is the fact that when using > XPathExpressionEngine this engine is also used for interpreting the > interpolated variables, i.e. the expressions in ${} syntax. If these > expressions are not valid XPath expressions, the corresponding values cannot > be retrieved; in this case the non-interpolated strings are returned. > > Oliver > > - > To unsubscribe, e-mail: user-unsubscr...@commons.apache.org > For additional commands, e-mail: user-h...@commons.apache.org > >
Re: [configuration] ConfigurationConverter differing behavior for ints and strings
Hi Mike, Am 01.02.2011 18:35, schrieb Mike Power: Curiosity question I am seeing the ConfigurationConverter behave differently depending on if I added an int or a string to a configuration object. Consider the following code: 01 Configuration confInt = new BaseConfiguration(); 02 Configuration confString = new BaseConfiguration(); 03 confInt.setProperty("port", 80); 04 confString.setProperty("port", "80"); 05 assertEquals(80, confInt.getInt("port")); 06 assertEquals(80, confString.getInt("port")); 07 08 Properties propString = ConfigurationConverter.getProperties(confString); 09 assertEquals("80", propString.getProperty("port")); 10 11 Properties propInt = ConfigurationConverter.getProperties(confInt); 12 13 assertEquals("80", propInt.getProperty("port")); As you can see the code is basically duplicated one set uses an int the other set uses a String. However an exception blows out of line 11. 'port' doesn't map to a List object: 80, a java.lang.Integer org.apache.commons.configuration.ConversionException: 'port' doesn't map to a List object: 80, a java.lang.Integer at org.apache.commons.configuration.AbstractConfiguration.getList(AbstractConfiguration.java:1144) at org.apache.commons.configuration.AbstractConfiguration.getList(AbstractConfiguration.java:1109) at org.apache.commons.configuration.ConfigurationConverter.getProperties(ConfigurationConverter.java:116) It seems for some reason since I used an int, the ConfigurationConverter wants to treat the property as a list. However since I actually put an integer into the property it errors out since it can not convert a integer to a list. This behavior seems odd. Why does it do this? Mike Power the code responsible for this odd behavior is actually in AbstractConfiguration.getList(). Here a single string value is treated in a special way: it is returned as single element of a newly created list. However, for other scalar types such a conversion is not performed. This code is pretty old, I guess it is in there from the very beginning. Probably it was just forgotten that a configuration could store other types of values, too. If you like, you can add a bug report in Jira. The current behavior is probably not desired. Oliver - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org
[jxpath] using AbstractFactory with Map in XPath
Hi, I have a problem with JXPath which I suppose is something that is not supported yet, though it's looks like a bug. I'm using AbstractFactory implementation to create missing objects in XPath when setting properties. (see http://commons.apache.org/jxpath/users-guide.html#Creating_Objects). Everything works fine as long as missing objects are Bean-like objects, or any Collections. But if missing object is one of objects in Map problems begin. Here is my issue (please find complete code of used classes and working example attached): public class Parent { private String name; private Map children; } public class Child { private String sex; private int age; } public class JXPathMap { public static void main (String[] args) { Parent p = new Parent("Dad"); p.setChildren(new LinkedHashMap() {{ put("Bobby", new Child("Male", 9)); put("Steven", null); put("Sandra", new Child("Female", 12)); }}); JXPathContext context = JXPathContext.newContext(p); context.setFactory(new AbstractFactory() { @Override public boolean createObject(JXPathContext context, Pointer pointer, Object parent, String name, int index) { System.out.println("parent: " + parent); System.out.println("name: " + name); System.out.println("index: " + index); return super.createObject(context, pointer, parent, name, index); } }); context.createPathAndSetValue("children/Steven/age", 4); } } * * this code results as following: *parent: {Bobby=Child[sex=Male, age=9], Steven=null, Sandra=Child[sex=Female, age=12]} name: Steven index: 0* Exception in thread "main" org.apache.commons.jxpath.JXPathException: Exception trying to create xpath children/Steven/age; Factory could not create an object for path: /children[@name='Steven'] at org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.createPathAndSetValue(JXPathContextReferenceImpl.java:549) at org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.createPathAndSetValue(JXPathContextReferenceImpl.java:533) at tests.xpath.JXPathMap.main(JXPathMap.java:29) Caused by: org.apache.commons.jxpath.JXPathAbstractFactoryException: Factory could not create an object for path: /children[@name='Steven'] at org.apache.commons.jxpath.ri.model.dynamic.DynamicPropertyPointer.createPath(DynamicPropertyPointer.java:230) at org.apache.commons.jxpath.ri.model.beans.NullPointer.createPath(NullPointer.java:100) at org.apache.commons.jxpath.ri.model.beans.NullPropertyPointer.createPath(NullPropertyPointer.java:138) at org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.setValue(JXPathContextReferenceImpl.java:584) at org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.createPathAndSetValue(JXPathContextReferenceImpl.java:546) ... 2 more * * I must mention that *context.createPathAndSetValue("children/Bobby/age", 4)*works fine - sets Bobby's age to 4. In case of missing object is element of collection - everything works fine, I would get *Parent* as parent object, * children* as property that has missing object and *index* so i know where to put my newly created object. In case of Map I don't get enough information to instantiate missing object. "Steven" as property name is most surprising. Exception is OK, cause nothing is created by factory. I suppose that AbstractFactory should have separate method in case of Map element is missed. JXPath easily detects that it is Map because setting * "children/Bobby/age"* works as expected. * *I'm quite sure that I will post this to issue tracking system, but first I'd like to ask if anybody had similar issue? may be i am missing something important? Any comments are appreciated. Regards, Aleksandr package tests.xpath; public class Child { private String sex; private int age; Child() {} Child(String sex, int age) { setSex(sex); setAge(age); } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return this.getClass().getSimpleName() + "[" + "sex=" + getSex() + ", " + "age=" + getAge() + "]"; } }package tests.xpath; import java.util.LinkedHashMap; import org.apache.commons.jxpath.AbstractFactory; import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.jxpath.Pointer; public class JXPathMap { public static void main (String[] args) { Parent p = new Parent("Dad"); p.setChildren(new LinkedHashMap() {{ put("Bobby", new Child("Male", 9)); put("Steven", null); put("Sandra", new Child("Female", 12)); }}); JXPathContext context = JXPath
[configuration] ConfigurationConverter differing behavior for ints and strings
Curiosity question I am seeing the ConfigurationConverter behave differently depending on if I added an int or a string to a configuration object. Consider the following code: 01 Configuration confInt = new BaseConfiguration(); 02 Configuration confString = new BaseConfiguration(); 03 confInt.setProperty("port", 80); 04 confString.setProperty("port", "80"); 05 assertEquals(80, confInt.getInt("port")); 06 assertEquals(80, confString.getInt("port")); 07 08 Properties propString = ConfigurationConverter.getProperties(confString); 09 assertEquals("80", propString.getProperty("port")); 10 11 Properties propInt = ConfigurationConverter.getProperties(confInt); 12 13 assertEquals("80", propInt.getProperty("port")); As you can see the code is basically duplicated one set uses an int the other set uses a String. However an exception blows out of line 11. 'port' doesn't map to a List object: 80, a java.lang.Integer org.apache.commons.configuration.ConversionException: 'port' doesn't map to a List object: 80, a java.lang.Integer at org.apache.commons.configuration.AbstractConfiguration.getList(AbstractConfiguration.java:1144) at org.apache.commons.configuration.AbstractConfiguration.getList(AbstractConfiguration.java:1109) at org.apache.commons.configuration.ConfigurationConverter.getProperties(ConfigurationConverter.java:116) It seems for some reason since I used an int, the ConfigurationConverter wants to treat the property as a list. However since I actually put an integer into the property it errors out since it can not convert a integer to a list. This behavior seems odd. Why does it do this? Mike Power - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org