Skip to content

Commit

Permalink
1116: GetRecords hardcoded prefixes in TypeNames check
Browse files Browse the repository at this point in the history
  • Loading branch information
heikkidoeleman committed Oct 29, 2012
1 parent bb778f8 commit 5f7fe25
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@
import org.fao.geonet.kernel.search.LuceneSearcher;
import org.fao.geonet.kernel.search.spatial.Pair;
import org.fao.geonet.util.ISODate;
import org.fao.geonet.util.xml.NamespaceUtils;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jdom.Namespace;
import org.springframework.util.CollectionUtils;

import java.io.File;
Expand Down Expand Up @@ -515,38 +517,82 @@ private String checkOutputFormat(Element request) throws InvalidParameterValueEx
* @throws InvalidParameterValueEx if typeNames does not have one of the mandated values
*/
private String checkTypenames(Element query) throws MissingParameterValueEx, InvalidParameterValueEx {
if(Log.isDebugEnabled(Geonet.CSW_SEARCH))
if(Log.isDebugEnabled(Geonet.CSW_SEARCH)) {
Log.debug(Geonet.CSW_SEARCH, "checking typenames in query:\n" + Xml.getString(query));
}
//
// get the prefix used for CSW namespace used in this input document
//
String cswPrefix = getPrefixForNamespace(query, Csw.NAMESPACE_CSW);
if(cswPrefix == null) {
if(Log.isDebugEnabled(Geonet.CSW_SEARCH)) {
Log.debug(Geonet.CSW_SEARCH, "checktypenames: csw prefix not found, using " + Csw.NAMESPACE_CSW.getPrefix());
}
cswPrefix = Csw.NAMESPACE_CSW.getPrefix();
}
//
// get the prefix used for GMD namespace used in this input document
//
String gmdPrefix = getPrefixForNamespace(query, Csw.NAMESPACE_GMD);
if(gmdPrefix == null) {
if(Log.isDebugEnabled(Geonet.CSW_SEARCH)) {
Log.debug(Geonet.CSW_SEARCH, "checktypenames: gmd prefix not found, using " + Csw.NAMESPACE_GMD.getPrefix());
}
gmdPrefix = Csw.NAMESPACE_GMD.getPrefix();
}
if(Log.isDebugEnabled(Geonet.CSW_SEARCH)) {
Log.debug(Geonet.CSW_SEARCH, "checktypenames: csw prefix set to " + cswPrefix + ", gmd prefix set to " + gmdPrefix);
}

Attribute typeNames = query.getAttribute("typeNames", query.getNamespace());
typeNames = query.getAttribute("typeNames");
if(typeNames != null) {
String typeNamesValue = typeNames.getValue();
// empty typenames element
if(StringUtils.isEmpty(typeNamesValue)) {
return "csw:Record";
return cswPrefix + ":Record";
}
// not empty: scan comma-separated string
Scanner commaSeparator = new Scanner(typeNamesValue);
commaSeparator.useDelimiter(",");
String result = "csw:Record";
String result = cswPrefix + ":Record";
while(commaSeparator.hasNext()) {
String typeName = commaSeparator.next();
typeName = typeName.trim();
if(Log.isDebugEnabled(Geonet.CSW_SEARCH))
if(Log.isDebugEnabled(Geonet.CSW_SEARCH)) {
Log.debug(Geonet.CSW_SEARCH, "checking typename in query:" + typeName);
if(!(typeName.equals("csw:Record") || typeName.equals("gmd:MD_Metadata"))) {
}
if(!(typeName.equals(cswPrefix + ":Record") || typeName.equals(gmdPrefix + ":MD_Metadata"))) {
throw new InvalidParameterValueEx("typeNames", "invalid value");
}
if(typeName.equals("gmd:MD_Metadata")) {
if(typeName.equals(gmdPrefix + ":MD_Metadata")) {
return typeName;
}
}
return result;
}
// missing typeNames element
else {
return "csw:Record";
return cswPrefix + ":Record";
}
}

/**
* Returns the prefix used in the scope of an element for a particular namespace, or null if the namespace is not in
* scope.
*
* @param element
* @param namespace
* @return
*/
private String getPrefixForNamespace(Element element, Namespace namespace) {
List<Namespace> namespacesInScope = NamespaceUtils.getNamespacesInScope(element);
for(Namespace ns : namespacesInScope) {
if(ns.getURI().equals(namespace.getURI())) {
return ns.getPrefix();
}
}
return null;
}

/**
Expand Down
53 changes: 53 additions & 0 deletions web/src/test/java/org/fao/geonet/test/TestCase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.fao.geonet.test;

import java.util.Collection;

/**
* Useful extensions to Junit TestCase.
*
* @author heikki doeleman
*/
public class TestCase extends junit.framework.TestCase {

/**
* Just to prevent junit.framework.AssertionFailedError: No tests found in org.fao.geonet.test.TestCase.
*/
public void testNothing() {}

/**
* Whether something is in a collection.
*
* @param msg
* @param o
* @param c
*/
public static void assertContains(String msg, Object o, Collection c) {
for(Object in : c) {
if(o.equals(in)) {
return;
}
}
fail(msg);
}

/**
* No-arg constructor to enable serialization. This method is not intended to be used by mere mortals without
* calling setName().
*/
public TestCase() {
super();
}
/**
* Constructs a test case with the given name.
*/
public TestCase(String name) {
super(name);
}
/**
* Sets the name of a TestCase.
* @param name the name to set
*/
public void setName(String name) {
super.setName(name);
}
}
90 changes: 90 additions & 0 deletions web/src/test/java/org/fao/geonet/util/xml/NamespaceUtilsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.fao.geonet.util.xml;

import jeeves.utils.Xml;
import org.fao.geonet.test.TestCase;
import org.jdom.Element;
import org.jdom.Namespace;

import java.util.List;

/**
*
* Unit test for NamespaceUtils.
*
* @author heikki doeleman
*
*/
public class NamespaceUtilsTest extends TestCase {

public NamespaceUtilsTest(String name) throws Exception {
super(name);
}

public void testNamespaceInScope() throws Exception {
String xml = "<?xml version=\"1.0\"?><root " +
"xmlns:a=\"http://aaa\" " +
"xmlns:b=\"http://bbb\" " +
"xmlns:c=\"http://ccc\" " +
"xmlns:d=\"http://ddd\">" +
"<a:a/></root>";
Element xmle = Xml.loadString(xml, false);
List<Namespace> inScope = NamespaceUtils.getNamespacesInScope(xmle);

assertContains("Expected inscope namespace " + Namespace.NO_NAMESPACE , Namespace.NO_NAMESPACE, inScope);
assertContains("Expected inscope namespace " + Namespace.getNamespace("a", "http://aaa") , Namespace.getNamespace("a", "http://aaa"), inScope);
assertContains("Expected inscope namespace " + Namespace.getNamespace("b", "http://bbb"), Namespace.getNamespace("b", "http://bbb"), inScope);
assertContains("Expected inscope namespace " + Namespace.getNamespace("c", "http://ccc"), Namespace.getNamespace("c", "http://ccc"), inScope);
assertContains("Expected inscope namespace " + Namespace.getNamespace("d", "http://ddd"), Namespace.getNamespace("d", "http://ddd"), inScope);

Element a = xmle.getChild("a", Namespace.getNamespace("a", "http://aaa"));
inScope = NamespaceUtils.getNamespacesInScope(a);

assertContains("Expected inscope namespace " + Namespace.NO_NAMESPACE , Namespace.NO_NAMESPACE, inScope);
assertContains("Expected inscope namespace " + Namespace.getNamespace("a", "http://aaa") , Namespace.getNamespace("a", "http://aaa"), inScope);
assertContains("Expected inscope namespace " + Namespace.getNamespace("b", "http://bbb"), Namespace.getNamespace("b", "http://bbb"), inScope);
assertContains("Expected inscope namespace " + Namespace.getNamespace("c", "http://ccc"), Namespace.getNamespace("c", "http://ccc"), inScope);
assertContains("Expected inscope namespace " + Namespace.getNamespace("d", "http://ddd"), Namespace.getNamespace("d", "http://ddd"), inScope);
}

public void testNamespaceInherited() throws Exception {
String xml = "<?xml version=\"1.0\"?><root " +
"xmlns:a=\"http://aaa\" " +
"xmlns:b=\"http://bbb\" " +
"xmlns:c=\"http://ccc\" " +
"xmlns:d=\"http://ddd\">" +
"<a:a/></root>";
Element xmle = Xml.loadString(xml, false);
List<Namespace> inHerited = NamespaceUtils.getNamespacesInherited(xmle);

assertContains("Expected inherited namespace " + Namespace.NO_NAMESPACE , Namespace.NO_NAMESPACE, inHerited);
assertContains("Expected inherited namespace " + Namespace.XML_NAMESPACE , Namespace.XML_NAMESPACE, inHerited);

Element a = xmle.getChild("a", Namespace.getNamespace("a", "http://aaa"));
inHerited = NamespaceUtils.getNamespacesInherited(a);

assertContains("Expected inherited namespace " + Namespace.NO_NAMESPACE , Namespace.NO_NAMESPACE, inHerited);
assertContains("Expected inherited namespace " + Namespace.XML_NAMESPACE , Namespace.XML_NAMESPACE, inHerited);
}

public void testNamespaceIntroduced() throws Exception {
String xml = "<?xml version=\"1.0\"?><root " +
"xmlns:a=\"http://aaa\" " +
"xmlns:b=\"http://bbb\" " +
"xmlns:c=\"http://ccc\" " +
"xmlns:d=\"http://ddd\">" +
"<a:a/></root>";
Element xmle = Xml.loadString(xml, false);
List<Namespace> introduced = NamespaceUtils.getNamespacesIntroduced(xmle);

assertContains("Expected introduced namespace " + Namespace.getNamespace("a", "http://aaa") , Namespace.getNamespace("a", "http://aaa"), introduced);
assertContains("Expected introduced namespace " + Namespace.getNamespace("b", "http://bbb"), Namespace.getNamespace("b", "http://bbb"), introduced);
assertContains("Expected introduced namespace " + Namespace.getNamespace("c", "http://ccc"), Namespace.getNamespace("c", "http://ccc"), introduced);
assertContains("Expected introduced namespace " + Namespace.getNamespace("d", "http://ddd"), Namespace.getNamespace("d", "http://ddd"), introduced);

Element a = xmle.getChild("a", Namespace.getNamespace("a", "http://aaa"));
introduced = NamespaceUtils.getNamespacesIntroduced(a);

assertEquals("Expected 0 introduced namespaces", 0, introduced.size());

}
}

0 comments on commit 5f7fe25

Please sign in to comment.