Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  // Copyright 2004, 2005 The Apache Software Foundation
  //
  // 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 org.apache.tapestry;
 
 import  org.apache.hivemind.ApplicationRuntimeException;
 import  org.apache.hivemind.Messages;
 import  org.apache.hivemind.impl.BaseLocatable;
 import  org.apache.hivemind.util.Defense;
 
 import java.util.*;

Abstract base class implementing the IComponentinterface.

Author(s):
Howard Lewis Ship
 
 
 public abstract class AbstractComponent extends BaseLocatable implements IDirectEvent, Component {
     
     private static final int MAP_SIZE = 5;
     
     private static final int BODY_INIT_SIZE = 5;

    
Used in place of JDK 1.3's Collections.EMPTY_MAP (which is not available in JDK 1.2).
 
 
     private static final Map EMPTY_MAP = Collections.unmodifiableMap(new HashMap(1));
    
    
The page that contains the component, possibly itself (if the component is in fact, a page).
 
 
     private IPage _page;

    
The component which contains the component. This will only be null if the component is actually a page.
 
 
     private IComponent _container;

    
The simple id of this component.
 
 
     private String _id;
    
    
The fully qualified id of this component. This is calculated the first time it is needed, then cached for later.
 
     private String _idPath;

    
The html tag name that was used to reference the component.
 
     private String _templateTagName;
    
    
A Mapof all bindings (for which there isn't a corresponding JavaBeans property); the keys are the names of formal and informal parameters.
 
 
     private Map _bindings;
 
     private Map _components;
 
     private INamespace _namespace;

    
The number of IRenderobjects in the body of this component.
 
 
     protected int _bodyCount = 0;

    
An aray of elements in the body of this component.
    protected IRender[] _body;

    
The components' asset map.
    private Map _assets;

    
A mapping that allows public instance methods to be dressed up as IActionListener listener objects.

Since:
1.0.2
    private ListenerMap _listeners;

    
A bean provider; these are lazily created as needed.

Since:
1.0.4
    private IBeanProvider _beans;

    
Returns true if the component is currently rendering.

Since:
4.0
See also:
prepareForRender(IRequestCycle)
cleanupAfterRender(IRequestCycle)
    private boolean _rendering;

    

Since:
4.0
    private boolean _active;

    

Since:
4.0
    private boolean _hasEvents;
    
    public void addAsset(String nameIAsset asset)
    {
        Defense.notNull(name"name");
        Defense.notNull(asset"asset");
        checkActiveLock();
        if ( == null)
             = new HashMap();
        .put(nameasset);
    }
    public void addComponent(IComponent component)
    {
        Defense.notNull(component"component");
        checkActiveLock();
        if ( == null)
             = new HashMap();
        
        .put(component.getId(), component);
    }

    
Adds an element (which may be static text or a component) as a body element of this component. Such elements are rendered by renderBody(IMarkupWriter, IRequestCycle).

Since:
2.2
    public void addBody(IRender element)
    {
        Defense.notNull(element"element");
        
        // Should check the specification to see if this component
        // allows body. Curently, this is checked by the component
        // in render(), which is silly.
        if ( == null)
        {
             = new IRender[];
            [0] = element;
             = 1;
            return;
        }
        // No more room? Make the array bigger.
        if ( == .)
        {
            IRender[] newWrapped;
            newWrapped = new IRender[. * 2];
            System.arraycopy(, 0, newWrapped, 0, );
             = newWrapped;
        }
        [++] = element;
    }
    
    public IRender[] getContainedRenderers()
    {
        return ;
    }
    public IRender[] getInnerRenderers()
    {
        return null;
    }
    public boolean hasEvents()
    {
        return ;
    }
    public void setHasEvents(boolean hasEvents)
    {
         = hasEvents;
    }

    
Invokes finishLoad(). Subclasses may overide as needed, but must invoke this implementation. BaseComponent loads its HTML template.
    public void finishLoad(IRequestCycle cycleIPageLoader loaderIComponentSpecification specification)
    {
        finishLoad();
    }

    
Converts informal parameters into additional attributes on the curently open tag.

Invoked from subclasses to allow additional attributes to be specified within a tag (this works best when there is a one-to-one corespondence between an IComponentand a HTML element.

Iterates through the bindings for this component. Filters out bindings for formal parameters.

For each acceptible key, the value is extracted using IBinding.getObject(). If the value is null, no attribute is written.

If the value is an instance of IAsset, then IAsset.buildURL() is invoked to convert the asset to a URL.

Finally, IMarkupWriter.attribute(String,String)is invoked with the value (or the URL).

The most common use for informal parameters is to support the HTML class attribute (for use with cascading style sheets) and to specify JavaScript event handlers.

Components are only required to generate attributes on the result phase; this can be skipped during the rewind phase.

    protected void renderInformalParameters(IMarkupWriter writerIRequestCycle cycle)
    {
        String attribute;
        if ( == null)
            return;
        Iterator i = .entrySet().iterator();
        while (i.hasNext())
        {
            Map.Entry entry = (Map.Entryi.next();
            String name = (Stringentry.getKey();
            if (isFormalParameter(name))
                continue;
            IBinding binding = (IBindingentry.getValue();
            Object value = binding.getObject();
            if (value == null)
                continue;
            if (value instanceof IAsset)
            {
                IAsset asset = (IAssetvalue;
                // Get the URL of the asset and insert that.
                attribute = asset.buildURL();
            }
            else
                attribute = value.toString();
            
            writer.attribute(nameattribute);
        }
    }
    
    
Renders the (unique) id attribute for this component.

Parameters:
writer The writer to render attribute in.
cycle The current request.
    protected void renderIdAttribute(IMarkupWriter writerIRequestCycle cycle)
    {
        String id = getClientId();
        
        if (id != null)
            writer.attribute("id"id);
    }
    
    

Since:
4.0
    private boolean isFormalParameter(String name)
    {
        Defense.notNull(name"name");
        
        return getSpecification().getParameter(name) != null;
    }
    
    
Returns the named binding, or null if it doesn't exist.

In Tapestry 3.0, it was possible to force a binding to be stored in a component property by defining a concrete or abstract property named "nameBinding" of type IBinding. This has been removed in release 4.0 and bindings are always stored inside a Map of the component.

See also:
setBinding(String,IBinding)
    public IBinding getBinding(String name)
    {
        Defense.notNull(name"name");
        if ( == null)
            return null;
        return (IBinding.get(name);
    }

    
Returns true if the specified parameter is bound.

Since:
4.0
    public boolean isParameterBound(String parameterName)
    {
        Defense.notNull(parameterName"parameterName");
        return  != null && .containsKey(parameterName);
    }
    public IComponent getComponent(String id)
    {
        Defense.notNull(id"id");
        IComponent result = null;
        if ( != null)
            result = (IComponent.get(id);
        if (result == null)
            throw new ApplicationRuntimeException(Tapestry.format("no-such-component"thisid),
                    thisnullnull);
        return result;
    }
    public IComponent getContainer()
    {
        return ;
    }
    public void setContainer(IComponent value)
    {
        checkActiveLock();
        if ( != null)
            throw new ApplicationRuntimeException(Tapestry
                    .getMessage("AbstractComponent.attempt-to-change-container"));
         = value;
    }

    
Returns the name of the page, a slash, and this component's id path. Pages are different, they override this method to simply return their page name.

See also:
getIdPath()
    public String getExtendedId()
    {
        if ( == null)
            return null;
        
        return .getPageName() + "/" + getIdPath();
    }

    

Since:
4.1
    
    public String getSpecifiedId()
    {
        String id = getBoundId();
        
        if (id != null)
            return id;
        
        return getId();
    }
    
    public String getId()
    {
        return ;
    }
    public void setId(String value)
    {
        if ( != null)
            throw new ApplicationRuntimeException(Tapestry.getMessage("AbstractComponent.attempt-to-change-component-id"));
         = value;
    }
    
    public String getIdPath()
    {
        if ( != null)
            return ;
        
        String containerIdPath;
        
        if ( == null)
            throw new NullPointerException(Tapestry.format("AbstractComponent.null-container"this));
        
        containerIdPath = .getIdPath();
        
        if (containerIdPath == null)
             = ;
        else
             = containerIdPath + "." + ;
        return ;
    }
    
    

Since:
4.1
    public abstract String getClientId();
    
    public abstract void setClientId(String id);
    
    
    public String peekClientId()
    {
        if (getPage() == null)
            return null;
        
        String id = getSpecifiedId();
        if (id == null)
            return null;
        
        return getPage().getRequestCycle().peekUniqueId(TapestryUtils.convertTapestryIdToNMToken(id));
    }
    
    protected void generateClientId()
    {
        String id = getSpecifiedId();
        
        if (id != null && getPage() != null && getPage().getRequestCycle() != null)
             setClientId(getPage().getRequestCycle().getUniqueId(TapestryUtils.convertTapestryIdToNMToken(id)));
    }
    
    protected String getBoundId()
    {
        if ( == null)
            return null;
        
        IBinding id = (IBinding).get("id");
        
        if (id == null || id.getObject() == null)
            return null;
        
        return id.getObject().toString();
    }
    
    public String getTemplateTagName()
    {
        return ;
    }
    
    
    public void setTemplateTagName(String tag)
    {
        if ( != null)
            throw new ApplicationRuntimeException(Tapestry.getMessage("AbstractComponent.attempt-to-change-template-tag"));
        
         = tag;
    }
    public IPage getPage()
    {
        return ;
    }
    public void setPage(IPage value)
    {
        if ( != null)
            throw new ApplicationRuntimeException(Tapestry.getMessage("AbstractComponent.attempt-to-change-page"));
         = value;
    }

    
Renders all elements wrapped by the receiver.
    public void renderBody(IMarkupWriter writerIRequestCycle cycle)
    {
        for (int i = 0; i < i++)
            cycle.getResponseBuilder().render(writer[i], cycle);
    }

    
Adds the binding with the given name, replacing any existing binding with that name.

See also:
getBinding(String)
    public void setBinding(String nameIBinding binding)
    {
        Defense.notNull(name"name");
        Defense.notNull(binding"binding");
        if ( == null)
             = new HashMap();
        .put(namebinding);
    }
    public String toString()
    {
        StringBuffer buffer;
        
        buffer = new StringBuffer(super.toString());
        buffer.append('[');
        buffer.append(getExtendedId());
        buffer.append(']');
        return buffer.toString();
    }

    
Returns an unmodifiable Mapof components, keyed on component id. Never returns null, but may return an empty map. The returned map is immutable.
    public Map getComponents()
    {
        if ( == null)
            return ;
        return ;
    }
    public Map getAssets()
    {
        if ( == null)
            return ;
        return ;
    }
    public IAsset getAsset(String name)
    {
        if ( == null)
            return null;
        return (IAsset.get(name);
    }
    public Collection getBindingNames()
    {
        // If no conainer, i.e. a page, then no bindings.
        if ( == null)
            return null;
        HashSet result = new HashSet();
        // All the informal bindings go into the bindings Map.
        if ( != null)
            result.addAll(.keySet());
        // Now, iterate over the formal parameters and add the formal parameters
        // that have a binding.
        List names = getSpecification().getParameterNames();
        int count = names.size();
        for (int i = 0; i < counti++)
        {
            String name = (Stringnames.get(i);
            if (result.contains(name))
                continue;
            if (getBinding(name) != null)
                result.add(name);
        }
        return result;
    }

    
Returns an unmodifiable Mapof all bindings for this component.

Since:
1.0.5
    public Map getBindings()
    {
        if ( == null)
            return ;
        return ;
    }

    
Returns a ListenerMap for the component. A ListenerMap contains a number of synthetic read-only properties that implement the IActionListenerinterface, but in fact, cause public instance methods to be invoked.

Since:
1.0.2
    public ListenerMap getListeners()
    {
        // This is what's called a violation of the Law of Demeter!
        // This should probably be converted over to some kind of injection, as with
        // getMessages(), etc.
        if ( == null)
        return ;
    }

    
Returns the IBeanProviderfor this component. This is lazily created the first time it is needed.

Since:
1.0.4
    public IBeanProvider getBeans()
    {
        if ( == null)
             = new BeanProvider(this);
        return ;
    }

    
Invoked, as a convienience, from finishLoad(IRequestCycle, IPageLoader, IComponentSpecification). This implemenation does nothing. Subclasses may override without invoking this implementation.

Since:
1.0.5
    protected void finishLoad()
    {
    }

    
The main method used to render the component. Invokes prepareForRender(IRequestCycle), then renderComponent(IMarkupWriter, IRequestCycle). cleanupAfterRender(IRequestCycle)is invoked in a finally block.

Subclasses should not override this method; instead they will implement renderComponent(IMarkupWriter, IRequestCycle).

Since:
2.0.3
    public final void render(IMarkupWriter writerIRequestCycle cycle)
    {
        try
        {
             = true;
            
            cycle.renderStackPush(this);
            
            generateClientId();
            
            prepareForRender(cycle);
            
            renderComponent(writercycle);
        }
        finally
        {
             = false;
            
            cleanupAfterRender(cycle);
            
            cycle.renderStackPop();
        }
    }

    
Invoked by render(IMarkupWriter, IRequestCycle)to prepare the component to render. This implementation sets JavaBeans properties from matching bound parameters. The default implementation of this method is empty.

Since:
2.0.3
    protected void prepareForRender(IRequestCycle cycle)
    {
    }

    
Invoked by render(IMarkupWriter, IRequestCycle)to actually render the component (with any parameter values already set). This is the method that subclasses must implement.

Since:
2.0.3
    protected abstract void renderComponent(IMarkupWriter writerIRequestCycle cycle);
    
    
Invoked by render(IMarkupWriter, IRequestCycle)after the component renders.

Since:
2.0.3
    protected void cleanupAfterRender(IRequestCycle cycle)
    {
        getRenderWorker().renderComponent(cyclethis);
    }
    public INamespace getNamespace()
    {
        return ;
    }
    public void setNamespace(INamespace namespace)
    {
         = namespace;
    }

    
Returns the body of the component, the element (which may be static HTML or components) that the component immediately wraps. May return null. Do not modify the returned array. The array may be padded with nulls.

Since:
2.3
See also:
getBodyCount()
    public IRender[] getBody()
    {
        return ;
    }

    
Returns the active number of elements in the the body, which may be zero.

Since:
2.3
See also:
getBody()
    public int getBodyCount()
    {
        return ;
    }

    
Empty implementation of org.apache.tapestry.event.PageRenderListener.pageEndRender(PageEvent). This allows classes to implement org.apache.tapestry.event.PageRenderListenerand only implement the org.apache.tapestry.event.PageRenderListener.pageBeginRender(PageEvent)method.

Since:
3.0
    public void pageEndRender(PageEvent event)
    {
    }

    

Since:
4.0
    public final boolean isRendering()
    {
        return ;
    }

    
Returns true if the component has been transitioned into its active state by invoking enterActiveState().

Since:
4.0
    protected final boolean isInActiveState()
    {
        return ;
    }

    

Since:
4.0
    public final void enterActiveState()
    {
         = true;
    }

    

Since:
4.0
    protected final void checkActiveLock()
    {
        if ()
            throw new UnsupportedOperationException(TapestryMessages.componentIsLocked(this));
    }
    public Messages getMessages()
    {
        throw new IllegalStateException(TapestryMessages.providedByEnhancement("getMessages"));
    }
    {
        throw new IllegalStateException(TapestryMessages.providedByEnhancement("getSpecification"));
    }

    

Since:
4.0
    {
        return ;
    }

    

Since:
4.0
    public final void setContainedComponent(IContainedComponent containedComponent)
    {
        Defense.notNull(containedComponent"containedComponent");
        if ( != null)
            throw new ApplicationRuntimeException(TapestryMessages
                    .attemptToChangeContainedComponent(this));
         = containedComponent;
    }
    
    
    {
        throw new IllegalStateException(TapestryMessages.providedByEnhancement("getEventInvoker"));
    }
    
    
    public void triggerEvent(IRequestCycle cycleBrowserEvent event)
    {
        getEventInvoker().invokeListeners(thiscycleevent);
    }
    
    {
        throw new IllegalStateException(TapestryMessages.providedByEnhancement("getRenderWorker"));
    }
    
    
    public boolean isStateful()
    {
        return false;
    }
    
    
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getClientId() == null) ? 0 : getClientId().hashCode());
        result = prime * result + (( == null) ? 0 : .hashCode());
        return result;
    }
    
    
    public boolean equals(Object obj)
    {
        if (this == objreturn true;
        if (obj == nullreturn false;
        if (getClass() != obj.getClass()) return false;
        final AbstractComponent other = (AbstractComponentobj;
        if (getClientId() == null) {
            if (other.getClientId() != nullreturn false;
        } else if (!getClientId().equals(other.getClientId())) return false;
        if ( == null) {
            if (other._id != nullreturn false;
        } else if (!.equals(other._id)) return false;
        return true;
    }
New to GrepCode? Check out our FAQ X