package com.breeze.webserver;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.SessionFactory;
import com.breeze.hib.HibernateSaveProcessor;
import com.breeze.hib.HibernateQueryProcessor;
import com.breeze.metadata.Metadata;
import com.breeze.query.EntityQuery;
import com.breeze.query.QueryProcessor;
import com.breeze.query.QueryResult;
import com.breeze.save.SaveProcessor;
import com.breeze.save.SaveResult;
import com.breeze.save.SaveWorkState;
import com.breeze.util.JsonGson;
public class BreezeControllerServlet extends ControllerServlet {
private static final long serialVersionUID = 1L;
protected SessionFactory _sessionFactory;
protected Metadata _metadata;
protected String _metadataJson;
/** Create instance using the injected ServletContext */
@Override
public void init() {
ServletContext ctx = getServletContext();
init((SessionFactory) ctx.getAttribute(AppContextListener.SESSIONFACTORY),
(Metadata) ctx.getAttribute(AppContextListener.METADATA));
}
/** Create instance using provided sessionFactory and metadata. */
private void init(SessionFactory sessionFactory, Metadata metadata) {
System.out.println("BreezeTests: sessionFactory=" + sessionFactory
+ ", metadata=" + metadata);
_sessionFactory = sessionFactory;
_metadata = metadata;
_metadataJson = metadata.toJson();
}
@Override
protected void handleRequest(HttpServletRequest request,
HttpServletResponse response) {
try {
String methodName = getMethodName(request);
if (methodName.equals("Metadata")) {
writeResponse(response, getMetadata());
return;
}
if (methodName.equals("SaveChanges")) {
saveChanges(request, response);
return;
}
Method method = getMethod(this, methodName);
if (method == null) {
executeQuery(request, response);
} else {
dispatch(this, method, request, response);
}
} catch (Throwable ex) {
writeError(response, HttpServletResponse.SC_BAD_REQUEST,
ex.getMessage(), getStackTrace(ex));
}
}
protected String getStackTrace(Throwable e) {
java.io.StringWriter sw = new java.io.StringWriter();
e.printStackTrace(new java.io.PrintWriter(sw));
return sw.toString();
}
protected String getMetadata() {
return _metadataJson;
}
protected void executeQuery(HttpServletRequest request,
HttpServletResponse response) {
String pathInfo = request.getPathInfo();
String resourceName = pathInfo.substring(1);
EntityQuery entityQuery = extractEntityQuery(request);
QueryResult qr = executeQuery(resourceName, entityQuery);
writeResponse(response, qr.toJson());
}
protected QueryResult executeQuery(String resourceName, String json) {
EntityQuery eq = new EntityQuery(json);
return createQueryProcessor().executeQuery(resourceName, eq);
}
protected QueryResult executeQuery(Class clazz, String json,
HttpServletResponse response) {
EntityQuery eq = new EntityQuery(json);
return createQueryProcessor().executeQuery(clazz, eq);
}
protected QueryResult executeQuery(String resourceName,
EntityQuery entityQuery) {
return createQueryProcessor().executeQuery(resourceName, entityQuery);
}
protected QueryResult executeQuery(Class clazz, EntityQuery entityQuery) {
return createQueryProcessor().executeQuery(clazz, entityQuery);
}
protected QueryProcessor createQueryProcessor() {
return new HibernateQueryProcessor(_metadata, _sessionFactory);
}
protected void saveChanges(HttpServletRequest request,
HttpServletResponse response) {
Map saveBundle = extractSaveBundle(request);
SaveWorkState sws = createSaveWorkState(saveBundle);
SaveResult sr = saveChanges(sws);
writeSaveResponse(response, sr);
}
// override this to provide default Before/After save Entities logic
protected SaveWorkState createSaveWorkState(Map saveBundle) {
return new SaveWorkState(saveBundle);
}
protected SaveResult saveChanges(SaveWorkState saveWorkState) {
SaveProcessor processor = new HibernateSaveProcessor(_metadata, _sessionFactory);
return processor.saveChanges(saveWorkState);
}
protected EntityQuery extractEntityQuery(HttpServletRequest request) {
String qs = request.getQueryString();
try {
qs = (qs != null) ? URLDecoder.decode(qs, "UTF-8") : null;
} catch (Exception e) {
throw new RuntimeException("Unable to decode: " + qs, e);
}
Map<String, String[]> map = request.getParameterMap();
String json = null;
for (Map.Entry<String, String[]> entry : map.entrySet()) {
String parameterName = entry.getKey();
// String[] value = entry.getValue();
if (qs.indexOf("&" + parameterName) == -1) {
json = parameterName;
// break;
}
}
// // Alternate version - not as safe because queryString might have an
// '&'
// String json = (qs != null) ? URLDecoder.decode(qs) : null;
// // Isolate other parameters from the query
// // all other parameters will have the syntax
// // HACK
// if (json != null && json.indexOf("&") >= 0) {
// json = json.substring(0, json.indexOf("&"));
// }
return new EntityQuery(json);
}
protected Map extractSaveBundle(HttpServletRequest request) {
String saveBundleString = readPostData(request);
Map saveBundle = JsonGson.fromJson(saveBundleString);
return saveBundle;
}
protected void writeQueryResponse(HttpServletResponse response,
QueryResult queryResult) {
writeResponse(response, queryResult.toJson());
}
protected void writeSaveResponse(HttpServletResponse response,
SaveResult saveResult) {
String json = saveResult.toJson();
if (saveResult.hasErrors()) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
writeResponse(response, json);
}
}