Author: oheger
Date: Fri Jul 29 19:23:09 2011
New Revision: 1152343
URL: http://svn.apache.org/viewvc?rev=1152343&view=rev
Log:
[CONFIGURATION-452] XPathExpressionEngine now supports keys for adding or
setting properties without a whitespace.
Added:
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngineInConfig.java
(with props)
Modified:
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/xpath/XPathExpressionEngine.java
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngine.java
Modified:
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/xpath/XPathExpressionEngine.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/xpath/XPathExpressionEngine.java?rev=1152343&r1=1152342&r2=1152343&view=diff
==============================================================================
---
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/xpath/XPathExpressionEngine.java
(original)
+++
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/xpath/XPathExpressionEngine.java
Fri Jul 29 19:23:09 2011
@@ -129,6 +129,12 @@ public class XPathExpressionEngine imple
+ ATTR_DELIMITER;
/**
+ * Constant for a space which is used as delimiter in keys for adding
+ * properties.
+ */
+ private static final String SPACE = " ";
+
+ /**
* Executes a query. The passed in property key is directly passed to a
* JXPath context.
*
@@ -213,18 +219,15 @@ public class XPathExpressionEngine imple
"prepareAdd: key must not be null!");
}
- int index = key.length() - 1;
- while (index >= 0 && !Character.isWhitespace(key.charAt(index)))
- {
- index--;
- }
+ String addKey = key;
+ int index = findKeySeparator(addKey);
if (index < 0)
{
- throw new IllegalArgumentException(
- "prepareAdd: Passed in key must contain a whitespace!");
+ addKey = generateKeyForAdd(root, addKey);
+ index = findKeySeparator(addKey);
}
- List nodes = query(root, key.substring(0, index).trim());
+ List nodes = query(root, addKey.substring(0, index).trim());
if (nodes.size() != 1)
{
throw new IllegalArgumentException(
@@ -233,7 +236,7 @@ public class XPathExpressionEngine imple
NodeAddData data = new NodeAddData();
data.setParent((ConfigurationNode) nodes.get(0));
- initNodeAddData(data, key.substring(index).trim());
+ initNodeAddData(data, addKey.substring(index).trim());
return data;
}
@@ -324,6 +327,37 @@ public class XPathExpressionEngine imple
}
/**
+ * Tries to generate a key for adding a property. This method is called if
a
+ * key was used for adding properties which does not contain a space
+ * character. It splits the key at its single components and searches for
+ * the last existing component. Then a key compatible for adding properties
+ * is generated.
+ *
+ * @param root the root node of the configuration
+ * @param key the key in question
+ * @return the key to be used for adding the property
+ */
+ private String generateKeyForAdd(ConfigurationNode root, String key)
+ {
+ int pos = key.lastIndexOf(PATH_DELIMITER, key.length());
+
+ while (pos >= 0)
+ {
+ String keyExisting = key.substring(0, pos);
+ if (!query(root, keyExisting).isEmpty())
+ {
+ StringBuffer buf = new StringBuffer(key.length() + 1);
+ buf.append(keyExisting).append(SPACE);
+ buf.append(key.substring(pos + 1));
+ return buf.toString();
+ }
+ pos = key.lastIndexOf(PATH_DELIMITER, pos - 1);
+ }
+
+ return SPACE + key;
+ }
+
+ /**
* Helper method for throwing an exception about an invalid path.
*
* @param path the invalid path
@@ -335,6 +369,23 @@ public class XPathExpressionEngine imple
+ "\" " + msg);
}
+ /**
+ * Determines the position of the separator in a key for adding new
+ * properties. If no delimiter is found, result is -1.
+ *
+ * @param key the key
+ * @return the position of the delimiter
+ */
+ private static int findKeySeparator(String key)
+ {
+ int index = key.length() - 1;
+ while (index >= 0 && !Character.isWhitespace(key.charAt(index)))
+ {
+ index--;
+ }
+ return index;
+ }
+
// static initializer: registers the configuration node pointer factory
static
{
Modified:
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngine.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngine.java?rev=1152343&r1=1152342&r2=1152343&view=diff
==============================================================================
---
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngine.java
(original)
+++
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngine.java
Fri Jul 29 19:23:09 2011
@@ -20,6 +20,8 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import junit.framework.TestCase;
+
import org.apache.commons.configuration.tree.ConfigurationNode;
import org.apache.commons.configuration.tree.DefaultConfigurationNode;
import org.apache.commons.configuration.tree.NodeAddData;
@@ -27,8 +29,6 @@ import org.apache.commons.jxpath.JXPathC
import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
import org.apache.commons.jxpath.ri.model.NodePointerFactory;
-import junit.framework.TestCase;
-
/**
* Test class for XPathExpressionEngine.
*
@@ -256,23 +256,6 @@ public class TestXPathExpressionEngine e
}
/**
- * Tests an add operation where the passed in key has an invalid format: it
- * does not contain a whitspace. This will cause an error.
- */
- public void testPrepareAddInvalidFormat()
- {
- try
- {
- engine.prepareAdd(ROOT, "anInvalidKey");
- fail("Could add an invalid key!");
- }
- catch (IllegalArgumentException iex)
- {
- // ok
- }
- }
-
- /**
* Tests an add operation with an empty path for the new node.
*/
public void testPrepareAddEmptyPath()
Added:
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngineInConfig.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngineInConfig.java?rev=1152343&view=auto
==============================================================================
---
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngineInConfig.java
(added)
+++
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngineInConfig.java
Fri Jul 29 19:23:09 2011
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.commons.configuration.tree.xpath;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.configuration.XMLConfiguration;
+
+/**
+ * A test class for XPathExpressionEngine that tests the engine integrated into
+ * a hierarchical configuration.
+ *
+ * @author <a
+ *
href="http://commons.apache.org/configuration/team-list.html">Commons
+ * Configuration team</a>
+ * @version $Id$
+ */
+public class TestXPathExpressionEngineInConfig extends TestCase
+{
+ /** Constant for a test key. */
+ private static final String KEY = "test/expression/xpath";
+
+ /** Constant for a value for test properties. */
+ private static final String VALUE = "success";
+
+ /** The test configuration. */
+ private XMLConfiguration config;
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ config = new XMLConfiguration();
+ config.setExpressionEngine(new XPathExpressionEngine());
+ }
+
+ /**
+ * Tests whether an already existing property can be changed using
+ * setProperty().
+ */
+ public void testSetPropertyExisting()
+ {
+ config.addProperty(" " + KEY, "failure");
+ config.setProperty(KEY, VALUE);
+ assertEquals("Value not changed", VALUE, config.getString(KEY));
+ }
+
+ /**
+ * Tests setProperty() if the specified path partly exists.
+ */
+ public void testSetPropertyPartlyExisting()
+ {
+ final String testKey = KEY + "/sub";
+ config.addProperty(" " + KEY, "test");
+ config.setProperty(testKey, VALUE);
+ assertEquals("Value not set", VALUE, config.getString(testKey));
+ }
+
+ /**
+ * Tests whether setProperty() can be used to add a new attribute.
+ */
+ public void testSetPropertyNewAttribute()
+ {
+ final String keyAttr = KEY + "/@attr";
+ config.addProperty(" " + KEY, "test");
+ config.setProperty(keyAttr, VALUE);
+ assertEquals("Value not set", VALUE, config.getString(keyAttr));
+ }
+
+ /**
+ * Tests whether setProperty() can be used to create a completely new key.
+ */
+ public void testSetPropertyNewKey()
+ {
+ config.setProperty(KEY, VALUE);
+ assertEquals("Value not set", VALUE, config.getString(KEY));
+ }
+
+ /**
+ * Tests whether addProperty() can be used to create more complex
+ * hierarchical structures.
+ */
+ public void testAddPropertyComplexStructures()
+ {
+ config.addProperty("tables/table/name", "tasks");
+ config.addProperty("tables/table[last()]/@type", "system");
+ config.addProperty("tables/table[last()]/fields/field/name", "taskid");
+ config.addProperty("tables/table[last()]/fields/field[last()]/@type",
+ "int");
+ config.addProperty("tables table/name", "documents");
+ assertEquals("Wrong table 1", "tasks",
+ config.getString("tables/table[1]/name"));
+ assertEquals("Wrong table 2", "documents",
+ config.getString("tables/table[2]/name"));
+ assertEquals("Wrong field type", "int",
+ config.getString("tables/table[1]/fields/field[1]/@type"));
+ }
+}
Propchange:
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngineInConfig.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngineInConfig.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange:
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngineInConfig.java
------------------------------------------------------------------------------
svn:mime-type = text/plain