Class Kwartz::JstlHandler
In: kwartz/binding/jstl.rb
Parent: Handler

directive handler for JSTL

Methods

Constants

JSTL_DIRECTIVE_PATTERN = /\A(\w+)(?:\s*\(\s*(.*)\))?\z/
JSTL_MAPPING_PATTERN = /\A'([-:\w]+)',\s*(.*)\z/
JSTL_DIRECTIVE_FORMAT = '%s(%s)'

Public Class methods

[Source]

# File kwartz/binding/jstl.rb, line 23
    def initialize(elem_rulesets=[], properties={})
      super
      @jstl_ver = properties[:jstl] || 1.2
    end

Public Instance methods

[Source]

# File kwartz/binding/jstl.rb, line 45
    def directive_format
      return JSTL_DIRECTIVE_FORMAT
    end

[Source]

# File kwartz/binding/jstl.rb, line 31
    def directive_pattern
      return JSTL_DIRECTIVE_PATTERN
    end

[Source]

# File kwartz/binding/jstl.rb, line 50
    def handle(directive_name, directive_arg, directive_str, stag_info, etag_info, cont_stmts, attr_info, append_exprs, stmt_list)
      ret = super
      return ret if ret

      d_name = directive_name
      d_arg  = directive_arg
      d_str  = directive_str

      case directive_name

      when :for, :For, :FOR, :list, :List, :LIST
        is_foreach = d_name == :for || d_name == :For || d_name == :FOR
        unless d_arg =~ /\A(\w+)\s*:\s*(.*)\z/
          raise convert_error("'#{d_str}': invalid argument.", 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"
        stmt_list << build_print_stmt(stag_info, attr_info, append_exprs)   if !is_foreach
        sb = "<c:forEach var=\"#{loopvar}\" items=\"${#{looplist}}\""
        sb << " varStatus=\"#{status}\"" if status
        sb << ">"
        stmt_list << NativeStatement.new(sb, :foreach)
        if counter
          stmt_list << NativeStatement.new("<c:set var=\"#{counter}\" value=\"${#{status}.count}\" />")
        end
        if toggle
          if @jstl_ver < 1.2
            stmt_list << NativeStatement.new("<c:choose><c:when test=\"${#{status}.count%2==0}\">")
            stmt_list << NativeStatement.new("<c:set var=\"#{toggle}\" value=\"${self.even}\"/>")
            stmt_list << NativeStatement.new("</c:when><c:otherwise>")
            stmt_list << NativeStatement.new("<c:set var=\"#{toggle}\" value=\"${self.odd}\"/>")
            stmt_list << NativeStatement.new("</c:otherwise></c:choose>")
          else
            sb = "<c:set var=\"#{toggle}\" value=\"${#{status}.count%2==0 ? #{self.even} : #{self.odd}}\" />"
            stmt_list << NativeStatement.new(sb)
          end
        end
        stmt_list  <<  build_print_stmt(stag_info, attr_info, append_exprs)   if is_foreach
        stmt_list.concat(cont_stmts)
        stmt_list  <<  build_print_stmt(etag_info, nil, nil)                  if is_foreach
        stmt_list  <<  NativeStatement.new("</c:forEach>", :foreach)
        stmt_list  <<  build_print_stmt(etag_info, nil, nil)                  if !is_foreach

      when :while, :loop
        raise convert_error("'#{d_str}': jstl doesn't support '#{d_arg}' directive.", stag_info.linenum)

      when :set
        unless d_arg =~ /\A(\S+)\s*=\s*(.*)\z/
          raise convert_error("'#{d_str}': invalid argument.", stag_info.linenum)
        end
        lhs = $1;  rhs = $2
        sb = "<c:set var=\"#{lhs}\" value=\"${#{rhs}}\" />"
        stmt_list << NativeStatement.new(sb, :set)
        stmt_list << build_print_stmt(stag_info, attr_info, append_exprs)
        stmt_list.concat(cont_stmts)
        stmt_list << build_print_stmt(etag_info, nil, nil)

      when :if
        sb = "<c:choose><c:when test=\"${#{d_arg}}\">"
        stmt_list << NativeStatement.new(sb, :if)
        stmt_list << build_print_stmt(stag_info, attr_info, append_exprs)
        stmt_list.concat(cont_stmts)
        stmt_list << build_print_stmt(etag_info, nil, nil)
        stmt_list << NativeStatement.new("</c:when></c:choose>", :if)

      when :elseif, :else
        unless !stmt_list.empty? && (st=stmt_list[-1]).is_a?(NativeStatement) && (st.kind == :if || st.kind == :elseif)
          raise convert_error("'#{d_str}': previous statement should be 'if' or 'elseif'.", stag_info.linenum)
        end
        stmt_list.pop    # delete '</c:when></c:choose>'
        if d_name == :else
          kind = :else
          sb = "</c:when><c:otherwise>"
          stmt_list << NativeStatement.new(sb, :else)
          sb = "</c:otherwise></c:choose>"
        else
          kind = :elseif
          sb = "</c:when><c:when test=\"${#{d_arg}}\">"
          stmt_list << NativeStatement.new(sb, :elseif)
          sb = "</c:when></c:choose>"
        end
        stmt_list << build_print_stmt(stag_info, attr_info, append_exprs)
        stmt_list.concat(cont_stmts)
        stmt_list << build_print_stmt(etag_info, nil, nil)
        stmt_list << NativeStatement.new(sb, kind)

      when :default, :Default, :DEFAULT
        error_if_empty_tag(stag_info, etag_info, d_name, d_arg)
        stmt_list << build_print_stmt(stag_info, attr_info, append_exprs)
        flag_escape = d_name == :default ? nil : (d_name == :Default)
        argstr = cont_stmts[0].args[0]
        sb =  "<c:out value=\"${#{d_arg}}\""
        sb << " escapeXml=\"#{flag_escape}\"" unless flag_escape == nil
        sb << " default=#{argstr.dump} />"
        stmt_list << NativeStatement.new_without_newline(sb)
        stmt_list << build_print_stmt(etag_info, nil, nil)

      when :catch
        if d_arg && !d_arg.empty? && d_arg !~ /\A\w+\z/
          raise convert_error("'#{d_str}': invalid varname.", stag_info.linenum)
        end
        sb = "<c:catch"
        sb << " var=\"#{d_arg}\"" if d_arg && !d_arg.empty?
        sb << ">"
        stmt_list << NativeStatement.new(sb)
        stmt_list.concat(cont_stmts)
        stmt_list << NativeStatement.new("</c:catch>")

      when :forEach, :forTokens
        stag, etag = eval "handle_jstl_#{d_name}(#{d_arg})"
        stmt_list << NativeStatement.new(stag)
        stmt_list << build_print_stmt(stag_info, attr_info, append_exprs)
        stmt_list.concat(cont_stmts)
        stmt_list << build_print_stmt(etag_info, nil, nil)
        stmt_list << NativeStatement.new(etag)

      when :redirect, :import, :url, :remove
        lines = eval "handle_jstl_#{d_name}(#{d_arg})"
        lines.each do |line|
          stmt_list << NativeStatement.new(line)
        end

      else
        return false

      end #case
      return true

    end

[Source]

# File kwartz/binding/jstl.rb, line 38
    def mapping_pattern
      return JSTL_MAPPING_PATTERN
    end

Protected Instance methods

[Source]

# File kwartz/binding/jstl.rb, line 261
    def _evaluate_options(options={})
      return options
    end

[Source]

# File kwartz/binding/jstl.rb, line 218
    def _handle_jstl_params(tagname, param_list, options)
      stag, etag = _handle_jstl_tag(tagname, param_list, options)
      lines = [stag]
      i = 0
      options.each do |name, value|
        i += 1
        if value.is_a?(Symbol)
          lines << " <c:param name=\"#{name}\" value=\"${#{value}}\"/>"
        else
          #lines << " <c:param name=\"#{name}\" value=\"#{value}\"/>"
        end
      end
      if i == 0
        stag.sub!(/>\z/, '/>')
      else
        lines << etag
      end
      return lines
    end

[Source]

# File kwartz/binding/jstl.rb, line 239
    def _handle_jstl_tag(tagname, param_list, options)
      sb = "<c:#{tagname}"
      param_list.each do |param|
        key = nil
        if options.key?(param.intern) ; key = param.intern
        elsif options.key?(param)     ; key = param
        end
        next if key == nil
        value = options.delete(key)
        if value.is_a?(Symbol)
          sb << " #{param}=\"${#{value}}\""
        else
          sb << " #{param}=\"#{value}\""
        end
      end
      sb << ">"
      stag = sb
      etag = "</c:#{tagname}>"
      return stag, etag
    end

[Source]

# File kwartz/binding/jstl.rb, line 206
    def handle_jstl_forEach(options)
      param_list = %w[var items varStatus begin end step]
      return _handle_jstl_tag('forEach', param_list, options)
    end

[Source]

# File kwartz/binding/jstl.rb, line 212
    def handle_jstl_forTokens(options)
      param_list = %w[items delims var varStatus begin end step]
      return _handle_jstl_tag('forTokens', param_list, options)
    end

[Source]

# File kwartz/binding/jstl.rb, line 191
    def handle_jstl_import(options)
      return _handle_jstl_params('import', %w[url context charEncoding var scope], options)
    end

[Source]

# File kwartz/binding/jstl.rb, line 186
    def handle_jstl_redirect(options)
      return _handle_jstl_params('redirect', %w[url context], options)
    end

[Source]

# File kwartz/binding/jstl.rb, line 201
    def handle_jstl_remove(options)
      return _handle_jstl_params('remove', %w[var scope], options)
    end

[Source]

# File kwartz/binding/jstl.rb, line 196
    def handle_jstl_url(options)
      return _handle_jstl_params('url', %w[value context var scope], options)
    end

[Validate]