001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019package org.apache.wiki.url; 020 021import org.apache.commons.lang3.StringUtils; 022import org.apache.wiki.api.core.Command; 023import org.apache.wiki.api.core.ContextEnum; 024import org.apache.wiki.api.core.Engine; 025import org.apache.wiki.ui.CommandResolver; 026import org.apache.wiki.util.TextUtil; 027 028import javax.servlet.http.HttpServletRequest; 029import java.nio.charset.Charset; 030import java.util.Properties; 031 032 033/** 034 * Implements the default URL constructor using links directly to the JSP pages. This is what JSPWiki by default is using. For example, 035 * WikiContext.VIEW points at "Wiki.jsp", etc. 036 * 037 * @since 2.2 038 */ 039public class DefaultURLConstructor implements URLConstructor { 040 041 protected Engine m_engine; 042 043 /** Contains the absolute path of the JSPWiki Web application without the actual servlet (which is the m_urlPrefix). */ 044 protected String m_pathPrefix = ""; 045 046 /** 047 * 048 * {@inheritDoc} 049 */ 050 @Override 051 public void initialize( final Engine engine, final Properties properties ) { 052 m_engine = engine; 053 m_pathPrefix = engine.getBaseURL() + "/"; 054 } 055 056 /** 057 * Does replacement of some particular variables. The variables are: 058 * 059 * <ul> 060 * <li> "%u" - inserts either the base URL (when absolute is required), or the base path (which is an absolute path without the host name). 061 * <li> "%U" - always inserts the base URL 062 * <li> "%p" - always inserts the base path 063 * <li> "%n" - inserts the page name 064 * </ul> 065 * 066 * @param baseptrn The pattern to use 067 * @param name The page name 068 * @return A replacement. 069 */ 070 protected final String doReplacement( String baseptrn, final String name ) { 071 final String baseurl = m_pathPrefix; 072 073 baseptrn = TextUtil.replaceString( baseptrn, "%u", baseurl ); 074 baseptrn = TextUtil.replaceString( baseptrn, "%U", m_engine.getBaseURL() ); 075 baseptrn = TextUtil.replaceString( baseptrn, "%n", encodeURI(name) ); 076 baseptrn = TextUtil.replaceString( baseptrn, "%p", m_pathPrefix ); 077 078 return baseptrn; 079 } 080 081 /** 082 * URLEncoder returns pluses, when we want to have the percent encoding. See http://issues.apache.org/bugzilla/show_bug.cgi?id=39278 083 * for more info. 084 * 085 * We also convert any %2F's back to slashes to make nicer-looking URLs. 086 */ 087 private String encodeURI( String uri ) { 088 uri = m_engine.encodeName(uri); 089 uri = StringUtils.replace( uri, "+", "%20" ); 090 uri = StringUtils.replace( uri, "%2F", "/" ); 091 092 return uri; 093 } 094 095 /** 096 * Returns the URL pattern for a supplied wiki request context. 097 * @param context the wiki context 098 * @param name the wiki page 099 * @return A pattern for replacement. 100 * @throws IllegalArgumentException if the context cannot be found 101 */ 102 public static String getURLPattern( final String context, final String name ) throws IllegalArgumentException { 103 if( context.equals( ContextEnum.PAGE_VIEW.getRequestContext() ) && name == null) { 104 // FIXME 105 return "%uWiki.jsp"; 106 } 107 108 // Find the action matching our pattern (could throw exception) 109 final Command command = CommandResolver.findCommand( context ); 110 111 return command.getURLPattern(); 112 } 113 114 /** 115 * Constructs the actual URL based on the context. 116 */ 117 private String makeURL( final String context, final String name ) { 118 return doReplacement( getURLPattern( context, name ), name ); 119 } 120 121 /** 122 * Constructs the URL with a bunch of parameters. 123 * @param parameters If null or empty, no parameters are added. 124 * 125 * {@inheritDoc} 126 */ 127 @Override 128 public String makeURL( final String context, final String name, String parameters ) { 129 if( parameters != null && !parameters.isEmpty() ) { 130 if( context.equals( ContextEnum.PAGE_ATTACH.getRequestContext() ) ) { 131 parameters = "?" + parameters; 132 } else if( context.equals( ContextEnum.PAGE_NONE.getRequestContext() ) ) { 133 parameters = name.indexOf( '?' ) != -1 ? "&" : "?" + parameters; 134 } else { 135 parameters = "&" + parameters; 136 } 137 } else { 138 parameters = ""; 139 } 140 return makeURL( context, name ) + parameters; 141 } 142 143 /** 144 * Should parse the "page" parameter from the actual request. 145 * 146 * {@inheritDoc} 147 */ 148 @Override 149 public String parsePage( final String context, final HttpServletRequest request, final Charset encoding ) { 150 String pagereq = request.getParameter( "page" ); 151 if( context.equals( ContextEnum.PAGE_ATTACH.getRequestContext() ) ) { 152 pagereq = URLConstructor.parsePageFromURL( request, encoding ); 153 } 154 155 return pagereq; 156 } 157 158 /** 159 * This method is not needed for the DefaultURLConstructor. 160 * 161 * @param request The HTTP Request that was used to end up in this page. 162 * @return "Wiki.jsp", "PageInfo.jsp", etc. Just return the name, JSPWiki will figure out the page. 163 */ 164 @Override 165 public String getForwardPage( final HttpServletRequest request ) { 166 return "Wiki.jsp"; 167 } 168 169}