Package org.apache.wicket.request.target.component

Source Code of org.apache.wicket.request.target.component.BookmarkableListenerInterfaceRequestTarget

/*
* 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.target.component;

import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.RequestListenerInterface;
import org.apache.wicket.Session;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.protocol.http.request.WebRequestCodingStrategy;
import org.apache.wicket.util.string.AppendingStringBuffer;
import org.apache.wicket.util.string.Strings;

/**
* Request target for bookmarkable page links that also contain component path and interface name.
* This is used for stateless forms and stateless links.
*
* @author Matej Knopp
*/
public class BookmarkableListenerInterfaceRequestTarget extends BookmarkablePageRequestTarget
{
  private final String componentPath;
  private final String interfaceName;
  private final int versionNumber;

  /**
   * This constructor is called when a stateless link is clicked on but the page wasn't found in
   * the session. Then this class will recreate the page and call the interface method on the
   * component that is targeted with the component path.
   *
   * @param pageMapName
   * @param pageClass
   * @param pageParameters
   * @param componentPath
   * @param interfaceName
   * @param versionNumber
   */
  public BookmarkableListenerInterfaceRequestTarget(String pageMapName, Class pageClass,
    PageParameters pageParameters, String componentPath, String interfaceName, int versionNumber)
  {
    super(pageMapName, pageClass, pageParameters);
    this.componentPath = componentPath;
    this.interfaceName = interfaceName;
    this.versionNumber = versionNumber;
  }

  /**
   * This constructor is called for generating the urls (RequestCycle.urlFor()) So it will alter
   * the PageParameters to include the 2 org.apache.wicket params
   * {@link WebRequestCodingStrategy#BOOKMARKABLE_PAGE_PARAMETER_NAME} and
   * {@link WebRequestCodingStrategy#INTERFACE_PARAMETER_NAME}
   *
   * @param pageMapName
   * @param pageClass
   * @param pageParameters
   * @param component
   * @param listenerInterface
   */
  public BookmarkableListenerInterfaceRequestTarget(String pageMapName, Class pageClass,
    PageParameters pageParameters, Component component,
    RequestListenerInterface listenerInterface)
  {
    this(pageMapName, pageClass, pageParameters, component.getPath(), listenerInterface
      .getName(), component.getPage().getCurrentVersionNumber());

    int version = component.getPage().getCurrentVersionNumber();
    setPage(component.getPage());

    // add the wicket:interface param to the params.
    // pagemap:(pageid:componenta:componentb:...):version:interface:behavior:urlDepth
    AppendingStringBuffer param = new AppendingStringBuffer(4 + componentPath.length() +
      interfaceName.length());
    if (pageMapName != null)
    {
      param.append(pageMapName);
    }
    param.append(Component.PATH_SEPARATOR);
    param.append(getComponentPath());
    param.append(Component.PATH_SEPARATOR);
    if (version != 0)
    {
      param.append(version);
    }
    // Interface
    param.append(Component.PATH_SEPARATOR);
    param.append(getInterfaceName());

    // Behavior (none)
    param.append(Component.PATH_SEPARATOR);

    // URL depth (not required)
    param.append(Component.PATH_SEPARATOR);

    pageParameters.put(WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME, param.toString());
  }

  public void processEvents(RequestCycle requestCycle)
  {
    Page page = getPage();
    if (page == null)
    {
      page = Session.get().getPage(getPageMapName(), componentPath, -1);
      if (page != null)
      {
        setPage(page);
      }
      else if (page == null)
      {
        page = getPage(requestCycle);
      }
    }

    final String pageRelativeComponentPath = Strings.afterFirstPathComponent(componentPath,
      Component.PATH_SEPARATOR);
    Component component = page.get(pageRelativeComponentPath);
    if (component == null)
    {
      // this is quite a hack to get components in repeater work.
      // But it still can fail if the repeater is a paging one or on every render
      // it will generate new index for the items...
      page.beforeRender();
      component = page.get(pageRelativeComponentPath);
      if (component == null)
      {
        throw new WicketRuntimeException(
          "unable to find component with path " +
            pageRelativeComponentPath +
            " on stateless page " +
            page +
            " it could be that the component is inside a repeater make your component return false in getStatelessHint()");
      }
    }
    RequestListenerInterface listenerInterface = RequestListenerInterface
      .forName(interfaceName);
    if (listenerInterface == null)
    {
      throw new WicketRuntimeException("unable to find listener interface " + interfaceName);
    }
    listenerInterface.invoke(page, component);
  }

  public void respond(RequestCycle requestCycle)
  {
    Page page = getPage(requestCycle);
    // if the listener call wanted to redirect
    // then do that if the page is not stateless.
    if (requestCycle.isRedirect() && !page.isPageStateless())
    {
      requestCycle.redirectTo(page);
    }
    else
    {
      // else render the page directly
      page.renderPage();
    }
  }

  /**
   * @return The component path.
   */
  public String getComponentPath()
  {
    return componentPath;
  }

  /**
   * @return The interface name
   */
  public String getInterfaceName()
  {
    return interfaceName;
  }
}
TOP

Related Classes of org.apache.wicket.request.target.component.BookmarkableListenerInterfaceRequestTarget

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.