Scala android and actors

Scala expressiveness strikes back !

 

A sample showing iteration between scala actors and android.Activity

Extending activity with a trait  to receive events from another actors, services, or any other source ( listeners , as a observer … )

 
class MainActivity extends Activity 
                      with ActivityUtil 
                      with Reactive { 

    override def onCreate(savedInstanceState: Bundle) { 
        super.onCreate(savedInstanceState) 

        setContentView(R.layout.main) 

        button(R.id.Button01).onClicked { 
            app.actor ! Ping(this) 
        } 
    } 

    onReact { 
        case Pong(count) => onUi { 
            textView(R.id.Label1).setText("Pong -> " + count) 
        } 
    } 
} 

Isn’t she pretty ?

 

  1. ActivityUtil
    • Allow us to access activity components directly

       
      button(R.id.Button01)
  2. Reactive
    • Converts the activity into a scala actor
    • Calling onReact with the desired partialFunctions, allow us to manage the external events
      
      onReact {
          case Pong(count) => onUi {
              textView(R.id.Label1).setText("Pong -> " + count)
          }
      } 

      One problem, onReact resides inside another thread ( the actor one ), so to access components of the view, we must use onUi function

  3. ViewConversions
    • With a bunch of implicit conversions, we can implement Listeners directly with functions

      
      button(R.id.Button01).onClicked {
          app.actor ! Ping(this)
      } 
  4. The application class contains the other actor who returns Pong
    
    
    class App extends Application { 
        val actor = new SampleActor 
    
        override def onCreate(): Unit = { 
            actor.start 
        } 
    } 
    
    
    case class Pong(count: Int) 
    case class Ping(a: Actor) 
    
    class SampleActor extends Actor with L { 
        private var count = 0 
        def act() { 
            loop { 
                receive { 
                    case Ping(a) => { 
                        count = count + 1 
                        a ! Pong(count) 
                    } 
                } 
            } 
        } 
    } 
    


I just remembered why I love scala so much :)

 

PD: I used giter8 to get a scala-android template

 g8 gseitz/android-sbt-project 

 

Gnome shell extension wallpaper

Simple gnome-shell extension to change the wallpaper from the overview.

Get it from :

To change where to search wallpapers edit src/extension.js and set

const DIRECTORIES = [
       "/usr/share/backgrounds",
       GLib.get_home_dir() + "/Pictures",
       "another_directory"
];


with the image directories that you want.

By default it searchs in /usr/share/backgrounds AND $HOME/Pictures

Kate plugin experiment

Just a nasty experiment,

a kate plugin to open and visualize open files.

  • Open a new file (win + O)

  • View open files (win + B)

i haven’t had much time to refactor code so …
http://github.com/jgoday/newkateplugin

Sample OpenOffice 3 extension with scala 2.8 and sbt

Sample OpenOffice 3 extension with scala and sbt

  • Here’s a small sample of a openoffice 3 extension using scala and sbt
  • Project link: sample scala addon
  • Openoffice devel documentation: DevGuide and sdk samples :

    folder examples/ on openoffice sdk (usually located in /usr/lib/openoffice-dev)
  • I just ported ProtocolHandlerAddon_java to scala and sbt

    under examples/DevelopersGuide/Components/Addons/ProtocolHandlerAddon_java
  • using sbt,
    a little task (create_extension) will help to create the oxt file (with the .xcu files, scala-library jar, manifest …)

    $> sbt
       :> update
       :> compile
       :> package
       :> create_extension
    

Fun with liftweb and jquery dialogs

Here’s a sample of jquery-ui (version 1.8) dialogs in lift,
the code (a little ugly) can be found here : http://github.com/jgoday/liftweb-jquery-dialogs-sample

The sample has two main classes

  • 1: JQueryDialog

    Allow create generic dialogs from templates or with explicit content
    We can create a dialog like this :

    
    new JQueryDialog(<div>Dialog content</div>) {
        override def elementId = "dialog_id"
        override def options = "modal:true" ::
                               "title:'dialog title!'" ::
                               "open: function (event, ui) {alert('dialog is opening!');}" ::
                                super.options
    }
    
    
  • 2: FormDialog
    To create generic dialogs from templates and with default actions (close)

    
    val item = new Item
    def _template: NodeSeq = bind("item",
                TemplateFinder.findAnyTemplate("templates-hidden/item" :: Nil) openOr
                                               <div>{"Cannot find template"}</div>,
                "name" -> item.name.toForm)
    
    val dialog = new FormDialog(true) {
        override def getFormContent = _template
        override def confirmDialog: NodeSeq = SHtml.ajaxSubmit("save",
                () => {println(item);this.closeCmd}) ++ super.confirmDialog
    }
    
    

Scala traits

Really love scala,
traits and the ability of define custom types as interfaces.


type ObjectWithName = {
    def getName: String
}

trait NicePerson[T <: ObjectWithName] {
    def greet: String = {
        "Hello ! My name is %s".format(this.asInstanceOf[ObjectWithName].getName)
    }
}

class Person(name: String) {
    def getName: String = name
}

val peter = new Person("Peter") with NicePerson[Person]
println(peter.greet) // = Hello ! My name is Peter


How nice it is ?

Some references:
http://markthomas.info/blog/?p=92
http://codemonkeyism.com/scala-goodness-structural-typing/

scala dsl to perform sql searches: part 1

Reading designing-internal-dsls-in-scala.html(recommended!)
I come up with the idea of doing some simple scala DSL,
to write and perform SQL searchs using lift-mapper objects.

The result would be something like that:


