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 lucee.commons.lang.ExceptionUtil;
022import lucee.commons.lang.StringUtil;
023import lucee.transformer.bytecode.cast.Cast;
024import lucee.transformer.bytecode.cast.CastString;
025import lucee.transformer.bytecode.expression.Expression;
026import lucee.transformer.bytecode.expression.var.Variable;
027import lucee.transformer.bytecode.expression.var.VariableString;
028import lucee.transformer.bytecode.literal.LitString;
029import lucee.transformer.bytecode.statement.tag.Attribute;
030import lucee.transformer.bytecode.statement.tag.Tag;
031import lucee.transformer.bytecode.statement.tag.TagBreak;
032import lucee.transformer.bytecode.util.ASMUtil;
033import lucee.transformer.cfml.evaluator.EvaluatorException;
034import lucee.transformer.cfml.evaluator.EvaluatorSupport;
035import lucee.transformer.library.tag.TagLibTag;
036
037
038
039/**
040 * Prueft den Kontext des Tag break.
041 * Das Tag <code>break</code> darf nur innerhalb des Tag <code>loop, while, foreach</code> liegen.
042 */
043public final class Break extends EvaluatorSupport {
044
045
046        @Override
047        public void evaluate(Tag tag,TagLibTag libTag) throws EvaluatorException { 
048                String ns=libTag.getTagLib().getNameSpaceAndSeparator();
049                String loopName=ns+"loop";
050                String whileName=ns+"while";
051                
052
053                // label
054                String label=null;
055                
056                Attribute attrLabel = tag.getAttribute("label");
057                if(attrLabel!=null){
058                        TagBreak tb=(TagBreak) tag;
059                        label=variableToString(tag,attrLabel,null);
060                        if(label!=null){
061                                tb.setLabel(label=label.trim());
062                                tag.removeAttribute("label");
063                        }
064                        
065                        else if(ASMUtil.isLiteralAttribute(tag, attrLabel, ASMUtil.TYPE_STRING, false, true)) {
066                                LitString ls=(LitString) CastString.toExprString(tag.getAttribute("label").getValue());
067                                label = ls.getString();
068                                if(!StringUtil.isEmpty(label,true)) {
069                                        tb.setLabel(label=label.trim());
070                                        tag.removeAttribute("label");
071                                }
072                                else label=null;
073                        }
074                }
075                
076                // no base tag found
077                if(!ASMUtil.hasAncestorBreakFCStatement(tag,label)) {
078                        if(tag.isScriptBase()) {
079                                if(StringUtil.isEmpty(label))
080                                        throw new EvaluatorException("Wrong Context, "+libTag.getName()+" must be inside a looping statement or tag");
081                                throw new EvaluatorException("Wrong Context, "+libTag.getName()+" must be inside a looping statement or tag with the label ["+label+"]");
082                                
083                        }
084                        
085                        
086                        if(StringUtil.isEmpty(label))
087                                throw new EvaluatorException("Wrong Context, tag "+libTag.getFullName()+" must be inside a "+loopName+" or "+whileName+" tag");
088                        throw new EvaluatorException("Wrong Context, tag "+libTag.getFullName()+" must be inside a "+loopName+" or "+whileName+" tag with the label ["+label+"]");
089                        
090                }
091
092        }
093
094        static String variableToString(Tag tag, Attribute attrLabel, String defaultValue) {
095                Expression value = attrLabel.getValue();
096                while(value instanceof Cast) value=((Cast)value).getExpr();
097                if(value instanceof Variable) {
098                        Variable var=(Variable)value;
099                        try {
100                                return VariableString.variableToString(var, true);
101                        } catch (Throwable t) {
102                                ExceptionUtil.rethrowIfNecessary(t);
103                        }
104                }
105                return defaultValue;
106        }
107
108}