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