Java tutorial
/* * Copyright (c) 2013 ITOCHU Techno-Solutions Corporation. * * 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.ctc_g.jse.vid; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; import jp.co.ctc_g.jfw.core.internal.Config; import jp.co.ctc_g.jfw.core.internal.InternalException; import jp.co.ctc_g.jfw.core.util.Args; import jp.co.ctc_g.jfw.core.util.Maps; import jp.co.ctc_g.jfw.core.util.Strings; import jp.co.ctc_g.jse.core.internal.WebCoreInternals; import org.apache.commons.lang.builder.ToStringBuilder; /** * <p> * ?????ID????? * </p> * <h4>???ID</h4> * <p> * ????????ID?JSP???????? * ???????????ID????????? * ????<strong>?????? * ?????????????? * ?????ID????????ID???????????</strong> * ??????????ID??????? * </p> * <pre class="brush:java"> * ViewId vid = new ViewId("VID#0001"); * ViewId.is(vid, request); * </pre> * <p> * ???????????? * ????????????????ID????? * </p> * <h4>?ID??</h4> * <p> * ?ID?{@link javax.servlet.http.HttpSession }???????? * {@link ViewId#is(ViewId, HttpServletRequest)}?????? * ???ID???????? * ???????ID?????????? * ?ID????????ID??? * ????????????????? * </p> * <p> * ????ID?????????????? * ??????ID???ID?<strong>?????</strong> * ?????????????????? * </p> * <h4>????</h4> * <p> * ?ID????????????{@link #equals(Object)}?<code>true</code>?????? * ??????ID????????? * ???{@link #hashCode()}??????ID??????????ID????????? * </p> * <h4>?</h4> * <p> * ?{@link Config ?}??????? * </p> * <table class="property_file_override_info"> * <thead> * <tr> * <th></th> * <th></th> * <th></th> * <th></th> * </tr> * </thead> * <tbody> * <tr> * <td>container_key</td> * <td>java.lang.String</td> * <td> * ?ID?{@link HttpSession }?????? * </td> * <td> * jp.co.ctc_g.jfw.vid.ViewId.CONTAINER_KEY * </td> * </tr> * <tr> * <td>queries_join_word</td> * <td>java.lang.String</td> * <td> * ?????? * </td> * <td> * * </td> * </tr> * <tr> * <td>override_if_container_has_already_managed_same_view_id</td> * <td>java.lang.String</td> * <td> * ????ID???????? * ????ID???ID??????????? * </td> * <td> * false * </td> * </tr> * </tbody> * </table> * @author ITOCHU Techno-Solutions Corporation. */ public class ViewId implements Serializable { private static final long serialVersionUID = 1832342195395194537L; private static final String ALL_PARAMETERS_INCLUDE_MARK = "*"; /** * ?ID??????? * {@link HttpSession}??????? */ public static final String VIEW_ID_CONTAINER_KEY; /** * {@link HttpSession}??????ID??? */ public static final String ID = "id"; /** * {@link HttpSession}???????? */ public static final String LABEL = "label"; /** * {@link HttpSession}?????URL??? */ public static final String URL = "url"; /** * {@link HttpSession}?????Query??? */ public static final String QUERY = "query"; /** * ?????? & ?? */ public static final String QUERIES_JOIN_WORD; private static final String PERCENT_ESCAPE_ENCODING_FOR_QUERY; private static final boolean OVERRIDE_THE_SAME_ONE; private static ViewIdStore.Factory factory = new ViewIdStore.Factory(); static { Config c = WebCoreInternals.getConfig(ViewId.class); VIEW_ID_CONTAINER_KEY = c.find("container_key"); QUERIES_JOIN_WORD = c.find("queries_join_word"); OVERRIDE_THE_SAME_ONE = Boolean.valueOf(c.find("override_if_container_has_already_managed_same_view_id")); PERCENT_ESCAPE_ENCODING_FOR_QUERY = c.find("percent_escape_encoding_for_query"); } /* * ?ID */ private String id; /* * ?????????? */ private String label; /* * ???????URL */ private String url; /* * ??? */ private Map<String, String[]> params; /* * ???????? */ private boolean pankuzu; /* * ???ID???????? */ private boolean frozen; /* * ??URL??????? */ private String include; /* * ??URL????????? */ private String exclude; /** * ?? */ public ViewId() { } /** * ??ID?ID??????????? * ?ID?????????????? * @param id ?ID */ public ViewId(String id) { Args.checkNotBlank(id); this.id = id; } /** * ??<code>ViewId</code>???ID?????? * @param self ???ID * @param request ??? */ public static void is(ViewId self, HttpServletRequest request) { is(self, factory.create(request)); } private static void is(ViewId self, ViewIdStore store) { Args.checkNotNull(self); self.freeze(); synchronized (store.semaphore()) { LinkedList<ViewId> ids = store.find(); assert ids != null; if (ids.contains(self)) { int index = ids.indexOf(self); for (int i = ids.size() - 1; i > index; i--) { ids.remove(i); } if (OVERRIDE_THE_SAME_ONE) { ids.set(index, self); } } else { ids.add(self); } store.store(ids); } } /** * ???ID???? * ????????????? * ??ID????????<code>null</code>???? * @param request ??? * @return ?ID */ public static ViewId current(HttpServletRequest request) { return current(factory.create(request)); } private static ViewId current(ViewIdStore store) { ViewId id = null; synchronized (store.semaphore()) { LinkedList<ViewId> ids = store.find(false); id = ids != null && !ids.isEmpty() ? ids.getLast() : null; } return id; } /** * ?ID????? * ????0?{@link ViewId#current(HttpServletRequest)}??? * ??ID????????<code>null</code>???? * @param history * @param request ??? * @return ?ID */ public static ViewId history(int history, HttpServletRequest request) { return history(history, factory.create(request)); } private static ViewId history(int history, ViewIdStore store) { ViewId id = null; synchronized (store.semaphore()) { LinkedList<ViewId> ids = store.find(false); id = (ids != null && !ids.isEmpty() && ids.size() > history) ? ids.get(ids.size() - history - 1) : null; } return id; } /** * ?ID????? * ????ID?????? * ??ID????????????????? * @param request ??? * @return ?ID? */ public static Iterator<ViewId> iterator(HttpServletRequest request) { return container(request).iterator(); } /** * ?ID?{@link java.lang.Iterable Iterable}???? * ??{@link java.lang.Iterable Iterable}??ID?????? * ???<code>null</code>????????? * ??ID??{@link java.lang.Iterable Iterable}?????????? * ?{@link java.lang.Iterable Iterable}???? * @param request ??? * @return ?ID? */ public static Iterable<ViewId> container(HttpServletRequest request) { return container(factory.create(request)); } @SuppressWarnings("unchecked") private static Iterable<ViewId> container(ViewIdStore store) { Iterable<ViewId> iterable = null; synchronized (store.semaphore()) { LinkedList<ViewId> ids = store.find(false); iterable = ids != null ? Collections.unmodifiableList((LinkedList<ViewId>) ids.clone()) : Collections.<ViewId>emptyList(); } return iterable; } /** * ?ID????? * {@link HttpSession}??ID??????0???? * @param request ??? * @return ?ID? */ public static int size(HttpServletRequest request) { return size(factory.create(request)); } private static int size(ViewIdStore store) { int size = 0; synchronized (store.semaphore()) { LinkedList<ViewId> ids = store.find(false); size = ids != null ? ids.size() : 0; } return size; } /** * {@link HttpSession}?????ID???? * @param request ??? */ public static void clear(HttpServletRequest request) { clear(factory.create(request)); } private static void clear(ViewIdStore store) { synchronized (store.semaphore()) { store.remove(); } } /** * {@link HttpSession}???????ID??ID??? * @param request ??? * @param id ?ID */ public static void clear(HttpServletRequest request, String id) { clear(factory.create(request), id); } private static void clear(ViewIdStore store, String id) { synchronized (store.semaphore()) { store.remove(id); } } /** * ?????URL???? * ????????????? * ?????{@link #setLabel(String)}??????? * ???????????? * ?????????id???? * URL????"javax.servlet.forward.request_uri"?????? * ????{@link HttpServletRequest#getParameterMap()}???? * @param request ?? * @return ?? */ public ViewId fill(HttpServletRequest request) { if (Strings.isBlank(id)) { throw new InternalException(ViewIdDefinitionTag.class, "E-VID#0004"); } // ????????ID?? label = label != null ? label : id; // URL???????????URL url = url != null ? url : (String) request.getAttribute("javax.servlet.forward.request_uri"); // ????????????include?????????? if (params == null) { Map<String, String[]> requestedParameters = new HashMap<String, String[]>(request.getParameterMap()); if (requestedParameters.size() > 0) { if (!Strings.isEmpty(exclude)) { params = excludeParameter(requestedParameters); } else if (!Strings.isEmpty(include)) { params = includeParameter(requestedParameters); } else { params = new HashMap<String, String[]>(); } } } return this; } private Map<String, String[]> excludeParameter(Map<String, String[]> requestedParameters) { Map<String, String[]> storedParameters = new HashMap<String, String[]>(); List<String> keys = Arrays.asList(exclude.split(",")); Set<String> sets = requestedParameters.keySet(); for (String key : sets) { if (!keys.contains(key)) { storedParameters.put(key, (String[]) requestedParameters.get(key)); } } return storedParameters; } private Map<String, String[]> includeParameter(Map<String, String[]> requestedParameters) { if (ALL_PARAMETERS_INCLUDE_MARK.equals(include)) { return requestedParameters; } else { Map<String, String[]> storedParameters = new HashMap<String, String[]>(); List<String> keys = Arrays.asList(include.split(",")); Set<String> sets = requestedParameters.keySet(); for (String key : sets) { if (keys.contains(key)) { storedParameters.put(key, (String[]) requestedParameters.get(key)); } } return storedParameters; } } /** * ??????? * ?????? * ??{@link #setId(String)}{@link #setLabel(String)}????? * ????????? * ????????????????? * {@link InternalException}?<code>E-VID#0001</code>????? * @see #checkFrozen() * @see #isFrozen() */ protected void freeze() { this.frozen = true; } /** * ???????????? * ?????????? * {@link InternalException}?<code>E-VID#0001</code>????? * @throws {@link InternalException} ???????? */ protected void checkFrozen() { if (isFrozen()) { throw new InternalException(ViewId.class, "E-VID#0001", Maps.hash("id", id)); } } /** * ????????????????? * @return ???????true */ public boolean isFrozen() { return frozen; } /** * ????ID???? * @return ?ID */ public String getId() { return id; } /** * ?ID??? * ????????{@link InternalException}???? * @param id ?ID */ public void setId(String id) { checkFrozen(); this.id = id; } /** * ??????? * ???ID????? * ??????? * @return */ public String getLabel() { return label; } /** * ??? * ???ID????? * ??????? * ????????{@link InternalException}???? * @param label */ public void setLabel(String label) { checkFrozen(); this.label = label; } /** * ???URL???? * ????URL?????? * @return URL */ public String getUrl() { return url; } /** * URL??? * ????URL?????? * ????????{@link InternalException}???? * @param url URL */ public void setUrl(String url) { checkFrozen(); this.url = url; } /** * ??????? * @return */ public Map<String, String[]> getParams() { return Collections.unmodifiableMap(params); } /** * ????????? * ??????????????? * ?????????????? * ????URL??? * @return ?? * @see java.net.URLEncoder */ public String getQuery() { return getQuery(true); } /** * ????????? * ??????????????? * ?????????????? * @param needToApplyPercentEscapeToQueryParameters URL????? * @return ???? * @see java.net.URLEncoder */ public String getQuery(boolean needToApplyPercentEscapeToQueryParameters) { if (Maps.isEmpty(params)) return ""; List<String> queries = new LinkedList<String>(); for (String key : params.keySet()) { String[] values = params.get(key); for (String value : values) { if (needToApplyPercentEscapeToQueryParameters) { try { queries.add(Strings.joinBy("=", URLEncoder.encode(key, PERCENT_ESCAPE_ENCODING_FOR_QUERY), URLEncoder.encode(value, PERCENT_ESCAPE_ENCODING_FOR_QUERY))); } catch (UnsupportedEncodingException e) { throw new InternalException(ViewId.class, "E-VID#0005", Maps.hash("encoding", PERCENT_ESCAPE_ENCODING_FOR_QUERY)); } } else { queries.add(Strings.joinBy("=", key, value)); } } } String query = Strings.joinBy(QUERIES_JOIN_WORD, queries); return query.length() > 0 ? "?" + query : ""; } /** * ??? * ????????{@link InternalException}???? * @param params */ public void setParams(HashMap<String, String[]> params) { checkFrozen(); this.params = params; } /** * ???????????????? * @return ??????true */ public boolean isPankuzu() { return pankuzu; } /** * ???????????????? * ????????{@link InternalException}???? * @param pankuzu ??????true */ public void setPankuzu(boolean pankuzu) { checkFrozen(); this.pankuzu = pankuzu; } /** * ??URL?????????? * @param include ??URL??????? */ public void setInclude(String include) { checkFrozen(); this.include = include; } /** * ??URL???????????? * @param exclude ??URL????????? */ public void setExclude(String exclude) { checkFrozen(); this.exclude = exclude; } /** * {@inheritDoc} * ??????????????? * ?????????????????? */ @Override public boolean equals(Object obj) { boolean eq = false; if (obj != null && obj instanceof ViewId) { ViewId another = (ViewId) obj; String anotherId = another.getId(); assert anotherId != null; eq = id.equals(anotherId); } return eq; } /** * {@inheritDoc} * ??????????????? * ?????????????????? */ @Override public int hashCode() { return id.hashCode(); } /** * {@inheritDoc} */ @Override public String toString() { return ToStringBuilder.reflectionToString(this); } }