Friday, September 28, 2012

Variables in Scala files for Play 2.x

The scala html files for Play 2.x will eventually be compiled in classes/methods. Each one has a signature to allow type-safe parameter passing from controller to the view. But sometimes we need to include a script in the page and that is when the need for local variables may occur.
For instance I want to make sure I add HTML only if the object is not null. In JAVA this would be equivalent to:
Feature f = features.getFeature(featureName);
if (f != null) {
  .... use the feature object ....
}
or if I need to iterate:
for (Feature f : features) {
  if (f == null) continue;
  .... use the feature object ....
}
Note that I test the object for null and use "continue" instead of enclosing everything in the if block. It is a matter of preference - I think it makes the code more readable.

Two problems arise when trying to do the same in Scala in the html pages:

  • declaring local variables in Play scala pages is quite cumbersome
  • there is no "continue" in Scala.

Here are a few workarounds for the issues mentioned above:


  • Use "Option". Option is a replacement for checking for null. The map is created only if not null. In this case a map of one element is created and is assigned to “feature”.



@Option(features.getFeature(featureName)).map {feature=>
........}
  • What if there are more that one?
@Option(features.getFeature(featureName)).map {feature=>      @Option(1).map (f2 =>       }}
  • You can also use for loops.
@for(feature1 <- Option(features.getFeature(featureName));     f2 <- Option(1)) {
}

  • If List is used instead of Option, the for loop will be executed once for each item in the List. 

Thursday, June 28, 2012

Upgrade from Play 2.0.1 to 2.0.2

Say you have a project in Play 2.0.1, but guess what? There is a new (minor) version out there that might just fix a bug you care about. How do you go about upgrading?
Well, first you need to download the new Play 2.0.2 framework and replace the old one. Then, you need to edit a couple files in  your project in order to make it compatible:

  • edit [appName]/project/build.properties and change sbt version from 0.11.2 to 0.11.3. Like this:
    sbt.version=0.11.3
  • edit [appName]/project/plugins.sbt and change the version of play from 2.0.1 to 2.0.2. Like this:
    addSbtPlugin("play" % "sbt-plugin" % "2.0.2")
That's it! Now launch play again and you should see that it updates a bunch of libraries and then its' ready.
Additionally if you are using Eclipse IDE, you might need to re-eclipsify your app in order to fix the Eclipse project classpath to point to the new 2.0.2 directory.

Friday, May 25, 2012

Play2 Port Change

Play 2.0.1 defaults the port to 9000. But if you want to develop more that one app at a time you need to be able to change the port. Googling this you'll find the recommendation for typing in command line:
play "run 9001"
But this does not work in Windows. Until they fix this you need to do this in two steps. First enter the Play console with a simple:
play
then while in the Play console you can run the application with the port of your choice:
[appName] $ run 9001

Play2 Project Dependency

I have recently started to use Play framework, and I quite like it. It may have its issues, but all in all it is a neat framework. Like many other developers out there I want to use it from within my favourite IDE - Eclipse. And Play makes that happen via it "eclipsify" command.
All is good, when you are working on a single application. But what happens when you want to create more than one application and you realize that you don't want to copy the boiler plate code in each of the project. Take the security feature for example. Each app will have to implement it and Play does provide the basics but there is still some code to be written. And I don't want to copy the file(s) each time a I create a new app.
Now Eclipse does have a neat feature where you can create project dependencies which means that all the classes from the project you depend on are added to the classpath of your current project. Great! That works fine for regular Java projects, but Play does its own building behind the scenes which has nothing to do with Eclipse's build.
There is however a way out. And it is quite simple. You see, each Play 2.x project will create the .class files in the [project_dir]/target/scala-2.9.1/classes. (I suspect that the location will change later, when the scala version is updated).
Now let's say you have a project called "common" where you add all the utilities and boiler plate code. Then you have "myApp" where you want to use the code from "common" without copying it. In Eclipse, you go to Project Properties for "myApp", "Java Build Path", select "Project" tab and add the "common" project in the list of required projects. That takes care of the Eclipse side.
To make it work in Play, there is one other thing you need to do. Locate "Build.scala" file from "myApp" project (this will be in myApp/project/ directory). This is the file that controls the Play build. you want to modify it and add the classes generated by "common" project to both runtime and compile classpaths. This is how you can do it:

val wsdir = (new java.io.File("./..")).getCanonicalPath // workspace dir
val appDependencies = Seq(
    // Add your project dependencies here,
)


val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA)
      .settings( 
          dependencyClasspath in Runtime ++= Seq(file(wsdir+"/common/target/scala-2.9.1/classes"))
      )
      .settings(
          dependencyClasspath in Compile ++= Seq(file(wsdir+"/common/target/scala-2.9.1/classes"))
      )
Note that this code snippet assumes that projects "myApp" and "common" share a common parent directory.
And that's it for development. Creating the final build for production is another story and that depends on how you want to deploy your projects.

Thursday, May 24, 2012

Single Sign On with SAML2

This is a complicated topic with a lot of information published in the form of articles all over the internet. While SSO can be done in various ways and with different technologies, it seems like the standard that has the most traction is the Web Browser SSO Profile in SAML2.
I find it odd that I could not find a good SSO or SAML book anywhere. Which makes it difficult for a beginner to tackle. There is a pretty good description of the process on Wikipedia though.
Well one has to start somewhere so, being in the Java camp I looked for the options available to the Java programmer. As it turns out, if you want to go the SAML way there is an open source solution called Shibboleth. This is based on OpenSAML 
There is even a test Identity Provider (IdP) available on the internet: TestShib. However, since I was working on the company network behind firewalls I could not use it. As part of the sequence of events, the IdP needs to redirect to the Service Provider (SP) and that part did not work for my setup.
As such I downloaded and installed Shibboleth IdP in a Tomcat instance and gave it a go. I must say that while there isn't much code involved (or that complicated), what proved to be the most difficult part was the configuration of Shibboleth IdP and the metadata file. Once you get that right as well as the certificates, it is not much to it.
So while there are examples out there (perhaps better written or more complete) I created my own and put it in  GitHub. Check it out here: https://github.com/cduicu/SAML2Authn.