001    package railo.transformer.bytecode.statement;
002    
003    import java.util.ArrayList;
004    import java.util.Iterator;
005    
006    import railo.transformer.bytecode.Body;
007    import railo.transformer.bytecode.BytecodeContext;
008    import railo.transformer.bytecode.BytecodeException;
009    import railo.transformer.bytecode.Position;
010    import railo.transformer.bytecode.Statement;
011    import railo.transformer.bytecode.expression.ExprBoolean;
012    import railo.transformer.bytecode.expression.Expression;
013    import railo.transformer.bytecode.literal.LitBoolean;
014    import railo.transformer.bytecode.util.ExpressionUtil;
015    import railo.transformer.bytecode.visitor.ConditionVisitor;
016    
017    public final class Condition extends StatementBaseNoFinal implements HasBodies {
018        
019        private ArrayList<Pair> ifs=new ArrayList<Pair>();
020        private Pair _else;
021    
022        /**
023         * Constructor of the class
024         * @param condition
025         * @param body
026         * @param line
027         */
028        public Condition(Position start,Position end) {
029            super(start,end);
030        }
031        
032        /**
033         * Constructor of the class
034         * @param condition
035         * @param body
036         * @param line
037         */
038        public Condition(ExprBoolean condition, Statement body, Position start,Position end) {
039            super(start,end);
040            addElseIf(condition,body,start,end);
041            
042            body.setParent(this);
043        }
044        
045        public Condition(boolean b, Statement body, Position start,Position end) {
046                    this(LitBoolean.toExprBoolean(b),body,start,end);
047            }
048    
049            /**
050         * adds a else statement
051         * @param condition
052         * @param body
053         */
054        public Pair addElseIf(ExprBoolean condition, Statement body, Position start,Position end) {
055            Pair pair;
056            ifs.add(pair=new Pair(condition,body,start,end));
057            body.setParent(this);
058            return pair;
059        }
060        
061        /**
062         * sets the else Block of the condition
063         * @param body
064         */
065        public Pair setElse(Statement body, Position start,Position end) {
066            _else=new Pair(null,body,start,end);
067            body.setParent(this);
068            return _else;
069        }
070        
071        public final class Pair {
072            private ExprBoolean condition;
073            private Statement body;
074            private Position start;
075            public Position end;
076    
077            public Pair(ExprBoolean condition, Statement body, Position start,Position end) {
078                this.condition=condition;
079                this.body=body;
080                this.start=start;
081                this.end=end;
082            }
083        }
084        
085        
086    
087        public void _writeOut(BytecodeContext bc) throws BytecodeException {
088            Iterator<Pair> it = ifs.iterator();
089            Pair pair;
090            ConditionVisitor cv=new ConditionVisitor();
091            cv.visitBefore();
092                    // ifs
093                    while(it.hasNext()) {
094                            pair=it.next();
095                            ExpressionUtil.visitLine(bc, pair.start);
096                            cv.visitWhenBeforeExpr();
097                                    pair. condition.writeOut(bc,Expression.MODE_VALUE);
098                            cv.visitWhenAfterExprBeforeBody(bc);
099                                    pair.body.writeOut(bc);
100                            cv.visitWhenAfterBody(bc);
101                            if(pair.end!=null)ExpressionUtil.visitLine(bc, pair.end);
102                    }
103                    // else
104                    if(_else!=null && _else.body!=null) {
105                            cv.visitOtherviseBeforeBody();
106                                    _else.body.writeOut(bc);
107                            cv.visitOtherviseAfterBody();
108                    }
109                    
110            cv.visitAfter(bc);
111        }
112    
113            /**
114             * @see railo.transformer.bytecode.statement.HasBodies#getBodies()
115             */
116            public Body[] getBodies() {
117                    int len=ifs.size(),count=0;
118                    if(_else!=null)len++;
119                    Body[] bodies=new Body[len];
120                    Pair p;
121                    Iterator<Pair> it = ifs.iterator();
122                    while(it.hasNext()) {
123                            p=it.next();
124                            bodies[count++]=(Body) p.body;
125                    }
126                    if(_else!=null)bodies[count++]=(Body) _else.body;
127                    
128                    return bodies;
129            }
130    }