Operation dispatch(Request req, Service serviceDescriptor)
throws Throwable {
if (req.getRequest() == null) {
String msg = "Could not determine geoserver request from http request " + req.getHttpRequest();
throw new ServiceException(msg, "MissingParameterValue", "request");
}
// ensure the requested operation exists
boolean exists = false;
for ( String op : serviceDescriptor.getOperations() ) {
if ( op.equalsIgnoreCase( req.getRequest() ) ) {
exists = true;
break;
}
}
// lookup the operation, initial lookup based on (service,request)
Object serviceBean = serviceDescriptor.getService();
Method operation = OwsUtils.method(serviceBean.getClass(), req.getRequest());
if (operation == null || !exists) {
String msg = "No such operation " + req;
throw new ServiceException(msg, "OperationNotSupported", req.getRequest());
}
//step 4: setup the paramters
Object[] parameters = new Object[operation.getParameterTypes().length];
for (int i = 0; i < parameters.length; i++) {
Class parameterType = operation.getParameterTypes()[i];
//first check for servlet request and response
if (parameterType.isAssignableFrom(HttpServletRequest.class)) {
parameters[i] = req.getHttpRequest();
} else if (parameterType.isAssignableFrom(HttpServletResponse.class)) {
parameters[i] = req.getHttpResponse();
}
//next check for input and output
else if (parameterType.isAssignableFrom(InputStream.class)) {
parameters[i] = req.getHttpRequest().getInputStream();
} else if (parameterType.isAssignableFrom(OutputStream.class)) {
parameters[i] = req.getHttpResponse().getOutputStream();
} else {
//check for a request object
Object requestBean = null;
//track an exception
Throwable t = null;
if (req.getKvp() != null && req.getKvp().size() > 0) {
//use the kvp reader mechanism
try {
requestBean = parseRequestKVP(parameterType, req);
}
catch (Exception e) {
//dont die now, there might be a body to parse
t = e;
}
}
if (req.getInput() != null) {
//use the xml reader mechanism
requestBean = parseRequestXML(requestBean,req.getInput(), req);
}
//if no reader found for the request, throw exception
//TODO: we may wish to make this configurable, as perhaps there
// might be cases when the service prefers that null be passed in?
if ( requestBean == null ) {
//unable to parse request object, throw exception if we
// caught one
if ( t != null ) {
throw t;
}
throw new ServiceException( "Could not find request reader (either kvp or xml) for: " + parameterType.getName() );
}
// GEOS-934 and GEOS-1288
Method setBaseUrl = OwsUtils.setter(requestBean.getClass(), "baseUrl", String.class);
if (setBaseUrl != null) {
setBaseUrl.invoke(requestBean, new String[] { RequestUtils.baseURL(req.getHttpRequest())});
}
// another couple of thos of those lovley cite things, version+service has to specified for
// non capabilities request, so if we dont have either thus far, check the request
// objects to try and find one
// TODO: should make this configurable
if (requestBean != null) {
//if we dont have a version thus far, check the request object
if (req.getService() == null) {
req.setService(lookupRequestBeanProperty(requestBean, "service", false));
}
if (req.getVersion() == null) {
req.setVersion(lookupRequestBeanProperty(requestBean, "version", false));
}
if (req.getOutputFormat() == null) {
req.setOutputFormat(lookupRequestBeanProperty(requestBean, "outputFormat",
true));
}
parameters[i] = requestBean;
}
}
}
//if we are in cite compliant mode, do some additional checks to make
// sure the "mandatory" parameters are specified, even though we
// succesfully dispatched the request.
if (citeCompliant) {
if (!"GetCapabilities".equalsIgnoreCase(req.getRequest())) {
if (req.getVersion() == null) {
//must be a version on non-capabilities requests
throw new ServiceException("Could not determine version",
"MissingParameterValue", "version");
} else {
//version must be valid
if (!req.getVersion().matches("[0-99].[0-99].[0-99]")) {
throw new ServiceException("Invalid version: " + req.getVersion(),
"InvalidParameterValue", "version");
}
//make sure the versoin actually exists
boolean found = false;
Version version = new Version(req.getVersion());
for (Iterator s = loadServices().iterator(); s.hasNext();) {
Service service = (Service) s.next();
if (version.equals(service.getVersion())) {
found = true;
break;
}
}
if (!found) {
throw new ServiceException("Invalid version: " + req.getVersion(),
"InvalidParameterValue", "version");
}
}
if (req.getService() == null) {
//give up
throw new ServiceException("Could not determine service",
"MissingParameterValue", "service");
}
}
}