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); } } }