Skip to content

Instantly share code, notes, and snippets.

@ymnk
Created September 16, 2009 07:58
Show Gist options
  • Save ymnk/187924 to your computer and use it in GitHub Desktop.
Save ymnk/187924 to your computer and use it in GitHub Desktop.
A simple Liftweb app: Clock with CometActor
package com.test
import _root_.java.io.File
import _root_.junit.framework._
import Assert._
import _root_.scala.xml.XML
import _root_.net.liftweb.util._
object AppTest {
def suite: Test = {
val suite = new TestSuite(classOf[AppTest])
suite
}
def main(args : Array[String]) {
_root_.junit.textui.TestRunner.run(suite)
}
}
/**
* Unit test for simple App.
*/
class AppTest extends TestCase("app") {
/**
* Rigourous Tests :-)
*/
def testOK() = assertTrue(true)
// def testKO() = assertTrue(false);
/**
* Tests to make sure the project's XML files are well-formed.
*
* Finds every *.html and *.xml file in src/main/webapp (and its
* subdirectories) and tests to make sure they are well-formed.
*/
def testXml() = {
var failed: List[File] = Nil
def handledXml(file: String) =
file.endsWith(".xml")
def handledXHtml(file: String) =
file.endsWith(".html") || file.endsWith(".htm") || file.endsWith(".xhtml")
def wellFormed(file: File) {
if (file.isDirectory)
for (f <- file.listFiles) wellFormed(f)
if (file.isFile && handledXml(file.getName)) {
try {
XML.loadFile(file)
} catch {
case e: _root_.org.xml.sax.SAXParseException => failed = file :: failed
}
}
if (file.isFile && handledXHtml(file.getName)) {
PCDataXmlParser(new java.io.FileInputStream(file.getAbsolutePath)) match {
case Full(_) => // file is ok
case _ => failed = file :: failed
}
}
}
wellFormed(new File("src/main/webapp"))
val numFails = failed.size
if (numFails > 0) {
val fileStr = if (numFails == 1) "file" else "files"
val msg = "Malformed XML in " + numFails + " " + fileStr + ": " + failed.mkString(", ")
println(msg)
fail(msg)
}
}
}
package bootstrap.liftweb
import _root_.net.liftweb.http._
import _root_.net.liftweb._
import provider._
import util._
import sitemap._
import Helpers._
/**
* A class that's instantiated early and run. It allows the application
* to modify lift's environment
*/
class Boot {
def boot {
// where to search snippet
LiftRules.addToPackages("com.test")
LiftRules.early.append(makeUtf8)
}
/**
* Force the request to be UTF-8
*/
private def makeUtf8(req: HTTPRequest) = {
req.setCharacterEncoding("UTF-8")
}
}
package com.test.comet
import _root_.net.liftweb._
import http._
import util._
import Helpers._
import js._
import JsCmds._
import _root_.scala.xml.Text
class Clock extends CometActor {
override def defaultPrefix = Full("clk")
ActorPing.schedule(this, Tick, 1 seconds)
private lazy val spanId = uniqueId+"_timespan"
def render = bind("time" -> timeSpan)
def timeSpan = (<span id={spanId}>{timeNow}</span>)
override def lowPriority = {
case Tick =>
partialUpdate(SetHtml(spanId, Text(timeNow.toString)))
ActorPing.schedule(this, Tick, 1 seconds)
}
}
case object Tick
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:lift="http://liftweb.net/">
<head>
<title>Real-Time Chat</title>
<lift:CSS.blueprint />
<lift:CSS.fancyType />
<script id="jq" src="/classpath/jquery.js" type="text/javascript"/>
<script id="json" src="/classpath/json.js" type="text/javascript"/>
</head>
<body>
<lift:bind name="content" />
</body>
</html>
<lift:surround with="default" at="content">
<h2>Clock</h2>
<lift:comet type="Clock">
Current Time: <clk:time>Missing Clock</clk:time>
</lift:comet>
</lift:surround>
import _root_.bootstrap.liftweb.Boot
import _root_.scala.tools.nsc.MainGenericRunner
object LiftConsole {
def main(args : Array[String]) {
// Instantiate your project's Boot file
val b = new Boot()
// Boot your project
b.boot
// Now run the MainGenericRunner to get your repl
MainGenericRunner.main(args)
// After the repl exits, then exit the scala script
exit(0)
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>clock</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>clock</name>
<inceptionYear>2009</inceptionYear>
<properties>
<scala.version>2.7.5</scala.version>
</properties>
<repositories>
<repository>
<id>scala-tools.org</id>
<name>Scala-Tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>scala-tools.org</id>
<name>Scala-Tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>net.liftweb</groupId>
<artifactId>lift-util</artifactId>
<version>1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.liftweb</groupId>
<artifactId>lift-webkit</artifactId>
<version>1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.liftweb</groupId>
<artifactId>lift-mapper</artifactId>
<version>1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>[6.1.6,)</version>
<scope>test</scope>
</dependency>
<!-- for LiftConsole -->
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-compiler</artifactId>
<version>${scala.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<configuration>
<contextPath>/</contextPath>
<scanIntervalSeconds>5</scanIntervalSeconds>
</configuration>
</plugin>
<plugin>
<groupId>net.sf.alchim</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<nosuffix>true</nosuffix>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<downloadSources>true</downloadSources>
<excludes>
<exclude>org.scala-lang:scala-library</exclude>
</excludes>
<classpathContainers>
<classpathContainer>ch.epfl.lamp.sdt.launching.SCALA_CONTAINER</classpathContainer>
</classpathContainers>
<projectnatures>
<java.lang.String>ch.epfl.lamp.sdt.core.scalanature</java.lang.String>
<java.lang.String>org.eclipse.jdt.core.javanature</java.lang.String>
</projectnatures>
<buildcommands>
<java.lang.String>ch.epfl.lamp.sdt.core.scalabuilder</java.lang.String>
</buildcommands>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
</configuration>
</plugin>
</plugins>
</reporting>
</project>
import _root_.org.mortbay.jetty.Connector
import _root_.org.mortbay.jetty.Server
import _root_.org.mortbay.jetty.webapp.WebAppContext
object RunWebApp extends Application {
val server = new Server(8080)
val context = new WebAppContext()
context.setServer(server)
context.setContextPath("/")
context.setWar("src/main/webapp")
server.addHandler(context)
try {
println(">>> STARTING EMBEDDED JETTY SERVER, PRESS ANY KEY TO STOP")
server.start()
while (System.in.available() == 0) {
Thread.sleep(5000)
}
server.stop()
server.join()
} catch {
case exc : Exception => {
exc.printStackTrace()
System.exit(100)
}
}
}
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<filter>
<filter-name>LiftFilter</filter-name>
<display-name>Lift Filter</display-name>
<description>The Filter that intercepts lift calls</description>
<filter-class>net.liftweb.http.LiftFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LiftFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment