package jp.agentec.sinaburocast.common.util;
import java.io.StringWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jp.agentec.sinaburocast.common.SinaburoConstant;
import jp.agentec.sinaburocast.common.SinaburoConstant.AttrKey;
import jp.agentec.sinaburocast.common.SinaburoConstant.MesResKey;
import jp.agentec.sinaburocast.vo.AuthenticatedTokenVO;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.velocity.Template;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.log.Log;
import org.apache.velocity.tools.view.servlet.VelocityViewServlet;
import org.mobylet.core.Mobylet;
import org.mobylet.core.MobyletFactory;
import org.seasar.struts.util.RequestUtil;
import org.seasar.struts.util.ServletContextUtil;
public class AgtVelocityViewServlet extends VelocityViewServlet {
private static final long serialVersionUID = 3202497865343082548L;
private static final String PROPERTY_ERROR_TEMPLATE = "tools.view.servlet.error.template";
private static final boolean __devmode = PropertyUtil.getBoolean("DEVMODE");
protected String errorTemplate;
private final Logger logger = Logger.getLogger(getClass());
/* (非 Javadoc)
* @see org.apache.velocity.tools.view.servlet.VelocityViewServlet#init(javax.servlet.ServletConfig)
*/
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
errorTemplate = getVelocityProperty(PROPERTY_ERROR_TEMPLATE, null);
}
@Override
public Template getTemplate(String name) throws ResourceNotFoundException,
ParseErrorException, Exception {
Template retValue = super.getTemplate(deviceJudge(name));
return retValue;
}
@Override
public Template getTemplate(String name, String encoding)
throws ResourceNotFoundException, ParseErrorException, Exception {
int devType = getDevice();
String prifix = ServletContextUtil.getViewPrefix();
if (SinaburoConstant.AccessType.MOBILE == devType){
name = name.replace(prifix, prifix + "/mb");
encoding = "UTF-8";
}else if (SinaburoConstant.AccessType.SMARTPHONE == devType){
name = name.replace(prifix, prifix + "/sp");
}
//ユーザーのエラーページに遷移するけど、管理者でログインしている場合
//パスを管理者ページに変更
if(!name.contains("/admin/") && name.contains("/error/")){
Object obj = RequestUtil.getRequest().getSession().getAttribute(AttrKey.AUTHENTICATED_TOKEN);
if(obj != null && ((AuthenticatedTokenVO)obj).adminUser != null){//管理者
name = name.replace("/error/", "/error/admin/");
}
}
Template retValue = super.getTemplate(name, encoding);
return retValue;
}
private String deviceJudge(String name){
String prifix = ServletContextUtil.getViewPrefix();
//携帯ユーザーだったら
if(getDevice().equals(SinaburoConstant.AccessType.MOBILE)){
//ServeletContextUtil s = null;
return name.replace(prifix, prifix + "/mb");
}else if(getDevice().equals(SinaburoConstant.AccessType.SMARTPHONE)){
return name.replace(prifix, prifix + "/sp");
}
return name;
}
/**
* userAgentで携帯、(PC,スマートフォン)
* @return 携帯の場合true,その他false
*/
public Integer getDevice(){
//final Log log = getVelocityEngine().getLog();
try {
Mobylet mobylet = MobyletFactory.getInstance();
return RequestUtils.getCarrierType(mobylet);
} catch (Exception e) {
String userAgent = RequestUtil.getRequest().getHeader("user-agent");
logger.error("AgtMobylet機種判別エラー: UserAgent=" + userAgent + " error=" + e.getMessage());
if (StringUtils.isEmpty(userAgent)) {
//nullの場合例外が発生するのでPCで返す
return SinaburoConstant.AccessType.PC;
}
//スマートフォン
if ((userAgent.indexOf("iPhone") > 0 && userAgent.indexOf("iPad") == -1)
|| userAgent.indexOf("iPod") > 0
|| userAgent.indexOf("Android") > 0){
return SinaburoConstant.AccessType.SMARTPHONE;
}
if( userAgent.startsWith("Mozilla") || userAgent.startsWith("Opera")){
//PC
return SinaburoConstant.AccessType.PC;
}
return SinaburoConstant.AccessType.MOBILE;
}
}
//choi-c ADD END
/* (非 Javadoc)
* @see org.apache.velocity.tools.view.servlet.VelocityViewServlet#error(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Exception)
*/
@Override
protected void error(HttpServletRequest request,
HttpServletResponse response, Exception e) throws ServletException {
if (__devmode || errorTemplate == null) {
super.error(request, response, e);
return;
}
final Log log = getVelocityEngine().getLog();
try {
if (e instanceof ResourceNotFoundException) {
log.warn("AgtVelocityViewServlet: some resources are not found. ", e);
response.sendError(HttpServletResponse.SC_NOT_FOUND, request.getRequestURI());
return;
}
// get a velocity context
Context ctx = createContext(request, response);
Throwable cause = e;
// if it's an MIE, i want the real cause and stack trace!
if (cause instanceof MethodInvocationException)
{
// get the real cause
cause = ((MethodInvocationException)e).getWrappedThrowable();
}
// grab the cause's stack trace and put it in the context
StringWriter sw = new StringWriter();
cause.printStackTrace(new java.io.PrintWriter(sw));
log.error(sw.toString());
final String errorCode = MesResKey.Errors.VelocityRenderError;
ctx.put("ERROR_CODE", errorCode);
ctx.put("ERROR_MSG", SinaburoViewUtil.getErrorMessage("errors.SystemException", errorCode));
// retrieve and render the error template
Template et = getTemplate(errorTemplate);
mergeTemplate(et, ctx, response);
} catch (Exception e2) {
log.error("AgtVelocityViewServlet: Error during error template rendering", e2);
// 本番環境ではスタックトレースは出力しない
throw new ServletException(e);
}
}
}