Thursday, October 30, 2008

Division operator in Groovy

Groovy similar to Ruby fairly,in groovy language all of thing is object,that means you have to operate an object by invocation its method.For example 123.abs() will return the absolute value of this integer.Groovy support Integer and Floating point numeric.Indeed,Groovy implement every operator as a method,for example "+" implement as plus:123.plus(456) means 123+456the return value is 578,it's a integer,then on the other hand,for division operator,when you type and run 5/2 the result is 2.5,it's floating point numeric;now how about 6/2,what the result,I think the result is 3,an integer numeric,but I'm wrong,indeed all of the result of division operator is a floating point,even if the result look like an integer.so the result of 6/2 is 3.0,it's a floating point numeric.
And if you want to obtain an integer you should invoke the method intdiv:6.intdiv(2) then the result is an integer:3

Friday, September 19, 2008

An ant example for how to Validate XML

<?xml version="1.0" encoding="UTF-8"?>

<tns:root xmlns:tns="http://www.example.org/Simple" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.example.org/Simple Simple.xsd ">

This is an user test

<tns:user role="admin">

<tns:name>tnsname1</tns:name>

<tns:age>18</tns:age>

<tns:gender>Male</tns:gender>

<tns:password>sfds3555</tns:password>

<tns:title/>

</tns:user>

<tns:user role="admin">

<tns:name>tnsname1</tns:name>

<tns:age>18</tns:age>

<tns:gender>Male</tns:gender>

<tns:password>sfds3555</tns:password>

<tns:title/>

</tns:user>

<tns:cost>0.22</tns:cost>

<tns:cost>0</tns:cost>

</tns:root>

A XSD Schema file for example.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

targetNamespace="http://www.example.org/Simple" xmlns:tns="http://www.example.org/Simple"

elementFormDefault="qualified">

<xs:complexType name="user" mixed="true">



<xs:sequence>

<xs:element name="name" type="xs:string" default="Eric001" />

<xs:element name="age" type="tns:age" default="30" />

<xs:element name="gender" type="tns:gender" default="Male" />

<xs:element name="password" type="tns:password" />

<xs:any maxOccurs="unbounded"></xs:any>

</xs:sequence>

<xs:attribute name="role" type="xs:string"/>



</xs:complexType>

<xs:simpleType name="gender">

<xs:restriction base="xs:string">

<xs:enumeration value="Male" />

<xs:enumeration value="Female" />

</xs:restriction>

</xs:simpleType>

<xs:simpleType name="age">

<xs:restriction base="xs:integer">

<xs:minInclusive value="1" />

<xs:maxInclusive value="120" />

</xs:restriction>

</xs:simpleType>

<xs:simpleType name="letter">

<xs:restriction base="xs:string">

<xs:pattern value="[A-Za-z0-9]"></xs:pattern>

</xs:restriction>

</xs:simpleType>

<xs:simpleType name="password">

<xs:restriction base="xs:string">

<xs:pattern value="(([0-9]+[a-zA-Z]+)|([a-zA-Z]+[0-9]+))"></xs:pattern>

<xs:minLength value="5" />

<xs:maxLength value="8" />

</xs:restriction>

</xs:simpleType>

<xs:simpleType name="amount">

<xs:restriction base="xs:decimal">

<xs:totalDigits value="2"></xs:totalDigits>

</xs:restriction>

</xs:simpleType>

<xs:element name="root">

<xs:complexType mixed="true">

<xs:sequence>

<xs:any maxOccurs="unbounded"></xs:any>

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:element name="user" type="tns:user" >



</xs:element>

<xs:element name="cost" type="tns:amount" />

<xs:element name="title"></xs:element>

</xs:schema>


Following is the XML file:
<?xml version="1.0" encoding="UTF-8"?>

<tns:root xmlns:tns="http://www.example.org/Simple" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.example.org/Simple Simple.xsd ">

This is an user test

<tns:user role="admin">

<tns:name>tnsname1</tns:name>

<tns:age>18</tns:age>

<tns:gender>Male</tns:gender>

<tns:password>sfds3555</tns:password>

<tns:title/>

</tns:user>

<tns:user role="admin">

<tns:name>tnsname1</tns:name>

<tns:age>18</tns:age>

<tns:gender>Male</tns:gender>

<tns:password>sfds3555</tns:password>

<tns:title/>

</tns:user>

<tns:cost>0.22</tns:cost>

<tns:cost>0</tns:cost>

</tns:root>

Wednesday, September 17, 2008

Add bookmark on docbook PDF

In this article I'll discuss two points about docbook that generate to PDF.I use the ant to generate docbook,following is my ant file.

<!--

- target: build-pdf

- description: Iterates through a directory and transforms

- .xml files into .fo files which can then be turned into DocBook XML

- files.

-->

<target name="build-pdf" depends="depends"

description="Generates PDF files from DocBook XML">

<xslt style="${fo.stylesheet}" extension=".fo"

basedir="${basedir}/src" destdir="${target.dir}/fo">

<classpath refid="xalan.classpath" />

<include name="**/*.xml" />

<exclude name="**/*chapter*.xml"/>

</xslt>





<property name="fop.home" value="${basedir}/lib/fop-0.95"/>

<taskdef name="fop" classname="org.apache.fop.tools.anttasks.Fop">

<classpath>

<fileset dir="${fop.home}/lib">

<include name="*.jar"/>

</fileset>

<fileset dir="${fop.home}/build">

<include name="fop.jar" />

</fileset>

</classpath>

</taskdef>



<fop format="application/pdf"

outdir="${target.dir}/pdf" basedir="${target.dir}/fo">

<fileset dir="${target.dir}/fo">

<include name="*.fo"/>

</fileset>

</fop>







</target>

following is my dobook segment:
<sect1>

<title>Section 1 title</title>

<para>

<sect2>

<title>section 2 title</title>

<para>

description...

</para>

<sect3>

<para>witing something...</para>

<sect3>

</sect2>

</sect1>

Now the question is;
1)I want to display the label of section.
2)I want to display the bookmark in PDF.

The final solution is change the param.xml file.
1)to display the label of section:
change following line
<xsl:param name="section.autolabel" select="0">

to this line

<xsl:param name="section.autolabel" select="1">



2)to display the bookmark in PDF.

change following line

<xsl:param name="fop1.extensions" select="0">

to this line

<xsl:param name="fop1.extensions" select="1">


Note:don't change following line otherwise you will get an exception like:
No element mapping definition found for (Namespace URI: "http://xml.apache.org/fop/extensions", Local Name: "destination")

<xsl:param name="fop.extensions" select="0">

Friday, September 12, 2008

How to change the locale in Grails.

It's simple to change the locale in Grail,just need put a param after you url.A better method is put a link in your template file,and include it in every your page,then write following code:

<span>

<g:link controller="${params.controller}" action="${params.action}" params="[lang:'en']" class="menuButton">English</g:link>

</span>

<span>

<g:link controller="${params.controller}" action="${params.action}" params="[lang:'de']" class="menuButton">German</g:link>

</span>



then you will have a change language in every page.or another way you can put this code in your layout.gsp file directly.

Error starting Sun's native2ascii: In Grails

If you run app in Grails and get this error message and app cannot run.This happened sometimes because you want to use i18n feature in your application.
Then try this method:
Copying %Java_Home%/lib/tools.jar to %Java_Home%/jre/lib/ext/tools.jar fixed this problem.
(a better approach is to set up JRE path to the directory JDK)

How to implement i18n message in controller

    In a Grails applicaton,actually it use spring message bundle for its i18n.let me give an example:
I have a Usercontroller and I want to display a message to our user when his user name or password is incorrectly and I want to show different language depend on the user's location.here is the code:

           if(user){
     session.userId=user.userId
     def redirectParams=session.originalRequestParams?session.originalRequestParams:[controler:'race']
     redirect(redirectParams)
     }else{    
                            //for now,it's a hard-code pattern.
     flash['message']='Please enter a valid user id and password'
     }

following we should do is add something in my message.propertis file.
in the file:grails-app/i18n/messages.properties we added English message
user.invilate.message=Please enter a valid user id and password
in the file:grails-app/i18n/messages_de.properties we added German message
user.invilate.message=Bitte geben Sie eine gültige Benutzer-ID und Passwort

then we change above code
flash['message']='${message(code:'user.invilate.message')}'

Thursday, September 11, 2008

Notes on Grails Internationalization (i18n)

Past from:http://cochransoftware.blogspot.com/2008/03/notes-on-grails-internationalization.html

When using Grails for web app development, it's desirable to place all text in messages.properties files. When you do this, you can easily change the text to another language, and that makes internationalization easier. You still have to deal with other issues such as date formats and currency, but at least the text is easy to modify that way.



Once you have all your properties files created, you can make change languages by passing in the lang parameter and setting it to the language of your choice. For instance, if you want to list out some values, you can call the "list" action and pass it the Spanish language as a parameter.



<g:link action="list" params="[lang:'es']">



Note: Once you pass this parameter to any page, your app will now be in that language until you change it.



So, in order to facilitate this, you need to create the necessary files and reference the properties in your code. For example, create a messages.properties file and add text such as "Search" for your home page.



home.search=Search



Now, you can create a messages_es.properties that contains your Spanish translations:



home.search=Buscar



So, once you have all the text defined in your messages.properties file(s), (one for each language you are translating to) all you then need to do is reference that particular property in your code. Grails picks that up and inserts the appropriate property for you. Here are some tips on doing that in your code.



In the GSP page, if you want to reference the file in just plain text, use the g:message tag:



<g:message code="home.search" default="Search"/>



This tells Grails to find the property "home.search" in the properties file, and insert that value here. If it cannot find "home.search" in your properties file, it will insert whatever is in the default parameter.



When using the sortableColumn GSP tag, use the "titleKey" parameter to set the property as follows:



<g:sortableColumn property="title" titleKey="certification.title"/>



To set the text of a button, you can pass in a variable from the controller. I've used the flash scope to pass data back to the view, but you can use another object if you want to and return it. First, grab the value from the flash scope in the GSP page as follows:



<input type="submit" value="${flash.search}"/>



Next, in the controller action, just set the flash.search parameter before you return:



flash.search = message(code: 'home.search')



Now, the action in the controller will grab the message and throw it into the flash.search variable. You simply read that variable in the GSP page and it's all good. There's probably a better way of reading that parameter directly in the GSP page, and when I find it, I'll post an update.

Log4j configuration in Grails

Today when I config log4j for Grails I meet an exception,"No such property: context for class: java.lang.String" it's because of sometypo ,here is the wrong writing.
development {
log4j {
appender.access="org.apache.log4j.ConsoleAppender"
appender.'access.layout'="org.apache.log4j.PatternLayout"
appender.access.layout.ConversionPattern==%d %p %x [%c] %m%n //you must put the quote around "access.layout.ConversionPattern"
logger
{
grails.'app.controller.UserController'='warn,access'
}

}
}
following statement is copy from Grails official site,it explain why we should do it like that
A couple things to keep in mind while modifying Config.groovy:

1) Unlike the flat format used by log4j, the Grails config format is hierarchical, so if you write:

grails.app.controller.YourController="debug,stdout"
grails="info,stdout"
You're actually overriding the first setting with the second. To get around this you have to quote the first:
grails.'app.controller.YourController'="debug,stdout"
grails="info,stdout"
2) If you're not using the 'quote' format shown above you must always define children before parents in the Config.groovy file. For example, putting a parent before a child as shown below will result in an error:

grails.app="info,stdout"
grails.app.controller="debug,stdout"

Reversing the lines will eliminate the error (but the definition of grails.app will override the definition of grails.app.controller):

grails.app.controller="debug,stdout"
grails.app="info,stdout"

But After I fix it,it sitll can not doesn't work.then I google again and again.finally,
I found there are something error in default generate from Grails.
we should change following line
logger
{
grails.'app.controller.UserController'='warn,access'
}
instead of like this:
logger.
logger.grails.'app.controller.UserController'='warn,access'

now it's work well done.

Deprecated constraints in Grails domain class

Following constraints has been deprecated in Grails domain class.
length
maxLength
minLength

instead of:
size
maxSize
minSize.

Just for remember

Wednesday, September 10, 2008

Premature end of file in Grails

When I create a app and run it.I got an error message:"[Fatal Error] :-1:-1: Premature end of file." at console,even if every there is notiong happened in your application,it seems that occured in FireFox.then I google it,I found it's seems that because of how firefox process the mime types,so a alternative method is remove the line "xml: ['text/xml', 'application/xml'], " in Config.groovy file.but actually it's a bug of Grails.you can find some discussing about it on http://jira.codehaus.org/browse/GRAILS-3088

Tuesday, September 9, 2008

How to define a closure by method

 To declaring a closure is to reuse something that is already declared: a method. Methods have a body, optionally return values, can take parameters, and can be called. The similarities with closures are obvious, so Groovy lets you reuse the code you already have in methods, but as a closure. Referencing a method as a closure is performed using the reference.& operator. The
reference is used to specify which instance should be used when the closure is called, just like a normal method call to reference.someMethod().
for example:
class TestClass{
   hello(String name){
     println("Hello ${name}")
 }
}
def tc=new TestClass()
def testClosure=tc.&hello //now you obtained a new closure by class method.

Safe dereferencing with the ?. operator

  When a reference doesn’t point to any specific object, its value is null. When calling a method or accessing a field on a null reference, a NullPointerException (NPE) is thrown. This is useful to protect code from working on undefined preconditions,but it can easily get in the way of “best effort” code that should be executed for valid references and just be silent otherwise.that is the "?." operator in Groovy.for example 
def map=[x:[y:[z:1]]]
assert map.x.y.z==1
assert map.x.a==null//it'll throw an null exception ,because there isn't a "a" attribute.
try{
assert map.x.a==null
}catch(Exception){
 //some code for process exception.
}
//this method is better,but it's a bit verbose.right?

assert map.x?.a=null  //it'll be safe,the null exception will be silent.it's the best way in Groovy.


How the Grails Link element work

Here are some examples:
<g:link action="show" id="1">Book 1</g:link>

<g:link action="show" id="${currentBook.id}">${currentBook.name}</g:link>

<g:link controller="book">Book Home</g:link>

<g:link controller="book" action="list">Book List</g:link>

<g:link url="[action:'list',controller:'book']">Book List</g:link>

<g:link action="list" params="[sort:'title',order:'asc',author:currentBook.author]">

Book List

</g:link>

Monday, September 8, 2008

Single or double quotes

   As a developer we almost need write html code every day.today I want to talk about "quote",especial in GSP page,Grails is an amazing framework,I really like it,Groovy Servers Pages (or GSP for short) is Grails' view technology. It is designed to be familiar for users of technologies such as ASP and JSP, but to be far more flexible and intuitive.To talk about quotes most of time we use double quotes but in some particular situation we should use single quote,for example,as an attribue of gsp taglib,a groovy map is allowed,so in this situation,you should use single quote for map's attribues.

Another method for redirection in index.gsp

   In the last blog I talked about how to redirection by useing Taglib method.another simple method is config your Url maping file
grails-app/conf/UrlMappings.groovy

class UrlMappings {
    static mappings = {
        "/"(controller:"race",action:"search")   //this is your index action.
        "/$controller/$action?/$id?" {
            constraints {
                // apply constraints here
            }
        }
    }
}

Sunday, September 7, 2008

How to redirect url from index.gsp?

   In the newly version of Grails,the index page is index.gsp but not index.jsp.you can't change the file name directly,it doesn't work.I think an alternative method is writen an TagLib.for example:
1,create a taglib file under  grails-app/taglib
TestTaglib
2,define a new tag
def redirectPage={ attrs->
  def url=attrs.get('url')
   response.sendRedirect("${request.contextPath}"+url)
}
3.in the index.gsp,writen like this:


Wednesday, March 19, 2008

Test in Grails

Grails provide us simplest test framework.if you want to test your function,jutst run following command:
>>grails create unit-test
then Grails will ask you which Domain you want to test.for example type project
Then Grials will generate a class in directory: gwork\gira\workspace\test\integration
Write some code like this
class ProjectTests extends GroovyTestCase {

void testSort() {

def sortByAttribute={property ->
Project.findAll().sort{it."$property"}.title
}


def titles=sortByAttribute("title")
assert titles
assert titles.size()==3
assert titles[0]=="App1"
}
void setUp(){
new Project(title:'App1',description:'This is a test',createDate:new Date()).save()
new Project(title:'App2',description:'This is a test',createDate:new Date()).save()
new Project(title:'App3',description:'This is a test',createDate:new Date()).save()
}
void tearDown(){
Project.list()*.delete()
}
}
Then run command:
>>grails run-test
You will get the test reult.

Dynamic scaffod in Grails

listed the all three command to create dynamic scaffod:
• grails generate-views: Generates views for the specified domain class

• grails generate-controller: Generates a controller for the specified domain class

• grails generate-all: Generates both a controller and associated views

Hpw to change the default context of Grails server

Today I commit my code into google code project.As before my project named sparrow,because sparrow is another project's name so I can't use it now,I changed it to gria.but when I run the command
>>grails run-app
I found the context of Grails server is still sparrow.Oh,how to change it.I found there is application.properties file in my project directory,I edit it like this
app.name=gria
Then the server's context change to gria.

Tuesday, March 18, 2008

The inList conatraint must follow blank constraint

I found an interesting thing,that is if you set the property of Grails's Domain class with a constratint--inList,like this:

priority(inList:["High","Low"])

then,when you open the page to edit or create this domain,you will find that the property can't be select by a HTML select box.So,you must follow another constraint blank and set it false.like this:

priority(inList:["High","Low"],blank:false)

Is it a bug?

Monday, March 17, 2008

Constraint in Grails

Grails use constraint key word for Domain class's constraint.As a note,I summary the constraint in Grails Domain Model.





























































































NameExampleDescription
blanktitle(blank:false)Set to false if a string value cannot be blank
emailemail(email:true)Set to true if the value must be an email address
inListsex(inList:['Man','Woman'])Value must be contain within the given list
lengthtitle(length:1..50)Use a range value to restrict the length of string or range
minage(min:new Date()Set the minimun value
minLengthtitle(minLength:5)Set the minimum length of a string or array property
minSizechildren(minSize:10)Set the minimum size of a collection or number property
matchesname(matches:/[a-zA-Z]/)Matches the supplied regular expression
maxage(max:new Date()Set the maximum value
maxLengthtitle(maxLength:5)Set the maximum length of a string or array property
maxSizechildren(maxSize:10)Set the maximum size of a collection or number property
notEqualname(notEqual:'Eric')Must not equal the special value
nullablenameSet to false if property value cannot be null
rangeage(range:30..60)Must occur within the special range
sizechildren(size:5..15)Use a range to restrict the size of a collection or number
uniquename(unique:true)Set to true if the property must be unique
urlurl(url:true)Set to true if a string value is a url address

HQL in Grail

Today we'll discuss the HQL query in Grail.as you know,Grails's GROM is based on Hibernate.So you can use HQL to implement sql query in Grails.Grails provide three static method:find,findAll and executeQuery.Here are some demonstrate

/**find method*/
//following method will return a project object whose attribute is 'App1'
def project=Project.find('from Project p where p.title=?',['App1'])
/**findAll method*/
//following method will return all of project objects.
def projectList=Project.findAll('from Project')
//Grails also provide a elegant IN operator
def plist=Project.findAll('from Project')
def ilist=Issue.findAll("from Issue as b where b.project in (:p)", [p:plist])
/**executeQuery method*/
def plist=Project.executeQuery("select distinct p.title from Project p")
//it is possible to perform more-advanced queries using joins, aggregate functions, and subqueries.
And also we can some limit for query result number,for example:
def plist=Project.executeQuery("select distinct p.title from Project p",[max:10,offset:5])
)

Sunday, March 16, 2008

Dynamic Finders in Grails

In last section,we discussed the CRUD method in Grails.Now,we'll learn one .of the most powerfull concept of GORM (findBy* method).Following figure shown a example method.
This figure from the book:the definitive guid to grails.
Now I list the available Dynamic Finder method and example:
Expression Arguments Example
Between 2 Project.findByCreateDateBetween(today-10,today)
Equals 1 Project.findByTitleEquals('App1')
GreaterThan 1 Project.findByCreateDateGreaterThan(lastmonth)
GreaterThanOrEqual 1 Project.findByCreateDateGreaterThanOrEqual(lastmon)
IsNull 1 Project.findByTitleIsNull()
IsNotNull 1 Project.findByTitleIsNotNull()
LessThan 1 Project.findByCreateDateLessThan(lastmonth)
LessThanOrEqual 1 Project.findByCreateDateLessThanOrEqual(lastmonth)
Like 1 Project.findByTitleLike('App1%')
NotEqual 1 Project.findByTitleNotEqual('App1')

All of findBy* method only return that fisrt be found object.
There are two cousins method findAllBy* and countBy*.
findAllBy* :return a list that is matched the query logic
countBy* :return a number that is matched result total.

Data operator CRUD in Grails

How to implement CRUD(create,read,update,delete) in Grails.The answer is ,it's simple.Because of the Grails's GROM is based on Hibernate and we have already have the Domain class,and it's alsp maped to database table.So now,you can just simple use save(),update(),delete() method.let me demonstrate how to do these:In this section,I will use the Project and Issue Domain Object in Sparrow.
/**Create data*/
//create a project
def project1=new Project(title:'Project1',description:'Hello world!',createDate:new Date())
//now we have the project object.we will save it.
project1.save()
//as you can see ,we never define the method save().but we can use it,because Grails auto //generate it in runtime for us.when we call this method,the project information will be saved in database table,it's cool.
//Now we'll define issue object
def issue1=new Issue(summary:'Issue1',description:'This is a issue',createDate:new Date(),project:project1)
//we created the issue object,but the different in this place.we have a parameter project:project1 ,because the project and issue has a one-many relationship,so we need point there whcih Project that this Issue belong to.
/**read*/
after we create the object information.we usually need get these data.how to do that?the answer is get(id) and exists(id) method.
//get Project by ID
def p1=Project.get(1)//we will use id parameter get a project,which id is 1
def boolean=Project.exist(1)//the exists method will return ture if it's exists.
The exists method, reads better and is arguably more performant than get method.
if(Project.get(1)){
def p=Project.get(1) //bad performant,because you called twice get method
}
if(Project.exists(1)){
def p=Project.get(1) //better performant
}
/**update Object*/
//update object is easy
def p=Project.get(1)
p.title='New title'
p.save()

/**delete Object*/
def p=Project.get(1)

p.delete()

/**sort,listing,and counting*/

GORM provides a list method, which takes a number of named arguments such as max, offset,
sort, and order to customize the results, the definitions of which are listed here:
• max: The maximum number of instances to return
• offset: The offset relative to 0 of the first result to return
• sort: The property name to sort by
• order: The order of the results, either asc or desc for ascending and descending order respectively

//demonstrate
//get all objecta
def allProject=Project.list()
//get top 10 objects
def topten=Project.list(max:10)
//sort objects
def sortingProject=Project.list(max:10,sort:'createDate')
//sort and order
def sortingProject2=Project.list(max:10,sort:'createDate',order:'desc')
//order by column name
def allBycreateDate=Project.listOrderByCreateDate()
Note:the listByCreateDate is auto generate by Grails.it's a role,that means listOrderBy+property'name

Friday, March 14, 2008

How to create the Domain-class of Grails--Sparrow begin

After several days basic setup and config,our architecture of project Sparrow has been create.Now we'll start our first step:create domain object.

But before the beginning of our process,let me introduce the requirement of our Sparrow.For facilitate,I will illustrate the requirement by a UML diagram.

As you can see, our project will include three functions.
1)create a project.
2)create issues for this project.
3)create issues type for existing issues.

Following is the Domain Class Model :

Now,let's begin.In Grails,it use the Hibernate for ROM ,but as the same time Grails extend the Hibernate,we call this extension "GOM".It's also based on "Convention Role",so we only need create a POJO class by Groovy language.In our project there are three domain class we'll create.Grail provide us a easy to used tool.To do this,just open the command line.type:

>>grails create-domain-class

then enter the class name ,for example :project.
Grails will auto generate a class with capitalize letter.like this:

class Project {
static hasMany=[issues:Issue]//one project can has many issues
String title
String description
Date createDate
}

Note:the hasMany is a key word of Grails,that means one project can has many issues.so Issue class will have a belongsTo attribute.like this:

class Issue {
static belongsTo=Project
Project project
String summary
String description
Date createDate
}

Because of we have create our database(postgreSql).now we run our application.

>>grails run-app

You'll see that grails auto create the database table for these two domain class.
As you can see Grails auto create two field "id" and "version".it's a convention,also id is a default key and it's request.And also,may be you have saw that the property field "createDate" in database table is create_date,because the createDate field has a capitalize letter "D",so it replace by "_d".yes it's also a convention.

Wednesday, March 12, 2008

How to config Grails's datasource

As you can see,there is a directory named conf($App_home$/grails-app/conf),it include many configuration file.Today we'll disscuss how to config Grails's datasoure.Because of Grails leverages Hibernate,it supports every database that Hibernate support.Following list the Grails supported database.
• DB2 7.1, 7.2, 8.1
• HSQLDB
• HypersonicSQL 1.61, 1.7.0, 1.7.2, 1.8
• Microsoft SQL Server 2000
• MySQL 3.23, 4.0, 4.1, 5.0
• Oracle 8i, 9i, 10g
• PostgreSQL 7.1.2, 7.2, 7.3, 7.4, 8.0, 8.1
• SAP DB 7.3
• Sybase 12.5 (JConnect 5.5)
• Timesten 5.1
Let me assume that we use postgresql.Then we should download the JDBC driver from postgresql homepage,and copy it into the directoty lib($App_home$/lib).Then edit the file DataSource.groovy in directory conf.like this(I add some comments for every section):
dataSource {
pooled = true //which allows you to configure whether to use a connection pool or not
driverClassName = "org.postgresql.Driver" //the database driver class name
username = "postgres" //database name
password = "123456" //database password
}
//It is the configurate for hibernate,you can change it fit your want.
hibernate {
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='org.hibernate.cache.EhCacheProvider'
}
// environment specific settings,there are three database for our application.
//sparrow_dev:for development phase.
//sparrow_test:for test phase.
//sparrow_pro:for product phase.
environments {
development {
dataSource {
dbCreate = "update" // one of 'create', 'create-drop','update'
url = "jdbc:postgresql://127.0.0.1:5432/sparrow_dev"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:postgresql://127.0.0.1:5432/sparrow_test"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:postgresql://127.0.0.1:5432/sparrow_pro"
}
}
}

Now,you can run you application under a database model.congratulation.

Monday, March 10, 2008

