Java tutorial
/* * Copyright 2016 OPEN TONE Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jp.co.opentone.bsol.framework.web.view.util; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.lang.reflect.InvocationTargetException; import java.net.SocketException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.faces.application.FacesMessage; import javax.faces.application.FacesMessage.Severity; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.model.SelectItem; import javax.mail.internet.MimeUtility; import javax.servlet.ServletOutputStream; import javax.servlet.ServletResponseWrapper; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jp.co.opentone.bsol.framework.core.config.SystemConfig; import jp.co.opentone.bsol.framework.core.dto.Code; import jp.co.opentone.bsol.framework.core.dto.StringCode; import jp.co.opentone.bsol.framework.core.exception.ApplicationFatalRuntimeException; import jp.co.opentone.bsol.framework.core.message.Message; import jp.co.opentone.bsol.framework.core.util.ArgumentValidator; /** * View????. * @author opentone */ public class ViewHelper implements Serializable { /** * SerialVersionUID. */ private static final long serialVersionUID = 8334223734895951826L; /** logger. */ private static final Logger log = LoggerFactory.getLogger(ViewHelper.class); /** * ???????. */ public static final String KEY_DOWNLOAD_HEADER_FILENAME_ENCODING = "download.header.filename.encoding"; /** ???. */ public static final String KEY_SERVER_NAME = "server.name"; /** * . */ public static final String BASE_PATH = "%s://%s%s%s"; /** * ?OutputStream. * <p> * @see #getDownloadOutputStream(String) * @see #completeDownload() */ private transient DownloadOutputStream out; /** * . */ public ViewHelper() { } /** * ExternalContext?. * @return ExternalContext */ public ExternalContext getExternalContext() { return FacesContext.getCurrentInstance().getExternalContext(); } /** * request?????. * @param <T> * ? * @param key * ?? * @return ?. ???null */ @SuppressWarnings("unchecked") public <T> T getRequestValue(String key) { return (T) getExternalContext().getRequestMap().get(key); } /** * request??. * @param key * * @param value * */ public void setRequestValue(String key, Object value) { getExternalContext().getRequestMap().put(key, value); } /** * request?????. * @param key * */ public void removeRequestValue(String key) { getExternalContext().getRequestMap().remove(key); } /** * session?????. * @param <T> * ? * @param key * ?? * @return ?. ???null */ @SuppressWarnings("unchecked") public <T> T getSessionValue(String key) { return (T) getExternalContext().getSessionMap().get(key); } /** * session??. * @param key * * @param value * */ public void setSessionValue(String key, Object value) { getExternalContext().getSessionMap().put(key, value); } /** * HttpSession??. * @return session. */ public HttpSession getHttpSession() { return (HttpSession) getExternalContext().getSession(true); } /** * session?????. * @param key * */ public void removeSessionValue(String key) { getExternalContext().getSessionMap().remove(key); } /** * application?????. * @param <T> * ? * @param key * ?? * @return ?. ???null */ @SuppressWarnings("unchecked") public <T> T getApplicationValue(String key) { return (T) getExternalContext().getApplicationMap().get(key); } /** * application??. * @param key * * @param value * */ public void setApplicationValue(String key, Object value) { getExternalContext().getApplicationMap().put(key, value); } /** * application?????. * @param key * */ public void removeApplicationValue(String key) { getExternalContext().getApplicationMap().remove(key); } /** * Cookie?????. * @param key * ?? * @return ?. ???null */ public String getCookieValue(String key) { String value = null; Cookie[] cookies = ((HttpServletRequest) getExternalContext().getRequest()).getCookies(); if (cookies != null) { for (int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; if (cookie.getName() != null && cookie.getName().equals(key)) { value = cookie.getValue(); } } } return value; } /** * request/session/application??????????. ???. * <ol> * <li>request</li> * <li>session</li> * <li>application</li> * </ol> * @param <T> * ? * @param key * ?? * @return ?. ???null */ @SuppressWarnings("unchecked") public <T> T getValue(String key) { // NOTE // T????????? // ???JDK????? // Eclipse???????????????? T value = (T) getRequestValue(key); if (value == null) { value = (T) getSessionValue(key); if (value == null) { value = (T) getApplicationValue(key); } } return value; } /** * ?. * @param message * */ public void addMessage(Message message) { addMessage(null, message); } /** * ?. * @param clientId * ???ID * @param message * */ public void addMessage(String clientId, Message message) { FacesContext context = FacesContext.getCurrentInstance(); context.addMessage(clientId, createFacesMessage(message)); } /** * ???????. * @param message * * @return ??? */ protected Severity getSeverity(Message message) { String messageCode = message.getMessageCode(); char mType = messageCode.charAt(0); switch (mType) { case 'I': return FacesMessage.SEVERITY_INFO; case 'E': return FacesMessage.SEVERITY_ERROR; case 'W': return FacesMessage.SEVERITY_WARN; case 'F': return FacesMessage.SEVERITY_FATAL; default: throw new IllegalArgumentException(String.format("Severity for %s is undefined.", messageCode)); } } /** * Message?FacesMessage??. * @param message * * @return FacesMessage */ public FacesMessage createFacesMessage(Message message) { Severity severity = getSeverity(message); String summary = message.getSummary() != null ? message.getSummary() : severity.toString(); FacesMessage fMessage = new FacesMessage(severity, summary, message.getMessage()); return fMessage; } /** * dto??JSF?SelectItem?????. * dtoList?null??? * @param dtoList * SelectItem?? * @param valuePropertyName * SelectItem??????dtoList??????? * @param labelPropertyName * SelectItem??????dtoList??????? * @return ?? */ public List<SelectItem> createSelectItem(List<?> dtoList, String valuePropertyName, String labelPropertyName) { ArgumentValidator.validateNotEmpty(valuePropertyName, "valuePropertyName"); ArgumentValidator.validateNotEmpty(labelPropertyName, "labelPropertyName"); List<SelectItem> result = new ArrayList<SelectItem>(); try { if (dtoList == null) { return result; } for (Object item : dtoList) { Object val = PropertyUtils.getProperty(item, valuePropertyName); String label = BeanUtils.getProperty(item, labelPropertyName); if (isValidSelectItem(val, label)) { result.add(new SelectItem(val, label)); } } return result; } catch (IllegalAccessException e) { throw new ApplicationFatalRuntimeException(e); } catch (InvocationTargetException e) { throw new ApplicationFatalRuntimeException(e); } catch (NoSuchMethodException e) { throw new ApplicationFatalRuntimeException(e); } } private boolean isValidSelectItem(Object val, String label) { if (val == null || label == null) { log.warn("Value or label is null. Maybe it's a bug. value={}, label={}", val, label); return false; } return true; } /** * Code??JSF?SelectItem?????. * Code??null??? * @param codeList * SelectItem?? * @return ?? */ public List<SelectItem> createSelectItem(List<Code> codeList) { List<SelectItem> result = new ArrayList<SelectItem>(); if (codeList == null) { return result; } for (Code ev : codeList) { Object val = ev.getValue(); String label = ev.getLabel(); if (isValidSelectItem(val, label)) { result.add(new SelectItem(val, label)); } } return result; } /** * StringCode???JSF?SelectItem?????. * StringCode???null??? * @param codes * SelectItem?? * @return ?? */ public List<SelectItem> createSelectItem(StringCode[] codes) { if (codes == null) { return new ArrayList<SelectItem>(); } return createSelectStringItem(Arrays.asList(codes)); } /** * StringCode??JSF?SelectItem?????. * StringCode??null??? * @param codeList * SelectItem?? * @return ?? */ public List<SelectItem> createSelectStringItem(List<StringCode> codeList) { List<SelectItem> result = new ArrayList<SelectItem>(); if (codeList == null) { return result; } for (StringCode ev : codeList) { Object val = ev.getValue(); String label = ev.getLabel(); if (isValidSelectItem(val, label)) { result.add(new SelectItem(val, label)); } } return result; } /** * Code???JSF?SelectItem?????. * Code???null??? * @param codes * SelectItem?? * @return ?? */ public List<SelectItem> createSelectItem(Code[] codes) { if (codes == null) { return new ArrayList<SelectItem>(); } return createSelectItem(Arrays.asList(codes)); } /** * StringCode???JSF?SelectItem?????. * StringCode???null??? * @param codes * SelectItem?? * @return ?? */ public List<SelectItem> createSelectStringItem(StringCode[] codes) { if (codes == null) { return new ArrayList<SelectItem>(); } return createSelectStringItem(Arrays.asList(codes)); } /** * ????????. * <p> * {@link #completeDownload()}???????? * ???. * * @see #completeDownload() * @param fileName ?? * @param downloadByRealName ????????????true * @return ? * @throws IOException ??? */ public OutputStream getDownloadOutputStream(String fileName, boolean downloadByRealName) throws IOException { HttpServletRequest request = (HttpServletRequest) getExternalContext().getRequest(); HttpServletResponse response = (HttpServletResponse) getExternalContext().getResponse(); out = null; out = new DownloadOutputStream(request, response, fileName, downloadByRealName); return out; } /** * ????????. * <p> * {@link #completeDownload()}???????? * ???. * * @see #completeDownload() * @param fileName ?? * @return ? * @throws IOException ??? */ public OutputStream getDownloadOutputStream(String fileName) throws IOException { return getDownloadOutputStream(fileName, false); } /** * ???. * @param fileName * ?? * @param content * ? * @throws IOException ? */ public void download(String fileName, byte[] content) throws IOException { download(fileName, content, false); } /** * ???. * @param fileName * ?? * @param content * ? * @param downloadByRealFileName ???????true * @throws IOException ? */ public void download(String fileName, byte[] content, boolean downloadByRealFileName) throws IOException { HttpServletRequest request = (HttpServletRequest) getExternalContext().getRequest(); HttpServletResponse response = (HttpServletResponse) getExternalContext().getResponse(); setDownloadResponseHeader(request, response, fileName, downloadByRealFileName, content.length); doDownload(response, new ByteArrayInputStream(content)); FacesContext.getCurrentInstance().responseComplete(); } public void download(String fileName, InputStream in, int length) throws IOException { HttpServletRequest request = (HttpServletRequest) getExternalContext().getRequest(); HttpServletResponse response = (HttpServletResponse) getExternalContext().getResponse(); setDownloadResponseHeader(request, response, fileName, false, length); doDownload(response, in); FacesContext.getCurrentInstance().responseComplete(); } protected void setDownloadResponseHeader(HttpServletRequest request, HttpServletResponse response, String fileName, boolean downloadByRealName, int length) { setContentType(response, fileName); setHeaderFileName(request, response, fileName, downloadByRealName); response.addHeader("Accept-Ranges", "none"); // For Acrobat Reader 7.0 if (length > 0) { response.setContentLength(length); } } /** * ???actionId??????true?. * @param actionId * ??. submit?id * @return ????????true */ public boolean isActionInvoked(String actionId) { HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext() .getRequest(); if (isPartialAjax()) { return StringUtils.equals(actionId, req.getParameter("javax.faces.source")); } else { return StringUtils.isNotEmpty(req.getParameter(actionId)); } } /** * ?????actionIds??????????true?. * @param actionIds * ??. submit?id * @return ????????????true */ public boolean isAnyActionsInvoked(String... actionIds) { for (String id : actionIds) { if (isActionInvoked(id)) { return true; } } return false; } /** * ???JSF2?Ajax?Partial Request???true?. * @return Partial Request???true */ public boolean isPartialAjax() { String value = ((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()) .getParameter("javax.faces.partial.ajax"); return Boolean.parseBoolean(value); } private void setContentType(HttpServletResponse response, String fileName) { String extension = getExtension(fileName); if (".xls".equals(extension)) { response.setContentType("application/vnd.ms-excel"); } else if (".word".equals(extension)) { response.setContentType("application/msword"); } else if (".pdf".equals(extension)) { response.setContentType("application/pdf"); } else if (".csv".equals(extension)) { response.setContentType("text/csv"); } else { response.setContentType("application/octet-stream"); } } /** * ???User-Agent???????. * <ul> * <li>IE????????????</li> * <li>User-Agent??????</li> * <li>?????256????????????????????</li> * </ul> * @param request * @param response ? * @param fileName ??? */ private void setHeaderFileName(HttpServletRequest request, HttpServletResponse response, String fileName, boolean downloadByRealFileName) { String headerFileName; String userAgent = request.getHeader("User-Agent"); try { if (userAgent.indexOf("MSIE") != -1) { // IE?????????? String enc = SystemConfig.getValue(KEY_DOWNLOAD_HEADER_FILENAME_ENCODING); headerFileName = new String(fileName.getBytes(enc), "iso-8859-1"); // ??????? // URL????? + ????256byte???????? // ??? // headerFileName = URLEncoder.encode(fileName, "UTF-8"); } else { // ???????MIME???? // see RFC2231 headerFileName = MimeUtility.encodeWord(fileName, "ISO-2022-JP", "B"); } // SpreadsheetMLExcel 2007?????????? // *.xml? if (!downloadByRealFileName && headerFileName.endsWith(".xls")) { headerFileName = headerFileName.replaceAll("\\.xls$", ".xml"); } response.addHeader("Content-Disposition", "attachment; filename=\"" + headerFileName + "\""); } catch (UnsupportedEncodingException ignore) { log.warn(String.format("failed to set filename to response header. %s", fileName), ignore); } } protected void doDownload(HttpServletResponse response, InputStream in) throws IOException { ServletOutputStream o = getServletOutputStream(response); try { final int bufLength = 4096; byte[] buf = new byte[bufLength]; int i = 0; while ((i = in.read(buf, 0, buf.length)) != -1) { o.write(buf, 0, i); } o.flush(); o.close(); } catch (IOException e) { if (isDownloadCanceled(e)) { log.warn("Download canceled."); } else { throw e; } } } protected ServletOutputStream getServletOutputStream(HttpServletResponse response) throws IOException { ServletOutputStream o; if (response instanceof ServletResponseWrapper) { log.warn("Response is instance of ServletResponseWrapper"); o = response.getOutputStream(); /* HttpServletResponse rawResponse = (HttpServletResponse) ((ServletResponseWrapper) response).getResponse(); o = rawResponse.getOutputStream(); */ } else { log.warn("Response is instance of ServletResponse"); o = response.getOutputStream(); } return o; } /** * ?. * {@link #getDownloadOutputStream(String)}??? * ?????????????????. * * @see #getDownloadOutputStream(String) */ public void completeDownload() { if (out.isOpen()) { FacesContext.getCurrentInstance().responseComplete(); out = null; } } /** * ???IOException?????????true?. * @param e ??? * @return ?????true */ public boolean isDownloadCanceled(IOException e) { return e instanceof SocketException || (e.getCause() != null && e.getCause() instanceof SocketException); } /** * HTML???. * @param content * ? * @param charset ??? * @throws IOException ? */ public void requestResponse(byte[] content, String charset) throws IOException { HttpServletResponse response = (HttpServletResponse) getExternalContext().getResponse(); setHtmlResponseHeader(response, charset); doDownload(response, new ByteArrayInputStream(content)); // doWrite(response, content); FacesContext.getCurrentInstance().responseComplete(); } protected void setHtmlResponseHeader(HttpServletResponse response, String charset) { response.setContentType(String.format("text/html; charset=%s", charset)); } protected void doWrite(HttpServletResponse response, byte[] content) throws IOException { ServletOutputStream o = response.getOutputStream(); o.write(content); o.flush(); o.close(); } private String getExtension(String fileName) { int i = fileName.lastIndexOf('.'); if (i == -1) { return null; } String extension = fileName.substring(i); return extension; } /** * URL?. * @return URL */ public String getBasePath() { HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext() .getRequest(); return String.format(BASE_PATH, request.getScheme(), SystemConfig.getValue(KEY_SERVER_NAME), getPort(request), request.getContextPath()); } /** * URL?. * @return URL */ public String getContextPath() { HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext() .getRequest(); return request.getContextPath(); } private String getPort(HttpServletRequest request) { final int portHttp = 80; final int portHttps = 443; switch (request.getServerPort()) { case portHttp: case portHttps: return ""; default: return String.format(":%s", request.getServerPort()); } } /** * ???{@link OutputStream}. * <p> * ???????Open?????. * </p> */ class DownloadOutputStream extends OutputStream { /** request. */ private HttpServletRequest request; /** response. */ private HttpServletResponse response; /** ???. */ private String fileName; /** ????????????true. */ private boolean downloadByRealName; /** ??{@link OutputStream}. */ private OutputStream out; /** * ????????. * @param request HttpServletRequest * @param response HttpServletResponse * @param fileName ?? */ public DownloadOutputStream(HttpServletRequest request, HttpServletResponse response, String fileName) { this.request = request; this.response = response; this.fileName = fileName; } /** * ????????. * @param request HttpServletRequest * @param response HttpServletResponse * @param fileName ?? * @param downloadByRealName ????????????true */ public DownloadOutputStream(HttpServletRequest request, HttpServletResponse response, String fileName, boolean downloadByRealName) { this.request = request; this.response = response; this.fileName = fileName; this.downloadByRealName = downloadByRealName; } public boolean isOpen() { return out != null; } private OutputStream getOutputStream() throws IOException { if (!isOpen()) { setDownloadResponseHeader(request, response, fileName, downloadByRealName, -1); out = getServletOutputStream(response); } return out; } /* (non-Javadoc) * @see java.io.OutputStream#write(int) */ @Override public void write(int b) throws IOException { getOutputStream().write(b); } /* (non-Javadoc) * @see java.io.OutputStream#write(byte[]) */ @Override public void write(byte[] b) throws IOException { getOutputStream().write(b); } /* (non-Javadoc) * @see java.io.OutputStream#write(byte[], int, int) */ @Override public void write(byte[] b, int off, int len) throws IOException { getOutputStream().write(b, off, len); } /* (non-Javadoc) * @see java.io.OutputStream#flush() */ @Override public void flush() throws IOException { if (isOpen()) { getOutputStream().flush(); } } /* (non-Javadoc) * @see java.io.OutputStream#close() */ @Override public void close() throws IOException { if (isOpen()) { getOutputStream().close(); } } } }