正規表現
package ryugate.text import java.util.regex.Pattern import java.util.regex.Matcher class Regexp(ptn:Pattern) { def this(str:String) = this(Pattern.compile(str)) def re_match(str:String):Matcher = { val md = ptn.matcher(str) if (md.matches) md else null } }
使うときには
val str = "/123" val md = new Regexp("\\/([0-9]+)").re_match(str)
のようになる。
しかし、 正規表現リテラルが無いだけで、
急に(ライトウェイトでないと言う意味で)ヘビーな言語に見えてくる。
「どう書く.org」にimplicitを使って
既存のクラスを拡張(したのと同じ効果を出す)方法
(http://ja.doukaku.org/51/lang/scala/)
が乗っていたので、
次はそいつを利用してみる予定。
ついでに(というか、正規表現に手を付けたのもこっちがきっかけだが)
httpdサーバのテストプログラムを改良して、
URLによっては画像を返すようにしてみた。
import java.io.PrintWriter import javax.servlet.http.HttpServlet import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse import org.mortbay.jetty.Connector import org.mortbay.jetty.Server import org.mortbay.jetty.nio.SelectChannelConnector import org.mortbay.jetty.servlet.ServletHandler import org.mortbay.jetty.NCSARequestLog import org.mortbay.jetty.handler.RequestLogHandler import org.apache.velocity.app.Velocity; import org.apache.velocity.VelocityContext; import org.apache.velocity.Template; import java.awt.Font import java.awt.Color import java.awt.GraphicsEnvironment import javax.imageio.ImageIO import ryugate.image._ import ryugate.video._ import ryugate.text._ //------------------------------------ class ServletServer extends HttpServlet { override protected def doGet(request:HttpServletRequest, response:HttpServletResponse) { common(request, response) } override protected def doPost(request:HttpServletRequest, response:HttpServletResponse) { common(request, response) } override protected def doPut(request:HttpServletRequest, response:HttpServletResponse) { common(request, response) } override protected def doDelete(request:HttpServletRequest, response:HttpServletResponse) { common(request, response) } //------------------------------------ def common(request:HttpServletRequest, response:HttpServletResponse) { val md = new Regexp("\\/([0-9]+)").re_match(request.getPathInfo) if (md != null) { val outstream = response.getOutputStream response.setContentType("image/png") ImageIO.write(make_image(md.group(1).toInt, 5).image, "png", outstream) } else { val outwriter = response.getWriter val context = makeContext context.put("request", request) context.put("body", read_body(request)) response.setContentType("text/html") Velocity.getTemplate("example.vm").merge(context, outwriter); } } //------------------------------------ def read_body(request:HttpServletRequest) = { val reader = request.getReader var body = "" var line = reader.readLine while(line != null) { body += line body += "\n" line = reader.readLine } reader.close body } //------------------------------------ def make_image(no:int, r:int) = { val img = new Image(400,300, Image.TYPE_INT_RGB) img.clearBackground(Color.BLUE) img.process{g => g.setFont("MS Gothic", Font.BOLD, 48) g.antialias{g => g.drawString(new Timecode(no).tc(r).toString, 50,100) g.drawString(Format.sprintf("%04d", no), 50,150) } } } //------------------------------------ def makeContext() = { val context = new VelocityContext(); context.put("array1", Array("10","20")) val ar = Array("10","20") context.put("array1", ar) val lst = List("30","40") context.put("list1", lst.toArray) val ar2 = lst.toArray context.put("array2", ar2) context } } //------------------------------------ object httpd extends Application { Velocity.init("velocity.properties"); //------------------------------------ val server = new Server val connector = new SelectChannelConnector val requestLog = new NCSARequestLog val requestLogHandler = new RequestLogHandler connector.setPort(8080) server.addConnector(connector) requestLog.setExtended(false) requestLogHandler.setRequestLog(requestLog) server.addHandler(requestLogHandler) //------------------------------------ val servletHandler = new ServletHandler servletHandler.addServletWithMapping(classOf[ServletServer], "/hoge/*") server.addHandler(servletHandler) //------------------------------------ server.start server.join }