Cómo hacer un catálogo básico (ABC) en Lift 2.6


En esta ocasión les presento cómo hacer un catálogo básico (ABC) en un ambiente web, utilizando este framework de desarrollo para aplicaciones web, llamado Lift.

De acuerdo a liftweb.net, Lift es el framework web más poderoso y más seguro que existe hoy día. Si te interesa ver a detalle las razones detrás de esta afirmación visita:http://seventhings.liftweb.net.

Las aplicaciones  desarrolladas en lift tienen las siguientes características:
  1. Seguras. Son resistentes a las vulnerabilidades comunes incluídas en varias de los top 10 OWASP.
  2. Centrado en el desarrollo. Son rápidas de construir, concisas y fáciles de mantener.
  3. Diseño amigable.
  4. Escalable. Son de alto rendimiento y escalan en un mundo real para soportar niveles de tráfico fuera de lo cumún.
  5. Modular. Se benefician de los módulos preconstruidos y fáciles de integrar entre sí.
  6. Interactivo como una aplicación de escritorio. El soporte de los Comet no tiene paralelo y el soporte de Ajax es súper fácil y muy seguro.
Como se puede apreciar, este framework asegura ofrecer grandes ventajas, las cuales hemos decidido probar.

Procedimiento
Antes de iniciar, debo decir que Lift está creado en Scala, lenguaje que soporta todas las librerías de Java, por lo que se pueden hacer cosas muy interesantes!

Todo lo aquí mostrado, está basado en el siguiente proyecto que se encuentra en GitHub: https://github.com/dph01/lift-CRUDBasic/

Lo primero que hay que hacer, es descargar Lift versión 2.6. Esta versión, ya está integrada con Bootstrap3, lo cual es una gran ventaja para un desarrollo aplicaciones web elegantes, adaptables (responsive) a los diversos dispositivos móviles disponibles hoy día.


Una vez que se ha descomprimido archivo ZIP o TAR que se ha descargado, se ingresa al directorio lift_advanced_bs3, y se escribe ./sbt. Se comenzarán a descargar todos las librerías necesarias para que esta aplicación se ejecute de manera correcta.

Según afirma la documentación, puedes levantar tu proyecto con Maven, Ant, Gradle o SBT.


Una vez finalicen las descargas, se escribe container:start para ejecutar el proyecto. Cuando alla compilado, en el navegador hay que poner localhost:8080. Si es necesario, se configurar el puerto que se prefiera. En este proyecto se usa el 8082, porque el 8080 dece que ya esta en uso. Para configurar el puerto, hay que ir al archivo build.sbt (este archivo esta en la raiz del proyecto), y agregar la siguiente lineaal final de todo el codigo: port in container.Configuration := 8082.

Ya debe ser posible ver el proyecto en el navegador. Es recomendable explorarlo para que ver cómo funciona, notaras que ya guarda datos(!ya se conecta a una base de datos¡).

Empieza lo mejor, hay que entrar a ./src/main. Hay 3 carpetas(resources, scala y webapp), es recomendable dar un vistazo general a todas las carpetas para ver que contiene cada una de ellas.

Para iniciar, hay que entrar a main/scala/bootstrap/liftweb/Boot.scala, cualquier editor de texto es bueno. Alli se puede encontrar el menú de esta app. Todas las modificaciones del menu, se harán en Boot.scala.

En este archivo se puede ver un menú asi:
object Site {
    import scala.xml._
    val divider1   = Menu("divider1") / "divider1"
    val ddLabel1   = Menu.i("UserDDLabel") / "ddlabel1"
    val home       = Menu.i("Home") / "index" 
    val userMenu   = User.AddUserMenusHere
    val static     = Menu(Loc("Static", Link(List("static"), true, "/static/index"), S.loc("StaticContent" , scala.xml.Text("Static Content")),LocGroup("lg2","topRight")))
   val twbs  = Menu(Loc("twbs", 
        ExtLink("http://getbootstrap.com/"), 
        S.loc("Bootstrap3", Text("Bootstrap3")), 
        LocGroup("lg2"),
        FoBo.TBLocInfo.LinkTargetBlank ))     
    
    
    def sitemap = SiteMap(
        home          >> LocGroup("lg1"),
        static,
        twbs,
        ddLabel1      >> LocGroup("topRight") >> PlaceHolder submenus (
            divider1  >> FoBo.TBLocInfo.Divider >> userMenu
            )
         )
  }


A continuacion se mostrara como agregar opciones al menú. En esta parte se agregara el modulo estación. Bajo la linea 5, seran agregadas las nuevas opciones del menu, si se desea, se puede copiar la linea 5  (val home = Menu.i("Home") / "index"), y pegarla justo en la siguiente línea, y cambiar el nombre a las variables por las que se agregaran, en este caso, estación, quedando la linea 6 de la siguiente manera val estacion = Menu.i("Estación") / "index". Ahora, es necesario ir a donde está la función Sitemap que se encuentra en la linea 15, hay que copiar la linea 16, y en la siguiente linea pegarla y cambiar el nombre, quedando de la siguiente forma:

