package cokr.xit.foundation; import java.util.Locale; /**현재 클라이언트(사용자)의 접근정보를 추출하여 제공하는 클래스. */ public class Access { protected static final ThreadLocal current = new ThreadLocal<>(); private String id, sessionID, action, ipAddress; private boolean newSession, mobile, ajaxRequest, jsonResponse; private Locale locale; private static final String LOCALHOST_V4 = "127.0.0.1", LOCALHOST_V6 = "0:0:0:0:0:0:0:1"; /**현재 클라이언트의 IP주소가 로컬호스트와 같으면 로컬호스트의 주소를 반환한다. * @param address 클라이언트의 IP 주소 * @param localhost 로컬호스트 주소 * @return * */ public static String getClientAddress(String address, String localhost) { return LOCALHOST_V4.equals(address) || LOCALHOST_V6.equals(address) ? localhost : address; } /**현재 클라이언트의 접근 아이디를 반환한다. * @return 현재 클라이언트의 접근 아이디 */ public String getId() { return Assert.ifEmpty(id, id = "access-" + System.currentTimeMillis()); } /**세션 아이디를 반환한다. * @return 세션 아이디 */ public String getSessionID() { return sessionID; } /**세션 아이디를 설정한다. * @param sessionID 세션 아이디 * @return Access */ public Access setSessionID(String sessionID) { this.sessionID = sessionID; return this; } /**접근 후 실행할 액션이름(예: uri나 url)을 반환한다. * @return 접근 후 실행할 액션이름 */ public String getAction() { return action; } /**접근 후 실행할 액션이름(예:uri나 url)을 설정한다. * @param action 접근 후 실행할 액션이름 * @return Access */ public Access setAction(String action) { this.action = action; return this; } /**클라이언트의 IP주소를 반환한다. * @return 클라이언트의 IP주소 */ public String getIpAddress() { return ipAddress; } /**클라이언트의 IP주소를 설정한다. * @param ipAddress 클라이언트의 IP주소 * @return Access */ public Access setIpAddress(String ipAddress) { this.ipAddress = ipAddress; return this; } /**현재 스레드의 클라이언트의 Access 정보를 반환한다. * @return 현재 스레드의 클라이언트의 Access */ public static Access current() { return Assert.ifEmpty(current.get(), Access::new); } /**현재 Access를 현재 스레드의 클라이언트의 접근정보로 설정한다. * @return Access */ public Access setCurrent() { current.set(this); return this; } /**현재 Access의 세션이 새 세션인지 반환한다. * @return * */ public boolean inNewSession() { return newSession; } /**현재 Access의 세션이 새 세션인지 설정한다. * @param newSession * * @return Access */ public Access setNewSession(boolean newSession) { this.newSession = newSession; return this; } /**클라이언트가 모바일 기기로 접근한 것인지 반환한다. * @return * */ public boolean isMobile() { return mobile; } /**클라이언트가 모바일 기기로 접근한 것인지 설정한다. * @param mobile * * @return Access */ public Access setMobile(boolean mobile) { this.mobile = mobile; return this; } /**접근요청이 AJAX로 된 것인지 반환한다. * @return * */ public boolean isAjaxRequest() { return ajaxRequest; } /**접근요청이 AJAX로 된 것인지 설정한다. * @param header HTTP 요청의 'X-Requested-With' 헤더값 * @return Access */ public Access setAjaxRequest(String header) { ajaxRequest = "XMLHttpRequest".equalsIgnoreCase(header); return this; } /**접근요청의 응답을 JSON으로 하는지 반환한다. * @return * */ public boolean isJsonResponse() { return jsonResponse; } /**접근요청의 응답을 JSON으로 하는지 설정한다. * @param header HTTP 요청의 'accept' 헤더값 * @return Access */ public Access setJsonResponse(String header) { this.jsonResponse = !Assert.isEmpty(header) && header.contains("json"); return this; } /**접근 요청의 Locale을 반환한다. * @return 접근 요청의 Locale */ public Locale getLocale() { return locale != null ? locale : Locale.getDefault(); } /**접근 요청의 Locale을 설정한다. * @param locale Locale * @return Access */ public Access setLocale(Locale locale) { this.locale = locale; return this; } /**접근요청이 디버그 모드에서 된 것인지 반환한다. * @return * */ public boolean isDebug() { return "true".equals(System.getProperty("debug")); } /**현재 Access를 현재 스레드에서 제거한다. * @return 제거된 Access */ public static Access release() { Access access = current.get(); current.remove(); return access; } @Override public String toString() { return String.format("%s(id:'%s', clientIP:'%s', action:'%s')", getClass().getSimpleName(), getId(), getIpAddress(), getAction()); } }