package com.buglabs.bug.ws.service;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.osgi.framework.BundleContext;
import org.osgi.service.cm.ConfigurationAdmin;
import com.buglabs.services.ws.IWSResponse;
import com.buglabs.services.ws.PublicWSDefinition;
import com.buglabs.services.ws.PublicWSProvider;
import com.buglabs.services.ws.PublicWSProvider2;
import com.buglabs.services.ws.PublicWSProviderWithParams;
import com.buglabs.util.xml.XmlNode;
/**
* This class used to do it all, but now it extends AbstractWSServlet so other
* Service view classes can share functionality. Some of this classes previous
* functionality has been pushed into it's abstract parent.
*
*
*/
public class WSServlet extends AbstractWSServlet {
private static final long serialVersionUID = 2559949124867457077L;
public WSServlet(BundleContext context, Map<String, PublicWSProvider> serviceMap, ConfigurationAdmin configAdmin) {
super(context, serviceMap, configAdmin);
}
protected void executeHttpMethod(HttpServletRequest req, HttpServletResponse resp, int method) throws IOException, ServletException {
if (req.getPathInfo() == null) {
returnServices(resp, getServiceMap());
return;
}
String urlPath = req.getPathInfo().substring(1);
String serviceName;
int end = urlPath.indexOf("/");
if (end < 0) {
serviceName = urlPath;
} else {
serviceName = urlPath.substring(0, end);
}
PublicWSProvider service = (PublicWSProvider) getServiceMap().get(serviceName.toUpperCase());
// Service is not found, return 404 error
if (service == null) {
resp.sendError(404, serviceName + " was not found");
return;
}
// check if service is disabled, if so send appropriate message to
// the user
if (!isServiceEnabled(getConfigurationAdmin(), service.getPublicName())) {
resp.sendError(503, service.getPublicName() + " has been disabled by the user.");
return;
}
IWSResponse response;
if (service instanceof PublicWSProviderWithParams) {
Map post;
Map get;
if (req.getMethod().equals("GET")) {
get = req.getParameterMap();
post = new HashMap();
} else {
get = new HashMap();
String query = req.getQueryString();
if (query != null) {
String[] params = query.split("&");
for (int i = 0; i < params.length; i++) {
String[] pair = params[i].split("=");
if (pair.length > 1) {
get.put(pair[0], pair[1]);
} else if (pair.length > 0) {
get.put(pair[0], null);
}
}
}
post = req.getParameterMap();
}
response = ((PublicWSProviderWithParams) service).execute(method, urlPath, get, post);
} else {
response = service.execute(method, urlPath);
}
if (response == null) {
// TODO make this error message more helpful.
resp.sendError(0, "Service failed. (NULL response)");
} else if (response.isError()) {
resp.sendError(response.getErrorCode(), response.getErrorMessage());
} else {
if (response.getMimeType() == null) {
resp.setContentType("text/plain");
} else {
resp.setContentType(response.getMimeType());
}
Object data = response.getContent();
if (data instanceof InputStream) {
IOUtils.copy((InputStream) data, resp.getOutputStream());
IOUtils.closeQuietly(((InputStream) data));
} else {
resp.getWriter().print(response.getContent());
}
}
}
private void returnServices(HttpServletResponse resp, Map<String, PublicWSProvider> serviceMap2) throws IOException {
resp.setContentType("text/xml");
resp.getWriter().print(mapToXml("service", serviceMap2).toString());
}
private XmlNode mapToXml(String entityName, Map<String, PublicWSProvider> serviceMap2) throws IOException {
// Collection container is plural.
// TODO: make sure 's' is the right pluralizer.
XmlNode root = new XmlNode(entityName + "s");
for (Iterator<String> i = serviceMap2.keySet().iterator(); i.hasNext();) {
String key = i.next();
Object v = serviceMap2.get(key);
XmlNode element = null;
if (v instanceof PublicWSProvider) {
PublicWSProvider pubService = (PublicWSProvider) v;
// service is disabled, don't create an element for it
if (!isServiceEnabled(getConfigurationAdmin(), pubService.getPublicName())) {
continue;
}
element = new XmlNode(root, entityName);
element.addAttribute("name", pubService.getPublicName());
element.addAttribute("description", pubService.getDescription());
PublicWSDefinition def = pubService.discover(PublicWSProvider2.GET);
if (def != null) {
XmlNode defNode = new XmlNode(element, "get");
defNode.setAttribute("returns", def.getReturnType());
if (def.getParameters() != null) {
defNode.setAttribute("parameters", def.getParameters().toString());
} else {
defNode.setAttribute("parameters", "");
}
}
def = pubService.discover(PublicWSProvider2.POST);
if (def != null) {
XmlNode defNode = new XmlNode(element, "post");
defNode.setAttribute("returns", def.getReturnType());
if (def.getParameters() != null) {
defNode.setAttribute("parameters", def.getParameters().toString());
} else {
defNode.setAttribute("parameters", "");
}
}
def = pubService.discover(PublicWSProvider2.DELETE);
if (def != null) {
XmlNode defNode = new XmlNode(element, "delete");
defNode.setAttribute("returns", def.getReturnType());
if (def.getParameters() != null) {
defNode.setAttribute("parameters", def.getParameters().toString());
} else {
defNode.setAttribute("parameters", "");
}
}
def = pubService.discover(PublicWSProvider2.PUT);
if (def != null) {
XmlNode defNode = new XmlNode(element, "put");
defNode.setAttribute("returns", def.getReturnType());
if (def.getParameters() != null) {
defNode.setAttribute("parameters", def.getParameters().toString());
} else {
defNode.setAttribute("parameters", "");
}
}
} else {
element = new XmlNode(root, entityName);
element.addAttribute("name", key);
}
}
return root;
}
}