jp.co.ctc_g.jse.vid.ViewId.java Source code

Java tutorial

Introduction

Here is the source code for jp.co.ctc_g.jse.vid.ViewId.java

Source

/*
 * 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>
 *     &nbsp;
 *    </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";

    /**
     * ?????? &amp; ??
     */
    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????&quot;javax.servlet.forward.request_uri&quot;??????
     * ????{@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);
    }

}