From d816b977b4b02ce1df4ff4a2677f2f5ea55672ad Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Wed, 6 Aug 2008 15:04:36 +0000 Subject: [PATCH] SOLR-614 -- Allow components to be configured with NamedListInitializedPlugin using arbitary XML in solrconfig without using XPath git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@683288 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 3 + .../org/apache/solr/common/util/DOMUtil.java | 42 ++++++++++- src/java/org/apache/solr/core/SolrConfig.java | 33 ++++++++- .../apache/solr/common/util/TestDOMUtil.java | 71 +++++++++++++++++++ 4 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 src/test/org/apache/solr/common/util/TestDOMUtil.java diff --git a/CHANGES.txt b/CHANGES.txt index bf6592ccba7..935e1d3ee46 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -345,6 +345,9 @@ New Features 69. SOLR-506: Emitting HTTP Cache headers can be enabled or disabled through configuration on a per-handler basis (shalin) + +70. SOLR-614: Allow components to be configured with NamedListInitializedPlugin using arbitary XML in solrconfig + without using XPath (Noble Paul, shalin) Changes in runtime behavior 1. SOLR-559: use Lucene updateDocument, deleteDocuments methods. This diff --git a/src/java/org/apache/solr/common/util/DOMUtil.java b/src/java/org/apache/solr/common/util/DOMUtil.java index 11d337b31af..71bb9a94804 100644 --- a/src/java/org/apache/solr/common/util/DOMUtil.java +++ b/src/java/org/apache/solr/common/util/DOMUtil.java @@ -89,7 +89,8 @@ public class DOMUtil { // Should these be moved to Config? Should all of these things? ////////////////////////////////////////////////////////// public static NamedList childNodesToNamedList(Node nd) { - return nodesToNamedList(nd.getChildNodes()); + NamedList nl = nodesToNamedList(nd.getChildNodes()); + return nl; } public static List childNodesToList(Node nd) { @@ -146,12 +147,51 @@ public class DOMUtil { val = childNodesToNamedList(nd); } else if ("arr".equals(type)) { val = childNodesToList(nd); + } else { + name = type; + val = readFlexibleNamedList(nd); } if (nlst != null) nlst.add(name,val); if (arr != null) arr.add(val); } + private static Object readFlexibleNamedList(Node nd) { + if (hasChildren(nd)) { + NamedList nl = new NamedList(); + readAttributes(nd, nl); + NodeList nlist = nd.getChildNodes(); + if (nlist != null) { + for (int i = 0; i < nlist.getLength(); i++) { + if (nlist.item(i).getNodeType() == Node.ELEMENT_NODE) + addToNamedList(nlist.item(i), nl, null); + } + } + return nl; + } else { + return getText(nd); + } + } + + private static void readAttributes(Node nd, NamedList nl) { + NamedNodeMap attrs = nd.getAttributes(); + if (attrs != null) { + for (int i = 0; i < attrs.getLength(); i++) { + Node nameNd = attrs.item(i); + nl.add("@"+nameNd.getNodeName(), nameNd.getNodeValue()); + } + } + } + + private static boolean hasChildren(Node nd){ + if(nd.hasAttributes()) return true; + NodeList nlst = nd.getChildNodes(); + for (int i=0; i getAllNodesAsNamedList(String xpath) { + NodeList nodes = (NodeList) evaluate(xpath, XPathConstants.NODESET); + List result = new ArrayList(); + for (int i = 0; i < nodes.getLength(); i++) { + result.add(DOMUtil.childNodesToNamedList(nodes.item(i))); + } + return result; + } + + /** + * Get the NamedList corresponding to the first node matched by the given XPath + * + * @param xpath the XPath to match + * @return the NamedList corresponding to the first node matched by the given XPath + */ + public NamedList getNodeAsNamedList(String xpath) { + List list = getAllNodesAsNamedList(xpath); + return list.isEmpty() ? null : list.get(0); + } + public static class JmxConfiguration { public boolean enabled = false; diff --git a/src/test/org/apache/solr/common/util/TestDOMUtil.java b/src/test/org/apache/solr/common/util/TestDOMUtil.java new file mode 100644 index 00000000000..0f5bc3361ef --- /dev/null +++ b/src/test/org/apache/solr/common/util/TestDOMUtil.java @@ -0,0 +1,71 @@ +package org.apache.solr.common.util; + +import org.junit.Test; +import org.junit.Assert; +import org.xml.sax.InputSource; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.StringReader; + +public class TestDOMUtil { + @Test + public void readFlexiSchemaNodes() throws Exception { + String xml ="\n" + + " val a\n" + + " val b\n" + + " \n" + + " val d\n" + + " val e\n" + + " \n" + + ""; + NamedList nl = DOMUtil.childNodesToNamedList(getRootNode(xml)); + Assert.assertEquals("val a",nl.get("a")); + Assert.assertEquals("val b",nl.get("b")); + NamedList c = (NamedList) nl.get("c"); + Assert.assertEquals("val d",c.get("d")); + Assert.assertEquals("val e",c.get("e")); + } + + @Test + public void readFlexiSchemaNodesWithAttributes() throws Exception { + String xml ="\n" + + " \n" + + " X1\n" + + " X2\n" + + " \n" + + ""; + NamedList nl = DOMUtil.childNodesToNamedList(getRootNode(xml)); + NamedList defaults = (NamedList) nl.get("defaults"); + Assert.assertEquals("A",defaults.get("@a")); + Assert.assertEquals("B",defaults.get("@b")); + Assert.assertEquals("C",defaults.get("@c")); + Assert.assertEquals("X1",defaults.getVal(3)); + Assert.assertEquals("X2",defaults.getVal(4)); + } + @Test + public void readFlexiSchemaNodesWithAttributesWithOldFormat() throws Exception { + String xml ="\n" + + " \n" + + " X1\n" + + " X2\n" + + " true\n" + + " \n" + + ""; + NamedList nl = DOMUtil.childNodesToNamedList(getRootNode(xml)); + NamedList defaults = (NamedList) nl.get("defaults"); + Assert.assertEquals("A",defaults.get("@a")); + Assert.assertEquals("B",defaults.get("@b")); + Assert.assertEquals("C",defaults.get("@c")); + Assert.assertEquals("X1",defaults.getVal(3)); + Assert.assertEquals("X2",defaults.getVal(4)); + Assert.assertEquals(Boolean.TRUE,defaults.get("boo")); + } + + private Node getRootNode(String xml) throws Exception { + javax.xml.parsers.DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Document doc = builder.parse(new InputSource(new StringReader(xml))); + return doc.getDocumentElement(); + } +}