I recently read one
topic , I looked for a bit of a utility on the Internet that would display the decryption of processor flags, I could not find it, so I took it and wrote my own. Using
LiftWeb .
I want to share the writing process. Immediately I warn you, there is a lot of text inside, but you can go directly to the practice, skipping the theoretical part.
So, we will need:
- maven (I used version 3)
- Internet connection (maven will download a lot of things)
- IDE or text editor
To create the skeleton of the application, use maven:
mvn archetype:generate -DarchetypeGroupId=net.liftweb -DarchetypeArtifactId=lift-archetype-blank_2.8.1 -DarchetypeVersion=2.2-RC6 -DarchetypeRepository=http://scala-tools.org/repo-snapshots -DremoteRepositories=http://scala-tools.org/repo-snapshots -DgroupId=app.example -DartifactId=cpuflags -Dpackage=app.example.cpuflags
And the project can already run! mvn jetty: run and go to localhost: 8080

Yes, while there is not enough functionality, and we will fix it.
')
But at the beginning there’s some theory
The project is a regular J2EE web application. There is a web.xml with a single purpose - to download LiftFilter, which will deal with all the magic.
During initialization, the filter calls the bootstrap.liftweb.Boot.boot method, which is responsible for setting up the framework. In particular, it describes in which packages to look for snippets (about them later). Also in this newly generated method a menu is created, but we don’t need it and can delete it.
Now about the life cycle of the request. When a URL is accessed, the framework finds the corresponding template, renders it and gives the result to the user. The rules for “finding” a template can be changed in the boot method, but this is a topic for a separate article. To begin with, we’ll have enough knowledge that the templates are located in the webapp directory and are mapped one-to-one to the request URL, that is, when you request localhost: 8080 / index.html, the index.html template will be rendered and so on.
Each template is an xml file. Here is the generated index.html for our project:
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p> <lift:helloWorld.howdy> <span>Welcome to cpuflags at <b:time/></span> </lift:helloWorld.howdy> </p> </lift:surround>
It uses the most important part of LiftWeb - snippets. A snippet is a scala method that accepts html as input, processes it in some way and outputs it as output.
For example, the lift: surround snippet performs an important function: template mapping in html. In this example, the following happens:
- in the templates-hidden directory, a file with the name default.html is searched (the name is taken from the with attribute, plus the html extension)
Here is this file:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:lift="http://liftweb.net/"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta name="description" content="" /> <meta name="keywords" content="" /> <title>app.example:cpuflags:1.0-SNAPSHOT</title> <script id="jquery" src="/classpath/jquery.js" type="text/javascript"></script> </head> <body> <lift:bind name="content" /> <lift:Menu.builder /> <lift:msgs/> </body> </html>
- inside this file, look for a lift: bind node with the name content (the name is taken from the at attribute)
- the contents of lift: bind is replaced by the contents of lift: surround from the template
Snippet lift: helloWorld.howdy is no longer a standard snippet, but a generated snippet. When LiftWeb encounters a link to a snippet, and if it is not a standard snippet, then a search takes place among our scala code. For this, the app.example.cpuflags package was specified in the boot method. In this case, a new instance of the app.example.cpuflags.HelloWorld class is created and its howdy method is called.
Here is this method:
def howdy(in: NodeSeq): NodeSeq = Helpers.bind("b", in, "time" -> (new _root_.java.util.Date).toString)
Everything is simple: inside in (which is the html input to the input), the b: time node is searched (which is in the template) and is replaced with the current date. The result is returned by the method.
Enough theory, it's time to start practicing
Change template:
<lift:surround with="default" at="content"> <h2>Enter your CPU flags</h2> <form method="get"> <input type="text" name="flags"/> <input type="submit"/> </form> <table cellpadding="10"> <lift:CpuInfo.flags> <tr> <td><flag:name/></td> <td><flag:description/></td> </tr> </lift:CpuInfo.flags> </table> </lift:surround>
Create a snippet app.example.cpuflags.snippet.CpuInfo.scala:
package app.example.cpuflags.snippet import xml.NodeSeq import net.liftweb.util.BindHelpers._ import net.liftweb.http.{S} import java.util.Properties class CpuInfo { def flags(html: NodeSeq): NodeSeq = { val a1 = CpuFlags.getInfo(S.param("flags").openOr("")) a1.flatMap( p => bind("flag", html, "name" -> p._1, "description" -> p._2) ) } } object CpuFlags { val propertyMap = { val props = new Properties props.load(this.getClass.getClassLoader.getResourceAsStream("cpuflags.properties")) props } def getInfo(flags: String) = { val s = flags.trim.toUpperCase if (s.size>0) s.split(" +").toList.map( (flag) => (flag, if (propertyMap.getProperty(flag)!=null) propertyMap.getProperty(flag) else "UNKNOWN FLAG") ) else List() } }
I created
cpuflags.properties using the information
from here . The list is not complete, but it was too lazy to look around and look further.
Everything, we restart jetty: run and we rejoice:

useful links