Open elawrey opened 8 years ago
GeoTools parser for GetCapabilities document enforce that the document follows the DTD rules (validation rules are actually hardcodded on the library). In the NASA GetCapabilities document, there is tags like this one:
<Dimension name="sequence" units=""/>
with no value defined for property "units".
NASA own custom DTD specifically (and hardcodded validation rules in GeoTools library) mentioned that the "units" tag is REQUIRED:
<!ATTLIST Dimension
name CDATA #REQUIRED
units CDATA #REQUIRED
unitSymbol CDATA #IMPLIED>
Parsing this document would either require developing our own GetCapabilities document parser or finding a way to disable DTD validation while parsing the document.
I found many ways to disable the DTD validation for the GeoTools parser, but none seems to work:
private WMSCapabilities getCapabilities(InputStream inputStream)
throws SAXException, RevivableThreadInterruptedException, ParserConfigurationException {
RevivableThread.checkForInterruption();
Map hints = new HashMap<Object, Object>();
hints.put(DocumentHandler.DEFAULT_NAMESPACE_HINT_KEY, WMSSchema.getInstance());
hints.put(DocumentFactory.VALIDATION_HINT, Boolean.FALSE);
// Disable DTD validation
hints.put(Hints.ENTITY_RESOLVER, null);
if (hints != null && hints.containsKey(Hints.ENTITY_RESOLVER)) {
Object resolver = hints.get(Hints.ENTITY_RESOLVER);
System.out.println("RESOLVER: " + resolver);
} else {
System.out.println("RESOLVER CAN NOT BE SET!!!");
}
// Disable DTD validation
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setFeature("http://xml.org/sax/features/namespaces", false);
saxParserFactory.setFeature("http://xml.org/sax/features/validation", false);
saxParserFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
saxParserFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxParserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
saxParserFactory.setValidating(false);
hints.put(XMLHandlerHints.SAX_PARSER_FACTORY, saxParserFactory);
Object object = DocumentFactory.getInstance(inputStream, hints, Level.WARNING);
RevivableThread.checkForInterruption();
if (object instanceof ServiceException) {
throw (ServiceException)object;
}
return (WMSCapabilities)object;
}
I eventually found out that GeoTools do not even care about the DTD. The specification is hardcodded in the library
org.geotools.data.wms.xml.WMSComplexTypes$_DimensionType
private static Attribute[] attrs =
new Attribute[] {
new WMSAttribute(
null,
"name",
WMSSchema.NAMESPACE,
XSISimpleTypes.String.getInstance(),
Attribute.REQUIRED,
null,
null,
false),
new WMSAttribute(
null,
"units", <=====
WMSSchema.NAMESPACE,
XSISimpleTypes.String.getInstance(),
Attribute.REQUIRED, <=====
null,
null,
false),
new WMSAttribute("unitSymbol", XSISimpleTypes.String.getInstance()),
new WMSAttribute("default", XSISimpleTypes.String.getInstance()),
new WMSAttribute("current", XSISimpleTypes.Boolean.getInstance()),
new WMSAttribute(
null,
"multipleValues",
WMSSchema.NAMESPACE,
XSISimpleTypes.Boolean.getInstance(),
Attribute.OPTIONAL,
"0",
null,
false),
new WMSAttribute(
null,
"nearestValue",
WMSSchema.NAMESPACE,
XSISimpleTypes.Boolean.getInstance(),
Attribute.OPTIONAL,
"0",
null,
false)
};
The WMS spec allows links to data in the capabilities document. It would be good to add support for this. The NASA Scientific Visualisation Studio is an example service with DataURLs http://svs.gsfc.nasa.gov/cgi-bin/wms?