| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you 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.apache.wiki.ui; |
| |
| import org.apache.wiki.api.core.Command; |
| import org.apache.wiki.util.TextUtil; |
| |
| |
| /** |
| * Abstract, immutable Command implementation class. All of the fields in this class are <code>final</code>. This class is thread-safe. |
| * |
| * @since 2.4.22 |
| */ |
| public abstract class AbstractCommand implements Command { |
| |
| private static final String HTTPS = "HTTPS://"; |
| private static final String HTTP = "HTTP://"; |
| |
| private final String m_jsp; |
| private final String m_jspFriendlyName; |
| private final String m_urlPattern; |
| private final String m_requestContext; |
| private final String m_contentTemplate; |
| private final Object m_target; |
| |
| /** |
| * Constructs a new Command with a specified wiki context, URL pattern, content template and target. The URL pattern is used to derive |
| * the JSP; if it is a "local" JSP (that is, it does not contain the <code>http://</code> or <code>https://</code> prefixes), |
| * then the JSP will be a cleansed version of the URL pattern; symbols (such as <code>%u</code>) will removed. If it the supplied |
| * URL pattern points to a non-local destination, the JSP will be set to the value supplied, unmodified. |
| * |
| * @param requestContext the request context |
| * @param urlPattern the URL pattern |
| * @param contentTemplate the content template; may be <code>null</code> |
| * @param target the target of the command, such as a WikiPage; may be <code>null</code> |
| * @throws IllegalArgumentException if the request content or URL pattern is <code>null</code> |
| */ |
| protected AbstractCommand( final String requestContext, final String urlPattern, final String contentTemplate, final Object target ) { |
| if( requestContext == null || urlPattern == null ) { |
| throw new IllegalArgumentException( "Request context, URL pattern and type must not be null." ); |
| } |
| |
| m_requestContext = requestContext; |
| if ( urlPattern.toUpperCase().startsWith( HTTP ) || urlPattern.toUpperCase().startsWith( HTTPS ) ) { |
| // For an HTTP/HTTPS url, pass it through without modification |
| m_jsp = urlPattern; |
| m_jspFriendlyName = "Special Page"; |
| } else { |
| // For local JSPs, take everything to the left of ?, then delete all variable substitutions |
| String jsp = urlPattern; |
| final int qPosition = urlPattern.indexOf( '?' ); |
| if ( qPosition != -1 ) { |
| jsp = jsp.substring( 0, qPosition ); |
| } |
| m_jsp = removeSubstitutions(jsp); |
| |
| // Calculate the "friendly name" for the JSP |
| if ( m_jsp.toUpperCase().endsWith( ".JSP" ) ) { |
| m_jspFriendlyName = TextUtil.beautifyString( m_jsp.substring( 0, m_jsp.length() - 4 ) ); |
| } else { |
| m_jspFriendlyName = m_jsp; |
| } |
| } |
| m_urlPattern = urlPattern; |
| m_contentTemplate = contentTemplate; |
| m_target = target; |
| } |
| |
| // |
| // This is just *so* much faster than doing String.replaceAll(). It would, in fact, be worth to cache this value. |
| // |
| private String removeSubstitutions( final String jsp ) { |
| //return jsp.replaceAll( "\u0025[a-z|A-Z]", "" ); |
| final StringBuilder newjsp = new StringBuilder( jsp.length() ); |
| for( int i = 0; i < jsp.length(); i++ ) { |
| final char c = jsp.charAt(i); |
| if( c == '%' && i < jsp.length() - 1 && Character.isLetterOrDigit( jsp.charAt( i + 1 ) ) ) { |
| i++; |
| continue; |
| } |
| newjsp.append( c ); |
| } |
| return newjsp.toString(); |
| } |
| |
| /** |
| * @see org.apache.wiki.api.core.Command#targetedCommand(Object) |
| */ |
| public abstract Command targetedCommand( final Object target ); |
| |
| /** |
| * @see org.apache.wiki.api.core.Command#getContentTemplate() |
| */ |
| public final String getContentTemplate() { |
| return m_contentTemplate; |
| } |
| |
| /** |
| * @see org.apache.wiki.api.core.Command#getJSP() |
| */ |
| public final String getJSP() { |
| return m_jsp; |
| } |
| |
| /** |
| * @see org.apache.wiki.api.core.Command#getName() |
| */ |
| public abstract String getName(); |
| |
| /** |
| * @see org.apache.wiki.api.core.Command#getRequestContext() |
| */ |
| public final String getRequestContext() { |
| return m_requestContext; |
| } |
| |
| /** |
| * @see org.apache.wiki.api.core.Command#getTarget() |
| */ |
| public final Object getTarget() { |
| return m_target; |
| } |
| |
| /** |
| * @see org.apache.wiki.api.core.Command#getURLPattern() |
| */ |
| public final String getURLPattern() { |
| return m_urlPattern; |
| } |
| |
| /** |
| * Returns the "friendly name" for this command's JSP, namely a beatified version of the JSP's name without the .jsp suffix. |
| * |
| * @return the friendly name |
| */ |
| protected final String getJSPFriendlyName() { |
| return m_jspFriendlyName; |
| } |
| |
| /** |
| * Returns a String representation of the Command. |
| * |
| * @see java.lang.Object#toString() |
| */ |
| public final String toString() { |
| return "Command" + |
| "[context=" + m_requestContext + "," + |
| "urlPattern=" + m_urlPattern + "," + |
| "jsp=" + m_jsp + |
| ( m_target == null ? "" : ",target=" + m_target + m_target.toString() ) + |
| "]"; |
| } |
| |
| } |