var find = FIND(Item)
    WITH(ItemType.name AS type_name, ItemResponsible.name as responsible)
    WHEN (
        "type_name" ILIKE _nameVariable,
        "cancelled" IS_NULL,
        OR (
            "responsible" IS_NULL,
            "ItemResponsible.id" EQUALS _getLoggedUserID()
        )
    )
    LIMIT 100 OFFSET 20

...
performSearch(find)

Here’s a sample code



// types
type Condition = (() => Boolean, () => String)
type Operator  = (String, List[Condition])    

def _mergeConditions(operator: Operator): String = {
    var shouldApplyAndOperator = false // ????      

    var sql = ""
    var operatorFilters = ""
    val (operatorSQL, conditions) = operator

    var shouldApplyOperatorFilters = false

    conditions.foreach(cdt => {
        val (condition, filter) = cdt

        if (condition()) {
            val filterValue = shouldApplyOperatorFilters match {
                case true  => " %s (%s) ".format(operatorSQL, filter())
                case _ => " %s ".format(filter())                      
            }                                                          

            operatorFilters += filterValue
            shouldApplyOperatorFilters = true
        }                                    
    })                                       

    if (shouldApplyOperatorFilters) {
        val filterValue = shouldApplyAndOperator match {                        
            case true  => " %s (%s) ".format("AND", operatorFilters)         
  
            case _ => " %s ".format(operatorFilters)                         
  
        }                                                                       
                                                             
        sql += filterValue                                                      
        shouldApplyAndOperator = true                                           
    }                                                                           
                                                             
    sql                                                                         
}                                                                               
                                                             

// Base class to search objects
class Find(obj: String) {      
    private var fields: List[Any]         = List()
    private var operators: List[Operator] = List()

    def toSQL: String = {
        def _getFieldsAsSQL = this.fields.reduceLeft(_ + "," + _)
        def _getTableName = this.obj                             
        def _getOperatorsAsSQL = {                               
            var sql = ""                                         

            this.operators.foreach(op => {
                sql += _mergeConditions(op)
            })                             

            if (sql != "") sql = " WHERE " + sql
            sql                                 
        }                                       

        "SELECT %s FROM %s %s".format(
                _getFieldsAsSQL,      
                _getTableName,        
                _getOperatorsAsSQL)   
    }                                 

    /**
     * Adds a list of conditions around a sql AND operator
     */                                                   
    def AND(conditions: Condition*): Find = {             
        this.operators = ("AND", conditions.toList) :: this.operators
        this                                                         
    }                                                                

    /**
     * Adds a list of conditions around a sql OR operator
     */                                                  
    def OR(conditions: Condition*): Find = {             
        this.operators = ("OR",  conditions.toList) :: this.operators
        this                                                         
    }                                                                

    /**
     * Selects the object with custom fields
     */                                     
    def WITH(fields: Any*): Find = {        
        this.fields = fields.toList ::: this.fields
        this                                       
    }                                              
}                                                  

/** Global operator methods to composite conditions around a find object **/
def AND(conditions: Condition*): Condition = {                              
    (() => true, () => _mergeConditions("AND", conditions.toList))        
 
}                                                                           

def OR(conditions: Condition*): Condition = {
    (() => true, () => _mergeConditions("OR", conditions.toList))
}                                                                

// CONDITIONS AND WRAPPERS

class StaticConditionWrapper(filter: String) extends FunctionConditionWrapper(()
=> filter)
class FunctionConditionWrapper(filter: () => String) {                       
 
    def ALWAYS: Condition = {                                                  
        (() => true, filter)                                                
    }                                                                         
    def IF(condition: () => Boolean): Condition = {                        
        (condition, filter)                                                     
    }
    def IF(value: Boolean): Condition = {
        (() => value, filter)
    }
    def ILIKE(value: String): Condition = {
        (() => value != "", () => " %s ILIKE '%%%s%%' ".format(filter(),
value))
    }
    def IS_NULL: Condition = {
        (() => true, () => " %s IS NULL ".format(filter()))
    }
    def NOT_NULL: Condition = {
        (() => true, () => " %s IS NOT NULL ".format(filter()))
    }
}

implicit def IF(filter: String) = new StaticConditionWrapper(filter)
implicit def IF(filter: () => String) = new FunctionConditionWrapper(filter)


// Object FIND to easy create find objects (FIND("object_name"))
object FIND {
    def apply(obj: String): Find = new Find(obj)
}


The result of evaluting


// TEST
def checkCondition: () =>> Boolean = () => true
def someFilter: () => String = () => " something true"

val f = (
    FIND("ObjectName") WITH(1,2,3,4,5)
    AND (
        someFilter ALWAYS,
        "A" IF true,
        "B" IF checkCondition,
        OR (
            "C" ALWAYS,
            AND (
                "NAME" ILIKE "Pepe",
                "CANCELLED" IS_NULL
            )
        )
    )
)

println(f.toSQL)

is


SELECT 1,2,3,4,5 FROM ObjectName 
    WHERE 
    something true AND (A)  AND (B)  AND
        (  C  OR (   NAME ILIKE '%Pepe%'   AND ( CANCELLED IS NULL )  )  )

really nice :)

All filtering is based on

  • Conditions :
    
    type Condition = (() => Boolean, () => String)
    
    sample : (() => {result_of_checking_condition()),
              () => {create_some_sql_filter()})
    

    A couple, containing a function that will decide if the filter applies or not,
    and a function that makes the filter

  • Operators :
    
    type Operator = (String, List[Condition])
    

    Allows to composite conditions and envolves them with a SQL Operator (And/Or)

Follow

Get every new post delivered to your Inbox.