/*
 * 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 wicket.protocol.http.request.urlcompressing;

import wicket.Application;
import wicket.Component;
import wicket.IRedirectListener;
import wicket.IRequestTarget;
import wicket.Page;
import wicket.RequestCycle;
import wicket.RequestListenerInterface;
import wicket.WicketRuntimeException;
import wicket.authorization.UnauthorizedActionException;
import wicket.markup.html.INewBrowserWindowListener;
import wicket.markup.html.WebPage;
import wicket.protocol.http.WebRequestCycleProcessor;
import wicket.protocol.http.request.urlcompressing.UrlCompressor.ComponentAndInterface;
import wicket.request.IRequestCodingStrategy;
import wicket.request.RequestParameters;
import wicket.request.target.component.listener.RedirectPageRequestTarget;
import wicket.util.string.Strings;

/**
 * Use this processor to minimize the wicket:interface urls. The component path
 * and the interface name will be removed from the url and only an uid will be
 * inserted into the url.
 * 
 * To use this url compressing behaviour you must override the
 * {@link Application}'s newRequestCycleProcessor() method and return an
 * instance of this.
 * 
 * @author jcompagner
 * 
 * @since 1.3
 */
public class UrlCompressingWebRequestProcessor extends WebRequestCycleProcessor
{
	/**
	 * Construct.
	 */
	public UrlCompressingWebRequestProcessor()
	{
	}

	/**
	 * @see wicket.protocol.http.WebRequestCycleProcessor#newRequestCodingStrategy()
	 */
	protected IRequestCodingStrategy newRequestCodingStrategy()
	{
		return new UrlCompressingWebCodingStrategy();
	}

	/**
	 * @see wicket.request.AbstractRequestCycleProcessor#resolveListenerInterfaceTarget(wicket.RequestCycle,
	 *      wicket.Page, java.lang.String, java.lang.String,
	 *      wicket.request.RequestParameters)
	 */
	protected IRequestTarget resolveListenerInterfaceTarget(final RequestCycle requestCycle,
			final Page page, final String componentPath, String interfaceName,
			final RequestParameters requestParameters)
	{
		String pageRelativeComponentPath = Strings.afterFirstPathComponent(componentPath,
				Component.PATH_SEPARATOR);
		Component component = null;
		if (page instanceof WebPage && !"IResourceListener".equals(interfaceName))
		{
			ComponentAndInterface cai = ((WebPage)page).getUrlCompressor()
					.getComponentAndInterfaceForUID(pageRelativeComponentPath);
			if (cai != null)
			{
				interfaceName = cai.getInterfaceName();
				component = cai.getComponent();
			}
		}

		if (interfaceName.equals(IRedirectListener.INTERFACE.getName()))
		{
			return new RedirectPageRequestTarget(page);
		}
		else if (interfaceName.equals(INewBrowserWindowListener.INTERFACE.getName()))
		{
			return INewBrowserWindowListener.INTERFACE.newRequestTarget(page, page,
					INewBrowserWindowListener.INTERFACE, requestParameters);
		}
		else
		{
			// Get the listener interface we need to call
			final RequestListenerInterface listener = RequestListenerInterface
					.forName(interfaceName);
			if (listener == null)
			{
				throw new WicketRuntimeException(
						"Attempt to access unknown request listener interface " + interfaceName);
			}

			// Get component
			if (component == null)
			{
				if (Strings.isEmpty(pageRelativeComponentPath))
				{
					component = page;
				}
				else
				{
					component = page.get(pageRelativeComponentPath);
				}
			}

			if (!component.isEnableAllowed())
			{
				throw new UnauthorizedActionException(component, Component.ENABLE);
			}

			// Ask the request listener interface object to create a request
			// target
			return listener.newRequestTarget(page, component, listener, requestParameters);
		}
	}
}

@@ -4118,16 +4118,256 @@
 %7D%0A%09%09%09%7D%0A%0A
+%09%09%09if (component == null)%0A%09%09%09%7B%0A%09%09%09%09// still null? that's not right%0A%09%09%09%09throw new WicketRuntimeException(%22cannot resolve component with path '%22%0A%09%09%09%09%09%09+ pageRelativeComponentPath + %22', listener %22 + listener + %22 on page %22%0A%09%09%09%09%09%09+ page);%0A%09%09%09%7D%0A%0A
 %09%09%09if (!

throw exception with more info which would otherwise be a NPE