Package org.apache.cocoon.faces.taglib

Source Code of org.apache.cocoon.faces.taglib.UIComponentTag

/*
* Copyright 1999-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.cocoon.faces.taglib;

import org.apache.avalon.framework.parameters.Parameters;

import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.taglib.Tag;
import org.apache.cocoon.taglib.XMLProducerTagSupport;

import org.apache.cocoon.faces.FacesUtils;
import org.apache.cocoon.faces.renderkit.XMLResponseWriter;
import org.apache.commons.lang.BooleanUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import javax.faces.application.Application;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* @version $Id: UIComponentTag.java 161271 2005-04-14 13:02:02Z vgritsenko $
*/
public abstract class UIComponentTag extends XMLProducerTagSupport {

    private static final String CREATED_COMPONENTS = "javax.faces.webapp.COMPONENT_IDS";
    private static final String CREATED_FACETS = "javax.faces.webapp.FACET_NAMES";

    //
    // Attributes
    //

    private String id;
    private String binding;
    private String rendered;

    //
    // Internal state
    //

    private FacesContext context;
    private UIComponent component;

    private boolean created;
    private List createdComponents;
    private List createdFacets;

    //
    // Services for subclasses
    //

    protected final FacesContext getFacesContext() {
        return this.context;
    }

    protected final Application getApplication() {
        return getFacesContext().getApplication();
    }

    protected final UIComponent getComponentInstance() {
        return this.component;
    }

    protected final boolean getCreated() {
        return this.created;
    }

    protected final ValueBinding createValueBinding(String valueRef) {
        return getApplication().createValueBinding(valueRef);
    }

    protected final Object evaluate(String value) {
        if (FacesUtils.isExpression(value)) {
            return createValueBinding(value).getValue(getFacesContext());
        }

        return value;
    }

    protected final boolean evaluateBoolean(String value) {
        if (FacesUtils.isExpression(value)) {
            Boolean obj = (Boolean) createValueBinding(value).getValue(getFacesContext());
            return obj.booleanValue();
        }

        return BooleanUtils.toBoolean(value);
    }

    protected final int evaluateInteger(String value) {
        if (FacesUtils.isExpression(value)) {
            Number obj = (Number) createValueBinding(value).getValue(getFacesContext());
            return obj.intValue();
        }

        return Integer.parseInt(value);
    }

    protected final long evaluateLong(String value) {
        if (FacesUtils.isExpression(value)) {
            Number obj = (Number) createValueBinding(value).getValue(getFacesContext());
            return obj.longValue();
        }

        return Long.parseLong(value);
    }

    protected final double evaluateDouble(String value) {
        if (FacesUtils.isExpression(value)) {
            Number obj = (Number) createValueBinding(value).getValue(getFacesContext());
            return obj.doubleValue();
        }

        return Double.parseDouble(value);
    }

    //
    // Tag Interface
    //

    public void setup(SourceResolver resolver, Map objectModel, Parameters parameters)
    throws SAXException, IOException {
        super.setup(resolver, objectModel, parameters);

        // Obtain Faces context
        this.context = FacesUtils.getFacesContext(this, objectModel);

        // Set up response writer
        ResponseWriter writer = this.context.getResponseWriter();
        if (writer == null) {
            // Not calling RenderKit here.
            Request request = ObjectModelHelper.getRequest(objectModel);
            writer = new XMLResponseWriter(this.xmlConsumer, null, request.getCharacterEncoding());
            this.context.setResponseWriter(writer);
        }
    }

    public int doStartTag(String namespaceURI, String localName, String qName, Attributes attrs)
    throws SAXException {
        final UIComponentTag parentTag = findParent();

        this.component = findComponent(parentTag);

        try {
            if (!isSuppressed()) {
                if (!this.component.getRendersChildren()) {
                    encodeBegin();
                    getFacesContext().getResponseWriter().flush();
                }
            }
        } catch (IOException e) {
            throw new SAXException("Exception in doStartTag", e);
        }

        return getDoStartValue();
    }

