You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by kn...@apache.org on 2009/03/28 18:53:08 UTC
svn commit: r759525 [2/7] - in
/wicket/sandbox/knopp/experimental/wicket-ng/src: main/java/org/
main/java/org/apache/ main/java/org/apache/wicket/
main/java/org/apache/wicket/behavior/ main/java/org/apache/wicket/markup/
main/java/org/apache/wicket/mar...
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/behavior/IBehavior.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/behavior/IBehavior.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/behavior/IBehavior.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/behavior/IBehavior.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,6 @@
+package org.apache.wicket.behavior;
+
+public interface IBehavior
+{
+
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/behavior/IBehavior.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/markup/html/link/ILinkListener.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/markup/html/link/ILinkListener.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/markup/html/link/ILinkListener.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/markup/html/link/ILinkListener.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,37 @@
+/*
+ * 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.wicket.markup.html.link;
+
+import org.apache.wicket.IRequestListener;
+import org.apache.wicket.RequestListenerInterface;
+
+/**
+ * Listener method for link clicks.
+ *
+ * @author Jonathan Locke
+ */
+public interface ILinkListener extends IRequestListener
+{
+ /** Listener interface */
+ public static final RequestListenerInterface INTERFACE = new RequestListenerInterface(
+ ILinkListener.class);
+
+ /**
+ * Called when a link is clicked.
+ */
+ void onLinkClicked();
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/markup/html/link/ILinkListener.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/model/IDetachable.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/model/IDetachable.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/model/IDetachable.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/model/IDetachable.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,35 @@
+/*
+ * 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.wicket.model;
+
+import java.io.Serializable;
+
+/**
+ * Interface to logic for detaching transient information from a detachable model. Detachable models
+ * are desirable because they reduce the amount of state required by a model, which makes the model
+ * cheaper to replicate in a clustered environment.
+ *
+ * @author Jonathan Locke
+ */
+public interface IDetachable extends Serializable
+{
+ /**
+ * Detaches model after use. This is generally used to null out transient references that can be
+ * re-attached later.
+ */
+ void detach();
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/model/IDetachable.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/model/IModel.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/model/IModel.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/model/IModel.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/model/IModel.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,75 @@
+/*
+ * 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.wicket.model;
+
+
+/**
+ * A IModel wraps the actual model Object used by a Component. IModel implementations are used as a
+ * facade for the real model so that users have control over the actual persistence strategy. Note
+ * that objects implementing this interface will be stored in the Session. Hence, you should use
+ * (non-transient) instance variables sparingly.
+ * <ul>
+ * <li><b>Basic Models </b>- To implement a basic (non-detachable) model which holds its entire
+ * state in the Session, you can use the simple model wrapper {@link Model}.
+ *
+ * <li><b>Detachable Models </b>- IModel inherits a hook, {@link IDetachable#detach()}, so that
+ * interface implementers can detach transient information when a model is no longer being actively
+ * used by the framework. This reduces memory use and reduces the expense of replicating the model
+ * in a clustered server environment. To implement a detachable model, you should generally extend
+ * {@link LoadableDetachableModel} instead of implementing IModel directly.
+ *
+ * <li><b>Property Models </b>- The AbstractPropertyModel class provides default functionality for
+ * property models. A property model provides access to a particular property of its wrapped model.
+ *
+ * <li><b>Compound Property Models </b>- The IModel interface is parameterized by Component,
+ * allowing a model to be shared among several Components. When the {@link IModel#getObject()}method
+ * is called, the value returned will depend on the Component which is asking for the value.
+ * Likewise, the {@link IModel#setObject(Object)}method sets a different property depending on
+ * which Component is doing the setting. For more information on CompoundPropertyModels and model
+ * inheritance, see {@link org.apache.wicket.model.CompoundPropertyModel}and
+ * {@link org.apache.wicket.Page}.
+ * </ul>
+ *
+ * @see org.apache.wicket.Component#sameInnermostModel(org.apache.wicket.Component)
+ * @see org.apache.wicket.Component#sameInnermostModel(IModel)
+ *
+ * @author Chris Turner
+ * @author Eelco Hillenius
+ * @author Jonathan Locke
+ *
+ * TODO 3.0: Vote on renaming get/setObject to get/setValue
+ *
+ * @param <T>
+ * Model object.
+ */
+public interface IModel<T> extends IDetachable
+{
+ /**
+ * Gets the model object.
+ *
+ * @return The model object
+ */
+ T getObject();
+
+ /**
+ * Sets the model object.
+ *
+ * @param object
+ * The model object
+ */
+ void setObject(final T object);
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/model/IModel.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/PageManager.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/PageManager.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/PageManager.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/PageManager.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,49 @@
+/*
+ * 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.wicket.page;
+
+import org.apache.wicket.Page;
+
+/**
+ * Session relative page manager.
+ *
+ * @author Matej Knopp
+ */
+public interface PageManager
+{
+ /**
+ * Retrieves page instance with given id.
+ *
+ * @param id
+ * @return page instance or <code>null</code>
+ */
+ public Page getPage(int id);
+
+ /**
+ * Marks page as changed
+ *
+ * @param page
+ */
+ public void touchPage(Page page);
+
+ /**
+ * Increases the page version
+ *
+ * @param page
+ */
+ public void bumpVersion(Page page);
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/PageManager.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/page-management.txt
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/page-management.txt?rev=759525&view=auto
==============================================================================
(empty)
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/page-management.txt
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/ContextParamWebApplicationFactory.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/ContextParamWebApplicationFactory.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/ContextParamWebApplicationFactory.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/ContextParamWebApplicationFactory.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,101 @@
+/*
+ * 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.wicket.protocol.http;
+
+import org.apache.wicket.WicketRuntimeException;
+
+/**
+ * Factory that creates application objects based on the class name specified in the
+ * {@link ContextParamWebApplicationFactory#APP_CLASS_PARAM} context variable.
+ *
+ * @author Igor Vaynberg (ivaynberg)
+ */
+public class ContextParamWebApplicationFactory implements IWebApplicationFactory
+{
+ /**
+ * context parameter name that must contain the class name of the application
+ */
+ public static final String APP_CLASS_PARAM = "applicationClassName";
+
+ /* @see IWebApplicationFactory#createApplication(WicketFilter) */
+ public WebApplication createApplication(WicketFilter filter)
+ {
+ final String applicationClassName = filter.getFilterConfig().getInitParameter(
+ APP_CLASS_PARAM);
+
+ if (applicationClassName == null)
+ {
+ throw new WicketRuntimeException(
+ "servlet init param [" +
+ APP_CLASS_PARAM +
+ "] is missing. If you are trying to use your own implementation of IWebApplicationFactory and get this message then the servlet init param [" +
+ WicketFilter.APP_FACT_PARAM + "] is missing");
+ }
+
+ return createApplication(applicationClassName);
+ }
+
+ /**
+ * Instantiates the application instance.
+ *
+ * @param applicationClassName
+ * the classname of the application to create
+ * @return the web application
+ */
+ protected WebApplication createApplication(final String applicationClassName)
+ {
+ try
+ {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if (loader == null)
+ {
+ loader = getClass().getClassLoader();
+ }
+ final Class<?> applicationClass = loader.loadClass(applicationClassName);
+ if (WebApplication.class.isAssignableFrom(applicationClass))
+ {
+ // Construct WebApplication subclass
+ return (WebApplication)applicationClass.newInstance();
+ }
+ else
+ {
+ throw new WicketRuntimeException("Application class " + applicationClassName +
+ " must be a subclass of WebApplication");
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new WicketRuntimeException("Unable to create application of class " +
+ applicationClassName, e);
+ }
+ catch (InstantiationException e)
+ {
+ throw new WicketRuntimeException("Unable to create application of class " +
+ applicationClassName, e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new WicketRuntimeException("Unable to create application of class " +
+ applicationClassName, e);
+ }
+ catch (SecurityException e)
+ {
+ throw new WicketRuntimeException("Unable to create application of class " +
+ applicationClassName, e);
+ }
+ }
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/ContextParamWebApplicationFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/IWebApplicationFactory.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/IWebApplicationFactory.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/IWebApplicationFactory.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/IWebApplicationFactory.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,43 @@
+/*
+ * 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.wicket.protocol.http;
+
+/**
+ * A factory interface used by wicket filter to create application objects. Configure your
+ * webapplication to use this factory in web.xml like:
+ *
+ * <pre>
+ * <init-param>
+ * <param-name>applicationFactoryClassName</param-name>
+ * <param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value>
+ * </init-param>
+ *
+ * </pre>
+ *
+ * @author Igor Vaynberg (ivaynberg)
+ */
+public interface IWebApplicationFactory
+{
+ /**
+ * Create application object
+ *
+ * @param filter
+ * the wicket filter
+ * @return application object instance
+ */
+ WebApplication createApplication(WicketFilter filter);
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/IWebApplicationFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/PageExpiredException.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/PageExpiredException.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/PageExpiredException.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/PageExpiredException.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,37 @@
+/*
+ * 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.wicket.protocol.http;
+
+import org.apache.wicket.WicketRuntimeException;
+
+/**
+ * Thrown when the {@link org.apache.wicket.protocol.http.WebRequestCycleProcessor} could not
+ * process the request or {@link org.apache.wicket.request.AbstractRequestCycleProcessor} could not
+ * resolve the rendered page.
+ */
+public class PageExpiredException extends WicketRuntimeException
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @see WicketRuntimeException#WicketRuntimeException(java.lang.String)
+ */
+ public PageExpiredException(final String message)
+ {
+ super(message);
+ }
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/PageExpiredException.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,200 @@
+/*
+ * 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.wicket.protocol.http;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.DefaultPageFactory;
+import org.apache.wicket.IPage;
+import org.apache.wicket.IPageFactory;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.RequestCycleContext;
+import org.apache.wicket.RequestListenerInterface;
+import org.apache.wicket.request.RequestHandler;
+import org.apache.wicket.request.RequestHandlerEncoder;
+import org.apache.wicket.request.RequestHandlerEncoderRegistry;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.encoder.BookmarkableEncoder;
+import org.apache.wicket.request.encoder.EncoderContext;
+import org.apache.wicket.request.encoder.PageInstanceEncoder;
+import org.apache.wicket.request.encoder.ResourceReferenceEncoder;
+import org.apache.wicket.request.request.Request;
+import org.apache.wicket.request.response.Response;
+import org.apache.wicket.resource.ResourceReferenceRegistry;
+
+public abstract class WebApplication extends Application
+{
+
+ public WebApplication()
+ {
+ super();
+ }
+
+ @Override
+ public void internalInit()
+ {
+ mount(new BookmarkableEncoder());
+ mount(new PageInstanceEncoder());
+ mount(new ResourceReferenceEncoder());
+ }
+
+ protected RequestCycleContext newRequestCycleContext()
+ {
+ RequestCycleContext context = new RequestCycleContext()
+ {
+ public RequestHandler decodeRequestHandler(Request request)
+ {
+ return getRequestHandlerEncoderRegistry().decode(request);
+ }
+
+ public Url encodeRequestHandler(RequestHandler handler)
+ {
+ return getRequestHandlerEncoderRegistry().encode(handler);
+ }
+
+ public RequestHandler getRequestHandlerForException(Exception e)
+ {
+ return WebApplication.this.getRequestHandlerForException(e);
+ }
+ };
+ return context;
+ };
+
+ protected RequestHandler getRequestHandlerForException(Exception e)
+ {
+ return null;
+ };
+
+ public RequestCycle newRequestCycle(Request request, Response response)
+ {
+ RequestCycleContext context = newRequestCycleContext();
+ return new RequestCycle(request, response, context);
+ };
+
+ private RequestHandlerEncoderRegistry requestHandlerEncoderRegistry;
+
+ public RequestHandlerEncoderRegistry getRequestHandlerEncoderRegistry()
+ {
+ if (requestHandlerEncoderRegistry == null)
+ {
+ requestHandlerEncoderRegistry = newRequestHandlerEncoderRegistry();
+ }
+ return requestHandlerEncoderRegistry;
+ };
+
+ protected RequestHandlerEncoderRegistry newRequestHandlerEncoderRegistry()
+ {
+ return new RequestHandlerEncoderRegistry();
+ };
+
+ public static WebApplication get()
+ {
+ return (WebApplication) Application.get();
+ }
+
+ private EncoderContext encoderContext = new EncoderContext()
+ {
+
+ public String getBookmarkableIdentifier()
+ {
+ return "bookmarkable";
+ }
+
+ public String getNamespace()
+ {
+ return "wicket";
+ }
+
+ public String getPageIdentifier()
+ {
+ return "page";
+ }
+
+ public String getResourceIdentifier()
+ {
+ return "resource";
+ }
+
+ public ResourceReferenceRegistry getResourceReferenceRegistry()
+ {
+ return WebApplication.this.getResourceReferenceRegistry();
+ }
+
+ public RequestListenerInterface requestListenerInterfaceFromString(String interfaceName)
+ {
+ return RequestListenerInterface.forName(interfaceName);
+ }
+
+ public String requestListenerInterfaceToString(RequestListenerInterface listenerInterface)
+ {
+ return listenerInterface.getName();
+ }
+
+ public IPage newPageInstance(Class<? extends IPage> pageClass, PageParameters pageParameters)
+ {
+ if (pageParameters == null)
+ {
+ return getPageFactory().newPage(pageClass);
+ }
+ else
+ {
+ return getPageFactory().newPage(pageClass, pageParameters);
+ }
+ }
+
+ public IPage getPageInstance(int pageId)
+ {
+ return Page.get(pageId);
+ }
+
+ public Class<? extends IPage> getHomePageClass()
+ {
+ return WebApplication.this.getHomePageClass();
+ }
+ };
+
+ public EncoderContext getEncoderContext()
+ {
+ return encoderContext;
+ }
+
+ private ResourceReferenceRegistry resourceReferenceRegistry;
+
+ public ResourceReferenceRegistry getResourceReferenceRegistry()
+ {
+ if (resourceReferenceRegistry == null)
+ {
+ resourceReferenceRegistry = new ResourceReferenceRegistry();
+ }
+ return resourceReferenceRegistry;
+ }
+
+ private IPageFactory pageFactory = new DefaultPageFactory();
+
+ public IPageFactory getPageFactory()
+ {
+ return pageFactory;
+ }
+
+ public void mount(RequestHandlerEncoder encoder)
+ {
+ getRequestHandlerEncoderRegistry().register(encoder);
+ }
+
+ public abstract Class<? extends IPage> getHomePageClass();
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplicationFactoryCreationException.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplicationFactoryCreationException.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplicationFactoryCreationException.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplicationFactoryCreationException.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,43 @@
+/*
+ * 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.wicket.protocol.http;
+
+import org.apache.wicket.WicketRuntimeException;
+
+/**
+ * Thrown when the {@link org.apache.wicket.protocol.http.IWebApplicationFactory} could not be
+ * created for some reason.
+ *
+ * @author Seth Ladd
+ */
+public class WebApplicationFactoryCreationException extends WicketRuntimeException
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor.
+ *
+ * @param appFactoryClassName
+ * name of the application factory
+ * @param e
+ * the cause for the creation problem
+ */
+ public WebApplicationFactoryCreationException(String appFactoryClassName, Exception e)
+ {
+ super("Unable to create application factory of class " + appFactoryClassName, e);
+ }
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplicationFactoryCreationException.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,499 @@
+/*
+ * 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.wicket.protocol.http;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.ThreadContext;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.request.request.ServletWebRequest;
+import org.apache.wicket.request.response.ServletWebResponse;
+import org.apache.wicket.util.string.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Filter for initiating handling of Wicket requests.
+ *
+ * <p>
+ * The advantage of a filter is that, unlike a servlet, it can choose not to process the request and
+ * let whatever is next in chain try. So when using a Wicket filter and a request comes in for
+ * foo.gif the filter can choose not to process it because it knows it is not a wicket-related
+ * request. Since the filter didn't process it, it falls on to the application server to try, and
+ * then it works."
+ *
+ * @see WicketServlet for documentation
+ *
+ * @author Jonathan Locke
+ * @author Timur Mehrvarz
+ * @author Juergen Donnerstag
+ * @author Igor Vaynberg (ivaynberg)
+ * @author Al Maw
+ * @author jcompagner
+ */
+public class WicketFilter implements Filter
+{
+ /**
+ * The name of the root path parameter that specifies the root dir of the app.
+ */
+ public static final String FILTER_MAPPING_PARAM = "filterMappingUrlPattern";
+
+ /**
+ * The name of the context parameter that specifies application factory class
+ */
+ public static final String APP_FACT_PARAM = "applicationFactoryClassName";
+
+
+ /**
+ * Checks if the request is for home page and lacks trailing slash. If necessary redirects to
+ * URL with trailing slash.
+ *
+ * @param request
+ * @param response
+ * @param filterPath
+ * @return <code>true</code> if there is a trailing slash, <code>false</code> if redirect was
+ * necessary.
+ */
+ private boolean checkForTrailingSlash(HttpServletRequest request, HttpServletResponse response,
+ String filterPath)
+ {
+ // current URI
+ String uri = Strings.stripJSessionId(request.getRequestURI());
+
+ // home page without trailing slash URI
+ String homePageUri = request.getContextPath() + "/" + filterPath;
+ if (homePageUri.endsWith("/"))
+ {
+ homePageUri = homePageUri.substring(0, homePageUri.length() - 1);
+ }
+
+ if (uri.equals(homePageUri))
+ {
+ // construct redirect URL
+ String redirect = uri + "/";
+ if (!Strings.isEmpty(request.getQueryString()))
+ {
+ redirect += "?" + request.getQueryString();
+ }
+ try
+ {
+ // send redirect - this will discard POST parameters if the request is POST
+ // - still better than getting an error because of lacking trailing slash
+ response.sendRedirect(response.encodeRedirectURL(redirect));
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException
+ {
+ try
+ {
+ HttpServletRequest httpServletRequest = (HttpServletRequest)request;
+ HttpServletResponse httpServletResponse = (HttpServletResponse)response;
+
+ String filterPath = getFilterPath(httpServletRequest);
+
+ webApplication.set();
+
+ if (checkForTrailingSlash(httpServletRequest, httpServletResponse, filterPath))
+ {
+ ServletWebRequest req = new ServletWebRequest(httpServletRequest, filterPath);
+ ServletWebResponse resp = new ServletWebResponse(httpServletResponse);
+
+ RequestCycle requestCycle = webApplication.newRequestCycle(req, resp);
+
+ if (requestCycle.processRequest())
+ {
+ requestCycle.detach();
+ }
+ else
+ {
+ chain.doFilter(request, response);
+ }
+ }
+ }
+ finally
+ {
+ ThreadContext.detach();
+ }
+ }
+
+ private WebApplication webApplication;
+
+ /**
+ * Creates the web application factory instance.
+ *
+ * If no APP_FACT_PARAM is specified in web.xml ContextParamWebApplicationFactory will be used
+ * by default.
+ *
+ * @see ContextParamWebApplicationFactory
+ *
+ * @return application factory instance
+ */
+ protected IWebApplicationFactory getApplicationFactory()
+ {
+ final String appFactoryClassName = filterConfig.getInitParameter(APP_FACT_PARAM);
+
+ if (appFactoryClassName == null)
+ {
+ // If no context param was specified we return the default factory
+ return new ContextParamWebApplicationFactory();
+ }
+ else
+ {
+ try
+ {
+ // Try to find the specified factory class
+ final Class<?> factoryClass = Thread.currentThread()
+ .getContextClassLoader()
+ .loadClass(appFactoryClassName);
+
+ // Instantiate the factory
+ return (IWebApplicationFactory)factoryClass.newInstance();
+ }
+ catch (ClassCastException e)
+ {
+ throw new WicketRuntimeException("Application factory class " +
+ appFactoryClassName + " must implement IWebApplicationFactory");
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new WebApplicationFactoryCreationException(appFactoryClassName, e);
+ }
+ catch (InstantiationException e)
+ {
+ throw new WebApplicationFactoryCreationException(appFactoryClassName, e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new WebApplicationFactoryCreationException(appFactoryClassName, e);
+ }
+ catch (SecurityException e)
+ {
+ throw new WebApplicationFactoryCreationException(appFactoryClassName, e);
+ }
+ }
+ }
+
+ public void init(FilterConfig filterConfig) throws ServletException
+ {
+ this.filterConfig = filterConfig;
+ IWebApplicationFactory factory = getApplicationFactory();
+ webApplication = factory.createApplication(this);
+ webApplication.setName(filterConfig.getFilterName());
+
+ initFilterPath();
+
+ webApplication.set();
+ try
+ {
+ webApplication.internalInit();
+ webApplication.init();
+ }
+ finally
+ {
+ ThreadContext.detach();
+ }
+ }
+
+ public FilterConfig getFilterConfig()
+ {
+ return filterConfig;
+ }
+
+ private void initFilterPath()
+ {
+ InputStream is = filterConfig.getServletContext().getResourceAsStream("/WEB-INF/web.xml");
+ if (is != null)
+ {
+ try
+ {
+ filterPath = getFilterPath(filterConfig.getFilterName(), is);
+ }
+ catch (ServletException e)
+ {
+ log.error("Error reading servlet/filter path from web.xml", e);
+ }
+ catch (SecurityException e)
+ {
+ // Swallow this at INFO.
+ log.info("Couldn't read web.xml to automatically pick up servlet/filter path: " +
+ e.getMessage());
+ }
+ if (filterPath == null)
+ {
+ log.info("Unable to parse filter mapping web.xml for " +
+ filterConfig.getFilterName() + ". " + "Configure with init-param " +
+ FILTER_MAPPING_PARAM + " if it is not \"/*\".");
+ }
+ }
+ };
+
+ private FilterConfig filterConfig;
+ private String filterPath;
+
+ private boolean servletMode = false;
+
+// private String getFilterPath(String filterName, InputStream is) throws ServletException
+// {
+// String prefix = servletMode ? "servlet" : "filter";
+// String mapping = prefix + "-mapping";
+// String name = prefix + "-name";
+//
+// // Filter mappings look like this:
+// //
+// // <filter-mapping> <filter-name>WicketFilter</filter-name>
+// // <url-pattern>/*</url-pattern> <...> <filter-mapping>
+// try
+// {
+// ArrayList<String> urlPatterns = new ArrayList<String>();
+// XmlPullParser parser = new XmlPullParser();
+// parser.parse(is);
+//
+// while (true)
+// {
+// XmlTag elem;
+// do
+// {
+// elem = (XmlTag)parser.nextTag();
+// }
+// while (elem != null && (!(elem.getName().equals(mapping) && elem.isOpen())));
+//
+// if (elem == null)
+// {
+// break;
+// }
+//
+// String encounteredFilterName = null, urlPattern = null;
+//
+// do
+// {
+// elem = (XmlTag)parser.nextTag();
+// if (elem.isOpen())
+// {
+// parser.setPositionMarker();
+// }
+// else if (elem.isClose() && elem.getName().equals(name))
+// {
+// encounteredFilterName = parser.getInputFromPositionMarker(elem.getPos())
+// .toString()
+// .trim();
+// }
+// else if (elem.isClose() && elem.getName().equals("url-pattern"))
+// {
+// urlPattern = parser.getInputFromPositionMarker(elem.getPos())
+// .toString()
+// .trim();
+// }
+// }
+// while (urlPattern == null || encounteredFilterName == null);
+//
+// if (filterName.equals(encounteredFilterName))
+// {
+// urlPatterns.add(urlPattern);
+// }
+// }
+//
+// String prefixUppered = Character.toUpperCase(prefix.charAt(0)) + prefix.substring(1);
+//
+// // By the time we get here, we have a list of urlPatterns we match
+// // this filter against.
+// // In all likelihood, we will only have one. If we have none, we
+// // have an error.
+// // If we have more than one, we pick the first one to use for any
+// // 302 redirects that require absolute URLs.
+// if (urlPatterns.size() == 0)
+// {
+// throw new IllegalArgumentException("Error initializing Wicket" + prefixUppered +
+// " - you have no <" + mapping + "> element with a url-pattern that uses " +
+// prefix + ": " + filterName);
+// }
+// String urlPattern = urlPatterns.get(0);
+//
+// // Check for leading '/' and trailing '*'.
+// if (!urlPattern.startsWith("/") || !urlPattern.endsWith("*"))
+// {
+// throw new IllegalArgumentException("<" + mapping + "> for Wicket" + prefixUppered +
+// " \"" + filterName + "\" must start with '/' and end with '*'.");
+// }
+//
+// // Strip trailing '*' and keep leading '/'.
+// return stripWildcard(urlPattern);
+// }
+// catch (IOException e)
+// {
+// throw new ServletException("Error finding <" + prefix + "> " + filterName +
+// " in web.xml", e);
+// }
+// catch (ParseException e)
+// {
+// throw new ServletException("Error finding <" + prefix + "> " + filterName +
+// " in web.xml", e);
+// }
+// catch (ResourceStreamNotFoundException e)
+// {
+// throw new ServletException("Error finding <" + prefix + "> " + filterName +
+// " in web.xml", e);
+// }
+// }
+
+ private String getFilterPath(String filterName, String name, Node node)
+ {
+ String foundUrlPattern = null;
+ String foundFilterName = null;
+
+ for (int i = 0; i < node.getChildNodes().getLength(); ++i)
+ {
+ Node n = node.getChildNodes().item(i);
+ if (name.equals(n.getNodeName()))
+ {
+ foundFilterName = n.getTextContent();
+ }
+ else if ("url-pattern".equals(n.getNodeName()))
+ {
+ foundUrlPattern = n.getTextContent();
+ }
+ }
+ if (filterName.equals(foundFilterName))
+ {
+ return foundUrlPattern;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private String getFilterPath(String filterName, String mapping, String name, NodeList nodeList)
+ {
+ for (int i = 0; i < nodeList.getLength(); ++i)
+ {
+ Node node = nodeList.item(i);
+ if (mapping.equals(node.getNodeName()))
+ {
+ String path = getFilterPath(filterName, name, node);
+ if (path != null)
+ {
+ return path;
+ }
+ }
+ else
+ {
+ String path = getFilterPath(filterName, mapping, name, node.getChildNodes());
+ if (path != null)
+ {
+ return path;
+ }
+ }
+ }
+ return null;
+ }
+
+ private String getFilterPath(String filterName, InputStream is) throws ServletException
+ {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ try
+ {
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document document = builder.parse(is);
+
+ String prefix = servletMode ? "servlet" : "filter";
+ String mapping = prefix + "-mapping";
+ String name = prefix + "-name";
+
+ String urlPattern = getFilterPath(filterName, mapping, name, document.getChildNodes());
+ return stripWildcard(urlPattern);
+ }
+ catch (Exception e)
+ {
+ throw new ServletException(e);
+ }
+ }
+
+ protected String getFilterPath(HttpServletRequest request)
+ {
+ if (filterPath != null)
+ {
+ return filterPath;
+ }
+ if (servletMode)
+ {
+ return filterPath = request.getServletPath();
+ }
+ String result;
+ // Legacy migration check.
+ // TODO: Remove this after 1.3 is released and everyone's upgraded.
+
+ result = filterConfig.getInitParameter(FILTER_MAPPING_PARAM);
+ if (result == null || result.equals("/*"))
+ {
+ return "";
+ }
+ else if (!result.startsWith("/") || !result.endsWith("/*"))
+ {
+ throw new WicketRuntimeException("Your " + FILTER_MAPPING_PARAM +
+ " must start with \"/\" and end with \"/*\". It is: " + result);
+ }
+ return filterPath = stripWildcard(result);
+ }
+
+ /**
+ * Strip trailing '*' and keep leading '/'
+ *
+ * @param result
+ * @return The stripped String
+ */
+ private String stripWildcard(String result)
+ {
+ return result.substring(1, result.length() - 1);
+ }
+
+ public void destroy()
+ {
+ if (webApplication != null)
+ {
+ webApplication.destroy();
+ webApplication = null;
+ }
+ }
+
+
+ private static final Logger log = LoggerFactory.getLogger(WicketFilter.class);
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketURLDecoder.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketURLDecoder.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketURLDecoder.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketURLDecoder.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,179 @@
+/*
+ * 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.wicket.protocol.http;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.WicketRuntimeException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Adapted from java.net.URLDecoder, but defines instances for query string decoding versus URL path
+ * component decoding.
+ * <p/>
+ * The difference is important because a space is encoded as a + in a query string, but this is a
+ * valid value in a path component (and is therefore not decode back to a space).
+ *
+ * @author Doug Donohoe
+ * @see java.net.URLDecoder
+ * @see {@link "http://www.ietf.org/rfc/rfc2396.txt"}
+ */
+public class WicketURLDecoder
+{
+ private static final Logger log = LoggerFactory.getLogger(Application.class);
+
+ private final boolean decodePlus;
+
+ /**
+ * Encoder used to decode name or value components of a query string.<br/>
+ * <br/>
+ *
+ * For example: http://org.acme/notthis/northis/oreventhis?buthis=isokay&asis=thispart
+ */
+ public static final WicketURLDecoder QUERY_INSTANCE = new WicketURLDecoder(true);
+
+ /**
+ * Encoder used to decode components of a path.<br/>
+ * <br/>
+ *
+ * For example: http://org.acme/foo/thispart/orthispart?butnot=thispart
+ */
+ public static final WicketURLDecoder PATH_INSTANCE = new WicketURLDecoder(false);
+
+ /**
+ * Create decoder
+ *
+ * @param decodePlus
+ * - whether to decode + to space
+ */
+ private WicketURLDecoder(boolean decodePlus)
+ {
+ this.decodePlus = decodePlus;
+ }
+
+ /**
+ * Calls decode with the application response request encoding as returned by
+ * Application.get().getRequestCycleSettings().getResponseRequestEncoding()
+ *
+ * @param s
+ * Value to encode
+ * @return String encoded using default Application request/respose encoding
+ */
+ public String decode(String s)
+ {
+ Application app = null;
+
+ try
+ {
+ app = Application.get();
+ }
+ catch (WicketRuntimeException ignored)
+ {
+ log.warn("No current Application found - defaulting encoding to UTF-8");
+ }
+ return decode(s, app == null ? "UTF-8" : app.getRequestCycleSettings().getResponseRequestEncoding());
+ }
+
+ /**
+ * @param s
+ * string to decode
+ * @param enc
+ * encoding to decode with
+ * @return decoded string
+ * @see java.net.URLDecoder#decode(String, String)
+ */
+ public String decode(String s, String enc)
+ {
+ boolean needToChange = false;
+ int numChars = s.length();
+ StringBuffer sb = new StringBuffer(numChars > 500 ? numChars / 2 : numChars);
+ int i = 0;
+
+ if (enc.length() == 0)
+ {
+ throw new WicketRuntimeException(new UnsupportedEncodingException("URLDecoder: empty string enc parameter"));
+ }
+
+ char c;
+ byte[] bytes = null;
+ while (i < numChars)
+ {
+ c = s.charAt(i);
+ switch (c)
+ {
+ case '+':
+ sb.append(decodePlus ? ' ' : '+');
+ i++;
+ needToChange = true;
+ break;
+
+ case '%':
+ /*
+ * Starting with this instance of %, process all consecutive substrings of the form
+ * %xy. Each substring %xy will yield a byte. Convert all consecutive bytes obtained
+ * this way to whatever character(s) they represent in the provided encoding.
+ */
+ try
+ {
+ // (numChars-i)/3 is an upper bound for the number
+ // of remaining bytes
+ if (bytes == null)
+ bytes = new byte[(numChars - i) / 3];
+ int pos = 0;
+
+ while (((i + 2) < numChars) && (c == '%'))
+ {
+ bytes[pos++] = (byte) Integer.parseInt(s.substring(i + 1, i + 3), 16);
+ i += 3;
+ if (i < numChars)
+ c = s.charAt(i);
+ }
+
+ // A trailing, incomplete byte encoding such as
+ // "%x" will cause an exception to be thrown
+ if ((i < numChars) && (c == '%'))
+ throw new IllegalArgumentException("URLDecoder: Incomplete trailing escape (%) pattern");
+
+ try
+ {
+ sb.append(new String(bytes, 0, pos, enc));
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new WicketRuntimeException(e);
+ }
+ }
+ catch (NumberFormatException e)
+ {
+ throw new IllegalArgumentException("URLDecoder: Illegal hex characters in escape (%) pattern - "
+ + e.getMessage());
+ }
+ needToChange = true;
+ break;
+
+ default:
+ sb.append(c);
+ i++;
+ break;
+ }
+ }
+
+ return (needToChange ? sb.toString() : s);
+ }
+}
\ No newline at end of file
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketURLDecoder.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketURLEncoder.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketURLEncoder.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketURLEncoder.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketURLEncoder.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,343 @@
+/*
+ * 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.wicket.protocol.http;
+
+import java.io.CharArrayWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.BitSet;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.WicketRuntimeException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Adapted from java.net.URLEncoder, but defines instances for query string encoding versus URL path
+ * component encoding.
+ * <p/>
+ * The difference is important because a space is encoded as a + in a query string, but this is a
+ * valid value in a path component (and is therefore not decode back to a space).
+ *
+ * @author Doug Donohoe
+ * @see java.net.URLEncoder
+ * @see {@link "http://www.ietf.org/rfc/rfc2396.txt"}
+ */
+public class WicketURLEncoder
+{
+ private static final Logger log = LoggerFactory.getLogger(Application.class);
+
+ /**
+ * encoder types
+ */
+ public enum Type
+ {
+ /**
+ * query type
+ */
+ QUERY, /**
+ * path type
+ */
+ PATH;
+ }
+
+ // list of what not to decode
+ protected BitSet dontNeedEncoding;
+
+ // used in decoding
+ protected static final int caseDiff = ('a' - 'A');
+
+ /**
+ * Encoder used to encode name or value components of a query string.<br/>
+ * <br/>
+ *
+ * For example: http://org.acme/notthis/northis/oreventhis?buthis=isokay&asis=thispart
+ */
+ public static final WicketURLEncoder QUERY_INSTANCE = new WicketURLEncoder(Type.QUERY);
+
+ /**
+ * Encoder used to encode components of a path.<br/>
+ * <br/>
+ *
+ * For example: http://org.acme/foo/thispart/orthispart?butnot=thispart
+ */
+ public static final WicketURLEncoder PATH_INSTANCE = new WicketURLEncoder(Type.PATH);
+
+ /**
+ * Allow subclass to call constructor.
+ *
+ * @param type
+ * encoder type
+ */
+ protected WicketURLEncoder(Type type)
+ {
+ /*
+ * This note from java.net.URLEncoder ==================================
+ *
+ * The list of characters that are not encoded has been determined as follows:
+ *
+ * RFC 2396 states: ----- Data characters that are allowed in a URI but do not have a
+ * reserved purpose are called unreserved. These include upper and lower case letters,
+ * decimal digits, and a limited set of punctuation marks and symbols.
+ *
+ * unreserved = alphanum | mark
+ *
+ * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
+ *
+ * Unreserved characters can be escaped without changing the semantics of the URI, but this
+ * should not be done unless the URI is being used in a context that does not allow the
+ * unescaped character to appear. -----
+ *
+ * It appears that both Netscape and Internet Explorer escape all special characters from
+ * this list with the exception of "-", "_", ".", "*". While it is not clear why they are
+ * escaping the other characters, perhaps it is safest to assume that there might be
+ * contexts in which the others are unsafe if not escaped. Therefore, we will use the same
+ * list. It is also noteworthy that this is consistent with O'Reilly's "HTML: The Definitive
+ * Guide" (page 164).
+ *
+ * As a last note, Intenet Explorer does not encode the "@" character which is clearly not
+ * unreserved according to the RFC. We are being consistent with the RFC in this matter, as
+ * is Netscape.
+ *
+ * This bit added by Doug Donohoe ================================== RFC 3986 (2005) updates
+ * this (http://tools.ietf.org/html/rfc3986):
+ *
+ * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ *
+ * pct-encoded = "%" HEXDIG HEXDIG
+ *
+ * reserved = gen-delims / sub-delims
+ *
+ * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
+ *
+ * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" // -- PATH
+ * COMPONENT -- //
+ *
+ * path = (see RFC for all variations) path-abempty =( "/" segment ) segment =pchar pchar =
+ * unreserved / pct-encoded / sub-delims / ":" / "@" // -- QUERY COMPONENT -- //
+ *
+ * query =( pchar / "/" / "?" )
+ */
+
+ // unreserved
+ dontNeedEncoding = new BitSet(256);
+ int i;
+ for (i = 'a'; i <= 'z'; i++)
+ {
+ dontNeedEncoding.set(i);
+ }
+ for (i = 'A'; i <= 'Z'; i++)
+ {
+ dontNeedEncoding.set(i);
+ }
+ for (i = '0'; i <= '9'; i++)
+ {
+ dontNeedEncoding.set(i);
+ }
+ dontNeedEncoding.set('-');
+ dontNeedEncoding.set('.');
+ dontNeedEncoding.set('_');
+ dontNeedEncoding.set('~'); // tilde encoded by java.net.URLEncoder version, but RFC is
+ // clear on this
+
+ // sub-delims
+ dontNeedEncoding.set('!');
+ dontNeedEncoding.set('$');
+ // "&" needs to be encoded for query stings
+ dontNeedEncoding.set('\'');
+ // "(" and ")" probably don't need encoding, but we'll be conservative
+ dontNeedEncoding.set('*');
+ // "+" needs to be encoded for query strings (since it means =
+ dontNeedEncoding.set(',');
+ // ";" encoded due to use in path and/or query as delim in some instances (e.g., jsessionid)
+ // "=" needs to be encoded for query strings
+
+ // pchar
+ dontNeedEncoding.set(':'); // allowed and used in wicket interface params
+ dontNeedEncoding.set('@');
+
+ // encoding type-specific
+ switch (type)
+ {
+ // this code consistent with java.net.URLEncoder version
+ case QUERY:
+ dontNeedEncoding.set(' '); /*
+ * encoding a space to a + is done in the encode() method
+ */
+ dontNeedEncoding.set('/'); // to allow direct passing of URL in query
+ dontNeedEncoding.set('?'); // to allow direct passing of URL in query
+ break;
+
+ // this added to deal with encoding a PATH component
+ case PATH:
+ // encode ' ' with a % instead of + in path portion
+
+ // path component sub-delim values we do not need to escape
+ dontNeedEncoding.set('&');
+ dontNeedEncoding.set('=');
+ dontNeedEncoding.set('+');
+ break;
+ }
+ }
+
+ /**
+ * Calls encode with the application response request encoding as returned by
+ * Application.get().getRequestCycleSettings().getResponseRequestEncoding()
+ *
+ * @param s
+ * Value to encode
+ * @return String encoded using default Application request/respose encoding
+ */
+ public String encode(String s)
+ {
+ Application app = null;
+
+ try
+ {
+ app = Application.get();
+ }
+ catch (WicketRuntimeException ignored)
+ {
+ log.warn("No current Application found - defaulting encoding to UTF-8");
+ }
+
+ return encode(s, app == null ? "UTF-8" : app.getRequestCycleSettings().getResponseRequestEncoding());
+ }
+
+ /**
+ * @param s
+ * string to encode
+ * @param enc
+ * encoding to use
+ * @return encoded string
+ * @see java.net.URLEncoder#encode(String, String)
+ */
+ public String encode(String s, String enc)
+ {
+ boolean needToChange = false;
+ StringBuffer out = new StringBuffer(s.length());
+ Charset charset;
+ CharArrayWriter charArrayWriter = new CharArrayWriter();
+
+ if (enc == null)
+ throw new NullPointerException("charsetName");
+
+ try
+ {
+ charset = Charset.forName(enc);
+ }
+ catch (IllegalCharsetNameException e)
+ {
+ throw new WicketRuntimeException(new UnsupportedEncodingException(enc));
+ }
+ catch (UnsupportedCharsetException e)
+ {
+ throw new WicketRuntimeException(new UnsupportedEncodingException(enc));
+ }
+
+ for (int i = 0; i < s.length();)
+ {
+ int c = s.charAt(i);
+ // System.out.println("Examining character: " + c);
+ if (dontNeedEncoding.get(c))
+ {
+ if (c == ' ')
+ {
+ c = '+';
+ needToChange = true;
+ }
+ // System.out.println("Storing: " + c);
+ out.append((char) c);
+ i++;
+ }
+ else
+ {
+ // convert to external encoding before hex conversion
+ do
+ {
+ charArrayWriter.write(c);
+ /*
+ * If this character represents the start of a Unicode surrogate pair, then pass
+ * in two characters. It's not clear what should be done if a bytes reserved in
+ * the surrogate pairs range occurs outside of a legal surrogate pair. For now,
+ * just treat it as if it were any other character.
+ */
+ if (c >= 0xD800 && c <= 0xDBFF)
+ {
+ /*
+ * System.out.println(Integer.toHexString(c) + " is high surrogate");
+ */
+ if ((i + 1) < s.length())
+ {
+ int d = s.charAt(i + 1);
+ /*
+ * System.out.println("\tExamining " + Integer.toHexString(d));
+ */
+ if (d >= 0xDC00 && d <= 0xDFFF)
+ {
+ /*
+ * System.out.println("\t" + Integer.toHexString(d) + " is low
+ * surrogate");
+ */
+ charArrayWriter.write(d);
+ i++;
+ }
+ }
+ }
+ i++;
+ }
+ while (i < s.length() && !dontNeedEncoding.get((c = s.charAt(i))));
+
+ charArrayWriter.flush();
+ String str = new String(charArrayWriter.toCharArray());
+ byte[] ba = new byte[0];
+ try
+ {
+ ba = str.getBytes(charset.name());
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new WicketRuntimeException(e);
+ }
+ for (int j = 0; j < ba.length; j++)
+ {
+ out.append('%');
+ char ch = Character.forDigit((ba[j] >> 4) & 0xF, 16);
+ // converting to use uppercase letter as part of
+ // the hex value if ch is a letter.
+ if (Character.isLetter(ch))
+ {
+ ch -= caseDiff;
+ }
+ out.append(ch);
+ ch = Character.forDigit(ba[j] & 0xF, 16);
+ if (Character.isLetter(ch))
+ {
+ ch -= caseDiff;
+ }
+ out.append(ch);
+ }
+ charArrayWriter.reset();
+ needToChange = true;
+ }
+ }
+
+ return (needToChange ? out.toString() : s);
+ }
+}
\ No newline at end of file
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketURLEncoder.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandler.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandler.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandler.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandler.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,48 @@
+/*
+ * 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.wicket.request;
+
+import org.apache.wicket.RequestCycle;
+
+/**
+ * A request handler is the base entity that is the subject of a request. Different types of request
+ * have different request targets. For instance a request for a bookmarkable page differs from a
+ * request for a link on a previously rendered page, which in turn differs from a request for a
+ * shared resource.
+ *
+ * @author Eelco Hillenius
+ * @author Matej Knopp
+ */
+public interface RequestHandler
+{
+ /**
+ * Generates a response.
+ *
+ * @param requestCycle
+ * the current request cycle
+ */
+ void respond(RequestCycle requestCycle);
+
+ /**
+ * This method is called at the end of a request cycle to indicate that processing is done and
+ * that cleaning up of the subject(s) of this target may be done.
+ *
+ * @param requestCycle
+ * the current request cycle
+ */
+ void detach(RequestCycle requestCycle);
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerEncoder.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerEncoder.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerEncoder.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerEncoder.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,66 @@
+/*
+ * 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.wicket.request;
+
+import org.apache.wicket.request.request.Request;
+
+/**
+ * Encodes {@link RequestHandler}(s) into {@link Url}(s) and decodes {@link Url}(s) to
+ * {@link RequestHandler}(s). For {@link RequestHandler}s and {@link Url}s the implementation
+ * doesn't know the {@link #encode(RequestHandler)} and {@link #decode(Url, RequestParameters)}
+ * methods must return <code>null</code>.
+ *
+ * @author Matej Knopp
+ */
+public interface RequestHandlerEncoder
+{
+ /**
+ * Returns {@link RequestHandler} for the request or <code>null</code> if the encoder does not
+ * recognize the URL.
+ *
+ * @param request
+ * provides access to request data (i.e. Url and Parameters)
+ *
+ * @return RequestHandler instance or <code>null</code>
+ */
+ RequestHandler decode(Request request);
+
+ /**
+ * Returns the amount of matching segments for the request. When two {@link RequestHandlerEncoder}s
+ * are capable of decoding a request, the one with highest matching segments count will be used.
+ * <p>
+ * For example when there are two encoders for mounted page, one mapped to <code>/foo</code> another
+ * to <code>/foo/bar</code> and the incomming reqest URL is </code>/foo/bar/baz</code>, the encoder
+ * mapped to <code>/foo/bar</code> will handle the request as it has matching segments count of 2
+ * while the first one has only matching segments count of 1.
+ * <p>
+ * Note that the method can return value > 0 even if the encoder can not decode the request.
+ *
+ * @param request
+ * @return count of matching segments
+ */
+ public int getMachingSegmentsCount(Request request);
+
+ /**
+ * Returns the {@link Url} for given {@link RequestHandler} or <code>null</code> if the
+ * encoder does not recognize the request handler.
+ *
+ * @param requestHandler
+ * @return Url instance or <code>null</code>.
+ */
+ Url encode(RequestHandler requestHandler);
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerEncoder.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerEncoderRegistry.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerEncoderRegistry.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerEncoderRegistry.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerEncoderRegistry.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,133 @@
+/*
+ * 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.wicket.request;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.wicket.request.request.Request;
+
+/**
+ * Thread safe registry of {@link RequestHandlerEncoder}s. The encoders are searched depending on
+ * the orders they were registered. If the {@link RequestHandlerEncoder}s can handle
+ * {@link Request} and they have same matching segments count, the last registered encoder has
+ * higher priority.
+ *
+ * @author Matej Knopp
+ */
+public class RequestHandlerEncoderRegistry
+{
+ /**
+ * Registers a {@link RequestHandlerEncoder}
+ *
+ * @param encoder
+ */
+ public void register(RequestHandlerEncoder encoder)
+ {
+ encoders.add(0, encoder);
+ }
+
+ /**
+ * Unregisters {@link RequestHandlerEncoder}
+ *
+ * @param encoder
+ */
+ public void unregister(RequestHandlerEncoder encoder)
+ {
+ encoders.remove(encoder);
+ }
+
+ /**
+ * Searches the registered {@link RequestHandlerEncoder}s to find one that can decode the
+ * {@link Request}. Each registered {@link RequestHandlerEncoder} is asked to decode the
+ * {@link Request}. The encoder with highest matching segments count that can decode the
+ * request is returned.
+ *
+ * @param request
+ * @return RequestHandler for the request or <code>null</code> if no encoder for the request
+ * is found.
+ */
+ public RequestHandler decode(Request request)
+ {
+ // last found RequestHandler with highest matching segments count
+ RequestHandler last = null;
+ int maxMatchingSegmentsCount = -1;
+
+ for (RequestHandlerEncoder encoder : encoders)
+ {
+ // no handler has been found yet
+ if (last == null)
+ {
+ // try to get the handler immediately, at this point we don't care for matching
+ // segments count
+ last = encoder.decode(request);
+ if (last != null)
+ {
+ // found one - get the matching segments count so that it can be compared
+ // to other encoders found later
+ maxMatchingSegmentsCount = encoder.getMachingSegmentsCount(request);
+ }
+ }
+ else
+ {
+ // we already have a handler, try to find out if this one has bigger matching
+ // segments count
+ int count = encoder.getMachingSegmentsCount(request);
+ if (count > maxMatchingSegmentsCount)
+ {
+ // seems so
+ RequestHandler handler = encoder.decode(request);
+ if (handler != null)
+ {
+ // replace the last one
+ last = handler;
+ maxMatchingSegmentsCount = count;
+ }
+ }
+ }
+ }
+ return last;
+ }
+
+ /**
+ * Searches the registered {@link RequestHandlerEncoder}s to find one that can encode the
+ * {@link RequestHandler}. Each registered {@link RequestHandlerEncoder} is asked to encode the
+ * {@link RequestHandler} until an encoder that can encode the {@link RequestHandler} is found
+ * or no more encoders are left.
+ * <p>
+ * The handlers are searched in reverse order as they have been registered. More recently
+ * registered handlers have bigger priority.
+ *
+ * @param handler
+ * @return Url for the handler or <code>null</code> if no encoder for the handler is found.
+ */
+ public Url encode(RequestHandler handler)
+ {
+ for (RequestHandlerEncoder encoder : encoders)
+ {
+ Url url = encoder.encode(handler);
+ if (url != null)
+ {
+ return url;
+ }
+ }
+ return null;
+ }
+
+ private List<RequestHandlerEncoder> encoders = new CopyOnWriteArrayList<RequestHandlerEncoder>();
+
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerEncoderRegistry.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerStack.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerStack.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerStack.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerStack.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,219 @@
+/*
+ * 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.wicket.request;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.request.response.Response;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Manages stack of {@link RequestHandler}s.
+ *
+ * @author Matej Knopp
+ */
+public abstract class RequestHandlerStack
+{
+ private Response response;
+
+ /**
+ * Construct.
+ *
+ * @param response
+ */
+ public RequestHandlerStack(Response response)
+ {
+ this.response = response;
+ }
+
+ // we need both Queue and List interfaces
+ private final LinkedList<RequestHandler> requestHandlers = new LinkedList<RequestHandler>();
+
+ private final List<RequestHandler> inactiveRequestHandlers = new ArrayList<RequestHandler>();
+
+ /**
+ * Returns currently active {@link RequestHandler}.
+ *
+ * @return Active RequestHandler or <code>null</code> if no handler is active.
+ */
+ public RequestHandler getActiveRequestHandler()
+ {
+ return requestHandlers.peek();
+ }
+
+ /**
+ * Executes the specified {@link RequestHandler}. When the specified {@link RequestHandler}
+ * finishes, the {@link RequestHandler} that invoked this method continues (unless the new
+ * {@link RequestHandler} called {@link #replaceAllRequestHandlers(RequestHandler)}.
+ *
+ * @param handler
+ */
+ public void executeRequestHandler(RequestHandler handler)
+ {
+ final boolean first = requestHandlers.isEmpty();
+ requestHandlers.add(handler);
+
+ RequestHandler replacementHandler = null;
+ Response originalResponse = response;
+ try
+ {
+ handler.respond(getRequestCycle());
+ }
+ catch (ReplaceHandlerException exception)
+ {
+ if (exception.removeAll && !first)
+ {
+ throw exception;
+ }
+ replacementHandler = exception.replacementRequestHandler;
+ }
+ finally
+ {
+ response = originalResponse;
+ requestHandlers.poll();
+ inactiveRequestHandlers.add(handler);
+ }
+
+ if (replacementHandler != null)
+ {
+ executeRequestHandler(replacementHandler);
+ }
+ }
+
+ /**
+ * Replaces the currently executed {@link RequestHandler} with new {@link RequestHandler}. The
+ * currently executed {@link RequestHandler} is terminated and the new {@link RequestHandler} is
+ * executed.
+ *
+ * @param handler
+ */
+ public void replaceCurrentRequestHandler(RequestHandler handler)
+ {
+ if (requestHandlers.isEmpty())
+ {
+ executeRequestHandler(handler);
+ }
+ else
+ {
+ throw new ReplaceHandlerException(handler, false);
+ }
+ }
+
+ /**
+ * Removes the whole {@link RequestHandler} stack, terminates currently running
+ * {@link RequestHandler} and executes the new {@link RequestHandler}.
+ *
+ * @param handler
+ */
+ public void replaceAllRequestHandlers(RequestHandler handler)
+ {
+ if (requestHandlers.isEmpty())
+ {
+ executeRequestHandler(handler);
+ }
+ else
+ {
+ throw new ReplaceHandlerException(handler, true);
+ }
+ }
+
+ /**
+ * Exception to stop current request handler and execute a new one.
+ *
+ * @author Matej Knopp
+ */
+ private static class ReplaceHandlerException extends RuntimeException
+ {
+ private static final long serialVersionUID = 1L;
+
+ private final boolean removeAll;
+ private final RequestHandler replacementRequestHandler;
+
+ public ReplaceHandlerException(RequestHandler replacementRequestHandler, boolean removeAll)
+ {
+ this.replacementRequestHandler = replacementRequestHandler;
+ this.removeAll = removeAll;
+ }
+
+ @Override
+ public synchronized Throwable fillInStackTrace()
+ {
+ // don't do anything here
+ return null;
+ }
+ };
+
+
+ /**
+ * Returns the active {@link Response}.
+ *
+ * @return response object.
+ */
+ public Response getResponse()
+ {
+ return response;
+ }
+
+ /**
+ * Replaces current {@link Response} with new {@link Response} instance. The original response
+ * is always restored after the {@link RequestHandler#respond(RequestCycle)} method is finished.
+ *
+ * @param response
+ * @return Response being replaced.
+ */
+ public Response setResponse(Response response)
+ {
+ Response current = this.response;
+ this.response = response;
+ return current;
+ }
+
+ protected abstract RequestCycle getRequestCycle();
+
+ /**
+ * Detaches all {@link RequestHandler}s.
+ */
+ public void detach()
+ {
+ if (!requestHandlers.isEmpty())
+ {
+ // All requests handlers should be inactive at this point
+ log.warn("Some of the request handlers are still active.");
+
+ inactiveRequestHandlers.addAll(requestHandlers);
+ requestHandlers.clear();
+ }
+
+ for (RequestHandler handler : inactiveRequestHandlers)
+ {
+ try
+ {
+ handler.detach(getRequestCycle());
+ }
+ catch (Throwable exception)
+ {
+ log.error("Error detaching RequestHandler", exception);
+ }
+ }
+ }
+
+ private static final Logger log = LoggerFactory.getLogger(RequestHandlerStack.class);
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestHandlerStack.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestParameters.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestParameters.java?rev=759525&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestParameters.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestParameters.java Sat Mar 28 17:53:05 2009
@@ -0,0 +1,60 @@
+/*
+ * 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.wicket.request;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.wicket.util.string.StringValue;
+
+/**
+ * Represents request parameters.
+ *
+ * @author Matej Knopp
+ */
+public interface RequestParameters
+{
+ /**
+ * Returns immutable set of all available parameter names.
+ *
+ * @return list of parameter names
+ */
+ public Set<String> getParameterNames();
+
+ /**
+ * Returns single value for parameter with specified name. This method always returns non-null
+ * result even if the parameter does not exist.
+ *
+ * @see StringValue#isNull()
+ *
+ * @param name
+ * parameter name
+ * @return {@link StringValue} wrapping the actual value
+ */
+ public StringValue getParameterValue(String name);
+
+ /**
+ * Returns list of values for parameter with specified name. If the parameter does not exist
+ * this method returns <code>null</code>
+ *
+ * @param name
+ * parameter name
+ * @return list of all values for given parameter or <code>null</code> if parameter does not
+ * exist
+ */
+ public List<StringValue> getParameterValues(String name);
+}
Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/RequestParameters.java
------------------------------------------------------------------------------
svn:mime-type = text/plain