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

com.sun.faces.facelets.compiler.TextUnit Maven / Gradle / Ivy

Go to download

Jakarta Faces defines an MVC framework for building user interfaces for web applications, including UI components, state management, event handing, input validation, page navigation, and support for internationalization and accessibility.

There is a newer version: 4.1.0
Show newest version
/*
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.faces.facelets.compiler;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import com.sun.faces.facelets.el.ELText;

import jakarta.el.ELException;
import jakarta.faces.view.facelets.CompositeFaceletHandler;
import jakarta.faces.view.facelets.FaceletHandler;
import jakarta.faces.view.facelets.Tag;
import jakarta.faces.view.facelets.TagAttribute;
import jakarta.faces.view.facelets.TagException;

/**
 *
 * @author Jacob Hookom
 * @version $Id$
 */
final class TextUnit extends CompilationUnit {

    private final StringBuffer buffer;

    private final StringBuffer textBuffer;

    private final List instructionBuffer;

    private final Stack tags;

    private final List children;

    private boolean startTagOpen;

    private final String alias;

    private final String id;

    public TextUnit(String alias, String id) {
        this.alias = alias;
        this.id = id;
        buffer = new StringBuffer();
        textBuffer = new StringBuffer();
        instructionBuffer = new ArrayList();
        tags = new Stack();
        children = new ArrayList();
        startTagOpen = false;
    }

    @Override
    public FaceletHandler createFaceletHandler() {
        flushBufferToConfig(true);

        if (children.size() == 0) {
            return LEAF;
        }

        FaceletHandler[] h = new FaceletHandler[children.size()];
        Object obj;
        for (int i = 0; i < h.length; i++) {
            obj = children.get(i);
            if (obj instanceof FaceletHandler) {
                h[i] = (FaceletHandler) obj;
            } else {
                h[i] = ((CompilationUnit) obj).createFaceletHandler();
            }
        }
        if (h.length == 1) {
            return h[0];
        }
        return new CompositeFaceletHandler(h);
    }

    private void addInstruction(Instruction instruction) {
        flushTextBuffer(false);
        instructionBuffer.add(instruction);
    }

    private void flushTextBuffer(boolean child) {
        if (textBuffer.length() > 0) {
            String s = textBuffer.toString();

            if (child) {
                s = trimRight(s);
            }
            if (s.length() > 0) {
                ELText txt = ELText.parse(s, alias);
                if (txt != null) {
                    if (txt.isLiteral()) {
                        instructionBuffer.add(new LiteralTextInstruction(txt.toString()));
                    } else {
                        instructionBuffer.add(new TextInstruction(alias, txt));
                    }
                }
            }

        }
        textBuffer.setLength(0);
    }

    public void write(String text) {
        finishStartTag();
        textBuffer.append(text);
        buffer.append(text);
    }

    public void writeInstruction(String text) {
        finishStartTag();
        ELText el = ELText.parse(text);
        if (el.isLiteral()) {
            addInstruction(new LiteralXMLInstruction(text));
        } else {
            addInstruction(new XMLInstruction(el));
        }
        buffer.append(text);
    }

    public void writeComment(String text) {
        finishStartTag();

        ELText el = ELText.parse(text);
        if (el.isLiteral()) {
            addInstruction(new LiteralCommentInstruction(text));
        } else {
            addInstruction(new CommentInstruction(el));
        }

        buffer.append("");
    }

    public void startTag(Tag tag) {

        // finish any previously written tags
        finishStartTag();

        // push this tag onto the stack
        tags.push(tag);

        // write it out
        buffer.append('<');
        buffer.append(tag.getQName());

        addInstruction(new StartElementInstruction(tag.getQName()));

        TagAttribute[] attrs = tag.getAttributes().getAll();
        if (attrs.length > 0) {
            for (int i = 0; i < attrs.length; i++) {
                String qname = attrs[i].getQName();
                String value = attrs[i].getValue();
                buffer.append(' ').append(qname).append("=\"").append(value).append("\"");

                ELText txt = ELText.parse(value);
                if (txt != null) {
                    if (txt.isLiteral()) {
                        addInstruction(new LiteralAttributeInstruction(qname, txt.toString()));
                    } else {
                        addInstruction(new AttributeInstruction(alias, qname, txt));
                    }
                }
            }
        }

        // notify that we have an open tag
        startTagOpen = true;
    }

    private void finishStartTag() {
        if (tags.size() > 0 && startTagOpen) {
            buffer.append(">");
            startTagOpen = false;
        }
    }

    public void endTag() {
        Tag tag = (Tag) tags.pop();

        addInstruction(new EndElementInstruction(tag.getQName()));

        if (startTagOpen) {
            buffer.append("/>");
            startTagOpen = false;
        } else {
            buffer.append("');
        }
    }

    @Override
    public void addChild(CompilationUnit unit) {
        // if we are adding some other kind of unit
        // then we need to capture our buffer into a UITextHandler
        finishStartTag();
        flushBufferToConfig(true);
        children.add(unit);
    }

    protected void flushBufferToConfig(boolean child) {

//        // NEW IMPLEMENTATION
//        if (true) {

        flushTextBuffer(child);

        int size = instructionBuffer.size();
        if (size > 0) {
            try {
                String s = buffer.toString();
                if (child) {
                    s = trimRight(s);
                }
                ELText txt = ELText.parse(s);
                if (txt != null) {
                    Instruction[] instructions = (Instruction[]) instructionBuffer.toArray(new Instruction[size]);
                    children.add(new UIInstructionHandler(alias, id, instructions, txt));
                    instructionBuffer.clear();
                }

            } catch (ELException e) {
                if (tags.size() > 0) {
                    throw new TagException((Tag) tags.peek(), e.getMessage());
                } else {
                    throw new ELException(alias + ": " + e.getMessage(), e.getCause());
                }
            }
        }

//            // KEEP THESE SEPARATE SO LOGIC DOESN'T GET FUBARED
//        } else if (this.buffer.length() > 0) {
//            String s = this.buffer.toString();
//            if (s.trim().length() > 0) {
//                if (child) {
//                    s = trimRight(s);
//                }
//                if (s.length() > 0) {
//                    try {
//                        ELText txt = ELText.parse(s);
//                        if (txt != null) {
//                            if (txt.isLiteral()) {
//                                this.children.add(new UILiteralTextHandler(txt
//                                        .toString()));
//                            } else {
//                                this.children.add(new UITextHandler(this.alias,
//                                        txt));
//                            }
//                        }
//                    } catch (ELException e) {
//                        if (this.tags.size() > 0) {
//                            throw new TagException((Tag) this.tags.peek(), e
//                                    .getMessage());
//                        } else {
//                            throw new ELException(this.alias + ": "
//                                    + e.getMessage(), e.getCause());
//                        }
//                    }
//                }
//            }
//        }

        // ALWAYS CLEAR FOR BOTH IMPL
        buffer.setLength(0);
    }

    public boolean isClosed() {
        return tags.empty();
    }

    private static String trimRight(String s) {
        int i = s.length() - 1;
        while (i >= 0) {
            if (Character.isWhitespace(s.charAt(i))) {
                i--;
            } else {
                return s;
            }
        }
        return "";
    }

    @Override
    public String toString() {
        return "TextUnit[" + children.size() + "]";
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy