Class MarkupContainer

  • All Implemented Interfaces:
    Serializable, Iterable<Component>, IEventSink, IEventSource, IFeedbackContributor, IConverterLocator, IMetadataContext<Serializable,​Component>, IHeaderContributor, IRequestableComponent, IHierarchical<Component>, IClusterable
    Direct Known Subclasses:
    AbstractOutputTransformerContainer, Page, WebMarkupContainer

    public abstract class MarkupContainer
    extends Component
    implements Iterable<Component>
    A MarkupContainer holds a map of child components.
    • Children - Children can be added by calling the add(Component...) method, and they can be looked up using a colon separated path. For example, if a container called "a" held a nested container "b" which held a nested component "c", then a.get("b:c") would return the Component with id "c". The number of children in a MarkupContainer can be determined by calling size(), and the whole hierarchy of children held by a MarkupContainer can be traversed by calling visitChildren(), passing in an implementation of IVisitor.
    • Markup Rendering - A MarkupContainer also holds/references associated markup which is used to render the container. As the markup stream for a container is rendered, component references in the markup are resolved by using the container to look up Components in the container's component map by id. Each component referenced by the markup stream is given an opportunity to render itself using the markup stream.

    Components may alter their referring tag, replace the tag's body or insert markup after the tag. But components cannot remove tags from the markup stream. This is an important guarantee because graphic designers may be setting attributes on component tags that affect visual presentation.

    The type of markup held in a given container subclass can be determined by calling getMarkupType(). Markup is accessed via a MarkupStream object which allows a component to traverse ComponentTag and RawMarkup MarkupElements while rendering a response. Markup in the stream may be HTML or some other kind of markup, such as VXML, as determined by the specific container subclass.

    A markup stream may be directly associated with a container via setMarkupStream. However, a container which does not have a markup stream (its getMarkupStream() returns null) may inherit a markup stream from a container above it in the component hierarchy. The Component.findMarkupStream() method will locate the first container at or above this container which has a markup stream.

    All Page containers set a markup stream before rendering by calling the method getAssociatedMarkupStream(boolean) to load the markup associated with the page. Since Page is at the top of the container hierarchy, it is guaranteed that Component.findMarkupStream() will always return a valid markup stream.

    Author:
    Jonathan Locke
    See Also:
    MarkupStream, Serialized Form
    • Method Detail

      • add

        public MarkupContainer add​(Component... children)
        Adds the child component(s) to this container.
        Parameters:
        children - The child(ren) to add.
        Returns:
        This
        Throws:
        IllegalArgumentException - Thrown if a child with the same id is replaced by the add operation.
      • addOrReplace

        public MarkupContainer addOrReplace​(Component... children)
        Replaces a child component of this container with another or just adds it in case no child with the same id existed yet.
        Parameters:
        children - The child(ren) to be added or replaced
        Returns:
        this markup container
      • autoAdd

        public final boolean autoAdd​(Component component,
                                     MarkupStream markupStream)
        This method allows a component to be added by an auto-resolver such as AutoLinkResolver. While the component is being added, the component's FLAG_AUTO boolean is set. The isAuto() method of Component returns true if a component or any of its parents has this bit set. When a component is added via autoAdd(), the logic in Page that normally (a) checks for modifications during the rendering process, and (b) versions components, is bypassed if Component.isAuto() returns true.

        The result of all this is that components added with autoAdd() are free from versioning and can add their own children without the usual exception that would normally be thrown when the component hierarchy is modified during rendering.

        Parameters:
        component - The component to add
        markupStream - Null, if the parent container is able to provide the markup. Else the markup stream to be used to render the component.
        Returns:
        True, if component has been added
      • contains

        public boolean contains​(Component component,
                                boolean recurse)
        Parameters:
        component - The component to check
        recurse - True if all descendents should be considered
        Returns:
        True if the component is contained in this container
      • get

        public final Component get​(String path)
        Get a child component by looking it up with the given path.

        A component path consists of component ids separated by colons, e.g. "b:c" identifies a component "c" inside container "b" inside this container.

        Specified by:
        get in interface IRequestableComponent
        Overrides:
        get in class Component
        Parameters:
        path - path to component
        Returns:
        The component at the path
      • getAssociatedMarkupStream

        public MarkupStream getAssociatedMarkupStream​(boolean throwException)
        Gets a fresh markup stream that contains the (immutable) markup resource for this class.
        Parameters:
        throwException - If true, throw an exception, if markup could not be found
        Returns:
        A stream of MarkupElement elements
      • getAssociatedMarkup

        public Markup getAssociatedMarkup()
        Gets a fresh markup stream that contains the (immutable) markup resource for this class.
        Returns:
        A stream of MarkupElement elements. Null if not found.
      • getMarkup

        public IMarkupFragment getMarkup​(Component child)
        Get the markup of the child.
        Parameters:
        child - The child component. If null, the container's markup will be returned. See Border, Panel or Enclosure where getMarkup(null) != getMarkup().
        Returns:
        The child's markup
        See Also:
        Component.getMarkup()
      • getMarkupType

        public MarkupType getMarkupType()
        Get the type of associated markup for this component. The markup type for a component is independent of whether or not the component actually has an associated markup resource file (which is determined at runtime).
        Returns:
        The type of associated markup for this component (for example, "html", "wml" or "vxml"). If there is no markup type for a component, null may be returned, but this means that no markup can be loaded for the class. Null is also returned if the component, or any of its parents, has not been added to a Page.
      • internalAdd

        public void internalAdd​(Component child)
        THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT. Adds a child component to this container.
        Parameters:
        child - The child
        Throws:
        IllegalArgumentException - Thrown if a child with the same id is replaced by the add operation.
      • iterator

        public Iterator<Componentiterator()
        Gives an iterator that allow you to iterate through the children of this markup container in the order the children were added. The iterator supports additions and removals from the list of children during iteration.
        Specified by:
        iterator in interface Iterable<Component>
        Returns:
        Iterator that iterates through children in the order they were added
      • iterator

        public final Iterator<Componentiterator​(Comparator<Component> comparator)
        Creates an iterator that iterates over children in the order specified by comparator. This works on a copy of the children list.
        Parameters:
        comparator - The comparator
        Returns:
        Iterator that iterates over children in the order specified by comparator
      • remove

        public MarkupContainer remove​(Component component)
        Removes a component from the children identified by the component.getId()
        Parameters:
        component - Component to remove from this container
        Returns:
        this for chaining
      • remove

        public MarkupContainer remove​(String id)
        Removes the given component
        Parameters:
        id - The id of the component to remove
        Returns:
        this for chaining
      • renderAssociatedMarkup

        @Deprecated(since="9.10.0",
                    forRemoval=true)
        public final void renderAssociatedMarkup​(String openTagName,
                                                 String exceptionMessage)
        Deprecated, for removal: This API element is subject to removal in a future version.
        Use renderAssociatedMarkup(String). The exceptionMessage parameter is ignored.
        Renders the entire associated markup for a container such as a Border or Panel. Any leading or trailing raw markup in the associated markup is skipped.
        Parameters:
        openTagName - the tag to render the associated markup for
        exceptionMessage - ignored
      • renderAssociatedMarkup

        public final void renderAssociatedMarkup​(String openTagName)
        Renders the entire associated markup for a container such as a Border or Panel. Any leading or trailing raw markup in the associated markup is skipped.
        Parameters:
        openTagName - the tag to render the associated markup for
      • setDefaultModel

        public MarkupContainer setDefaultModel​(IModel<?> model)
        Description copied from class: Component
        Sets the given model.

        WARNING: DO NOT OVERRIDE THIS METHOD UNLESS YOU HAVE A VERY GOOD REASON FOR IT. OVERRIDING THIS MIGHT OPEN UP SECURITY LEAKS AND BREAK BACK-BUTTON SUPPORT.

        Overrides:
        setDefaultModel in class Component
        Parameters:
        model - The model
        Returns:
        This
      • size

        public int size()
        Get the number of children in this container.
        Returns:
        Number of children in this container
      • toString

        public String toString()
        Description copied from class: Component
        Gets the string representation of this component.
        Overrides:
        toString in class Component
        Returns:
        The path to this component
      • toString

        public String toString​(boolean detailed)
        Overrides:
        toString in class Component
        Parameters:
        detailed - True if a detailed string is desired
        Returns:
        String representation of this container
      • visitChildren

        public final <S extends Component,​R> R visitChildren​(Class<?> clazz,
                                                                   IVisitor<S,​R> visitor)
        Traverses all child components of the given class in this container, calling the visitor's visit method at each one. Make sure that if you give a type S that the clazz parameter will only resolve to those types. Else a class cast exception will occur.
        Type Parameters:
        S - The type that goes into the Visitor.component() method.
        R -
        Parameters:
        clazz - The class of child to visit
        visitor - The visitor to call back to
        Returns:
        The return value from a visitor which halted the traversal, or null if the entire traversal occurred
      • visitChildren

        public final <R> R visitChildren​(IVisitor<Component,​R> visitor)
        Traverses all child components in this container, calling the visitor's visit method at each one.
        Type Parameters:
        R -
        Parameters:
        visitor - The visitor to call back to
        Returns:
        The return value from a visitor which halted the traversal, or null if the entire traversal occurred
      • renderNext

        protected boolean renderNext​(MarkupStream markupStream)
        THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE OR OVERWRITE IT. Renders the next element of markup in the given markup stream.
        Parameters:
        markupStream - The markup stream
        Returns:
        true, if element was rendered as RawMarkup
      • onComponentTagBody

        public void onComponentTagBody​(MarkupStream markupStream,
                                       ComponentTag openTag)
        Handle the container's body. If your override of this method does not advance the markup stream to the close tag for the openTag, a runtime exception will be thrown by the framework.
        Overrides:
        onComponentTagBody in class Component
        Parameters:
        markupStream - The markup stream
        openTag - The open tag for the body
      • renderAll

        protected final void renderAll​(MarkupStream markupStream,
                                       ComponentTag openTag)
        Loop through the markup in this container
        Parameters:
        markupStream -
        openTag -
      • onDetach

        protected void onDetach()
        Description copied from class: Component
        Called to allow a component to detach resources after use. Overrides of this method MUST call the super implementation, the most logical place to do this is the last line of the override method.
        Overrides:
        onDetach in class Component
      • queue

        public MarkupContainer queue​(Component... components)
        Queues one or more components to be dequeued later. The advantage of this method over the add(Component...) method is that the component does not have to be added to its direct parent, only to a parent upstream; it will be dequeued into the correct parent using the hierarchy defined in the markup. This allows the component hierarchy to be maintained only in markup instead of in markup and in java code; affording designers and developers more freedom when moving components in markup.
        Parameters:
        components - the components to queue
        Returns:
        this for method chaining
      • onInitialize

        protected void onInitialize()
        Description copied from class: Component
        This method is meant to be used as an alternative to initialize components. Usually the component's constructor is used for this task, but sometimes a component cannot be initialized in isolation, it may need to access its parent component or its markup in order to fully initialize. This method is invoked once per component's lifecycle when a path exists from this component to the Page thus providing the component with an atomic callback when the component's environment is built out.

        Overrides must call super#Component.onInitialize(). Usually this should be the first thing an override does, much like a constructor.

        Parent containers are guaranteed to be initialized before their children

        It is safe to use Component.getPage() in this method

        NOTE:The timing of this call is not precise, the contract is that it is called sometime before Component.onBeforeRender().

        Overrides:
        onInitialize in class Component
      • dequeuePreamble

        protected void dequeuePreamble​(DequeueContext dequeue)
        Run preliminary operations before running dequeue(DequeueContext). More in detail it throws an exception if the container is already dequeuing, and it also takes care of setting flag RFLAG_CONTAINER_DEQUEING to true before running dequeue(DequeueContext) and setting it back to false after dequeuing is completed.
        Parameters:
        dequeue - the dequeue context to use
      • dequeue

        public void dequeue​(DequeueContext dequeue)
        Dequeues components. The default implementation iterates direct children of this container found in its markup and tries to find matching components in queues filled by a call to queue(Component...). It then delegates the dequeueing to these children. Certain components that implement custom markup behaviors (such as repeaters and borders) override this method to bring dequeueing in line with their custom markup handling.
        Parameters:
        dequeue - the dequeue context to use
      • findChildComponent

        protected Component findChildComponent​(ComponentTag tag)
        Search the child component for the given tag.
        Parameters:
        tag - the component tag
        Returns:
        the child component for the given tag or null if no child can not be found.
      • canDequeueTag

        protected DequeueTagAction canDequeueTag​(ComponentTag tag)
        Checks if this container can dequeue a child represented by the specified tag. This method should be overridden when containers can dequeue components represented by non-standard tags. For example, borders override this method and dequeue their body container when processing the body tag. By default all ComponentTags are supported as well as WicketTags that return a non-null value from ComponentTag.getAutoComponentFactory() method.
        Parameters:
        tag -
      • findComponentToDequeue

        public Component findComponentToDequeue​(ComponentTag tag)
        Queries this container to find a child that can be dequeued that matches the specified tag. The default implementation will check if there is a component in the queue that has the same id as a tag, but sometimes custom tags can be dequeued and in those situations this method should be overridden.
        Parameters:
        tag -
        Returns:
      • addDequeuedComponent

        protected void addDequeuedComponent​(Component component,
                                            ComponentTag tag)
        Adds a dequeued component to this container. This method should rarely be overridden because the common case of simply forwarding the component to add(Component...) method should cover most cases. Components that implement a custom hierarchy, such as borders, may wish to override it to support edge-case non-standard behavior.
        Parameters:
        component -
        tag -
      • stream

        public Stream<Componentstream()
        Returns a sequential Stream with the direct children of this markup container as its source. This stream doesn't traverse the component tree.
        Returns:
        a sequential Stream over the direct children of this markup container
        Since:
        8.0
      • streamChildren

        public Stream<ComponentstreamChildren()
        Returns a sequential Stream with the all children of this markup container as its source. This stream does traverse the component tree.
        Returns:
        a sequential Stream over the all children of this markup container
        Since:
        8.0