001    package railo.transformer.bytecode.statement.tag;
002    
003    import java.util.Iterator;
004    import java.util.List;
005    
006    import org.objectweb.asm.Label;
007    import org.objectweb.asm.Opcodes;
008    import org.objectweb.asm.commons.GeneratorAdapter;
009    
010    import railo.transformer.bytecode.Body;
011    import railo.transformer.bytecode.BytecodeContext;
012    import railo.transformer.bytecode.BytecodeException;
013    import railo.transformer.bytecode.Statement;
014    import railo.transformer.bytecode.cast.CastBoolean;
015    import railo.transformer.bytecode.expression.ExprBoolean;
016    import railo.transformer.bytecode.expression.Expression;
017    import railo.transformer.bytecode.util.ExpressionUtil;
018    
019    public final class TagIf extends TagBase {
020    
021            
022            /**
023             * Constructor of the class
024             * @param tag
025             */
026            public TagIf(int sl) {
027                    this(sl,-1);
028            }
029            public TagIf(int sl,int el) {
030                    super(sl,el);
031            }
032    
033            public void _writeOut(BytecodeContext bc) throws BytecodeException {
034                    GeneratorAdapter adapter = bc.getAdapter();
035                    Label end = new Label();
036                    Body ifBody=getBody();
037                    
038                    List stats = ifBody.getStatements();
039                    Iterator it = stats.iterator();
040                    Tag t;
041                    Label endIf=writeOutElseIfStart(bc, this);
042                    boolean hasElse=false;
043                    while(it.hasNext()) {
044                            Statement stat = ((Statement)it.next());
045                            if(!hasElse && stat instanceof Tag) {
046                                    t=(Tag) stat;
047                                    if(t.getTagLibTag().getTagClassName().equals("railo.runtime.tag.ElseIf")) {
048                                            writeOutElseIfEnd(adapter, endIf, end);
049                                            endIf=writeOutElseIfStart(bc,t);
050                                            continue;
051                                    }
052                                    else if(t.getTagLibTag().getTagClassName().equals("railo.runtime.tag.Else")) {
053                                            ExpressionUtil.visitLine(bc, t.getLine());
054                                    hasElse=true;
055                                            writeOutElseIfEnd(adapter, endIf, end);
056                                            //endIf=writeOutElseIfStart(adapter,t);
057                                            continue;
058                                    }
059                            }
060                            stat.writeOut(bc);
061                    }
062                    if(!hasElse)writeOutElseIfEnd(adapter, endIf, end);
063                    
064                    adapter.visitLabel(end);
065            }
066    
067            private static Label writeOutElseIfStart(BytecodeContext bc, Tag tag) throws BytecodeException {
068                    GeneratorAdapter adapter = bc.getAdapter();
069    
070                    ExprBoolean cont = CastBoolean.toExprBoolean(tag.getAttribute("condition").getValue());
071                    
072                    Label endIf = new Label();
073            
074                    ExpressionUtil.visitLine(bc, tag.getLine());
075            cont.writeOut(bc,Expression.MODE_VALUE);
076            adapter.ifZCmp(Opcodes.IFEQ, endIf);
077            return endIf;
078            }
079            private static void writeOutElseIfEnd(GeneratorAdapter adapter, Label endIf, Label end) {
080    
081            adapter.visitJumpInsn(Opcodes.GOTO, end);
082            adapter.visitLabel(endIf);
083            }
084    
085    
086    }