estacion    >>      LocGroup("lg1").

La opción estación ya esta agregada al sitMap, por lo tanto ya es posible verla en el menu, pero aun no es posible acceder a dicha opción.

Es tiempo de crear el catálogo, para eso hay que ir a  main/webapp y crear una carpeta, se llamara catálogos, dentro de la carpeta se creara el archivo estacionForm.html.

estacionForm.html


En la  linea 2 se esta llamando a un snippet con el nombre de EstacionSn, que a su vez llama a la funcion create, lo siguiente será crear el snippet EstacionSn.

Dentro de scala/code/snippet se creara el archivo EstacionSn.scala.
package code
package snippet

import net.liftweb._
import http._
import common._
import util.Helpers._
import scala.xml.NodeSeq

import net.liftweb.http._
import util._
import Helpers._
import TimeHelpers._
import net.liftweb.common.Logger
import net.liftweb.mapper._
import scala.xml._

import code.model.catalogos.Estacion

/**
 * A stateful snippet. The state associated with this
 * snippet is in instance variables
 */



class EstacionSn extends Logger {

  object estacionVar extends RequestVar[Estacion](Estacion.create)

  def processSubmit() = {
    estacionVar.is.validate match {
      case Nil => {
       
        estacionVar.is.save
        S.notice("Estacion guardada")
       
        S.seeOther("/catalogos%2FestacionList")
      }
      case errors => S.error(errors)
    }
  }
}

 Una vez creado el snippet EscalaSn.scala, sera necesario agregar la funcion create, bajo la linea 42 se agregaran las siguientes lineas:

def create = {
    
    val estacion = estacionVar.is
    
    "#hidden" #> SHtml.hidden(() => estacionVar(estacion) ) &
    "#estacionname" #> SHtml.text(estacionVar.is.estacionName, name => estacionVar.is.estacionName(name) ) &
    "#submit" #> SHtml.onSubmitUnit(processSubmit)
  }

Tambien sera necesario un model Estacion.scala, esto se hara en una nueva carpeta que se llamara catalogos, que estara adentro de la carpte model, ubicada en /src/main/scala/code/model.
Una vez creada la carpeta, adentro de ella, se creara el archivo Estacion.scala

Estacion.scala
package code
package model
package catalogos

import net.liftweb.mapper._
import net.liftweb.util._
import net.liftweb.common._
import net.liftweb.sitemap.Loc._
import net.liftweb.http._
import net.liftweb.http.SHtml._
import net.liftmodules.FoBoBs.mapper._

import net.liftweb.common.Logger
import net.liftweb.mapper.{MappedString, ValidateLength, LongKeyedMetaMapper, LongKeyedMapper, IdPK}

class Estacion extends LongKeyedMapper[Estacion]
with IdPK with Logger {
def getSingleton = Estacion

object estacionName extends MappedString(this, 30) with ValidateLength {
}

}

object Estacion extends Estacion
with LongKeyedMetaMapper[Estacion] {} 

Es necesario importar catalogos en el Boot.scala, en la parte de los import, agregaremos la siguiente linea bajo la linea 13

import catalogos._

Ahora el catálogo esta terminado y funcionando.

Lo que sigue ahora es guardar en la base de datos, aqui se muestra el ejemplo con PostgreSQL, basicamente es lo mismo para otras bases de datos, para esto es necesario hacer algunos import.

Al final de los import se agrega la siguiente linea

import _root_.java.sql._

Hay que modificar este codigo

if (!DB.jndiJdbcConnAvailable_?) {
      val vendor = 
 new StandardDBVendor(Props.get("db.driver") openOr "org.h2.Driver",
        Props.get("db.url") openOr 
        "jdbc:h2:lift_proto.db;AUTO_SERVER=TRUE",
        Props.get("db.user"), Props.get("db.password"))

      LiftRules.unloadHooks.append(vendor.closeAllConnections_! _)

      DB.defineConnectionManager(util.DefaultConnectionIdentifier, vendor)
    }

Muy bien, para no estar tumbando el proyecto cada vez que se añade codigo nuevo, se pueden guardar los cambios y compilar al mismo tiempo y una sola vez, esto se hace en la terminal, después de escribir la sentencia ./sbt, se escribe la siuiente sentencia ~;container:start; container:reload / esto permite compilar automaticamente cada vez que se guardan los cambios en el archivo que se ha modificado.

Conclusión
De manera breve, aquí se mostró cómo tener una opción nueva en el menú, un formulario de captura, un model y el snippet que recibe los datos de captura.
Como se puede apreciar, para aquellos que venimos de las tierras de Java y Spring, esta forma de desarrollo es muy distinta! Sin embargo, es más sencilla.

En posteriores publicaciones, se compartirán nuevos avances en el desarrollo de aplicaciones web.

Revisado por: Omar Soto

Comentarios

Entradas populares de este blog

Batch File como Servicio de Windows

Cómo crear archivos XML en Java con JAXB

Ejecutando Jetty como un Servicio en Windows Server 2012