/*
* This file is part of the Echo Web Application Framework (hereinafter "Echo").
* Copyright (C) 2002-2009 NextApp, Inc.
*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*/
package nextapp.echo2.webcontainer;
import nextapp.echo2.app.Component;
import nextapp.echo2.app.update.ServerComponentUpdate;
/**
* A stateless peer object used to synchronize the state of a given type of
* <code>nextapp.echo2.app.Component</code> between the server and client.
* <p>
* A <code>ComponentSynchronizePeer</code> may implement optional interfaces such as
* <code>DomUpdateSupport</code> which enables rendering hierarchies of
* components directly to (X)HTML code. The optional
* <code>ActionProcessor</code> and <code>InputProcessor</code> interfaces
* may be used when the client-side rendering of the component may send back
* information to the server in response to user input.
* <p>
* A <b>single</b> instance of a given <code>ComponentSynchronizePeer</code>
* will be created to synchronize the state of <b>ALL</b> instances of
* a particular class of <code>Component</code>. Thus, it is not possible to
* store information about a component's state in this object (in contrast
* to Echo v1.x, where a peer was created for each component instance). Such
* rendering state information should now be stored in the
* <code>ContainerInstance</code>, see the
* <code>ContainerInstance.setRenderState()</code> method for details.
*/
public interface ComponentSynchronizePeer {
/**
* Returns the id of the HTML element in which the specified
* <code>component</code> should be rendered. The specified
* <code>component</code> must be an immediate child of
* an instance of the class of component that this peer supports.
* A child component's renderer may invoke this method to
* determine where it should place its rendered content.
*
* @param child a <code>Component</code> whose parent is of the type
* synchronized by this peer object.
* @return the id of the element which should contain the child
* component's rendered HTML.
*/
public String getContainerId(Component child);
/**
* Renders a client update which adds an HTML representation of the
* provided component to the client DOM as a child of the HTML element
* identified by <code>targetId</code>.
*
* @param rc the relevant <code>RenderContext</code>
* @param update the <code>ServerComponentUpdate</code> for which this
* operation is being performed
* @param targetId the id of the HTML element in which the component's
* HTML output should be rendered
* @param component the component to be rendered (this component must
* be of a type supported by this synchronization peer).
*/
public void renderAdd(RenderContext rc, ServerComponentUpdate update, String targetId, Component component);
/**
* Renders a client update to dispose of resources/listeners created
* for the specified component on the client. Operations such as
* removing event listeners on the client should be performed by the
* implementation. In cases where no such clean-up work is required, an
* empty implementation is sufficient. Note that the actual removal of
* HTML code will be performed by an ancestor component's
* <code>renderUpdate()</code> method being invoked, and thus
* implementations SHOULD NOT redundantly attempt
* to remove the HTML in this method.
* Implementations must handle the condition where the component to be
* disposed is not present in the client DOM, as this method may be invoked
* under such a condition.
*
* @param rc the relevant <code>RenderContext</code>
* @param update the <code>ServerComponentUpdate</code> for which this
* operation is being performed
*/
public void renderDispose(RenderContext rc, ServerComponentUpdate update, Component component);
/**
* Renders the specified <code>ServerComponentUpdate</code> by adding and
* removing children and updating properties of the specified
* <code>component</code>.
* <p>
* If the component is not a container, the implementation only needs to
* analyze the updated properties of the component. If the component is
* a container, the implementation should additionally query
* <code>update</code> for information about added children, removed
* children, and children with updated <code>LayoutData</code> states.
* <p>
* The implementation is responsible for rendering added children by
* obtaining their <code>ComponentSynchronizePeer</code>s and invoking their
* <code>renderAdd()</code> methods. Alternatively, if a child's
* <code>ComponentSynchronizePeer</code> implements the
* <code>DomUpdateSupport</code> interface, the implementation may invoke
* the child peer's <code>renderHtml()</code> method instead.
* <p>
* This method should return true if, in the course of its rendering
* operation, it has re-rendered the entire component hierarchy beneath
* the parent component of the update. Returning true will ensure
* that updates to descendants are NOT rendered. The method should
* return false in all cases if the component is not a container.
*
* @param rc the relevant <code>RenderContext</code>
* @param update the <code>ServerComponentUpdate</code> for which this
* operation is being performed
* @param targetId the id of the HTML element inside of which the
* components HTML code should be rendered.
* @return true if updates to descendants should NOT be performed
*/
public boolean renderUpdate(RenderContext rc, ServerComponentUpdate update, String targetId);
}