/* * Copyright 2008-2010 the T2 Project ant the Others. * * 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 org.t2framework.confeito.internal; import javax.servlet.http.HttpServletRequest; import org.t2framework.confeito.contexts.Request; import org.t2framework.confeito.util.Assertion; import org.t2framework.confeito.util.StringUtil; /** * <#if locale="en"> * <p> * PathUtil is an utility class for creating path. This class is basically * expected to use within T2 framework. * </p> * <#else> * <p> * PathUtilはT2で使うパスを作るためのユーティリティクラスです.このクラスは主にT2フレームワークで内部的に使われることを意図しています. * </p> * </#if> * * @author shot * @author c9katayama */ public class PathUtil { /** * <#if locale="en"> * <p> * Get page path from {@link Request}. Page path is a path removed context * path from original path. * * </p> * <#else> * <p> * {@link Request}からページパスを取得します.ページパスはオリジナルなパスから、コンテキストパスを除いたパスです. * </p> * </#if> * * @param request * <#if locale="en"> * <p> * {@link Request} instance * </p> * <#else> * <p> * {@link Request}インスタンス * </p> * </#if> * @return <#if locale="en"> * <p> * the page path * </p> * <#else> * <p> * ページパス * </p> * </#if> */ public static String getPagePath(Request request) { final HttpServletRequest req = request.getNativeResource(); return getPagePath(req); } /** * <#if locale="en"> * <p> * Get page path from {@link HttpServletRequest}. * * </p> * <#else> * <p> * {@link HttpServletRequest}からページパスを取得します. * ページパスはオリジナルなパスから、コンテキストパスを除いたパスです. * </p> * </#if> * * @param request * <#if locale="en"> * <p> * {@link HttpServletRequest} instance * </p> * <#else> * <p> * {@link HttpServletRequest}インスタンス * </p> * </#if> * @return <#if locale="en"> * <p> * the page path * </p> * <#else> * <p> * ページパス * </p> * </#if> */ public static String getPagePath(HttpServletRequest request) { final String contextPath = request.getContextPath(); final String requestURI = request.getRequestURI(); return getPagePath(contextPath, requestURI); } /** * <#if locale="en"> * <p> * Get page path from context path and decoded request URI.The path should * be found by these pattern below: * * <pre> * URI contextpath getPagePath * / / / * /index / /index * /index/ / /index * /index/hoge / /index/hoge * /index /index / * /index/hoge /index /hoge * /index/hoge/ /index /hoge * </pre> * * </p> * <#else> * <p> * コンテキストパスとデコードされたリクエストURIからページパスを取得します.リクエストされたURIとコンテキストパス、 * ページパスの関係は下記のパターンのようになります. * * <pre> * URI contextpath getPagePath * / / / * /index / /index * /index/ / /index * /index/hoge / /index/hoge * /index /index / * /index/hoge /index /hoge * /index/hoge/ /index /hoge * </pre> * * </p> * </#if> * * @param contextPath * <#if locale="en"> * <p> * the context path * </p> * <#else> * <p> * コンテキストパス * </p> * </#if> * @param decodedUri * <#if locale="en"> * <p> * decoded request URI string * </p> * <#else> * <p> * デコードされたリクエストURI文字列 * </p> * </#if> * @return <#if locale="en"> * <p> * the page path * </p> * <#else> * <p> * ページパス * </p> * </#if> */ public static String getPagePath(String contextPath, String decodedUri) { String requestUri = removalJSessionId(decodedUri); int index = requestUri.indexOf(contextPath); String path = null; if (index >= 0) { path = requestUri.substring(index + contextPath.length(), requestUri.length()); } else { path = requestUri; } if (path.startsWith("/") == false) { path = "/" + path; } if (path.equals("/") == false && path.endsWith("/")) { path = removeEndSlashIfNeed(path); } return path; } /** * <#if locale="en"> * <p> * Get action method path from page path. * * </p> * <#else> * <p> * * </p> * </#if> * * @param request * @param pageTemplatePath * @return action path */ public static String getActionPath(final Request request, String pageTemplatePath) { pageTemplatePath = PathUtil.appendStartSlashIfNeed(Assertion .notNull(pageTemplatePath)); String actualPath = getPagePath(request); pageTemplatePath = appendStartSlashIfNeed(pageTemplatePath); int pos1 = pageTemplatePath.indexOf('{'); int pos2 = pageTemplatePath.indexOf('}'); if (pos1 < 0 || pos2 < 0 || pos2 < pos1) { if (actualPath.startsWith(pageTemplatePath)) { actualPath = actualPath.substring(pageTemplatePath.length()); actualPath = appendStartSlashIfNeed(actualPath); return actualPath; } else { return actualPath; } } else { String[] templates = StringUtil.split(pageTemplatePath, "/"); String[] actuals = StringUtil.split(actualPath, "/"); boolean ret = true; if (templates.length <= actuals.length) { for (int i = 0; i < templates.length; i++) { String t = templates[i]; int index1 = t.indexOf('{'); if (index1 < 0) { if (t.equals(actuals[i])) { continue; } else { ret = false; break; } } int index2 = t.indexOf('}'); if (index2 < 0 || index2 < index1) { ret = false; break; } } if (ret) { StringBuilder builder = new StringBuilder("/"); for (int i = templates.length; i < actuals.length; i++) { builder.append(actuals[i]); builder.append("/"); } int len = builder.length(); if (1 < len) { builder.setLength(len - 1); } return new String(builder); } else { return actualPath; } } else { return actualPath; } } } /** * <#if locale="en"> * <p> * Append slash to the first if the path is not started with slash. * * </p> * <#else> * <p> * * </p> * </#if> * * @param path * @return slash-added path */ public static String appendStartSlashIfNeed(final String path) { if (path != null && !startsWithSlash(path)) { return "/" + path; } return path; } /** * <#if locale="en"> * <p> * Append slash to the end if the path is not ended with slash. * * </p> * <#else> * <p> * * </p> * </#if> * * @param path * @return end slash-added path */ public static String appendEndSlashIfNeed(final String path) { if (path != null && !endsWithSlash(path)) { return path + "/"; } return path; } /** * <#if locale="en"> * <p> * Remove slash from the begin. * * </p> * <#else> * <p> * * </p> * </#if> * * @param path * @return start-slash removed path */ public static String removeStartSlashIfNeed(final String path) { if (path != null && startsWithSlash(path)) { return path.substring(1, path.length()); } return path; } /** * <#if locale="en"> * <p> * Remove slash from the end. * * </p> * <#else> * <p> * * </p> * </#if> * * @param path * @return end-slash removed path */ public static String removeEndSlashIfNeed(final String path) { if (path != null && path.endsWith("/")) { return path.substring(0, path.length() - 1); } return path; } /** * <#if locale="en"> * <p> * Check if the path starts with slash. * </p> * <#else> * <p> * パスが/で始まっている場合、trueを返します. * </p> * </#if> * * @param path * <#if locale="en"> * <p> * the path * </p> * <#else> * <p> * パス * </p> * </#if> * @return <#if locale="en"> * <p> * true if path starts with {@literal /}, otherwise false * </p> * <#else> * <p> * パスが/で終わっている場合、true.それ以外の場合false. * </p> * </#if> */ public static boolean startsWithSlash(final String path) { if (StringUtil.isEmpty(path)) { return false; } return path.indexOf("/") == 0; } /** * <#if locale="en"> * <p> * Check if the path ends with slash. * </p> * <#else> * <p> * パスの末端が/で終わっている場合、trueを返します. * </p> * </#if> * * @param path * <#if locale="en"> * <p> * the path * </p> * <#else> * <p> * パス * </p> * </#if> * @return <#if locale="en"> * <p> * true if path ends with {@literal /}, otherwise false * </p> * <#else> * <p> * パスの末端が/で終わっている場合、true.それ以外の場合false. * </p> * </#if> */ public static boolean endsWithSlash(final String path) { if (StringUtil.isEmpty(path)) { return false; } return path.lastIndexOf("/") == path.length() - 1; } /** * <#if locale="en"> * <p> * Remove jsessionid from the path. * </p> * <#else> * <p> * jsessionidをパスから削除します. * </p> * </#if> * * @param path * <#if locale="en"> * <p> * the path * </p> * <#else> * <p> * パス * </p> * </#if> * @return <#if locale="en"> * <p> * jsessionid removed path * </p> * <#else> * <p> * jsessionidを削除したパス * </p> * </#if> */ public static String removalJSessionId(final String path) { int idx = path.indexOf(';'); if (0 <= idx) { return path.substring(0, idx); } return path; } }