All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.contextfw.web.application.component.Component Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2010 Marko Lavikainen
 *
 * Licensed 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 net.contextfw.web.application.component;

import java.util.HashSet;
import java.util.Set;

import net.contextfw.web.application.WebApplicationException;
import net.contextfw.web.application.internal.component.ComponentBuilder;

/**
 * The base class of a component
 * 
 */
@Buildable
public abstract class Component {

    private final Set partialUpdates = new HashSet();
    private String partialUpdateName;
    private RefreshMode refreshMode = RefreshMode.NONE;
    private Component parent = null;
    private Set children = null;
    private Set waitingToRegister = null;

    private boolean enabled = true;

    private enum RefreshMode {
        NONE, PASS, UPDATE, PARTIAL_UPDATE
    };

    @Attribute
    private String id;

    /**
     * Assigns an id for the component
     * 
     * 

* Id is generated automatically by the web framework so setting an id is * not necesssary. the id is of a form el[n] where * [n] is an incrementing value. *

*

* It is also possible to set a custom id, but to be sure that setting * succceeds it must be don during initialization. *

*/ public void setId(String id) { if (this.id != null) { throw new WebApplicationException("Component id can be set only once"); } this.id = id; } /** * Get's component id * *

* The id is null initially, but when component is * registered to thes system id is generated automatically. This means that * id may not be in use at initialization phase and developer * should not rely on using id in class properties. *

*/ public String getId() { return id; } /** * Adds a component to be a child of this component. * *

* Registering child components is a mandatory task so that the framework is * able to register all components in the page and assign proper ids for * them. *

* *

* Component registering is lazy. If parent component has not yet been * registered then registering for child components is delayd untit parent * is also registered. *

* * @param * Component type * @param el * The Component * @return The added component */ public T registerChild(T el) { if (children == null) { children = new HashSet(); waitingToRegister = new HashSet(); } children.add(el); el.parent = this; if (bubbleRegisterUp(el)) { el.registerChildren(); } else { waitingToRegister.add(el); } return el; } private void registerChildren() { if (waitingToRegister != null) { for (Component comp : waitingToRegister) { registerChild(comp); } waitingToRegister.clear(); } } /** * For internal use only */ protected boolean bubbleRegisterUp(Component el) { if (parent != null) { return parent.bubbleRegisterUp(el); } else { return false; } } /** * For internal use only */ protected void bubbleUnregisterUp(Component el) { if (parent != null) { parent.bubbleUnregisterUp(el); } } /** * Removes component (this) from its parent, if parent exists. */ public void detach() { if (parent != null) { parent.unregisterChild(this); } } /** * Removes child component from the framework */ public void unregisterChild(Component el) { if (children != null) { children.remove(el); bubbleUnregisterUp(el); el.parent = null; } } /** * Refreshes component state to web client * *

* When component needs to update its state on web client, this method must * be called. Framework recognizes the request and creates property update * during rendering phase. *

* *

* Note! If paren component also requests update, then the update of * this component is canceled, because in normal circumstances this * component if fully redrawn by the parent component. *

*/ public void refresh() { refresh(RefreshMode.UPDATE); } private void refresh(RefreshMode mode) { if (id != null) { refreshMode = mode; Component p = parent; while (p != null) { if (p.refreshMode == RefreshMode.NONE) { p.refreshMode = RefreshMode.PASS; p = p.parent; } else { p = null; } } } } /** * For internal use only */ public final void buildComponentUpdate(DOMBuilder domBuilder, ComponentBuilder builder) { if (refreshMode == RefreshMode.UPDATE) { builder.buildUpdate(domBuilder, this, "update"); } else if (refreshMode == RefreshMode.PARTIAL_UPDATE) { builder.buildPartialUpdate(domBuilder, this, partialUpdateName, partialUpdates); } if ((refreshMode == RefreshMode.PASS || refreshMode == RefreshMode.PARTIAL_UPDATE) && children != null) { for (Component child : children) { child.buildComponentUpdate(domBuilder, builder); } } clearCascadedUpdate(); } /** * Requests a partial update for component * *

* When there is a need to only partially update component, then this method * is used *

* * * @param buildName * @param updates */ public void partialRefresh(String buildName, String... updates) { if (partialUpdates != null && refreshMode != RefreshMode.UPDATE) { this.partialUpdateName = buildName; for (String partialUpdate : updates) { partialUpdates.add(partialUpdate); } partialUpdates.add("id"); refresh(RefreshMode.PARTIAL_UPDATE); } } /** * For internal use only */ public void clearCascadedUpdate() { if (refreshMode == RefreshMode.NONE) { return; } refreshMode = RefreshMode.NONE; if (children != null) { for (Component child : children) { child.clearCascadedUpdate(); } } partialUpdates.clear(); partialUpdateName = null; } /** * Defines if this component is enabled or disabled. * *

* If component is disabled then it is not added to DOM-tree during * rendering phase. Also disabled component does not listen remote calls. *

* * @param enabled */ public void setEnabled(boolean enabled) { this.enabled = enabled; } public boolean isEnabled() { return enabled; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy