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: