You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@wicket.apache.org by Maxim Solodovnik <so...@gmail.com> on 2017/12/07 08:29:04 UTC

Re: wicket git commit: render independently from web or tester

Hello Sven,

Is this correct import?
import com.google.common.base.Supplier;

On Thu, Dec 7, 2017 at 3:24 PM,  <sv...@apache.org> wrote:
> Repository: wicket
> Updated Branches:
>   refs/heads/sandbox/component-renderer [created] 6e6c273fd
>
>
> render independently from web or tester
>
>
> Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
> Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/6e6c273f
> Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/6e6c273f
> Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/6e6c273f
>
> Branch: refs/heads/sandbox/component-renderer
> Commit: 6e6c273fd32325a447cc32c751d5ce0c083e7ed1
> Parents: 693dad3
> Author: Sven Meier <sv...@apache.org>
> Authored: Thu Dec 7 09:24:12 2017 +0100
> Committer: Sven Meier <sv...@apache.org>
> Committed: Thu Dec 7 09:24:12 2017 +0100
>
> ----------------------------------------------------------------------
>  .../core/util/string/ComponentRenderer.java     | 324 ++++++++++++++++++-
>  .../ComponentRendererInstanceTest.java          |  52 +++
>  2 files changed, 369 insertions(+), 7 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/6e6c273f/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
> ----------------------------------------------------------------------
> diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java b/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
> index 0cf63bf..e971bc2 100644
> --- a/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
> +++ b/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
> @@ -16,35 +16,341 @@
>   */
>  package org.apache.wicket.core.util.string;
>
> +import java.io.Serializable;
> +import java.util.List;
> +import java.util.Set;
> +
>  import org.apache.wicket.Application;
>  import org.apache.wicket.Component;
>  import org.apache.wicket.MarkupContainer;
> +import org.apache.wicket.Page;
> +import org.apache.wicket.RuntimeConfigurationType;
> +import org.apache.wicket.Session;
>  import org.apache.wicket.ThreadContext;
>  import org.apache.wicket.core.request.handler.PageProvider;
>  import org.apache.wicket.markup.IMarkupCacheKeyProvider;
>  import org.apache.wicket.markup.IMarkupResourceStreamProvider;
>  import org.apache.wicket.markup.MarkupNotFoundException;
>  import org.apache.wicket.markup.html.WebPage;
> +import org.apache.wicket.mock.MockApplication;
> +import org.apache.wicket.mock.MockWebRequest;
>  import org.apache.wicket.protocol.http.BufferedWebResponse;
> +import org.apache.wicket.protocol.http.WebApplication;
> +import org.apache.wicket.protocol.http.mock.MockServletContext;
> +import org.apache.wicket.request.Request;
>  import org.apache.wicket.request.Response;
> +import org.apache.wicket.request.Url;
>  import org.apache.wicket.request.cycle.RequestCycle;
> +import org.apache.wicket.request.http.WebRequest;
> +import org.apache.wicket.serialize.ISerializer;
> +import org.apache.wicket.session.ISessionStore;
>  import org.apache.wicket.util.resource.IResourceStream;
>  import org.apache.wicket.util.resource.StringResourceStream;
>  import org.slf4j.Logger;
>  import org.slf4j.LoggerFactory;
>
> +import com.google.common.base.Supplier;
> +
>  /**
>   * A helper class for rendering components and pages.
> - *
> - * <p><strong>Note</strong>: {@link #renderComponent(Component)} does <strong>not</strong>
> - * support rendering {@link org.apache.wicket.markup.html.panel.Fragment} instances!</p>
> + * <p>
> + * With the static methods of this class components and pages can be rendered
> + * on a thread already processing an {@link Application}.
> + * <p>
> + * If you want to render independently from any web request processing (e.g. generating an email
> + * body on a worker thread), you can create an instance of this class.<br/>
> + * You may use an existing application, create a fresh one or just use the defaults of
> + * {@link #ComponentRenderer()} for a mocked application with sensible defaults.
> + * <p>
> + * Note: For performance instances can and should be reused, be sure to call {@link #destroy()}
> + * when they are no longer needed.
>   */
>  public class ComponentRenderer
>  {
>         private static final Logger LOGGER = LoggerFactory.getLogger(ComponentRenderer.class);
>
> +       private WebApplication application;
> +
> +       /**
> +        * A renderer using a default mocked application, which
> +        * <ul>
> +        * <li>never shares anything in a session</li>
> +        * <li>never serializes anything</li>
> +        * </ul>
> +        */
> +       public ComponentRenderer()
> +       {
> +               this(new MockApplication()
> +               {
> +                       @Override
> +                       public RuntimeConfigurationType getConfigurationType()
> +                       {
> +                               return RuntimeConfigurationType.DEPLOYMENT;
> +                       }
> +
> +                       @Override
> +                       protected void init()
> +                       {
> +                               super.init();
> +
> +                               setSessionStoreProvider(() -> new NeverSessionStore());
> +                               getFrameworkSettings().setSerializer(new NeverSerializer());
> +                       }
> +               });
> +       }
> +
> +       /**
> +        * A renderer using the given application.
> +        * <p>
> +        * If the application was not yet initialized - e.g. it is not reused from an already running web
> +        * container - it will be initialized.
> +        */
> +       public ComponentRenderer(WebApplication application)
> +       {
> +               this.application = application;
> +
> +               if (application.getName() == null) {
> +                       // not yet initialized
> +
> +                       inThreadContext(new Runnable()
> +                       {
> +                               @Override
> +                               public void run()
> +                               {
> +                                       application.setServletContext(new MockServletContext(application, null));
> +                                       application.setName("ComponentRenderer[" + System.identityHashCode(ComponentRenderer.this) + "]");
> +                                       application.initApplication();
> +                               }
> +                       });
> +               }
> +       }
> +
> +       /**
> +        * Destroy this renderer.
> +        */
> +       public void destroy()
> +       {
> +               inThreadContext(new Runnable()
> +               {
> +                       @Override
> +                       public void run()
> +                       {
> +                               application.internalDestroy();
> +                       }
> +               });
> +       }
> +
> +       /**
> +        *
> +        * Collects the html generated by the rendering a component.
> +        *
> +        * @param component
> +        *            supplier of the component
> +        * @return the html rendered by the panel
> +        */
> +       public CharSequence renderComponent(final Supplier<Component> component)
> +       {
> +               return renderPage(new Supplier<Page>()
> +               {
> +                       @Override
> +                       public Page get()
> +                       {
> +                               return new RenderPage(component.get());
> +                       }
> +               });
> +       }
> +
> +       /**
> +        * Collects the html generated by the rendered a component.
> +        *
> +        * @param page
> +        *            supplier of the page
> +        * @return the html rendered by the panel
> +        */
> +       public CharSequence renderPage(final Supplier<? extends Page> page)
> +       {
> +               return inThreadContext(new Supplier<CharSequence>()
> +               {
> +                       @Override
> +                       public CharSequence get()
> +                       {
> +                               WebRequest request = newWebRequest();
> +
> +                               BufferedWebResponse response = new BufferedWebResponse(null);
> +
> +                               RequestCycle cycle = application.createRequestCycle(request, response);
> +
> +                               ThreadContext.setRequestCycle(cycle);
> +
> +                               page.get().renderPage();
> +
> +                               return response.getText();
> +                       }
> +               });
> +       }
> +
> +       /**
> +        * Run the given runnable inside a valid {@link ThreadContext}.
> +        *
> +        * @param runnable
> +        *            runnable
> +        */
> +       private void inThreadContext(Runnable runnable) {
> +               inThreadContext(() -> {
> +                       runnable.run();
> +                       return null;
> +               });
> +       }
> +
> +       /**
> +        * Get the result from the given supplier inside a valid {@link ThreadContext}.
> +        *
> +        * @param supplier
> +        *            supplier
> +        * @return result of {@link Supplier#get()}
> +        */
> +       private <T> T inThreadContext(Supplier<T> supplier)
> +       {
> +               ThreadContext oldContext = ThreadContext.detach();
> +
> +               try
> +               {
> +                       ThreadContext.setApplication(application);
> +
> +                       return supplier.get();
> +               }
> +               finally
> +               {
> +
> +                       ThreadContext.restore(oldContext);
> +               }
> +       }
> +
> +       /**
> +        * Create a new request, by default a {@link MockWebRequest}.
> +        */
> +       protected WebRequest newWebRequest()
> +       {
> +               return new MockWebRequest(Url.parse("/"));
> +       }
> +
> +       /**
> +        * Never serialize.
> +        */
> +       private static final class NeverSerializer implements ISerializer
> +       {
> +               @Override
> +               public byte[] serialize(Object object)
> +               {
> +                       return null;
> +               }
> +
> +               @Override
> +               public Object deserialize(byte[] data)
> +               {
> +                       return null;
> +               }
> +       }
> +
> +       /**
> +        * Never share anything.
> +        */
> +       private static class NeverSessionStore implements ISessionStore
> +       {
> +
> +               @Override
> +               public Serializable getAttribute(Request request, String name)
> +               {
> +                       return null;
> +               }
> +
> +               @Override
> +               public List<String> getAttributeNames(Request request)
> +               {
> +                       return null;
> +               }
> +
> +               @Override
> +               public void setAttribute(Request request, String name, Serializable value)
> +               {
> +               }
> +
> +               @Override
> +               public void removeAttribute(Request request, String name)
> +               {
> +               }
> +
> +               @Override
> +               public void invalidate(Request request)
> +               {
> +               }
> +
> +               @Override
> +               public String getSessionId(Request request, boolean create)
> +               {
> +                       return null;
> +               }
> +
> +               @Override
> +               public Session lookup(Request request)
> +               {
> +                       return null;
> +               }
> +
> +               @Override
> +               public void bind(Request request, Session newSession)
> +               {
> +               }
> +
> +               @Override
> +               public void flushSession(Request request, Session session)
> +               {
> +               }
> +
> +               @Override
> +               public void destroy()
> +               {
> +               }
> +
> +               @Override
> +               public void registerUnboundListener(UnboundListener listener)
> +               {
> +               }
> +
> +               @Override
> +               public void unregisterUnboundListener(UnboundListener listener)
> +               {
> +               }
> +
> +               @Override
> +               public Set<UnboundListener> getUnboundListener()
> +               {
> +                       return null;
> +               }
> +
> +               @Override
> +               public void registerBindListener(BindListener listener)
> +               {
> +               }
> +
> +               @Override
> +               public void unregisterBindListener(BindListener listener)
> +               {
> +               }
> +
> +
> +               @Override
> +
> +               public Set<BindListener> getBindListeners()
> +               {
> +                       return null;
> +               }
> +       }
> +
>         /**
>          * Collects the html generated by the rendering of a page.
> +        * <p>
> +        * Important note: Must be called on a thread already processing a {@link WebApplication}!
>          *
>          * @param pageProvider
>          *            the provider of the page class/instance and its parameters
> @@ -75,12 +381,16 @@ public class ComponentRenderer
>
>         /**
>          * Collects the html generated by the rendering of a component.
> -        *
>          * <p>
> -        * NOTE: this method is meant to render fresh component instances that are disposed after the
> +        * Important notes:
> +        * <ul>
> +        * <li>this method is meant to render fresh component instances that are disposed after the
>          * html has been generate. To avoid unwanted side effects do not use it with components that
> -        * are from an existing hierarchy.
> -        * </p>
> +        * are from an existing hierarchy.</li>
> +        * <li>does <strong>not</strong> support rendering
> +        * {@link org.apache.wicket.markup.html.panel.Fragment} instances</li>
> +        * <li>must be called on a thread already processing a {@link WebApplication}!</li>
> +        * </ul>
>          *
>          * @param component
>          *            the component to render.
>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/6e6c273f/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java
> ----------------------------------------------------------------------
> diff --git a/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java b/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java
> new file mode 100644
> index 0000000..4aa6dfa
> --- /dev/null
> +++ b/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java
> @@ -0,0 +1,52 @@
> +/*
> +/*
> + * 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.core.util.string.componentrenderer;
> +
> +import static org.junit.Assert.assertEquals;
> +
> +import org.apache.wicket.core.util.string.ComponentRenderer;
> +import org.apache.wicket.markup.html.basic.Label;
> +import org.junit.After;
> +import org.junit.Before;
> +import org.junit.Test;
> +
> +/**
> + * Tests for {@link ComponentRenderer}
> + */
> +public class ComponentRendererInstanceTest
> +{
> +       private ComponentRenderer renderer;
> +
> +       @Before
> +       public void setup() {
> +               renderer = new ComponentRenderer();
> +       }
> +
> +       @After
> +       public void destroy() {
> +               renderer.destroy();
> +       }
> +
> +       @Test
> +       public void render()
> +       {
> +               CharSequence html = renderer.renderComponent(() -> new Label("id", "Hello renderer"));
> +
> +               assertEquals("Hello renderer", html.toString());
> +       }
> +}
> \ No newline at end of file
>



-- 
WBR
Maxim aka solomax

Re: wicket git commit: render independently from web or tester

Posted by Sven Meier <sv...@meiers.net>.
Wow, you're fast :P

Sven


Am 07.12.2017 um 09:29 schrieb Maxim Solodovnik:
> Hello Sven,
>
> Is this correct import?
> import com.google.common.base.Supplier;
>
> On Thu, Dec 7, 2017 at 3:24 PM,  <sv...@apache.org> wrote:
>> Repository: wicket
>> Updated Branches:
>>    refs/heads/sandbox/component-renderer [created] 6e6c273fd
>>
>>
>> render independently from web or tester
>>
>>
>> Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
>> Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/6e6c273f
>> Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/6e6c273f
>> Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/6e6c273f
>>
>> Branch: refs/heads/sandbox/component-renderer
>> Commit: 6e6c273fd32325a447cc32c751d5ce0c083e7ed1
>> Parents: 693dad3
>> Author: Sven Meier <sv...@apache.org>
>> Authored: Thu Dec 7 09:24:12 2017 +0100
>> Committer: Sven Meier <sv...@apache.org>
>> Committed: Thu Dec 7 09:24:12 2017 +0100
>>
>> ----------------------------------------------------------------------
>>   .../core/util/string/ComponentRenderer.java     | 324 ++++++++++++++++++-
>>   .../ComponentRendererInstanceTest.java          |  52 +++
>>   2 files changed, 369 insertions(+), 7 deletions(-)
>> ----------------------------------------------------------------------
>>
>>
>> http://git-wip-us.apache.org/repos/asf/wicket/blob/6e6c273f/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
>> ----------------------------------------------------------------------
>> diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java b/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
>> index 0cf63bf..e971bc2 100644
>> --- a/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
>> +++ b/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
>> @@ -16,35 +16,341 @@
>>    */
>>   package org.apache.wicket.core.util.string;
>>
>> +import java.io.Serializable;
>> +import java.util.List;
>> +import java.util.Set;
>> +
>>   import org.apache.wicket.Application;
>>   import org.apache.wicket.Component;
>>   import org.apache.wicket.MarkupContainer;
>> +import org.apache.wicket.Page;
>> +import org.apache.wicket.RuntimeConfigurationType;
>> +import org.apache.wicket.Session;
>>   import org.apache.wicket.ThreadContext;
>>   import org.apache.wicket.core.request.handler.PageProvider;
>>   import org.apache.wicket.markup.IMarkupCacheKeyProvider;
>>   import org.apache.wicket.markup.IMarkupResourceStreamProvider;
>>   import org.apache.wicket.markup.MarkupNotFoundException;
>>   import org.apache.wicket.markup.html.WebPage;
>> +import org.apache.wicket.mock.MockApplication;
>> +import org.apache.wicket.mock.MockWebRequest;
>>   import org.apache.wicket.protocol.http.BufferedWebResponse;
>> +import org.apache.wicket.protocol.http.WebApplication;
>> +import org.apache.wicket.protocol.http.mock.MockServletContext;
>> +import org.apache.wicket.request.Request;
>>   import org.apache.wicket.request.Response;
>> +import org.apache.wicket.request.Url;
>>   import org.apache.wicket.request.cycle.RequestCycle;
>> +import org.apache.wicket.request.http.WebRequest;
>> +import org.apache.wicket.serialize.ISerializer;
>> +import org.apache.wicket.session.ISessionStore;
>>   import org.apache.wicket.util.resource.IResourceStream;
>>   import org.apache.wicket.util.resource.StringResourceStream;
>>   import org.slf4j.Logger;
>>   import org.slf4j.LoggerFactory;
>>
>> +import com.google.common.base.Supplier;
>> +
>>   /**
>>    * A helper class for rendering components and pages.
>> - *
>> - * <p><strong>Note</strong>: {@link #renderComponent(Component)} does <strong>not</strong>
>> - * support rendering {@link org.apache.wicket.markup.html.panel.Fragment} instances!</p>
>> + * <p>
>> + * With the static methods of this class components and pages can be rendered
>> + * on a thread already processing an {@link Application}.
>> + * <p>
>> + * If you want to render independently from any web request processing (e.g. generating an email
>> + * body on a worker thread), you can create an instance of this class.<br/>
>> + * You may use an existing application, create a fresh one or just use the defaults of
>> + * {@link #ComponentRenderer()} for a mocked application with sensible defaults.
>> + * <p>
>> + * Note: For performance instances can and should be reused, be sure to call {@link #destroy()}
>> + * when they are no longer needed.
>>    */
>>   public class ComponentRenderer
>>   {
>>          private static final Logger LOGGER = LoggerFactory.getLogger(ComponentRenderer.class);
>>
>> +       private WebApplication application;
>> +
>> +       /**
>> +        * A renderer using a default mocked application, which
>> +        * <ul>
>> +        * <li>never shares anything in a session</li>
>> +        * <li>never serializes anything</li>
>> +        * </ul>
>> +        */
>> +       public ComponentRenderer()
>> +       {
>> +               this(new MockApplication()
>> +               {
>> +                       @Override
>> +                       public RuntimeConfigurationType getConfigurationType()
>> +                       {
>> +                               return RuntimeConfigurationType.DEPLOYMENT;
>> +                       }
>> +
>> +                       @Override
>> +                       protected void init()
>> +                       {
>> +                               super.init();
>> +
>> +                               setSessionStoreProvider(() -> new NeverSessionStore());
>> +                               getFrameworkSettings().setSerializer(new NeverSerializer());
>> +                       }
>> +               });
>> +       }
>> +
>> +       /**
>> +        * A renderer using the given application.
>> +        * <p>
>> +        * If the application was not yet initialized - e.g. it is not reused from an already running web
>> +        * container - it will be initialized.
>> +        */
>> +       public ComponentRenderer(WebApplication application)
>> +       {
>> +               this.application = application;
>> +
>> +               if (application.getName() == null) {
>> +                       // not yet initialized
>> +
>> +                       inThreadContext(new Runnable()
>> +                       {
>> +                               @Override
>> +                               public void run()
>> +                               {
>> +                                       application.setServletContext(new MockServletContext(application, null));
>> +                                       application.setName("ComponentRenderer[" + System.identityHashCode(ComponentRenderer.this) + "]");
>> +                                       application.initApplication();
>> +                               }
>> +                       });
>> +               }
>> +       }
>> +
>> +       /**
>> +        * Destroy this renderer.
>> +        */
>> +       public void destroy()
>> +       {
>> +               inThreadContext(new Runnable()
>> +               {
>> +                       @Override
>> +                       public void run()
>> +                       {
>> +                               application.internalDestroy();
>> +                       }
>> +               });
>> +       }
>> +
>> +       /**
>> +        *
>> +        * Collects the html generated by the rendering a component.
>> +        *
>> +        * @param component
>> +        *            supplier of the component
>> +        * @return the html rendered by the panel
>> +        */
>> +       public CharSequence renderComponent(final Supplier<Component> component)
>> +       {
>> +               return renderPage(new Supplier<Page>()
>> +               {
>> +                       @Override
>> +                       public Page get()
>> +                       {
>> +                               return new RenderPage(component.get());
>> +                       }
>> +               });
>> +       }
>> +
>> +       /**
>> +        * Collects the html generated by the rendered a component.
>> +        *
>> +        * @param page
>> +        *            supplier of the page
>> +        * @return the html rendered by the panel
>> +        */
>> +       public CharSequence renderPage(final Supplier<? extends Page> page)
>> +       {
>> +               return inThreadContext(new Supplier<CharSequence>()
>> +               {
>> +                       @Override
>> +                       public CharSequence get()
>> +                       {
>> +                               WebRequest request = newWebRequest();
>> +
>> +                               BufferedWebResponse response = new BufferedWebResponse(null);
>> +
>> +                               RequestCycle cycle = application.createRequestCycle(request, response);
>> +
>> +                               ThreadContext.setRequestCycle(cycle);
>> +
>> +                               page.get().renderPage();
>> +
>> +                               return response.getText();
>> +                       }
>> +               });
>> +       }
>> +
>> +       /**
>> +        * Run the given runnable inside a valid {@link ThreadContext}.
>> +        *
>> +        * @param runnable
>> +        *            runnable
>> +        */
>> +       private void inThreadContext(Runnable runnable) {
>> +               inThreadContext(() -> {
>> +                       runnable.run();
>> +                       return null;
>> +               });
>> +       }
>> +
>> +       /**
>> +        * Get the result from the given supplier inside a valid {@link ThreadContext}.
>> +        *
>> +        * @param supplier
>> +        *            supplier
>> +        * @return result of {@link Supplier#get()}
>> +        */
>> +       private <T> T inThreadContext(Supplier<T> supplier)
>> +       {
>> +               ThreadContext oldContext = ThreadContext.detach();
>> +
>> +               try
>> +               {
>> +                       ThreadContext.setApplication(application);
>> +
>> +                       return supplier.get();
>> +               }
>> +               finally
>> +               {
>> +
>> +                       ThreadContext.restore(oldContext);
>> +               }
>> +       }
>> +
>> +       /**
>> +        * Create a new request, by default a {@link MockWebRequest}.
>> +        */
>> +       protected WebRequest newWebRequest()
>> +       {
>> +               return new MockWebRequest(Url.parse("/"));
>> +       }
>> +
>> +       /**
>> +        * Never serialize.
>> +        */
>> +       private static final class NeverSerializer implements ISerializer
>> +       {
>> +               @Override
>> +               public byte[] serialize(Object object)
>> +               {
>> +                       return null;
>> +               }
>> +
>> +               @Override
>> +               public Object deserialize(byte[] data)
>> +               {
>> +                       return null;
>> +               }
>> +       }
>> +
>> +       /**
>> +        * Never share anything.
>> +        */
>> +       private static class NeverSessionStore implements ISessionStore
>> +       {
>> +
>> +               @Override
>> +               public Serializable getAttribute(Request request, String name)
>> +               {
>> +                       return null;
>> +               }
>> +
>> +               @Override
>> +               public List<String> getAttributeNames(Request request)
>> +               {
>> +                       return null;
>> +               }
>> +
>> +               @Override
>> +               public void setAttribute(Request request, String name, Serializable value)
>> +               {
>> +               }
>> +
>> +               @Override
>> +               public void removeAttribute(Request request, String name)
>> +               {
>> +               }
>> +
>> +               @Override
>> +               public void invalidate(Request request)
>> +               {
>> +               }
>> +
>> +               @Override
>> +               public String getSessionId(Request request, boolean create)
>> +               {
>> +                       return null;
>> +               }
>> +
>> +               @Override
>> +               public Session lookup(Request request)
>> +               {
>> +                       return null;
>> +               }
>> +
>> +               @Override
>> +               public void bind(Request request, Session newSession)
>> +               {
>> +               }
>> +
>> +               @Override
>> +               public void flushSession(Request request, Session session)
>> +               {
>> +               }
>> +
>> +               @Override
>> +               public void destroy()
>> +               {
>> +               }
>> +
>> +               @Override
>> +               public void registerUnboundListener(UnboundListener listener)
>> +               {
>> +               }
>> +
>> +               @Override
>> +               public void unregisterUnboundListener(UnboundListener listener)
>> +               {
>> +               }
>> +
>> +               @Override
>> +               public Set<UnboundListener> getUnboundListener()
>> +               {
>> +                       return null;
>> +               }
>> +
>> +               @Override
>> +               public void registerBindListener(BindListener listener)
>> +               {
>> +               }
>> +
>> +               @Override
>> +               public void unregisterBindListener(BindListener listener)
>> +               {
>> +               }
>> +
>> +
>> +               @Override
>> +
>> +               public Set<BindListener> getBindListeners()
>> +               {
>> +                       return null;
>> +               }
>> +       }
>> +
>>          /**
>>           * Collects the html generated by the rendering of a page.
>> +        * <p>
>> +        * Important note: Must be called on a thread already processing a {@link WebApplication}!
>>           *
>>           * @param pageProvider
>>           *            the provider of the page class/instance and its parameters
>> @@ -75,12 +381,16 @@ public class ComponentRenderer
>>
>>          /**
>>           * Collects the html generated by the rendering of a component.
>> -        *
>>           * <p>
>> -        * NOTE: this method is meant to render fresh component instances that are disposed after the
>> +        * Important notes:
>> +        * <ul>
>> +        * <li>this method is meant to render fresh component instances that are disposed after the
>>           * html has been generate. To avoid unwanted side effects do not use it with components that
>> -        * are from an existing hierarchy.
>> -        * </p>
>> +        * are from an existing hierarchy.</li>
>> +        * <li>does <strong>not</strong> support rendering
>> +        * {@link org.apache.wicket.markup.html.panel.Fragment} instances</li>
>> +        * <li>must be called on a thread already processing a {@link WebApplication}!</li>
>> +        * </ul>
>>           *
>>           * @param component
>>           *            the component to render.
>>
>> http://git-wip-us.apache.org/repos/asf/wicket/blob/6e6c273f/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java
>> ----------------------------------------------------------------------
>> diff --git a/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java b/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java
>> new file mode 100644
>> index 0000000..4aa6dfa
>> --- /dev/null
>> +++ b/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java
>> @@ -0,0 +1,52 @@
>> +/*
>> +/*
>> + * 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.core.util.string.componentrenderer;
>> +
>> +import static org.junit.Assert.assertEquals;
>> +
>> +import org.apache.wicket.core.util.string.ComponentRenderer;
>> +import org.apache.wicket.markup.html.basic.Label;
>> +import org.junit.After;
>> +import org.junit.Before;
>> +import org.junit.Test;
>> +
>> +/**
>> + * Tests for {@link ComponentRenderer}
>> + */
>> +public class ComponentRendererInstanceTest
>> +{
>> +       private ComponentRenderer renderer;
>> +
>> +       @Before
>> +       public void setup() {
>> +               renderer = new ComponentRenderer();
>> +       }
>> +
>> +       @After
>> +       public void destroy() {
>> +               renderer.destroy();
>> +       }
>> +
>> +       @Test
>> +       public void render()
>> +       {
>> +               CharSequence html = renderer.renderComponent(() -> new Label("id", "Hello renderer"));
>> +
>> +               assertEquals("Hello renderer", html.toString());
>> +       }
>> +}
>> \ No newline at end of file
>>
>
>