package org.jibeframework.core.app.request;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonGenerator;
import org.jibeframework.core.Context;
import org.jibeframework.core.annotation.Interceptor;
import org.jibeframework.core.app.method.ArgumentsResolver;
import org.jibeframework.core.app.method.MethodHolder;
import org.jibeframework.core.service.MethodService;
import org.jibeframework.core.ui.builder.InvokeFunctionCommand;
import org.jibeframework.core.util.JacksonUtil;
import org.jibeframework.core.util.JibeUtil;
import org.springframework.beans.factory.annotation.Autowired;
public class RemoteMethodRequestHandler implements RequestHandler {
private static final Log logger = LogFactory.getLog(RemoteMethodRequestHandler.class);
@Autowired
private MethodService methodService;
@Autowired
private ArgumentsResolver argumentsResolver;
private List<String> notAuth;
public void handleRequest(Context context) {
Object retValue = null;
try {
final String remoteMethod = (String) context.getParams().get("remoteMethod");
argumentsResolver.initializeArgumentCandidates(context);
MethodHolder methodHolder = methodService.resolveHolder(remoteMethod);
if (methodHolder != null) {
Interceptor interceptor = methodHolder.getMethod().getAnnotation(Interceptor.class);
if (interceptor != null) {
for (String intercName : interceptor.value()) {
methodService.invokeServiceMethod(intercName);
}
}
retValue = methodService.invoke(remoteMethod);
}
} catch (Exception e) {
Throwable root = JibeUtil.getRootCause(e);
if (context != null) {
InvokeFunctionCommand.create().namespace("jibe.API.core").invoke("showMessage", "Exception",
root.getMessage(), "ext-mb-error");
}
logger.error(root.getMessage(), root);
} finally {
writeResponse(retValue, context);
}
}
public void handleAuthenticationFailed(Context context) {
InvokeFunctionCommand.create().namespace("jibe.API.core").invoke("reloadCurrentPage");
writeResponse(null, context);
}
public void handleException(Exception e, Context context) {
Throwable root = JibeUtil.getRootCause(e);
if (context != null) {
InvokeFunctionCommand.create().namespace("jibe.API.core").invoke("showMessage", "Exception",
root.getMessage(), "ext-mb-error");
}
logger.error(root.getMessage(), root);
}
public boolean shouldAuthenticate(Context context) {
Map<String, Object> data = (Map<String, Object>) context.getParams();
Object rm = data.get("remoteMethod");
return rm != null && !notAuth.contains(rm);
}
public boolean applies(Context context) {
return context.getParams().containsKey("remoteMethod");
}
private void writeResponse(Object retValue, Context context) {
HttpServletResponse response = context.getServletResponse();
if (!response.isCommitted()) {
try {
StringWriter writer = new StringWriter();
if (retValue != null) {
writer.append(JacksonUtil.toJson(retValue));
} else {
JsonGenerator g = JacksonUtil.getMapper().getJsonFactory().createJsonGenerator(writer);
g.writeStartObject();
g.writeFieldName("__cmds");
g.writeStartArray();
List<Object> functions = new ArrayList<Object>(context.getFunctions());
for (Object function : functions) {
g.writeObject(function);
}
g.writeEndArray();
g.writeEndObject();
g.close();
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/javascript");
response.setStatus(200);
response.getWriter().write(writer.toString());
response.getWriter().flush();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
public void setNotAuth(List<String> notAuth) {
this.notAuth = notAuth;
}
}