Sunday, September 5, 2010

Google Web Toolkit RPC

Google Web Toolkit
  • GWT Java-to-JavaScript Compiler
  • JRE emulation library
  • GWT web UI
  • Development tools (Hosted web browser, shell,..)
  • RPC

Communicating with the server
  • RPC
  • XML
  • JSON

Packages

 


Making GWT Remote Procedure Calls

 



Modul

 



UI

package cz.kibo.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.TextBox;

public class SayHelloEntryPoint implements EntryPoint {

    private TextBox name = new TextBox();  
    private Label response = new Label();
    private Button button = new Button("Send");

    private HelloServiceAsync service;
    private AsyncCallback serviceCallback = new AsyncCallback() {
           public void onSuccess(Object result) {
              String string = (String) result;               
              response.setText(string);
           }

           public void onFailure(Throwable caught) {
               response.setText("There was an error: " + caught.toString());
           }
    };

    /**
    * Creates a new instance of MainEntryPoint
    */
    public SayHelloEntryPoint() {
    }

    /**
    * The entry point method, called automatically by loading a module
    * that declares an implementing class as an entry-point
    */
    public void onModuleLoad() {
     
       //Obtain Async service for interface
       service = GWT.create(HelloService.class);

       //go to URL
       //or use @RemoteServiceRelativePath("hello")
       ServiceDefTarget endpoint = (ServiceDefTarget) service;
       endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() + "hello");


       RootPanel root = RootPanel.get("content");       
       root.add(new Label("Name"));
       root.add(name);     

       // Listen for mouse events on the Add button.
       button.addClickHandler(new ClickHandler() {
             public void onClick(ClickEvent event) {
                   service.sayHello(new Person(name.getText()), serviceCallback);
             }
       });

       root.add(button);
       root.add(response);

    }
}


Service
  • extends RemoteService
package cz.kibo.client;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

//@RemoteServiceRelativePath("hello")
public interface HelloService extends RemoteService
{
    String sayHello(Person p);

}

AsyncService
  • return void
  • have last param AsyncCallback
package cz.kibo.client;

import com.google.gwt.user.client.rpc.AsyncCallback;

public interface HelloServiceAsync {
    void sayHello(Person p, AsyncCallback callback);
}

Service implementation

  • can extends RemoteServiceServlet
  • or you have to implements HelloServlet yet
package cz.kibo.server;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import cz.kibo.client.HelloService;
import cz.kibo.client.Person;

public class HelloServiceImpl extends RemoteServiceServlet implements HelloService{

    public String sayHello(Person p) {
       return "Hello " + p.name;
    }
}

RemoteServiceServlet
  • getThreadLocalRequest() 
  • getThreadLocalResponse()
  • onBeforeRequestDeserialized (String) 
  • onAfterResponseSerialized (String) 
  • shouldCompressResponse (HttpServletRequest, HttpServletResponse, String)
  • processCall(String)



Model
  • implements Serializable or IsSerializable
package cz.kibo.client;

import java.io.Serializable;

public class Person implements Serializable{

    public String name;
  
    public Person(){
              this(null);
    }

    public Person(String name) {
          super();
          this.name = name;      
    }
}

Netbeans project

Wednesday, August 18, 2010

XSLT

Text are from http://www.w3schools.com/xsl/


  • XSL stands for EXtensible Stylesheet Language.
  • CSS - Style Sheet for HTML
  • XSL - Style Sheet fot XML
  • XSL describes how the XML document should be displayed!

XSL consists of three parts:
  • XSLT - a language for transforming XML documents
  • XPath - a language for navigating in XML documents
  • XSL-FO - a language for formatting XML documents

XSLT

  • XSLT stands for XSL Transformations
  • XSLT is the most important part of XSL
  • XSLT transforms an XML document into another XML document
  • XSLT uses XPath to navigate in XML documents
  • All major browsers have support for XML and XSLT.

XSLT - Transformation

Declaration
The root element that declares the document to be an XSL style sheet is <xsl:stylesheet> or <xsl:transform>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
or
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

example transformation 
Source xml file.


Source XSL Style Sheet file.
 

Result of transformation.
 


<xsl:template>

The <xsl:template> element is used to build templates.

The match attribute is used to associate a template with an XML element. The match attribute can also be used to define a template for the entire XML document. The value of the match attribute is an XPath expression (i.e. match="/" defines the whole document).

example:
 



<xsl:value-of>

The <xsl:value-of> element can be used to extract the value of an XML element and add it to the output stream of the transformation:
 


<xsl:for-each>

The XSL <xsl:for-each> element can be used to select every XML element of a specified node-set:
 