What the Grails application directory contains?

When you run command grails create-app,what happened?The answer is it create a lot of directory and file to you.they are the core of a Grails application.Today let me explain what are these folders and files means to you.I make a summary of these stuff as a list:

grails-app:This directory containing core Grails artifacts
+conf: Contains configuration elements,such as DataSource.groovy,UrlMappings.groovy
+controllers :Controllers that handle requests
+domain:Contains domain object class.
+i18n:Contains internationalization message bundles.
+services:Services that encapsulate business logic
+taglib:Dynamic tag libraries
+views:Groovy server page or JSP.
+layouts:the GSP or JSP layouts powered by sitemesh.
grails-test:application unit tests.
hibernate:optional Hibernate configuration.
lib:java lib jar archives
spring:optional Spring configuration.
src:Include other Groovy or Java sources.
+java:Further Java sources for compilation.
+groovy:Further Groovy sources for compilation.
web-app:web application resources (CSS, JavaScript, etc.)

How to change the default servlet version of Grails

Because Grails use Jetty as its default servlet container,so its default servlet version is "2.4".for some reason,may be we need to develop our application under the version 2.3 or 2.5 then how to change its default behavior?Then way is:
1)passs argument -Dservlet.version,for example:
>>grails -Dservlet.version=2.5 run-app
2)Or we can directly edit the Init.groovy file in directory Grails_Home/scripts.find the key "servletVersion" and change its default value from 2.4 to others what you want,for example:
servletVersion = System.getProperty("servlet.version") ? System.getProperty("servlet.version") : "2.5"

How to display database comments of table's columns

If you want to show the comments of a database tbale's column then try this way.
select * from user_col_comments where table_name='table name'
as same principle.we can show the table's comments:
select * from user_tab_comments where table_name='table name'

How to change the default port number of Grails server

Grails use Jetty as its server,and run port 8080 by default.for some reason,we should change it ,for example 9090,how to do?There are two ways:
1) when you do run-app,add command -Dserver.port=9090.for example
>>grails -Dserver.port=9090 run-app
2) if you want to change the port to 9090 as default value,then Edit the file GRAILS_HOME/scripts/Init.groovy and change the phrase 8080 to another port number like 9090 .

A good IDE for develop dynamic language.

Recently,we begin our new project named Sparrow.It's a project manage and trace application.
We decide to find a easy to use and free license IDE for our team.After a several of days,we found a good tools open komodo .It's support a lot of existing dynamic language.such as python,ruby,lisp and several of dynamic language such as django. etc....Also it's support customizable feature ,such as customize command,customize menu etc.. We'll use this IDE in our Sparrow application.

Sunday, March 9, 2008

The Controllers in Grails framework

Grails is an MVC framework and has models,controllers and views to cleanly separate concerns.
So let's create our first controller for our Sparrow.let's assume we want a page to say hello for everyone who access our app.The requirement is simple,it's just print a "hello world "(Yes,always hello world).It's easy to do this in Grails.We need a controllers,type following command:
>>cd sparrow
>>grails create-controller
Grails will ask you what's controller name.pls type hello
After a minute,Grails will create a HelloController.groovy in path /sparrow/grails-app/controllers/
then open it and find the index method.Note every methods in this groovy file are action .the index method is the default behavior when you navigate following url:http://127.0.0.1:8080/sparrow/hello/
We will modify this method like this :
def index = {
render "Hello World!"
}

When you navigate http://127.0.0.1:8080/sparrow/hello/
you'll see a page with "Hello World!" string.Note this file is a standard groovy file.index method is a default method as I said at above.the render also a keyword.We can assume it like Response object's write method in Java servelt.
If you want define other action in hello controller.just define a new method in the file HelloController.groovy.for example.I want to show a good bye information.Just add following method :
def saygoodbye={
render "Good Bye!"
}
then navigate to following url: http://127.0.0.1:8080/sparrow/hello/saygoodbye.
Note:in this url,
the http://127.0.0.1:8080/ is domain and port.
the saprrow is context path.
the hello is controler name.
the saygoodbye is action name.
In future section we'll discuss it detail.

My friend get a new job

From 9 months wait in home,my friend Bony get her new job.She will work for a computer company ,too(like me).I'll congratulate her,and I'll have a dinner with her tonight,it'll be my treat.Oh,one more thing,what's for dinner?I think tuna salad is good,I like it:).
In the end, I wish she have a good luck beginning.God bless her.

Getting start with Grails for our Sparrow app

