001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.transformer.cfml.evaluator.impl;
020
021import java.util.Iterator;
022import java.util.List;
023
024import lucee.transformer.bytecode.Page;
025import lucee.transformer.bytecode.Statement;
026import lucee.transformer.bytecode.cast.CastBoolean;
027import lucee.transformer.bytecode.cast.CastString;
028import lucee.transformer.bytecode.expression.Expression;
029import lucee.transformer.bytecode.literal.LitBoolean;
030import lucee.transformer.bytecode.literal.LitString;
031import lucee.transformer.bytecode.statement.tag.Attribute;
032import lucee.transformer.bytecode.statement.tag.Tag;
033import lucee.transformer.bytecode.util.ASMUtil;
034import lucee.transformer.cfml.evaluator.EvaluatorException;
035import lucee.transformer.cfml.evaluator.EvaluatorSupport;
036import lucee.transformer.library.tag.TagLibTag;
037
038
039
040/**
041 * Prueft den Kontext des Tag break.
042 * Das Tag <code>break</code> darf nur innerhalb des Tag <code>loop, while, foreach</code> liegen.
043 */
044public class Component extends EvaluatorSupport {
045
046
047        /**
048         * @see lucee.transformer.cfml.evaluator.EvaluatorSupport#evaluate(org.w3c.dom.Element, lucee.transformer.library.tag.TagLibTag)
049         */
050
051        public void evaluate(Tag tag,TagLibTag tlt) throws EvaluatorException { 
052
053                Statement pPage = tag.getParent();
054                String className=tag.getTagLibTag().getTagClassName();
055                
056                // is direct in document
057                if(!(pPage instanceof Page)){
058                        
059                        // is script Component
060                        Tag p = ASMUtil.getParentTag(tag);
061                        if(p.getTagLibTag().getName().equals("script") && (pPage = p.getParent()) instanceof Page){
062                                
063                                // move imports from script to component body
064                                List children = p.getBody().getStatements();
065                                Iterator it = children.iterator();
066                                Statement stat;
067                                Tag t;
068                                while(it.hasNext()){
069                                        stat=(Statement) it.next();
070                                        if(!(stat instanceof Tag)) continue;
071                                        t=(Tag) stat;
072                                        if(t.getTagLibTag().getName().equals("import")){
073                                                tag.getBody().addStatement(t);
074                                        }
075                                }
076                                
077                                // replace script with component        
078                                ASMUtil.replace(p, tag, false);
079                        }
080                        else
081                                throw new EvaluatorException("Wrong Context, tag "+tlt.getFullName()+" can't be inside other tags, tag is inside tag "+p.getFullname());
082                }
083
084                Page page=(Page) pPage;
085                
086                // is inside a file named cfc
087                String src=page.getPageSource().getDisplayPath();
088                int pos=src.lastIndexOf(".");
089                if(!(pos!=-1 && pos<src.length() && src.substring(pos+1).equals("cfc")))
090                        throw new EvaluatorException("Wrong Context, "+tlt.getFullName()+" tag must be inside a file with extension cfc");
091                
092                // check if more than one component in document and remove any other data
093                List stats = page.getStatements();
094                Iterator it = stats.iterator();
095                Statement stat;
096                int count=0;
097                while(it.hasNext()) {
098                        stat=(Statement) it.next();
099                        if(stat instanceof Tag) {
100                                tag=(Tag) stat;
101                                if(tag.getTagLibTag().getTagClassName().equals(className)) count++;
102                        }
103                }
104                if(count>1)
105                        throw new EvaluatorException("inside one cfc file only one tag "+tlt.getFullName()+" is allowed, now we have "+count);
106
107                boolean isComponent="lucee.runtime.tag.Component".equals(tlt.getTagClassName());
108                boolean isInterface="lucee.runtime.tag.Interface".equals(tlt.getTagClassName());
109                if(isComponent)page.setIsComponent(true);
110                if(isInterface)page.setIsInterface(true);
111                
112// Attributes
113                
114                // output
115                // "output=true" wird in "lucee.transformer.cfml.attributes.impl.Function" gehaendelt
116                Attribute attr = tag.getAttribute("output");
117                if(attr!=null) {
118                        Expression expr = CastBoolean.toExprBoolean(attr.getValue());
119                        if(!(expr instanceof LitBoolean))
120                                throw new EvaluatorException("Attribute output of the Tag "+tlt.getFullName()+", must contain a static boolean value (true or false, yes or no)");
121                        //boolean output = ((LitBoolean)expr).getBooleanValue();
122                        //if(!output) ASMUtil.removeLiterlChildren(tag, true);
123                }
124                
125                // extends
126                attr = tag.getAttribute("extends");
127                if(attr!=null) {
128                        Expression expr = CastString.toExprString(attr.getValue());
129                        if(!(expr instanceof LitString)) throw new EvaluatorException("Attribute extends of the Tag "+tlt.getFullName()+", must contain a literal string value");
130                }
131                
132                // implements
133                if(isComponent){
134                        attr = tag.getAttribute("implements");
135                        if(attr!=null) {
136                                Expression expr = CastString.toExprString(attr.getValue());
137                                if(!(expr instanceof LitString)) throw new EvaluatorException("Attribute implements of the Tag "+tlt.getFullName()+", must contain a literal string value");
138                        }
139                }
140        }
141}
142
143
144
145