Package org.apache.wicket.ajax

Source Code of org.apache.wicket.ajax.XmlAjaxResponse

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

import java.util.Collection;

import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.request.Response;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.http.WebResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* An AbstractAjaxResponse that serializes itself to XML.
* <p>
*     The elements of such response are:
*     <ul>
*         <li>priority-evaluate - an item of the prepend JavaScripts</li>
*         <li>component - the markup of the updated component</li>
*         <li>evaluate - an item of the onDomReady and append JavaScripts</li>
*         <li>header-contribution - all HeaderItems which have been contributed in components'
*         and their behaviors' #renderHead(Component, IHeaderResponse)</li>
*     </ul>
* </p>
*/
abstract class XmlAjaxResponse extends AbstractAjaxResponse
{
  private static final Logger LOG = LoggerFactory.getLogger(XmlAjaxResponse.class);

  XmlAjaxResponse(final Page page)
  {
    super(page);
  }

  @Override
  public void setContentType(WebResponse response, String encoding)
  {
    response.setContentType("text/xml; charset=" + encoding);
  }

  @Override
  protected void writeHeader(Response response, String encoding)
  {
    response.write("<?xml version=\"1.0\" encoding=\"");
    response.write(encoding);
    response.write("\"?>");
    response.write("<ajax-response>");
  }

  @Override
  protected void writeComponent(Response response, String markupId, Component component, String encoding)
  {
    if (component.getRenderBodyOnly() == true)
    {
      throw new IllegalStateException(
          "Ajax render cannot be called on component that has setRenderBodyOnly enabled. Component: " +
              component.toString());
    }

    component.setOutputMarkupId(true);

    // substitute our encoding response for the real one so we can capture
    // component's markup in a manner safe for transport inside CDATA block
    encodingBodyResponse.reset();
    RequestCycle.get().setResponse(encodingBodyResponse);

    // Initialize temporary variables
    final Page page = component.findParent(Page.class);
    if (page == null)
    {
      // dont throw an exception but just ignore this component, somehow
      // it got removed from the page.
      LOG.debug("component: " + component + " with markupid: " + markupId +
          " not rendered because it was already removed from page");
      return;
    }

    page.startComponentRender(component);

    try
    {
      component.prepareForRender();

      // render any associated headers of the component
      writeHeaderContribution(response, component);
    }
    catch (RuntimeException e)
    {
      try
      {
        component.afterRender();
      }
      catch (RuntimeException e2)
      {
        // ignore this one could be a result off.
      }
      // Restore original response
      RequestCycle.get().setResponse(response);
      encodingBodyResponse.reset();
      throw e;
    }

    try
    {
      component.render();
    }
    catch (RuntimeException e)
    {
      RequestCycle.get().setResponse(response);
      encodingBodyResponse.reset();
      throw e;
    }

    page.endComponentRender(component);

    // Restore original response
    RequestCycle.get().setResponse(response);

    response.write("<component id=\"");
    response.write(markupId);
    response.write("\" ");
    if (encodingBodyResponse.isContentsEncoded())
    {
      response.write(" encoding=\"");
      response.write(getEncodingName());
      response.write("\" ");
    }
    response.write("><![CDATA[");
    response.write(encodingBodyResponse.getContents());
    response.write("]]></component>");

    encodingBodyResponse.reset();
  }

  @Override
  protected void writeFooter(Response response, String encoding)
  {
    response.write("</ajax-response>");
  }

  @Override
  protected void writeHeaderContribution(Response response)
  {
    if (encodingHeaderResponse.getContents().length() != 0)
    {
      response.write("<header-contribution");

      if (encodingHeaderResponse.isContentsEncoded())
      {
        response.write(" encoding=\"");
        response.write(getEncodingName());
        response.write("\" ");
      }

      // we need to write response as CDATA and parse it on client,
      // because konqueror crashes when there is a <script> element
      response.write("><![CDATA[<head xmlns:wicket=\"http://wicket.apache.org\">");
      response.write(encodingHeaderResponse.getContents());
      response.write("</head>]]>");
      response.write("</header-contribution>");
    }
  }

  @Override
  protected void writeNormalEvaluations(final Response response, final Collection<CharSequence> scripts)
  {
    writeEvaluations(response, "evaluate", scripts);

  }

  @Override
  protected void writePriorityEvaluations(Response response, Collection<CharSequence> scripts)
  {
    writeEvaluations(response, "priority-evaluate", scripts);
  }

  private void writeEvaluations(final Response response, String elementName, Collection<CharSequence> scripts)
  {
    for (CharSequence script : scripts)
    {
      writeEvaluation(elementName, response, script);
    }
  }

  /**
  * @param invocation
  *            type of invocation tag, usually {@literal evaluate} or
  *            {@literal priority-evaluate}
  * @param response
  * @param js
  */
  private void writeEvaluation(final String invocation, final Response response, final CharSequence js)
  {
    boolean encoded = false;
    CharSequence javascript = js;

    // encode the response if needed
    if (needsEncoding(js))
    {
      encoded = true;
      javascript = encode(js);
    }

    response.write("<");
    response.write(invocation);
    if (encoded)
    {
      response.write(" encoding=\"");
      response.write(getEncodingName());
      response.write("\"");
    }
    response.write(">");

    response.write("<![CDATA[");
    response.write(javascript);
    response.write("]]>");

    response.write("</");
    response.write(invocation);
    response.write(">");

    encodingBodyResponse.reset();
  }

}
TOP

Related Classes of org.apache.wicket.ajax.XmlAjaxResponse

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.