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