Today we'll start to our Sparrow app.As a learning project we'll begin from how to create and run an application.
As you can see,our app's name is Sparrow,then how to create it,follow me.
open your command line.type
>>make dir learnapp
>>cd learnapp
>>grails create-app
after this,grails will ask your what's name your project.we'll tyep
>>sparrow
then grails will generate all of you need to start an application.Note,Grails is a role framework.so you will see somes like domain,controllors,tlb folder etc.in the future,we'll create relative file to fit our application.for now,we only need a blamk frame,but it's a runable application.we'll start our first grails app.type following command:
>>cd sparrow
>>grails run-app
You will see some run time information in console.then open your favorite browser then type:
http://127.0.0.1:8080/sparrow/
you will see a welcom page like this:

Grails used Jetty as its default servlet container.In the future,may be you want to move it to other containers such as tomcat .or some appservers such as JBoss.You can just type grails war .Grails will generate a war file for you,then you can make your own deployment in others environment.
Now.through only a few commmand you create a runable application.It's really cool.In the following section,we'll discuss how to add our first domain model project.we'll add some useful feature for our application and introduce what grails's domain model is as same time.

Grails Command-Line Help

Because our Sparrow is a learning project for Grails.So,let me list the command-line help for how to create a project.here they are:
>grails
help:
Usage: grails [target]
Targets:
"create-app" - Create a new grails app
"create-controller" - Create a new controller
"create-service" - Create a new service
"create-domain-class" - Create a new domain class
"create-taglib" - Create a new tag library class
"create-test-suite" - Create a new test suite
"create-job" - Create a quartz scheduled job
"generate-controller" - Generates a controller from a domain class
"generate-views" - Generates the views from a domain class
"generate-all" - Generates all artifacts from a domain class
"test-app" - Run current app's unit tests
"run-app" - Run the application locally and wait
"create-webtest" - Create the functional test layout
"run-webtest" - Run the functional tests for a running app
"shell" - Opens the Grails interactive command line shell
"console" - Opens the Grails interactive swing console
"war" - Create a deployable Web Application Archive (WAR)

While you run these command.you will note at this point that Grails uses the Apache Ant.

Domain model for Sparrow


Today we create the domain model for Sparrow system.For now,it's only a draft version.
Also you can find the soure file from here

Start new project Sparrow

Today we plan to start a new project named Sparrow.It's a project manage framework.In this project we'll provide project manage feature.It'll based on Grails framework,as you will see.we'll create it as a learning project.That means,we'll learning it and development it step by step.

Friday, March 7, 2008

Lock step iteration in Python

Today I will log this big feature in python 2.x.That is lock set iteration.so what's that?let's assume,we have two list and for some reason we want to iteration them in the same time.In other language(eg.Java).we need a nesting loop.But in python .we can use map function,it's build-in.following code is a example.
>>a=(1,2,3)
>>b=(4,5,6)
>>for i in map(None,a,b): print i
The result is :
(1, 4)
(2, 5)
(3, 6)
Wow.It's cool ,right.now assume the length of each list is different.for example,we set them like this
>>a=(1,2,3)
>>b=(4,5,6,7,8)
The result is:
(1, 4)
(2, 5)
(3, 6)
(None, 7)
(None, 8)

As you can see,now we have two extra small list with the element None.Yes,Python auto append a None type in last list,because it is the first parameter in the map function.Until now,it looks good ,right ?we only write one line code ,then map function do two times loop.But it's not elegant.because :
 - It is non-obvious to programmers without a functional
programming background.
- The use of the magic `None' first argument is non-obvious.
- It has arbitrary, often unintended, and inflexible semantics
when the lists are not of the same length: the shorter sequences
are padded with `None'.

Fortunately,we have another function,zip.yes it's good to use.let me give a example:
>>a=(1,2,3)
>>b=(4,5,6,7,8)
>>zip(a,b)
The result is:
(1, 4)
(2, 5)
(3, 6)
Yes,as you can see,no other two redundant list.it's more clearly.of course,if you think that
other twos is useful,you can also use the map function.But now we have another choose.

get up on the wrong side of the bed

It' a bad day today.I feel bad because I have a mistake in my work.I feel bad because I can't put up with my mistake.It should not be happened.It's happened just because I careless of the description in the document.just one sentence I missed.although it is only a small mistake but I can't bear me to do that again.I promise I will never ever slip a cog like this.never!

Wednesday, March 5, 2008

How should I say,I like grails

In my several years development by profession.I used several computer languages,such as C++,Java,Python and many of web framework.But for Grails,I said ,it's really a good framework.because it's based on Groovy language,and very easy to use,also it can access all most of Java library ,that means I never have to give up I have know about Java.So I think I'll be successful.