Filtering

We can also filter the output from the XML file by adding a criterion to the select attribute in the <xsl:for-each> element.
 



<xsl:sort>

The <xsl:sort> element is used to sort the output.



<xsl:if>

The <xsl:if> element is used to put a conditional test against the content of the XML file.


<xsl:choose>

The <xsl:choose> element is used in conjunction with <xsl:when> and <xsl:otherwise> to express multiple conditional tests.




<xsl:apply-templates>

The <xsl:apply-templates> element applies a template to the current element or to the current element's child nodes.
If we add a select attribute to the <xsl:apply-templates> element it will process only the child element that matches the value of the attribute. We can use the select attribute to specify the order in which the child nodes are processed.

Friday, August 6, 2010

Grails: Unit testing

Source:


The core of the testing plugin is the grails.test.GrailsUnitTestCase class.


mockDomain(class, testInstances)

Takes a class and makes mock implementations of all the domain class methods.

example:
void testSomething() {
  def testInstances=[]
  mockDomain(Song, testInstances)
  assertEquals(0, Song.count())
  new Song(name:"Supper's Ready").save()
  assertEquals(1, Song.count())
}

example:
def testInstances = [ new Item(code: "NH-4273997", name: "Laptop"),
                new Item(code: "EC-4395734", name: "Lamp"),
                new Item(code: "TF-4927324", name: "Laptop") ]
mockDomain(Item, testInstances)



mockForConstraintsTests(class, testInstances)

Highly specialised mocking for domain classes and command objects that allows you to check whether the constraints are behaving as you expect them to.

example:
class Book {
  String title
  String author
    static constraints = {
        title(blank: false, unique: true)
        author(blank: false, minSize: 5)
    }
}

class BookTests extends GrailsUnitTestCase {
  void testConstraints() {
      def existingBook = new Book(title: "Misery", author: "Stephen King")
      mockForConstraintsTests(Book, [ existingBook ])
        // Validation should fail if both properties are null.
        def book = new Book()
        assertFalse book.validate()
        assertEquals "nullable", book.errors["title"]
        assertEquals "nullable", book.errors["author"]
        // So let's demonstrate the unique and minSize constraints.
        book = new Book(title: "Misery", author: "JK")
        assertFalse book.validate()
        assertEquals "unique",     book.errors["title"]
        assertEquals "minSize", book.errors["author"]
        // Validation should pass!
        book = new Book(title: "The Shining", author: "Stephen King")
        assertTrue book.validate()
    }
}



mockFor(class)

 

This range determines how many times you expect the method to be called, so if the number of invocations falls outside of that range then an assertion error will be thrown. If no range is specified, a default of "1..1" is assumed.

The closure arguments should match the number and types of the mocked method, but otherwise you are free to add whatever you want in the body.


example:
def strictControl = mockFor(MyService)
strictControl.demand.someMethod(0..2) { String arg1, int arg2 -> … }
strictControl.demand.static.aStaticMethod {-> … }

example:
class MyService { def otherService
    String createSomething() {        
        def stringId = otherService.newIdentifier()        
        def item = new Item(code: stringId, name: "Bangle")        
        item.save()        
        return stringId      
   }
   
   int countItems(String name) {        
        def items = Item.findAllByName(name)        
        return items.size()    
   }
}

import grails.test.GrailsUnitTestCase
class MyServiceTests extends GrailsUnitTestCase {
    void testCreateSomething() {
        // Mock the domain class.
        mockDomain(Item)

        // Mock the "other" service.
        String testId = "NH-12347686"
        def otherControl = mockFor(OtherService)
        otherControl.demand.newIdentifier(1..1) {-> return testId }

        // Initialise the service and test the target method.
        def testService = new MyService()
        testService.otherService = otherControl.createMock()

        def retval = testService.createSomething()

        // Check that the method returns the identifier returned by the
        // mock "other" service and also that a new Item instance has
        // been saved.
        def testInstances = Item.list()        
        assertEquals testId, retval
        assertEquals 1, testInstances.size()
        assertTrue testInstances[0] instanceof Item
    }

    void testCountItems() {
        // Mock the domain class, this time providing a list of test
        // Item instances that can be searched.
        def testInstances = [ new Item(code: "NH-4273997", name: "Laptop"),
                         new Item(code: "EC-4395734", name: "Lamp"),
                         new Item(code: "TF-4927324", name: "Laptop") ]
        mockDomain(Item, testInstances)
       

// Initialise the service and test the target method.

def testService = new MyService()
        assertEquals 2, testService.countItems("Laptop")
        assertEquals 1, testService.countItems("Lamp")
        assertEquals 0, testService.countItems("Chair")
    }
}