    public int doEndTag(String namespaceURI, String localName, String qName)
    throws SAXException {
        removeOldChildren();
        removeOldFacets();
        try {
            if (!isSuppressed()) {
                if (this.component.getRendersChildren()) {
                    encodeBegin();
                    encodeChildren();
                }
                encodeEnd();
                getFacesContext().getResponseWriter().flush();
            }
        } catch (IOException e) {
            throw new SAXException("Exception in doEndTag", e);
        }

        return getDoEndValue();
    }


    //
    // Lifecycle
    //

    public void recycle() {
        super.recycle();

        this.component = null;
        this.context = null;

        this.id = null;
        this.binding = null;
        this.created = false;
        this.rendered = null;

        this.createdComponents = null;
        this.createdFacets = null;
    }


    //
    // Methods to be implemented or overridden in subclasses
    //

    protected abstract String getComponentType();

    protected abstract String getRendererType();

    protected int getDoEndValue() {
        return Tag.EVAL_PAGE;
    }

    protected int getDoStartValue() {
        return Tag.EVAL_BODY;
    }

    protected void encodeBegin() throws IOException {
        this.component.encodeBegin(this.context);
    }

    protected void encodeChildren() throws IOException {
        this.component.encodeChildren(this.context);
    }

    protected void encodeEnd() throws IOException {
        this.component.encodeEnd(this.context);
    }

    protected void setProperties(UIComponent component) {
        if (this.rendered != null) {
            if (FacesUtils.isExpression(this.rendered)) {
                ValueBinding vb = createValueBinding(this.rendered);
                component.setValueBinding("rendered", vb);
            } else {
                component.setRendered(BooleanUtils.toBoolean(this.rendered));
            }
        }

        if (getRendererType() != null) {
            component.setRendererType(getRendererType());
        }
    }

    protected final void setProperty(UIComponent component, String name, String value) {
        if (value != null) {
            if (FacesUtils.isExpression(value)) {
                ValueBinding vb = createValueBinding(value);
                component.setValueBinding(name, vb);
            } else {
                component.getAttributes().put(name, value);
            }
        }
    }

    protected final void setBooleanProperty(UIComponent component, String name, String value) {
        if (value != null) {
            if (FacesUtils.isExpression(value)) {
                ValueBinding vb = createValueBinding(value);
                component.setValueBinding(name, vb);
            } else {
                component.getAttributes().put(name, BooleanUtils.toBooleanObject(value));
            }
        }
    }

    protected final void setIntegerProperty(UIComponent component, String name, String value) {
        if (value != null) {
            if (FacesUtils.isExpression(value)) {
                ValueBinding vb = createValueBinding(value);
                component.setValueBinding(name, vb);
            } else {
                component.getAttributes().put(name, new Integer(value));
            }
        }
    }


    //
    // Implementation methods
    //

    private UIComponentTag findParent() {
        Tag parent = this;
        do {
            parent = parent.getParent();
        } while (parent != null && !(parent instanceof UIComponentTag));

        return (UIComponentTag) parent;
    }

    /**
     * Creates or finds (if pre-created) UIComponent for this tag instance
     */
    private UIComponent findComponent(UIComponentTag parentTag) {
        // Check if this is root
        if (parentTag == null) {
            UIComponent root = getFacesContext().getViewRoot();
            setProperties(root);
            if (this.id != null) {
                root.setId(this.id);
            }
            return root;
        }

        String id = createId();

        // Create  facet
        String facet = getFacetName();
        if (facet != null) {
            return createFacet(parentTag, facet, id);
        }

        // Create child
        return createChild(parentTag, id);
    }

    /**
     * Get name of the facet or null
     */
    private String getFacetName() {
        final Tag parentTag = getParent();
        if (parentTag instanceof FacetTag) {
            return ((FacetTag) parentTag).getName();
        }

        return null;
    }

