001 package railo.transformer.bytecode.statement.tag; 002 003 import java.util.Iterator; 004 import java.util.List; 005 006 import org.objectweb.asm.Type; 007 import org.objectweb.asm.commons.GeneratorAdapter; 008 import org.objectweb.asm.commons.Method; 009 010 import railo.transformer.bytecode.BytecodeContext; 011 import railo.transformer.bytecode.BytecodeException; 012 import railo.transformer.bytecode.Position; 013 import railo.transformer.bytecode.Statement; 014 import railo.transformer.bytecode.expression.Expression; 015 import railo.transformer.bytecode.util.Types; 016 import railo.transformer.bytecode.visitor.ConditionVisitor; 017 import railo.transformer.bytecode.visitor.DecisionIntVisitor; 018 019 public final class TagSwitch extends TagBaseNoFinal { 020 021 // int listFindNoCase(String list, String value, String delimiter) 022 private static final Method LIST_FIND_NO_CASE = new Method( 023 "listFindForSwitch", 024 Types.INT_VALUE, 025 new Type[]{Types.STRING,Types.STRING,Types.STRING}); 026 027 /** 028 * Constructor of the class 029 * @param sl 030 * @param el 031 */ 032 public TagSwitch(Position start,Position end) { 033 super(start,end); 034 } 035 036 /** 037 * 038 * @see railo.transformer.bytecode.statement.tag.TagBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter) 039 */ 040 public void _writeOut(BytecodeContext bc) throws BytecodeException { 041 GeneratorAdapter adapter = bc.getAdapter(); 042 043 // expression 044 int expression=adapter.newLocal(Types.STRING); 045 getAttribute("expression").getValue().writeOut(bc, Expression.MODE_REF); 046 adapter.storeLocal(expression); 047 048 049 List statements = getBody().getStatements(); 050 Statement stat; 051 Tag tag; 052 053 ConditionVisitor cv=new ConditionVisitor(); 054 cv.visitBefore(); 055 056 // cases 057 Iterator it = statements.iterator(); 058 Tag def=null; 059 while(it.hasNext()) { 060 stat=(Statement) it.next(); 061 if(stat instanceof Tag) { 062 tag=(Tag) stat; 063 if(tag.getTagLibTag().getTagClassName().equals("railo.runtime.tag.Case")) { 064 addCase(bc,cv,tag,expression); 065 continue; 066 } 067 else if(tag.getTagLibTag().getTagClassName().equals("railo.runtime.tag.Defaultcase")) { 068 if(def!=null) 069 throw new BytecodeException("multiple defaultcases are not allowed",getStart()); 070 def=tag; 071 //setDefaultCase(bc,cv,tag); 072 //break; 073 } 074 } 075 } 076 077 // default 078 if(def!=null)setDefaultCase(bc,cv,def); 079 080 cv.visitAfter(bc); 081 082 083 /* 084 085 <!-- cases --> 086 <xsl:for-each select="./body/tag[@name='case']"> 087 if(List.listFindNoCase(case.value,expression, 088 <xsl:if test="./attribute[@name='delimiters']">,delimiters)!=-1) { 089 <xsl:apply-templates select="./body/*"/> 090 } 091 </xsl:for-each> 092 093 <!-- default --> 094 <xsl:if test="./body/tag[@name='defaultcase']"> 095 <xsl:if test="count(./body/tag[@name='case'])>0">else </xsl:if> { 096 <xsl:apply-templates select="./body/tag[@name='defaultcase']/body/*"/> 097 } 098 </xsl:if> 099 </xsl:template>*/ 100 } 101 102 private void setDefaultCase(BytecodeContext bc, ConditionVisitor cv, Tag tag) throws BytecodeException { 103 cv.visitOtherviseBeforeBody(); 104 tag.getBody().writeOut(bc); 105 cv.visitOtherviseAfterBody(); 106 } 107 108 private void addCase(BytecodeContext bc, ConditionVisitor cv, Tag tag, int expression) throws BytecodeException { 109 GeneratorAdapter adapter = bc.getAdapter(); 110 111 cv.visitWhenBeforeExpr(); 112 DecisionIntVisitor div=new DecisionIntVisitor(); 113 div.visitBegin(); 114 // List.listFindNoCase(case.value,expression,del); 115 tag.getAttribute("value").getValue().writeOut(bc,Expression.MODE_REF); 116 adapter.loadLocal(expression); 117 Attribute attr = tag.getAttribute("delimiters"); 118 if(attr!=null)attr.getValue().writeOut(bc,Expression.MODE_REF); 119 else adapter.push(","); 120 adapter.invokeStatic(Types.LIST_UTIL, LIST_FIND_NO_CASE); 121 div.visitNEQ(); 122 adapter.push(-1); 123 div.visitEnd(bc); 124 cv.visitWhenAfterExprBeforeBody(bc); 125 tag.getBody().writeOut(bc); 126 cv.visitWhenAfterBody(bc); 127 128 129 130 /*if(List.listFindNoCase(case.value,expression,delimiters)!=-1) { 131 <xsl:apply-templates select="./body/*"/> 132 }*/ 133 } 134 135 }