/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.vfny.geoserver.wcs.requests;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import org.geoserver.wcs.WCSInfo;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.XMLFilterImpl;
import com.vividsolutions.jts.geom.Envelope;
/**
* DOCUMENT ME!
*
* @author $Author: Alessio Fabiani (alessio.fabiani@gmail.com) $ (last modification)
* @author $Author: Simone Giannecchini (simboss1@gmail.com) $ (last modification)
*/
public class CoverageHandler extends XMLFilterImpl implements ContentHandler {
/** Class logger */
private static Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.vfny.geoserver.requests.wcs");
/** Service handling the request */
private CoverageRequest request = null;
private String currentTag = new String();
private Double[] coordinates = new Double[4];
private Double[] lowers = new Double[2];
private Double[] highers = new Double[2];
private Double[] origin = new Double[2];
private Double[] offsetVector = new Double[2];
private boolean insideEnvelope = false;
private boolean insideGrid = false;
private boolean insideRange = false;
private int paramNum = -1;
private ArrayList paramNames = new ArrayList();
private HashMap params = new HashMap();
private int minTmp;
/**
* Empty constructor.
*/
public CoverageHandler(WCSInfo wcs) {
super();
request = new CoverageRequest(wcs);
}
public CoverageRequest getRequest(HttpServletRequest req) {
request.setHttpServletRequest(req);
return request;
}
/**
* Notes the start of the element and sets type names and query attributes.
*
* @param namespaceURI URI for namespace appended to element.
* @param localName Local name of element.
* @param rawName Raw name of element.
* @param atts Element attributes.
* @throws SAXException When the XML is not well formed.
*/
public void startElement(String namespaceURI, String localName, String rawName, Attributes atts)
throws SAXException {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest("at start element: " + localName);
}
// at start of element, set inside flag to whatever tag we are inside
currentTag = localName;
if (currentTag.equals("GetCoverage")) {
final int length = atts.getLength();
String curAtt;
for (int i = 0; i < length; i++) {
curAtt = atts.getLocalName(i);
if (curAtt.equals("service")) {
request.setService(atts.getValue(i));
} else if (curAtt.equals("version")) {
request.setVersion(atts.getValue(i));
}
}
} else if (currentTag.equals("Envelope")) {
insideEnvelope = true;
final int length = atts.getLength();
String curAtt;
for (int i = 0; i < length; i++) {
curAtt = atts.getLocalName(i);
if (curAtt.equals("srsName")) {
request.setCRS(atts.getValue(i));
if (request.getResponseCRS() == null) {
request.setResponseCRS(atts.getValue(i));
}
}
}
} else if (currentTag.equals("Grid") || currentTag.equals("RectifiedGrid")) {
insideGrid = true;
final int length = atts.getLength();
String curAtt;
for (int i = 0; i < length; i++) {
curAtt = atts.getLocalName(i);
if (curAtt.equals("dimension")) {
request.setGridDimension(atts.getValue(i));
}
}
} else if (currentTag.equals("rangeSubset")) {
insideRange = true;
} else if (currentTag.equals("axisSubset") && insideRange) {
final int length = atts.getLength();
String curAtt;
for (int i = 0; i < length; i++) {
curAtt = atts.getLocalName(i);
if (curAtt.equals("name")) {
paramNames.add(atts.getValue(i));
paramNum++;
}
}
}
}
/**
* Notes the end of the element exists query or bounding box.
*
* @param namespaceURI URI for namespace appended to element.
* @param localName Local name of element.
* @param rawName Raw name of element.
* @throws SAXException When the XML is not well formed.
*/
public void endElement(String namespaceURI, String localName, String rawName)
throws SAXException {
LOGGER.finer("at end element: " + localName);
currentTag = localName;
if (currentTag.equals("Envelope")) {
insideEnvelope = false;
} else if (currentTag.equals("Grid") || currentTag.equals("RectifiedGrid")) {
insideGrid = false;
} else if (currentTag.equals("rangeSubset")) {
insideRange = false;
request.setParameters(params);
}
currentTag = "";
}
/**
* Checks if inside parsed element and adds its contents to the appropriate variable.
*
* @param ch URI for namespace appended to element.
* @param start Local name of element.
* @param length Raw name of element.
* @throws SAXException When the XML is not well formed.
*/
public void characters(char[] ch, int start, int length)
throws SAXException {
String s = new String(ch, start, length);
s = s.trim();
// if inside a property element, add the element
if (currentTag.equals("sourceCoverage")) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found Coverage name: ").append(s).toString());
}
request.setCoverage(s);
} else if (currentTag.equals("interpolationMethod")) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found Interpolation Method: ").append(s).toString());
}
request.setInterpolation(s);
} else if (currentTag.equals("crs")) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found Output CRS: ").append(s).toString());
}
request.setCRS(s);
if (request.getResponseCRS() == null) {
request.setResponseCRS(s);
}
} else if (currentTag.equals("responseCrs")) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found Output CRS: ").append(s).toString());
}
request.setResponseCRS(s);
} else if (currentTag.equals("format")) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found Output Format: ").append(s).toString());
}
request.setOutputFormat(s);
} else if (currentTag.equals("pos") && insideEnvelope) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found Envelope Coordinates: ").append(s).toString());
}
if (coordinates[0] == null) {
String[] coords = s.split(" ");
try {
double arg0 = Double.parseDouble(coords[0]);
double arg1 = Double.parseDouble(coords[1]);
coordinates[0] = new Double(arg0);
coordinates[1] = new Double(arg1);
} catch (NumberFormatException e) {
coordinates[0] = null;
coordinates[1] = null;
}
} else if (coordinates[2] == null) {
String[] coords = s.split(" ");
try {
double arg0 = Double.parseDouble(coords[0]);
double arg1 = Double.parseDouble(coords[1]);
coordinates[2] = new Double(arg0);
coordinates[3] = new Double(arg1);
Envelope env = new Envelope(coordinates[0].doubleValue(),
coordinates[2].doubleValue(), coordinates[1].doubleValue(),
coordinates[3].doubleValue());
request.setEnvelope(env);
} catch (NumberFormatException e) {
coordinates[2] = null;
coordinates[3] = null;
}
}
} else if (currentTag.equals("low") && insideGrid) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found Grid Lowers: ").append(s).toString());
}
String[] coords = s.split(" ");
try {
double arg0 = Double.parseDouble(coords[0]);
double arg1 = Double.parseDouble(coords[1]);
lowers[0] = new Double(arg0);
lowers[1] = new Double(arg1);
request.setGridLow(lowers);
} catch (NumberFormatException e) {
lowers[0] = null;
lowers[1] = null;
}
} else if (currentTag.equals("high") && insideGrid) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found Grid Highers: ").append(s).toString());
}
String[] coords = s.split(" ");
try {
double arg0 = Double.parseDouble(coords[0]);
double arg1 = Double.parseDouble(coords[1]);
highers[0] = new Double(arg0);
highers[1] = new Double(arg1);
request.setGridHigh(highers);
} catch (NumberFormatException e) {
highers[0] = null;
highers[1] = null;
}
} else if (currentTag.equals("pos") && insideGrid) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found Grid Origin: ").append(s).toString());
}
String[] coords = s.split(" ");
try {
double arg0 = Double.parseDouble(coords[0]);
double arg1 = Double.parseDouble(coords[1]);
origin[0] = new Double(arg0);
origin[1] = new Double(arg1);
request.setGridOrigin(origin);
} catch (NumberFormatException e) {
origin[0] = null;
origin[1] = null;
}
} else if (currentTag.equals("offsetVector") && insideGrid) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found Grid Offset-Vector: ").append(s).toString());
}
String[] coords = s.split(" ");
try {
double arg0 = Double.parseDouble(coords[0]);
double arg1 = Double.parseDouble(coords[1]);
if (offsetVector[0] == null) {
offsetVector[0] = new Double(arg0);
} else {
offsetVector[1] = new Double(arg1);
request.setOffsetVector(offsetVector);
}
} catch (NumberFormatException e) {
offsetVector[0] = null;
offsetVector[1] = null;
}
} else if (currentTag.equals("singleValue") && insideRange
&& (paramNum == (paramNames.size() - 1))) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found axisSubset{" + paramNames.get(paramNum)
+ "} > singleValue: ").append(s).toString());
}
final String key = (String) paramNames.get(paramNum);
if (params.get(key) == null) {
params.put(key, s);
}
} else if (currentTag.equals("min") && insideRange && (paramNum == (paramNames.size() - 1))) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found axisSubset{" + paramNames.get(paramNum)
+ "} > min: ").append(s).toString());
}
minTmp = (int) Math.round(Double.parseDouble(s));
} else if (currentTag.equals("max") && insideRange && (paramNum == (paramNames.size() - 1))) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(new StringBuffer("found axisSubset{" + paramNames.get(paramNum)
+ "} > max: ").append(s).toString());
}
final String key = (String) paramNames.get(paramNum);
if (params.get(key) == null) {
int maxTmp = (int) Math.round(Double.parseDouble(s));
params.put(key, minTmp + "/" + maxTmp);
minTmp = 0;
}
}
currentTag = "";
}
}