def handle(stmt_list, handler_arg)
ret = super
return ret if ret
arg = handler_arg
d_name = arg.directive_name
d_arg = arg.directive_arg
d_str = arg.directive_str
case d_name
when :for, :For, :FOR, :list, :List, :LIST
is_foreach = d_name == :for || d_name == :For || d_name == :FOR
error_if_empty_tag(arg) unless is_foreach
unless d_arg =~ /\A(\w+)\s*:\s*(.*)\z/
raise convert_error("'#{d_str}': invalid argument.", arg.stag_info.linenum)
end
loopvar = $1 ; looplist = $2
counter = d_name == :for || d_name == :list ? nil : "#{loopvar}_ctr"
toggle = d_name != :FOR && d_name != :LIST ? nil : "#{loopvar}_tgl"
status = d_name == :for || d_name == :list ? nil : "#{loopvar}_status"
foreach_code = "<c:forEach var=\"#{loopvar}\" items=\"${#{looplist}}\""
foreach_code << " varStatus=\"#{status}\"" if status
foreach_code << ">"
code = []
code << foreach_code
code << "<c:set var=\"#{counter}\" value=\"${#{status}.count}\"/>" if counter
if toggle
if @jstl_ver < 1.2
code << "<c:choose><c:when test=\"${#{status}.count%2==0}\">"
code << "<c:set var=\"#{toggle}\" value=\"${self.even}\"/>"
code << "</c:when><c:otherwise>"
code << "<c:set var=\"#{toggle}\" value=\"${self.odd}\"/>"
code << "</c:otherwise></c:choose>"
else
code << "<c:set var=\"#{toggle}\" value=\"${#{status}.count%2==0 ? #{self.even} : #{self.odd}}\"/>"
end
end
end_code = "</c:forEach>"
if is_foreach
wrap_element_with_native_stmt(stmt_list, arg, code, end_code, :set)
else
wrap_content_with_native_stmt(stmt_list, arg, code, end_code, :set)
end
when :while, :loop
msg = "'#{d_str}': jstl doesn't support '#{d_arg}' directive."
raise convert_error(msg, arg.stag_info.linenum)
when :set
unless d_arg =~ /\A(\S+)\s*=\s*(.*)\z/
raise convert_error("'#{d_str}': invalid argument.", arg.stag_info.linenum)
end
lhs = $1; rhs = $2
code = "<c:set var=\"#{lhs}\" value=\"${#{rhs}}\"/>"
wrap_element_with_native_stmt(stmt_list, arg, code, nil, :set)
when :if
start_code = "<c:choose><c:when test=\"${#{d_arg}}\">"
end_code = "</c:when></c:choose>"
wrap_element_with_native_stmt(stmt_list, arg, start_code, end_code, :if)
when :elseif, :else
error_when_last_stmt_is_not_if(stmt_list, arg)
stmt_list.pop
if d_name == :else
kind = :else
start_code = "</c:when><c:otherwise>"
end_code = "</c:otherwise></c:choose>"
else
kind = :elseif
start_code = "</c:when><c:when test=\"${#{d_arg}}\">"
end_code = "</c:when></c:choose>"
end
wrap_element_with_native_stmt(stmt_list, arg, start_code, end_code, kind)
when :default, :Default, :DEFAULT
error_if_empty_tag(arg)
stmt_list << stag_stmt(arg)
flag_escape = d_name == :default ? nil : (d_name == :Default)
argstr = arg.cont_stmts[0].args[0]
code = "<c:out value=\"${#{d_arg}}\""
code << " escapeXml=\"#{flag_escape}\"" unless flag_escape == nil
code << " default=\"#{argstr}\"/>"
stmt_list << NativeStatement.new_without_newline(code)
stmt_list << etag_stmt(arg)
when :catch
if d_arg && !d_arg.empty? && d_arg !~ /\A\w+\z/
raise convert_error("'#{d_str}': invalid varname.", arg.stag_info.linenum)
end
code = "<c:catch"
code << " var=\"#{d_arg}\"" if d_arg && !d_arg.empty?
code << ">"
stmt_list << NativeStatement.new(code)
stmt_list.concat(arg.cont_stmts)
stmt_list << NativeStatement.new("</c:catch>")
when :forEach, :forTokens
options = eval "{ #{d_arg} }"
stag, etag = self.__send__ "handle_jstl_#{d_name}", options
wrap_element_with_native_stmt(stmt_list, arg, stag, etag, nil)
when :redirect, :import, :url, :remove
options = eval "{ #{d_arg} }"
lines = self.__send__ "handle_jstl_#{d_name}", options
lines.each do |line|
stmt_list << NativeStatement.new(line.chomp)
end
else
return false
end
return true
end