    private boolean isSuppressed() {
        if (getFacetName() != null) {
            return true;
        }

        if (!this.component.isRendered()) {
            return true;
        }

        for (UIComponent component = this.component.getParent(); component != null; component = component.getParent()) {
            if (!component.isRendered()) {
                return true;
            }

            if (component.getRendersChildren()) {
                return true;
            }
        }

        return false;
    }

    private void addChild(UIComponent child) {
        if (createdComponents == null) {
            createdComponents = new ArrayList();
        }
        createdComponents.add(child.getId());
    }

    private void addFacet(String name) {
        if (createdFacets == null) {
            createdFacets = new ArrayList();
        }
        createdFacets.add(name);
    }

    private UIComponent createComponent(String id) {
        UIComponent component;
        Application application = context.getApplication();
        if (this.binding != null) {
            ValueBinding vb = application.createValueBinding(this.binding);
            component = application.createComponent(vb, context, getComponentType());
            component.setValueBinding("binding", vb);
        } else {
            component = application.createComponent(getComponentType());
        }
        component.setId(id);
        this.created = true;

        setProperties(component);
        return component;
    }

    private UIComponent createChild(UIComponentTag parentTag, String id) {
        final UIComponent parent = parentTag.getComponentInstance();
        UIComponent component = FacesUtils.getChild(parent, id);
        if (component == null) {
            component = createComponent(id);
            parent.getChildren().add(component);
        }

        parentTag.addChild(component);
        return component;
    }

    private UIComponent createFacet(UIComponentTag parentTag, String name, String id) {
        final UIComponent parent = parentTag.getComponentInstance();
        UIComponent component = (UIComponent) parent.getFacets().get(name);
        if (component == null) {
            component = createComponent(id);
            parent.getFacets().put(name, component);
        }

        parentTag.addFacet(name);
        return component;
    }

    private String createId() {
        if (this.id == null) {
            return getFacesContext().getViewRoot().createUniqueId();
        }

        return this.id;
    }

    private void removeOldChildren() {
        List oldList = (List) component.getAttributes().remove(CREATED_COMPONENTS);
        if (oldList != null) {
            if (createdComponents != null) {
                for (Iterator olds = oldList.iterator(); olds.hasNext();) {
                    String old = (String) olds.next();
                    if (!createdComponents.contains(old)) {
                        FacesUtils.removeChild(component, old);
                    }
                }
            } else {
                for (Iterator i = oldList.iterator(); i.hasNext();) {
                    FacesUtils.removeChild(component, (String) i.next());
                }
            }
        }

        if (createdComponents != null) {
            component.getAttributes().put(CREATED_COMPONENTS, createdComponents);
            createdComponents = null;
        }
    }

    private void removeOldFacets() {
        List oldList = (List) component.getAttributes().remove(CREATED_FACETS);
        if (oldList != null) {
            if (createdFacets != null) {
                for (Iterator olds = oldList.iterator(); olds.hasNext();) {
                    String old = (String) olds.next();
                    if (!createdFacets.contains(old)) {
                        component.getFacets().remove(old);
                    }
                }
            } else {
                for (Iterator olds = oldList.iterator(); olds.hasNext(); ) {
                    String old = (String) olds.next();
                    component.getFacets().remove(old);
                }
            }
        }

        if (createdFacets != null) {
            component.getAttributes().put(CREATED_FACETS, createdFacets);
            createdFacets = null;
        }
    }


    //
    // Setters / Getters
    //

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getBinding() {
        return this.binding;
    }

    public void setBinding(String binding) {
        if (!FacesUtils.isExpression(binding)) {
            throw new IllegalArgumentException("Binding value must be an expression");
        }

        this.binding = binding;
    }

    public String getRendered() {
        return this.rendered;
    }

    public void setRendered(String rendered) {
        this.rendered = rendered;
    }
}
TOP

Related Classes of org.apache.cocoon.faces.taglib.UIComponentTag

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.