/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
/*
* Created on April 20, 2005
*
*/
package org.vfny.geoserver.util;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.List;
import java.util.logging.Logger;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;
public class SLDValidator {
static Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.vfny.geoserver");
EntityResolver entityResolver;
public SLDValidator() {
}
/**
* validates against the SLD schema in the classpath
*
* @param xml
* @param baseUrl GeoServer base URL
*
*
*/
@Deprecated
public List validateSLD(InputStream xml, String baseUrl) {
return validateSLD(xml);
}
/**
* validates against the SLD schema in the classpath
*
* @param xml
* @param baseUrl GeoServer base URL
*
*
*/
public List validateSLD(InputStream xml) {
return validateSLD(new InputSource(xml));
}
public EntityResolver getEntityResolver() {
return entityResolver;
}
public void setEntityResolver(EntityResolver entityResolver) {
this.entityResolver = entityResolver;
}
public static String getErrorMessage(InputStream xml, List errors) {
return getErrorMessage(new InputStreamReader(xml), errors);
}
/**
* returns a better formated error message - suitable for framing. There's
* a more complex version in StylesEditorAction. This will kick out a VERY
* LARGE errorMessage.
*
* @param xml
* @param errors
*
* @return DOCUMENT ME!
*/
public static String getErrorMessage(Reader xml, List errors) {
BufferedReader reader = null;
StringBuffer result = new StringBuffer();
result.append("Your SLD is not valid.\n");
result.append(
"Most common problems are: \n(1) no namespaces - use <ows:GetMap>, <sld:Rule>, <ogc:Filter>, <gml:Point> - the part before the ':' is important\n");
result.append("(2) capitialization - use '<And>' not '<and>' \n");
result.append("(3) Order - The order of elements is important \n");
result.append(
"(4) Make sure your first tag imports the correct namespaces. ie. xmlns:sld=\"http://www.opengis.net/sld\" for EVERY NAMESPACE \n");
result.append("\n");
try {
reader = new BufferedReader(xml);
String line = reader.readLine();
int linenumber = 1;
int exceptionNum = 0;
//check for lineNumber -1 errors --> invalid XML
if (errors.size() > 0) {
SAXParseException sax = (SAXParseException) errors.get(0);
if (sax.getLineNumber() < 0) {
result.append(" INVALID XML: " + sax.getLocalizedMessage() + "\n");
result.append(" \n");
exceptionNum = 1; // skip ahead (you only ever get one error in this case)
}
}
while (line != null) {
line.replace('\n', ' ');
line.replace('\r', ' ');
String header = linenumber + ": ";
result.append(header + line + "\n"); // record the current line
boolean keep_going = true;
while (keep_going) {
if ((exceptionNum < errors.size())) {
SAXParseException sax = (SAXParseException) errors.get(exceptionNum);
if (sax.getLineNumber() <= linenumber) {
String head = "---------------------".substring(0, header.length() - 1);
String body = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
int colNum = sax.getColumnNumber(); //protect against col 0 problems
if (colNum < 1) {
colNum = 1;
}
if (colNum > body.length()) {
body = body + body + body + body + body + body; // make it longer (not usually required, but might be for SLD_BODY=... which is all one line)
if (colNum > body.length()) {
colNum = body.length();
}
}
result.append(head + body.substring(0, colNum - 1) + "^\n");
result.append(" (line " + sax.getLineNumber() + ", column "
+ sax.getColumnNumber() + ")" + sax.getLocalizedMessage() + "\n");
exceptionNum++;
} else {
keep_going = false; //report later (sax.getLineNumber() > linenumber)
}
} else {
keep_going = false; // no more errors to report
}
}
line = reader.readLine(); //will be null at eof
linenumber++;
}
for (int t = exceptionNum; t < errors.size(); t++) {
SAXParseException sax = (SAXParseException) errors.get(t);
result.append(" (line " + sax.getLineNumber() + ", column "
+ sax.getColumnNumber() + ")" + sax.getLocalizedMessage() + "\n");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return result.toString();
}
/**
* validate a .sld against the schema
*
* @param xml input stream representing the .sld file
* @param baseURL
* @param SchemaUrl location of the schemas. Normally use
* ".../schemas/sld/StyleLayerDescriptor.xsd"
*
* @return list of SAXExceptions (0 if the file's okay)
*/
@Deprecated
public List validateSLD(InputSource xml, String baseUrl) {
return validateSLD(xml);
}
/**
* validate a .sld against the schema
*
* @param xml input stream representing the .sld file
*
* @return list of SAXExceptions (0 if the file's okay)
*/
public List validateSLD(InputSource xml) {
URL schemaURL = SLDValidator.class.getResource("/schemas/sld/StyledLayerDescriptor.xsd");
return ResponseUtils.validate(xml, schemaURL, false, entityResolver);
}
}