/scalate-jsp-converter/src/main/scala/org/fusesource/scalate/converter/JspParser.scala
http://github.com/scalate/scalate · Scala · 134 lines · 73 code · 36 blank · 25 comment · 2 complexity · 78491c394889908a71cb0e242a5c9737 MD5 · raw file
- /**
- * Copyright (C) 2009-2011 the original author or authors.
- * See the notice.md file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.fusesource.scalate.converter
- import org.fusesource.scalate.TemplateException
- import util.parsing.input.{ Positional, CharSequenceReader, NoPosition, Position }
- import org.fusesource.scalate.support.Text
- sealed abstract class PageFragment extends Positional {
- }
- case class QualifiedName(
- prefix: String,
- name: String) extends Positional {
- val qualifiedName = prefix + ":" + name
- override def toString = qualifiedName
- }
- case class Attribute(
- name: String,
- value: Expression) extends Positional
- case class CommentFragment(
- comment: Text) extends PageFragment
- case class DollarExpressionFragment(
- code: Text) extends PageFragment {
- val toScala = ExpressionLanguage.asScala(code.toString)
- override def toString = "${" + toScala + "}"
- }
- case class TextFragment(
- text: Text) extends PageFragment {
- override def toString = text.toString
- }
- case class Element(
- qname: QualifiedName,
- attributes: List[Attribute],
- body: List[PageFragment]) extends PageFragment {
- val qualifiedName = qname.qualifiedName
- lazy val attributeMap: Map[String, Expression] = Map(attributes.map(a => a.name -> a.value): _*)
- /**
- * Returns the mandatory expression for the given attribute name or throw an expression if its not found
- */
- def attribute(name: String): Expression = attributeMap.get(name) match {
- case Some(e) => e
- case _ => throw new IllegalArgumentException("No '" + name + "' attribute on tag " + this)
- }
- }
- /**
- * Parser of JSP for the purposes of transformation to Scalate; so its not perfect but gives folks a head start
- *
- * @version $Revision : 1.1 $
- */
- class JspParser extends MarkupScanner {
- protected val expressionParser = new ExpressionParser
- private def phraseOrFail[T](p: Parser[T], in: String): T = {
- val x = phrase(p)(new CharSequenceReader(in))
- x match {
- case Success(result, _) => result
- case NoSuccess(message, next) => throw new InvalidJspException(message, next.pos);
- }
- }
- def parsePage(in: String) = {
- phraseOrFail(page, in)
- }
- def page = rep(pageFragment)
- val pageFragment: Parser[PageFragment] = positioned(markup | expression | textFragment)
- val textFragment = upto(markup | expression) ^^ { TextFragment(_) }
- def elementTextContent = someUpto(closeElement | markup | expression) ^^ { TextFragment(_) }
- def markup: Parser[PageFragment] = element | emptyElement
- def emptyElement = (openElement("/>")) ^^ {
- case q ~ al => Element(q, al, Nil)
- }
- def element = (openElement(">") ~ rep(markup | expression | elementTextContent) ~ closeElement) ^^ {
- case (q ~ al) ~ b ~ q2 =>
- if (q != q2) throw new InvalidJspException("Expected close element of " + q + " but found " + q2, q2.pos)
- Element(q, al, b)
- }
- def qualifiedName: Parser[QualifiedName] = positioned(((IDENT <~ ":") ~ IDENT) ^^ { case p ~ n => QualifiedName(p, n) })
- def openElement(end: String) = "<" ~> qualifiedName ~ attributeList <~ end
- def closeElement: Parser[QualifiedName] = ("</" ~> qualifiedName) <~ repS ~ ">"
- def attributeList = rep(attribute)
- def attribute = ((S ~> IDENT <~ repS <~ "=" <~ repS) ~ STRING) ^^ { case n ~ v => Attribute(n, toExpression(v)) }
- val expression = wrapped("${", "}") ^^ { DollarExpressionFragment(_) }
- def toExpression(text: String) = expressionParser.parseExpression(text)
- }
- class InvalidJspException(
- val brief: String,
- val pos: Position = NoPosition) extends TemplateException(brief + " at " + pos)