mockLogging(class, enableDebug = false)

Adds a mock "log" property to a class. Any messages passed to the mock logger are echoed to the console.




mockController(class)

Adds mock versions of the dynamic controller properties and methods to the given class. This is typically used in conjunction with the ControllerUnitTestCase class.

Mock controller properties available in unit tests
  • request
  • response
  • session
  • flash
  • params
  • redirectArgs
  • renderArgs
  • template
  • modelAndView
example:
class PostControllerUnitTests extends grails.test.ControllerUnitTestCase {
     void testShow() {
          mockDomain(User, [
                    new User(userId: "glen"),
                    new User(userId: "peter") ]
          this.controller.params.id = "peter"
          def model = this.controller.show()
          assertEquals "peter", model["viewUser"]?.userId
     }
}

example - action returns a model:
void testList() {
     mockDomain(Album, [ new Album(title: "Odelay"),
     new Album(title: "Abbey Road"] )
     def model = controller.list()
     assertEquals 2, model.albumList.size()
}

example - Testing the Contents of the Response:
void testIndex() {
     controller.index()
     assertEquals "Welcome to the gTunes store!", controller.response.contentAsString
}

example - contents of render args
render(view: "show", model:[album:Album.get(params.id)])

void testShow() {
     mockDomain(Album, new Album(id:1, title: "Aha Shake Heartbreak"))
     mockParams.id = 1
     controller.show()
     assertEquals "show", renderArgs.view
     assertEquals 1, renderArgs.model.album.id
     assertEquals "Aha Shake Heartbreak", renderArgs.model.album.title
}

mockParams: this property provides a mock implementation of the params object that you can populate with values before calling the controller. In addition to a mock implementation of the params object, the ControllerUnitTestCase class provides the following properties that mock various aspects of the controller API:
  • mockRequest
  • mockResponse
  • mockSession
  • mockParams
  • mockFlash
note:ControllerUnitTestCase not support some dynamic method. For instance: bindData(). Then is better use integration testing, or you can add this method to controller:
 example:
this.controller.metaClass.bindData = { obj, params ->
           params.each { key, value ->
                       obj."$key" = value
               }
       }

this.controller.metaClass.getGrailsApplication = {-> return [config: [:]] }


example - redirect:
//in controller
redirect(controller: "post", action: "list")

// in test
assertEquals "post", this.controller.redirectArgs["controller"]
assertEquals "list", this.controller.redirectArgs["action"]

example - testing action:
def register = {
     if(request.method == 'POST') {
          def u = new User(params)
          if(u.password != params.confirm) {
                u.errors.rejectValue("password", "user.password.dontmatch")
                return [user:u]
          }else if(u.save()) {
                session.user = u
                redirect(controller:"store")
          }else {
                return [user:u]
          }

     }
}

void testRegistrationFailed() {
     mockRequest.method = 'POST'
     mockDomain(User)

     mockParams.login = ""
     def model = controller.register()

     assertNull mockSession.user
     assert model
     def user = model.user
     assert user.hasErrors()
     assertEquals "blank", user.errors.login
     assertEquals "nullable", user.errors.password
     assertEquals "nullable",
     user.errors.firstName
     assertEquals "nullable", user.errors.firstName
}

void testRegistrationSuccess() {
     mockRequest.method = 'POST'
     mockDomain(User)

     mockParams.login = "joebloggs"
     mockParams.password = "password"
     mockParams.confirm = "password"
     mockParams.firstName = "Joe"
     mockParams.lastName = "Blogs"

     def model = controller.register()

     assertEquals 'store',redirectArgs.controller
     assertNotNull mockSession.user
}

example - test Command
def login = { LoginCommand cmd ->
     if(request.method == 'POST') {
        if(!cmd.hasErrors()) {
             session.user = cmd.getUser()
             redirect(controller:'store')
        }else {
             render(view:'/store/index', model:[loginCmd:cmd])
        }
     }else {
            render(view:'/store/index')
     }
}

void testLoginUserNotFound() {
     mockRequest.method = 'POST'
     mockDomain(User)
     MockUtils.prepareForConstraintsTests(LoginCommand)
     def cmd = new LoginCommand(login:"fred", password:"letmein")
     cmd.validate()
     controller.login(cmd)
     assertTrue cmd.hasErrors()
     assertEquals "user.not.found", cmd.errors.login
     assertEquals "/store/index", renderArgs.view
}

void testLoginPasswordInvalid() {
     mockRequest.method = 'POST'
     mockDomain(User, [new User(login:"fred", password:"realpassword")])
     MockUtils.prepareForConstraintsTests(LoginCommand)
     def cmd = new LoginCommand(login:"fred", password:"letmein")
     cmd.validate()
     controller.login(cmd)
     assertTrue cmd.hasErrors()
     assertEquals "user.password.invalid", cmd.errors.password
     assertEquals "/store/index", renderArgs.view
}

void testLoginSuccess() {
     mockRequest.method = 'POST'
     mockDomain(User, [new User(login:"fred", password:"letmein")])
     MockUtils.prepareForConstraintsTests(LoginCommand)
     def cmd = new LoginCommand(login:"fred", password:"letmein")
     cmd.validate()
     controller.login(cmd)
     assertFalse cmd.hasErrors()
     assertNotNull mockSession.user
     assertEquals "store", redirectArgs.controller
}



mockTagLib(class)

Adds mock versions of the dynamic taglib properties and methods to the given class. This is typically used in conjunction with the TagLibUnitTestCase class.

example:
class MyTagLib {
     def repeat = { attrs, body ->
            attrs.times?.toInteger().times { n ->
                      body(n)
             }
      }
}

<g:repeat times="3">Hello number ${it}</g:repeat>

import grails.test.*
class MyTagLibTests extends TagLibUnitTestCase {

     MyTagLibTests() {
         super(MyTagLib)
     }

     void testRepeat() {
         tagLib.repeat(times: '2') {
            'output<br/>'
         }

     assertEquals 'output<br/>output<br/>', tagLib.out.toString()
     }
}

example:





One oddity is the empty map ([:]) as an argument, which is required because the tag
expects an attribute map as the first argument. If we were passing in at least one attri-
bute value, we could use the implicit syntax instead:
tagLib.isLoggedIn(attr1: "value") { ... }


In order to check whether the appropriate text has been generated by the tag, we
then perform a toString() on the out property and compare it to the expected value

mockConfig

In your controller you have to use org.codehaus.groovy.grails.commons.ConfigurationHolder. Then is very simple used mockConfig.

example:
private void takeOverDemoTestsets(school) {
       def String[] ids = ConfigurationHolder.config.cz.svse.testy.demo.testsets.ids.split(",")
       ids.each(){ id ->
           def testset = Testset.get(id)
           if(testset){
               school.addToTestsets( testset.clone(  school ) )
               log.info(" add testset: ${testset.title}" )              
           }
   }
}

class SchoolControllerTests extends grails.test.ControllerUnitTestCase {
  
    protected void setUp() {
       super.setUp()
           
       mockDomain(Testset, [
                   new Testset(id:1, title:"one"),
                   new Testset(id:2, title:"two")
       ])

       mockDomain(School,[])

       mockConfig ('''
               cz.svse.testy.demo.testsets.ids="1,2"
       ''')     
    }

    protected void tearDown() {
           super.tearDown()
    }
  
    void testTakeOverDemoTestsets() {
           
       def school = new School()
       assertEquals 0, school.testsets.size()

       this.controller.takeOverDemoTestsets(school)
       assertEquals 2, school.testsets.size()                
    }
}

Wednesday, August 4, 2010

UML - class diagram

All text are from: http://www.ibm.com/developerworks/rational/library/content/RationalEdge/sep04/bell/


Class

  • name
  • attributes
  • operations


Inheritance

  1. class
  2. interface
a) class
 
The class BankAccount is abstract class and the method: withdrawal is abstract. Notice the italicized text. You can use stereotype abstract too.


b) interface
 

Asociation

  1. Bi-directional
  2. Uni-directional
a) Bi-directional
 


b) Uni-directional




Association class
In modeling an association, there are times when you need to include another class because it includes valuable information about the relationship. For this you would use an association class that you tie to the primary association. An association class is represented like a normal class.
 

Aggregation
An association with an aggregation relationship indicates that one class is a part of another class. In an aggregation relationship, the child class instance can outlive its parent class.
 


Composition
Because the relationship is a composition relationship, when the Company instance is removed/destroyed, the Department instance is automatically removed/destroyed as well. Another important feature of composition aggregation is that the part class can only be related to one instance of the parent class.
 


Reflexive association
A class can also be associated with itself, using a reflexive association.
 


Visibility

MarkVisibility type
+Public
#    Protected
-    Private
~Package


Multiplicity

IndicatorMeaning
0..1    Zero or one
1One only
0..*Zero or more
*    Zero or more
1..*One or more
3Three only
0..5Zero to Five
5..15    Five to Fifteen