<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-6377108869773463365</id><updated>2008-12-02T13:23:46.965+01:00</updated><title type="text">dahernan</title><subtitle type="html">This is a Unit Test</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://dahernan.net/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://dahernan.net/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>30</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/Dahernan" type="application/atom+xml" /><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-1805435780931436127</id><published>2008-10-20T13:47:00.004+02:00</published><updated>2008-10-28T19:15:14.989+01:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-10-28T19:15:14.989+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="openid" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="jsecurity" /><title type="text">Grails: Hacking JSecurity plugin to supports OpenId</title><content type="html">I'm currently developing an application for my &lt;a href="http://heralsoft.com/"&gt;new brand company&lt;/a&gt; and I'd like that supports authentication with username and password , and OpenId.&lt;br /&gt;&lt;br /&gt;I could install &lt;a href="http://www.grails.org/AcegiSecurity+Plugin"&gt;Acegi Grails Plugin&lt;/a&gt;, but I'm very happy using &lt;a href="http://www.grails.org/JSecurity+Plugin"&gt;JSecurity&lt;/a&gt;, ok no problem let's hack.&lt;br /&gt;First, I have to install &lt;a href="http://www.grails.org/OpenID+Plugin"&gt;OpenId Plugin&lt;/a&gt; to support OpenId authenticantion&lt;a href="http://www.grails.org/OpenID+Plugin"&gt;&lt;/a&gt;, with this plugin I can manage login process and get openid identifier for OpenId users.&lt;br /&gt;&lt;br /&gt;With JSecurity installed and done &lt;a href="http://www.grails.org/JSecurity+Plugin+-+Quick+Start"&gt;QuickStart,&lt;/a&gt; I need to pass Openid identifier in auth process, for this I've created class &lt;span style="font-style: italic; font-weight: bold;"&gt;OpenIdContextHolder&lt;/span&gt; to save in a ThreadLocal context.&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;class OpenIdContextHolder{&lt;br /&gt; &lt;br /&gt; private static final ThreadLocal openIdContextHolder = new ThreadLocal();&lt;br /&gt; &lt;br /&gt; static void resetContext() {&lt;br /&gt;  openIdContextHolder.set(null);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; static def getOpenIdIdentifier(){&lt;br /&gt;  openIdContextHolder.get()&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; static void setOpenIdIdentifier(id){&lt;br /&gt;  openIdContextHolder.set(id)  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;Now I have to hack &lt;span style="font-weight: bold; font-style: italic;"&gt;AuthController&lt;/span&gt; to manage openid issues. The trick is when a user try to signIn, if I recive an OpenId identifier from OpenId Plugin then I put it in OpenIdContextHolder.&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;def login = {&lt;br /&gt;  if(openidService.isLoggedIn(session)){&lt;br /&gt;        return redirect(action:'signIn')&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     return [ username: params.username, rememberMe: (params.rememberMe != null), targetUri: params.targetUri ]&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;def signIn = {&lt;br /&gt;  // if is logged with openid set contextholder&lt;br /&gt;     if(openidService.isLoggedIn(session)){&lt;br /&gt;      def openId = openidService.getIdentifier(session)&lt;br /&gt;      OpenIdContextHolder.setOpenIdIdentifier(openId)&lt;br /&gt;      params.rememberMe = true&lt;br /&gt;      params.username = openId&lt;br /&gt;      params.password = "nullpass"&lt;br /&gt;     }&lt;br /&gt;     def authToken = new UsernamePasswordToken(params.username, params.password)&lt;br /&gt;  &lt;br /&gt;// continues the default generated code...&lt;br /&gt;// ...&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;Next step is update &lt;span style="font-weight: bold;"&gt;JsecDbRealm&lt;/span&gt; generated. I have to retrieve OpenId identifier from ContextHolder, and lookup in my domain objects. I use the trick to register my openId users in JScecurity with the password 'secret' but if anyone try to access with username and password in this kind of users, I throw an Exception.&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;def authenticate(authToken) {&lt;br /&gt;      log.info "Attempting to authenticate ${authToken.username} in DB realm..."&lt;br /&gt;   &lt;br /&gt;      // experimental!!&lt;br /&gt;      def openid = OpenIdContextHolder.getOpenIdIdentifier()&lt;br /&gt;      OpenIdContextHolder.resetContext()&lt;br /&gt;      log.info "OpenIdContextHolder request with openid: ${openid}"&lt;br /&gt;      if(openid){&lt;br /&gt;       def openidUser = User.findByOpenid(openid)&lt;br /&gt;       if (!openidUser)&lt;br /&gt;        throw new UnknownAccountException("No account found for user [${username}]")&lt;br /&gt;       log.info "Jsecurity with Openid ${openidUser.username} : ${openidUser.openid}"&lt;br /&gt;       authToken.password = 'secret'&lt;br /&gt;       authToken.username = openidUser.username&lt;br /&gt;      }else {&lt;br /&gt;       def openidUser = User.findByUsername(authToken.username)&lt;br /&gt;       if(openidUser?.openid?.trim()){&lt;br /&gt;        // trying to access with password for openid user&lt;br /&gt;        log.info "Jsecurity: Trying to access with password for user: ${openidUser.username} : ${openidUser.openid}"&lt;br /&gt;        throw new IncorrectCredentialsException("Invalid password for openid user '${authToken.username}', try to use openid instead user:password")&lt;br /&gt;       }     &lt;br /&gt;      }&lt;br /&gt;    &lt;br /&gt;      def username = authToken.username&lt;br /&gt;// continues the default generated code...&lt;br /&gt;// ...&lt;/pre&gt;&lt;/div&gt;The last step is redirect, openid users to signIn controller after logged (you only have to change it in OpenId Plugin).&lt;br /&gt;&lt;br /&gt;And that's all folks.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=2B1gM"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=2B1gM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=RUMIM"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=RUMIM" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/1805435780931436127/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=1805435780931436127" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/1805435780931436127?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/1805435780931436127?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/434972513/grails-hacking-jsecurity-plugin-to.html" title="Grails: Hacking JSecurity plugin to supports OpenId" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2008/10/grails-hacking-jsecurity-plugin-to.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-3541661053452349358</id><published>2008-09-06T17:03:00.007+02:00</published><updated>2008-09-08T12:32:48.304+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-09-08T12:32:48.304+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="me" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="heralsoft" /><title type="text">New hopes and expectations</title><content type="html">I've been very busy those months, because I have a lot of work to do. The main reason is that I quit my old job and I've started the adventure to work in my own company.&lt;br /&gt;&lt;br /&gt;Now I work for the best company in the world &lt;a href="http://heralsoft.com/"&gt;Heralsoft&lt;/a&gt;, and of course the best company only can use the best technology, Grails :D.&lt;br /&gt;To start, I eat my own food because the company website is a Grails application. In less than one week of development, I did a professional site with i18n (English and Spanish), blog (only English), feeds, authentication, searchable.&lt;br /&gt;&lt;br /&gt;Visit &lt;a href="http://heralsoft.com/"&gt;my company home page&lt;/a&gt; and &lt;a href="http://heralsoft.com/contact/index"&gt;contact to me&lt;/a&gt; if you have any comment, or business oportunities.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=cwh1L"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=cwh1L" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=SeD6L"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=SeD6L" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/3541661053452349358/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=3541661053452349358" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/3541661053452349358?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/3541661053452349358?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/386567991/new-hopes-and-expectations.html" title="New hopes and expectations" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://dahernan.net/2008/09/new-hopes-and-expectations.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-5268070086119712140</id><published>2008-06-18T10:06:00.006+02:00</published><updated>2008-06-18T10:51:55.440+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-06-18T10:51:55.440+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gant" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title type="text">Script to deploy Grails Applications Remote</title><content type="html">I spent some time this week doing a script to deploy my grails applications in remote Jetty container.&lt;br /&gt;To do my deploy script I use &lt;a href="http://gant.codehaus.org/"&gt;Gant,&lt;/a&gt; with &lt;a href="http://grails.org/doc/1.0.x/guide/4.%20The%20Command%20Line.html#4.1%20Creating%20Gant%20Scripts"&gt;Grails support&lt;/a&gt;. To deploy War in Jetty you have two options:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://docs.codehaus.org/display/JETTY/WebAppDeployer"&gt;Static&lt;/a&gt;. To do in static way you only have to copy your War to &lt;span style="font-style: italic;"&gt;"webapps"&lt;/span&gt; directory and restart container.&lt;/li&gt;&lt;li&gt;&lt;a href="http://docs.codehaus.org/display/JETTY/ContextDeployer"&gt;Hot deploy&lt;/a&gt;. I prefer hot deploy to avoid restart container and I have to copy War in &lt;span style="font-style: italic;"&gt;"webapps"&lt;/span&gt; directory and generate XML with context description.&lt;/li&gt;&lt;/ul&gt;To copy War remote, &lt;span style="font-style: italic; font-weight: bold;"&gt;Ant.scp&lt;/span&gt; is the best way, make sure that you have Ant optional task and and jsch.jar in  classpath (you can copy from Eclipse to &lt;span style="font-style: italic;"&gt;GRAILS_HOME/lib&lt;/span&gt; for example).&lt;br /&gt;&lt;br /&gt;To generate XML, Groovy is fantastic I mix some &lt;span style="font-weight: bold;"&gt;withWriter&lt;/span&gt; closure to generate the head of the document, and &lt;span style="font-weight: bold;"&gt;MarkupBuilder&lt;/span&gt; to do the hard work.&lt;br /&gt;&lt;br /&gt;And this is the script:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;import org.codehaus.groovy.grails.commons.GrailsClassUtils as GCU&lt;br /&gt;import groovy.xml.MarkupBuilder&lt;br /&gt;&lt;br /&gt;grailsHome = Ant.project.properties."environment.GRAILS_HOME"&lt;br /&gt;&lt;br /&gt;includeTargets &amp;lt;&amp;lt; new File ( "${grailsHome}/scripts/War.groovy" )&lt;br /&gt;&lt;br /&gt;target('default': "Deploy war in server") {&lt;br /&gt;depends(war)&lt;br /&gt;&lt;br /&gt;// avoid War with dots (problems with static deploy)&lt;br /&gt;def warTmp = "${grailsAppName}.war"&lt;br /&gt;Ant.copy(file:warName, tofile:warTmp)&lt;br /&gt;&lt;br /&gt;def dir = "/opt/jetty"&lt;br /&gt;&lt;br /&gt;def host = "myhost.com"&lt;br /&gt;def port = "22"&lt;br /&gt;def user = "myuser"&lt;br /&gt;def dsa = "${basedir}/scripts/key/id_dsa"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def swriter = new StringWriter()&lt;br /&gt;def xml = new MarkupBuilder(swriter)&lt;br /&gt;&lt;br /&gt;xml.Configure('class': "org.mortbay.jetty.webapp.WebAppContext") {&lt;br /&gt; Set(name: 'contextPath','/')&lt;br /&gt; Set(name: 'war'){&lt;br /&gt;  SystemProperty(name: 'jetty.home', default: '.')&lt;br /&gt;  mkp.yield("/webapps/${warTmp}")&lt;br /&gt; }&lt;br /&gt; Set(name: 'defaultsDescriptor'){&lt;br /&gt;  SystemProperty(name: 'jetty.home', default: '.')&lt;br /&gt;  mkp.yield("/etc/webdefault.xml")&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;def xmlDescriptor = "${basedir}/${grailsAppName}.xml"&lt;br /&gt;new File(xmlDescriptor).withWriter{ writer -&amp;gt;&lt;br /&gt;writer &amp;lt;&amp;lt; '&amp;lt;?xml version="1.0"  encoding="ISO-8859-1"?&amp;gt;\r\n'&lt;br /&gt;writer &amp;lt;&amp;lt; '&amp;lt;!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"&amp;gt;\r\n'&lt;br /&gt;writer &amp;lt;&amp;lt; swriter.toString()&lt;br /&gt;writer &amp;lt;&amp;lt; '\r\n'&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;echo "Deploying files to remote: ${host}"&lt;br /&gt;scp(file: warTmp, todir: "${user}@${host}:${dir}/webapps", keyfile:"${dsa}", port:"${port}", passphrase:"", trust:"true")&lt;br /&gt;scp(file: xmlDescriptor, todir: "${user}@${host}:${dir}/contexts", keyfile:"${dsa}", port:"${port}", passphrase:"", trust:"true")&lt;br /&gt;echo "Finished :)"&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;I have an &lt;a href="http://www.nabble.com/Failed-to-do-hotdeploy-with-jetty-in-production-environment-td17895368.html#a17895368"&gt;issue with hot deploy in Jetty&lt;/a&gt;  and Grails (if anyone can help?) , but the script works well :D&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=I2IVwI"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=I2IVwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=FaCCWI"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=FaCCWI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/5268070086119712140/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=5268070086119712140" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5268070086119712140?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5268070086119712140?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/314470111/script-to-deploy-grails-applications.html" title="Script to deploy Grails Applications Remote" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://dahernan.net/2008/06/script-to-deploy-grails-applications.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-8887025612602844484</id><published>2008-05-17T11:40:00.005+02:00</published><updated>2008-05-17T12:38:52.190+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-05-17T12:38:52.190+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="spring web flow" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title type="text">The advantage of Grails</title><content type="html">This week Spring Source have released, &lt;a href="http://www.springframework.org/go-webflow2"&gt;Spring Web Flow 2&lt;/a&gt;, I've read release notes and this make me think about the advantage of Grails.&lt;br /&gt;&lt;br /&gt;Let's see release notes:&lt;br /&gt;&lt;ul style="font-style: italic;"&gt;&lt;li&gt;"The Web Flow module is a MVC extension that allows you to define Controllers using a &lt;a href="http://static.springframework.org/spring-webflow/docs/2.0.x/reference/html/ch02s04.html" target="_blank"&gt;domain-specific-language&lt;/a&gt;."&lt;/li&gt;&lt;/ul&gt;DSL to define flows the fact is XML+EL.  I think is much readable &lt;a href="http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html#6.5%20Web%20Flow"&gt;Grails DSL to define WebFlows&lt;/a&gt; and less verbose.&lt;br /&gt;&lt;ul style="font-style: italic;"&gt;&lt;li&gt;Spring Javascript is a JavaScript abstraction framework that allows you to progressively enhance a web page with behavior.&lt;/li&gt;&lt;/ul&gt;Spring Javascript is built over Dojo to provide Ajax abstractions and rich widget behavior, and &lt;a href="http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html#6.7%20Ajax"&gt;Grails do it&lt;/a&gt;, with tags, and Ajax agnostic calls (Prototype, Dojo, YUI, etc).&lt;br /&gt;&lt;ul&gt;&lt;li style="font-style: italic;"&gt;The &lt;a target="_blank" href="http://static.springframework.org/spring-webflow/docs/2.0.x/reference/html/ch11.html"&gt;Spring Faces&lt;/a&gt; module contains Spring's support for JavaServerFaces.&lt;/li&gt;&lt;/ul&gt;Who cares JSF? The EJBs in the view layer, jeje.&lt;br /&gt;&lt;ul style="font-style: italic;"&gt;&lt;li&gt;Using Spring Security to secure your flows in a declarative manner&lt;/li&gt;&lt;/ul&gt;A lot of security plugins for Grails.&lt;br /&gt;&lt;ul style="font-style: italic;"&gt;&lt;li&gt;Using Tiles for JSP page composition and Ajax partial-rendering&lt;/li&gt;&lt;/ul&gt;Grails layouts, templates and content negotiation are fantastic to do this.&lt;br /&gt;&lt;br /&gt;And the best, Grails can be updated to use Spring Webflow 2.&lt;br /&gt;&lt;br /&gt;But, the advantage goes further, with Servlet 3.0 and generation of &lt;span style="font-weight: bold; font-style: italic;"&gt;web.xml&lt;/span&gt;, I can do it with Grails plugins,&lt;span style="font-weight: bold; font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;and really futher with Java 7 and closures.&lt;span style="font-style: italic; font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=8vsmjH"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=8vsmjH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=L1bRWH"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=L1bRWH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/8887025612602844484/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=8887025612602844484" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8887025612602844484?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8887025612602844484?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/292220283/advantage-of-grails.html" title="The advantage of Grails" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2008/05/advantage-of-grails.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-5036918496462255006</id><published>2008-05-12T09:40:00.003+02:00</published><updated>2008-05-12T09:57:15.576+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-05-12T09:57:15.576+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="course" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><title type="text">Great feedback in Grails Course</title><content type="html">In last week I've been teaching in Groovy and Grails course, around 15 students, some people from Struts 1.x, some people from PHP, some portal developers with Vignette, and newbie people from University.&lt;br /&gt;&lt;br /&gt;The people were very interested in Grails, and all said that is very easy learn, and create Web apps.&lt;br /&gt;&lt;br /&gt;Great experience.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=W0R3eH"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=W0R3eH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=DbfjvH"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=DbfjvH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/5036918496462255006/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=5036918496462255006" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5036918496462255006?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5036918496462255006?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/288537019/great-feedback-in-grails-course.html" title="Great feedback in Grails Course" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2008/05/great-feedback-in-grails-course.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-3939625187494512403</id><published>2008-04-17T16:55:00.004+02:00</published><updated>2008-04-17T20:44:09.570+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-04-17T20:44:09.570+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="course" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title type="text">Grails course in Asturias, Spain</title><content type="html">I'm pleased to annonce a Grails course in Asturias, Spain. The course is organized by the &lt;a href="http://www.coiipa.org/servicios/cursos.html"&gt;College of Engineers of Principado de Asturias&lt;/a&gt;, from 5th to 10th of may, around 15 hours training in Groovy and Grails technologies.&lt;br /&gt;&lt;br /&gt;The title of course can be translate as "Agile Development in Java EE with Grails". If any one is interested, can contact to me by mail.&lt;br /&gt;&lt;br /&gt;Here the slides (in Spanish) for my first class.&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://docs.google.com/EmbedSlideshow?docid=dffnz52r_15vzw852dv" frameborder="0" height="342" width="410"&gt;&lt;/iframe&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=kaFeboG"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=kaFeboG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=a5PXlrG"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=a5PXlrG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/3939625187494512403/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=3939625187494512403" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/3939625187494512403?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/3939625187494512403?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/272364775/grails-course-in-asturias-spain.html" title="Grails course in Asturias, Spain" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2008/04/grails-course-in-asturias-spain.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-8725780312906554476</id><published>2008-04-07T20:24:00.004+02:00</published><updated>2008-04-07T21:00:18.910+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-04-07T21:00:18.910+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="spring" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="dsl" /><title type="text">Grails: Plugglabe Service, Reloaded</title><content type="html">Yesterday I've read, the post from &lt;a href="http://josh-in-antarctica.blogspot.com/2008/04/pluggable-service-implementations-in.html"&gt;Josh Creed about a pluggable service&lt;/a&gt; in Grails and I've been thinking the way to do with IoC and wire provider with Spring.&lt;br /&gt;&lt;br /&gt;Let's do it, with small test.&lt;br /&gt;&lt;br /&gt;First my service class &lt;span style="font-style: italic;"&gt;GreetService&lt;/span&gt;:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;class GreetService {&lt;br /&gt;&lt;br /&gt; def provider&lt;br /&gt;&lt;br /&gt; def sayHello(String name){&lt;br /&gt;         provider.sayHello(name)&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;Now, two Providers:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;class DevProvider {&lt;br /&gt;  def sayHello(String name){&lt;br /&gt;          println "DevProvider: hello ${name}"&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class TestProvider {&lt;br /&gt;  def sayHello(String name){&lt;br /&gt;          println "TestProvider: hello ${name}"&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;Now I'm gonna use Spring DSL, in &lt;span style="font-style: italic;"&gt;resources.groovy&lt;/span&gt;, to define &lt;span style="font-style: italic;"&gt;provider&lt;/span&gt; bean that depends of environment:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;import grails.util.*&lt;br /&gt;beans = {&lt;br /&gt;   switch(GrailsUtil.environment) {&lt;br /&gt;           case "test":&lt;br /&gt;                   provider(TestProvider)&lt;br /&gt;           break&lt;br /&gt;           case "development":&lt;br /&gt;                   provider(DevProvider)&lt;br /&gt;           break&lt;br /&gt;           }&lt;br /&gt;   }&lt;/pre&gt;&lt;/div&gt;And that's all with Groovy and Grails magic, here the test:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;class GreetServiceTests extends GroovyTestCase {&lt;br /&gt;&lt;br /&gt;    def greetService&lt;br /&gt;&lt;br /&gt;    void testGreet() {&lt;br /&gt;&lt;br /&gt;            greetService.sayHello("World!!!!!!")&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;// output: TestProvider: hello World!!!!!!&lt;/pre&gt;&lt;/div&gt;And in Grails console, another test:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;def service = ctx.getBean("greetService")&lt;br /&gt;service.sayHello("world")&lt;br /&gt;&lt;br /&gt;// output: DevProvider: hello world&lt;/pre&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=3CHHt6G"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=3CHHt6G" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=gN1T8hG"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=gN1T8hG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/8725780312906554476/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=8725780312906554476" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8725780312906554476?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8725780312906554476?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/265828443/grails-plugglabe-service-reloaded.html" title="Grails: Plugglabe Service, Reloaded" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2008/04/grails-plugglabe-service-reloaded.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-5805870960601204053</id><published>2008-03-13T10:05:00.003+01:00</published><updated>2008-03-13T10:21:12.405+01:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-03-13T10:21:12.405+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="plugin" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title type="text">Grails: JettyStatic plugin released</title><content type="html">The &lt;a href="http://dahernan.net/2008/02/my-first-grails-plugin.html"&gt;past month&lt;/a&gt; I did a plugin to server static content with jetty for grails, now I publish the plugin for anyone that could be useful.&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://code.google.com/p/jettystatic/wiki/Usage"&gt;How to use the plugin&lt;/a&gt;.&lt;/li&gt;&lt;li&gt; &lt;a href="http://jettystatic.googlecode.com/files/grails-jettystatic-0.1.zip"&gt;Download the plugin.&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a href="http://code.google.com/p/jettystatic/source/browse"&gt;Source code&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=dIac6WF"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=dIac6WF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=RHiICWF"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=RHiICWF" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/5805870960601204053/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=5805870960601204053" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5805870960601204053?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5805870960601204053?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/250653973/grails-jettystatic-plugin-released.html" title="Grails: JettyStatic plugin released" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2008/03/grails-jettystatic-plugin-released.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-8766283926930444904</id><published>2008-02-28T16:29:00.004+01:00</published><updated>2008-02-28T23:06:21.809+01:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-02-28T23:06:21.809+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><title type="text">Grails: Hacking paginate tag to make Ajax way</title><content type="html">I one thing I miss in Grails is a remotePaginate Taglib (&lt;a href="http://jira.codehaus.org/browse/GRAILS-2519"&gt;you can vote in Jira&lt;/a&gt;), today I'm going to hack paginate tag to make an Ajax paginate.&lt;br /&gt;&lt;br /&gt;For this I have various options, I can modify the actual paginated taglib or the option I've chosen, hack with prototype observe the links generated by paginate tag.&lt;br /&gt;&lt;br /&gt;To make easy, I've used &lt;a href="http://dahernan.net/2008/01/grails-tag-for-prototype-observe.html"&gt;observe tag&lt;/a&gt;, to capture clicks events, let's go with the example of &lt;span style="font-weight: bold;"&gt;list.gsp&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;You have to wrap your list with &lt;span style="font-weight: bold;"&gt;div&lt;/span&gt; for this example '&lt;span style="font-weight: bold;"&gt;ajax_wrap&lt;/span&gt;' to refresh with Ajax calls.&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;div id="ajax_wrap"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div class="list"&amp;gt;                     &lt;br /&gt;   &amp;lt;g:render template="archive" collection="${archiveList}" var="archive"/&amp;gt; &lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div class="paginateButtons"&amp;gt;                           &lt;br /&gt;  &amp;lt;g:paginate action="list" total="${Archive.count()}" /&amp;gt;    &lt;br /&gt;       &amp;lt;g:observe classes="${['step','prevLink','nextLink']}" event="click" function="clickPaginate"/&amp;gt;           &lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;I've used &lt;span style="font-weight: bold;"&gt;g:observe &lt;/span&gt;to capture click events in generated links by &lt;span style="font-weight: bold;"&gt;g:paginate&lt;/span&gt;,  and define a function handler &lt;span style="font-weight: bold; font-style: italic;"&gt;clickPaginate&lt;/span&gt; that performs the Ajax calls.&lt;br /&gt;&lt;br /&gt;Here function handler defnition:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;function clickPaginate(event){&lt;br /&gt; event.stop();&lt;br /&gt; var link = event.element();&lt;br /&gt; if(link.href == null){&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt;  &lt;br /&gt; new Ajax.Updater(&lt;br /&gt;  { success: $('ajax_wrap') },&lt;br /&gt;   link.href,&lt;br /&gt;  {&lt;br /&gt;      evalScripts: true&lt;br /&gt;  });&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;The Ajax call update the element '&lt;span style="font-weight: bold;"&gt;ajax_wrap&lt;/span&gt;'.&lt;br /&gt;&lt;br /&gt;With this you have an elegant way to make your list paginated effortlessly&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=jnW925E"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=jnW925E" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=gmaPUiE"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=gmaPUiE" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/8766283926930444904/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=8766283926930444904" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8766283926930444904?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8766283926930444904?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/242964946/grails-hacking-paginate-tag-to-make.html" title="Grails: Hacking paginate tag to make Ajax way" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://dahernan.net/2008/02/grails-hacking-paginate-tag-to-make.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-1701794905640426898</id><published>2008-02-18T16:29:00.009+01:00</published><updated>2008-02-18T22:58:45.664+01:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-02-18T22:58:45.664+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tip" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title type="text">Grails: Tip for scaffolding required fields</title><content type="html">Scaffolding is one of the most useful features of grails and customizing scaffolding   it's basic for increase your productivity.&lt;br /&gt;&lt;br /&gt;One thing I've customized is render a '&lt;span style="font-weight: bold;"&gt;*&lt;/span&gt;' for required fields, for this you have to install scaffolding templates with &lt;a style="font-style: italic;" href="http://grails.org/doc/1.0.x/ref/Command%20Line/install-templates.html"&gt;grails install-templates&lt;/a&gt;&lt;span style="font-style: italic;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is a fragment of the original &lt;span style="font-style: italic;"&gt;templates/scaffolding/create.gsp&lt;/span&gt;,&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;props.each { p -&amp;gt;&lt;br /&gt;if(p.type != Set.class) {&lt;br /&gt;        cp = domainClass.constrainedProperties[p.name]&lt;br /&gt;        display = (cp ? cp.display : true)    &lt;br /&gt;        if(display) { %&amp;gt;&lt;br /&gt;&amp;lt;tr class="prop"&amp;gt;&lt;br /&gt;    &amp;lt;td valign="top" class="name"&amp;gt;&lt;br /&gt;        &amp;lt;label for="${p.name}"&amp;gt;${p.naturalName}:&amp;lt;/label&amp;gt;&lt;br /&gt;    &amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;td valign="top" class="value \${hasErrors(bean:${domainClass.propertyName},field:'${p.name}','errors')}"&amp;gt;&lt;br /&gt;        ${renderEditor(p)}&lt;br /&gt;    &amp;lt;/td&amp;gt;&lt;br /&gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;&amp;lt;%  }   }   } %&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I'm going to introduce a line, to check if the field has a constraint &lt;span style="font-style: italic; font-weight: bold;"&gt;blank:false&lt;/span&gt;, and in this case render as a required field.&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;if(!cp?.blank) { %&amp;gt;&amp;lt;span class="req"&amp;gt;*&amp;lt;/span&amp;gt;&amp;lt;% } %&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The updated version complete:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;   props.each { p -&amp;gt;&lt;br /&gt;if(p.type != Set.class) {&lt;br /&gt;        cp = domainClass.constrainedProperties[p.name]&lt;br /&gt;        display = (cp ? cp.display : true)    &lt;br /&gt;        if(display) { %&amp;gt;&lt;br /&gt;&amp;lt;tr class="prop"&amp;gt;&lt;br /&gt;    &amp;lt;td valign="top" class="name"&amp;gt;&lt;br /&gt;        &amp;lt;% if(!cp?.blank) { %&amp;gt;&amp;lt;span class="req"&amp;gt;*&amp;lt;/span&amp;gt;&amp;lt;% } %&amp;gt;&lt;br /&gt;        &amp;lt;label for="${p.name}"&amp;gt;${p.naturalName}:&amp;lt;/label&amp;gt;&lt;br /&gt;    &amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;td valign="top" class="value \${hasErrors(bean:${domainClass.propertyName},field:'${p.name}','errors')}"&amp;gt;&lt;br /&gt;        ${renderEditor(p)}&lt;br /&gt;    &amp;lt;/td&amp;gt;&lt;br /&gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;&amp;lt;%  }   }   } %&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;That's all folks.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=E98tFLE"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=E98tFLE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=Oqft4aE"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=Oqft4aE" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/1701794905640426898/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=1701794905640426898" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/1701794905640426898?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/1701794905640426898?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/237196820/grails-tip-for-scaffolding-required.html" title="Grails: Tip for scaffolding required fields" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://dahernan.net/2008/02/grails-tip-for-scaffolding-required.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-3207475481137130674</id><published>2008-02-11T23:32:00.001+01:00</published><updated>2008-02-12T20:04:44.385+01:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-02-12T20:04:44.385+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="plugin" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title type="text">My first Grails plugin</title><content type="html">The grails plugin architecture it's fantastic, I've spent one afternoon doing a static content plugin, yeah there is a oficial &lt;a href="http://grails.codehaus.org/Static+Resources+Plugin"&gt;static plugin&lt;/a&gt;, but I use jetty for development and production, and the static content it's uploaded by the users.&lt;br /&gt;With Jetty servlet to server static content is enought for me, and with some configuration parameters, if required can be disabled.&lt;br /&gt;&lt;br /&gt;Another advantage is that this way you can protect your static content with the Acegi plugin.&lt;br /&gt;&lt;br /&gt;The first step it's create plugin:&lt;br /&gt;&lt;pre&gt;grails create-plugin jettystatic&lt;br /&gt;&lt;/pre&gt; The project looks like a normal grails project, excepts that you have a plugin descriptor file.&lt;br /&gt;In the JettystaticGrailsPlugin.groovy I've updated the &lt;span style="font-style: italic;"&gt;web.xml &lt;/span&gt;generated:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;def doWithWebDescriptor = { webXml -&amp;gt;&lt;br /&gt;   log.info "Jetty Static Initializing servlet"&lt;br /&gt;    def dir = application.config?.jettystatic.dir&lt;br /&gt;    if(!dir){     &lt;br /&gt;     dir = './static'&lt;br /&gt;    } &lt;br /&gt;  &lt;br /&gt;    if(application.config?.jettystatic.ignore){&lt;br /&gt;     log.info "Jetty Static: No jetty static servlet inicialized"&lt;br /&gt;     return&lt;br /&gt;    }&lt;br /&gt;  &lt;br /&gt;    log.info "Jetty Static dir '${dir}' and mapping '${mapping}'"&lt;br /&gt;    def mapping = '/resources/*'&lt;br /&gt;    def servlets = webXml.'servlet'&lt;br /&gt;&lt;br /&gt; servlets[servlets.size()-1] + {&lt;br /&gt;  'servlet' {&lt;br /&gt;    log.info 'Jetty Static generating &amp;lt;servlet&amp;gt; for static content'&lt;br /&gt;  &lt;br /&gt;   'servlet-name'("jettystatic")&lt;br /&gt;   'servlet-class'("org.mortbay.jetty.servlet.DefaultServlet")  &lt;br /&gt;&lt;br /&gt;   'init-param' {&lt;br /&gt;    'param-name'("resourceBase")&lt;br /&gt;    'param-value'(dir)&lt;br /&gt;   }  &lt;br /&gt;  &lt;br /&gt;   'init-param' {&lt;br /&gt;     'param-name'("dirAllowed")&lt;br /&gt;     'param-value'("false")&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;   'init-param' {&lt;br /&gt;    'param-name'("gzip")&lt;br /&gt;    'param-value'("true")&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   'load-on-startup'("1")&lt;br /&gt;  }  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;    def mappings = webXml.'servlet-mapping'&lt;br /&gt;    mappings[mappings.size()-1] + {&lt;br /&gt;  'servlet-mapping' {&lt;br /&gt;   'servlet-name'("jettystatic")&lt;br /&gt;   'url-pattern'(mapping)&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;  }&lt;/pre&gt;&lt;/div&gt;The other thing I need, is a taglib to make links to static content, and I'd like that the tag transform from absolute path of static content to a relative web path, this make easy upload content, and server the content uploaded.&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;def resource = {attrs -&amp;gt;&lt;br /&gt; def url = grailsApplication.config?.jettystatic.absolute.url&lt;br /&gt; def dir = grailsApplication.config?.jettystatic.basepath&lt;br /&gt; def file = attrs.file&lt;br /&gt; def baseUrl = ""&lt;br /&gt;&lt;br /&gt; if(dir){&lt;br /&gt;  if(!dir.endsWith('/')){&lt;br /&gt;   dir = dir + '/'&lt;br /&gt;  }&lt;br /&gt;  file = file.replaceFirst(dir,"")&lt;br /&gt; }&lt;br /&gt; if(url){&lt;br /&gt;  baseUrl = url&lt;br /&gt; }else{&lt;br /&gt;  baseUrl = g.createLinkTo(dir:'resources')&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; def env = GrailsUtil.environment&lt;br /&gt; if(env &amp;amp;&amp;amp; env == "development"){&lt;br /&gt;  baseUrl = g.createLinkTo(dir:'resources')&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; if(!baseUrl.endsWith('/')){&lt;br /&gt;  baseUrl = baseUrl + '/'&lt;br /&gt; } &lt;br /&gt; out&amp;lt;&amp;lt; "${baseUrl}${file}"&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;At this point the only thing I have to do is package my plugin (&lt;span style="font-style: italic;"&gt;grails package-plugin&lt;/span&gt;) to use in any project.&lt;br /&gt;&lt;br /&gt;I can't imagine doing something like this in java and spend this time.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=yoRpDYE"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=yoRpDYE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=b8SNB5E"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=b8SNB5E" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/3207475481137130674/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=3207475481137130674" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/3207475481137130674?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/3207475481137130674?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/233905383/my-first-grails-plugin.html" title="My first Grails plugin" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://dahernan.net/2008/02/my-first-grails-plugin.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-4890975207412216172</id><published>2008-01-30T20:07:00.000+01:00</published><updated>2008-01-30T21:33:38.690+01:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-01-30T21:33:38.690+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="prototype" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title type="text">Grails: Tag for Prototype observe</title><content type="html">Continuing with Grails taglib, now I'm going to do a taglib to easy capture and group javascript events. I'll use prototype &lt;a href="http://www.prototypejs.org/api/element/observe"&gt;element observe method&lt;/a&gt;. Here the code:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;def observe = {attrs -&amp;gt;&lt;br /&gt;if(!attrs.noScript){&lt;br /&gt; out &amp;lt;&amp;lt; '&amp;lt;script type="text/javascript"&amp;gt;'&lt;br /&gt;}&lt;br /&gt;if(attrs.element &amp;amp;&amp;amp; attrs.element instanceof String){ &lt;br /&gt; printObserve("\$('${attrs.element}')", attrs.event, attrs.function, out) &lt;br /&gt;}&lt;br /&gt;if(attrs.element &amp;amp;&amp;amp; attrs.element instanceof List){&lt;br /&gt; attrs.element.each{it -&amp;gt; printObserve("\$('${it}')", attrs.event, attrs.function, out)}&lt;br /&gt;}&lt;br /&gt;if(attrs.classes &amp;amp;&amp;amp; attrs.classes instanceof String){&lt;br /&gt; printObserveClass(attrs.classes, attrs.event, attrs.function, out)&lt;br /&gt;}&lt;br /&gt;if(attrs.classes &amp;amp;&amp;amp; attrs.classes instanceof List){&lt;br /&gt; attrs.classes.each{ it -&amp;gt; printObserveClass(it, attrs.event, attrs.function, out)}&lt;br /&gt;}&lt;br /&gt;if(!attrs.noScript){&lt;br /&gt; out &amp;lt;&amp;lt; '&amp;lt;/script&amp;gt;'&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def printObserveClass(className, event, function, out){&lt;br /&gt;out &amp;lt;&amp;lt;  "var classes  = \$\$('.' + '${className}');"&lt;br /&gt;out &amp;lt;&amp;lt;  "for(i = 0; i &amp;lt; classes.length; i++) {"&lt;br /&gt;printObserve("classes[i]", event, function, out)&lt;br /&gt;out &amp;lt;&amp;lt;  "}"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def printObserve(element, event, function, out){&lt;br /&gt;if(event &amp;amp;&amp;amp; event instanceof String){&lt;br /&gt; out &amp;lt;&amp;lt; "${element}.observe('${event}', ${function});"&lt;br /&gt;}&lt;br /&gt;if(event &amp;amp;&amp;amp; event instanceof List){&lt;br /&gt; attrs.event.each{ it -&amp;gt; out &amp;lt;&amp;lt; "${element}.observe('${it}', ${function});"}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now, some examples.&lt;br /&gt;&lt;br /&gt;Simple use:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;g:javascript&amp;gt;&lt;br /&gt;function testing(event){event.stop();alert('hello');}&lt;br /&gt;&amp;lt;/g:javascript&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;a id="idTest" href="http://grails.org"&amp;gt;Grails Rulez&amp;lt;/a&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;g:observe element="idTest" event="click" function="testing"/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;With a list of elements:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;g:observe element="${['id1','id2','id3']}" event="click" function="testing"/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;With a list of events:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;g:observe element="${['id1','id2','id3']}" event="${['click','load']}" function="testing"/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;With a list of classes:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;g:observe element="${['id1','id2']}" classes="${['class1','class2']}" event="change" function="testing"/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=17wJLMD"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=17wJLMD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=KHuskHD"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=KHuskHD" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/4890975207412216172/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=4890975207412216172" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/4890975207412216172?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/4890975207412216172?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/226086251/grails-tag-for-prototype-observe.html" title="Grails: Tag for Prototype observe" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2008/01/grails-tag-for-prototype-observe.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-7065742346942866343</id><published>2008-01-27T13:47:00.000+01:00</published><updated>2008-01-27T14:28:44.602+01:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-01-27T14:28:44.602+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title type="text">Grails: Easy tags (remoteDiv)</title><content type="html">TagLibs in Grails are extremely easy, you have some tags for Ajax like remoteField, remoteFuntion, remoteLink. But this time I need to get div asynchronous when page loads, this is very useful for example to show the users connected.&lt;br /&gt;&lt;br /&gt;There isn't remoteDiv tag in Grails but in five minutes I've got my tag:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;def remoteDiv = { attrs,body -&amp;gt;&lt;br /&gt;   def complete = ""&lt;br /&gt;   if(attrs.onComplete){&lt;br /&gt;    complete = ",onComplete: ${attrs.onComplete}"&lt;br /&gt;   } &lt;br /&gt;   &lt;br /&gt;   out &amp;lt;&amp;lt; """&lt;br /&gt;   &amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;       new Ajax.Updater(&lt;br /&gt;           { success: '${attrs.id}' }, &lt;br /&gt;           '${attrs.url}', &lt;br /&gt;           { &lt;br /&gt;               method: 'get',&lt;br /&gt;               evalScripts: true&lt;br /&gt;    ${complete}&lt;br /&gt;           });&lt;br /&gt;   &amp;lt;/script&amp;gt;&lt;br /&gt;       """&lt;br /&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;An example of use:&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;div id="testAjax"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;g:remoteDiv &lt;br /&gt; id="testAjax" &lt;br /&gt; url="${createLink(action: 'show', id:'1')}" &lt;br /&gt; onComplete="new Effect.Highlight('testAjax')"&lt;br /&gt;/&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I've use prototype AjaxUpdater to do asynchronous request, it's not library agnostic like others remote tags in Grails but it's simple :D&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=wZBRM9D"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=wZBRM9D" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=hQDwqiD"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=hQDwqiD" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/7065742346942866343/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=7065742346942866343" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/7065742346942866343?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/7065742346942866343?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/223990614/grails-easy-tags-remotediv.html" title="Grails: Easy tags (remoteDiv)" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2008/01/grails-easy-tags-remotediv.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-5358152231508710892</id><published>2008-01-19T12:20:00.000+01:00</published><updated>2008-01-20T12:32:36.614+01:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-01-20T12:32:36.614+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title type="text">Grails, be agile my friend</title><content type="html">This month I've been testing Grails, (it was in &lt;a href="http://dahernan.net/2007/05/things-that-id-like-to-test.html"&gt;my Todo list&lt;/a&gt; some time ago).&lt;br /&gt;First I've read some about Groovy, and it's really easy the syntax and I like it.&lt;br /&gt;&lt;br /&gt;Then, I've read about &lt;a href="http://grails.codehaus.org/Developer+Documentation"&gt;Grails architecture&lt;/a&gt; and the &lt;a href="http://grails.org/doc/1.0.x/"&gt;User Guide&lt;/a&gt;.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Impressions&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My impresion it's Grails is not much diferent than Appfuse, step by step:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;GORM and Domain Model, is based in JPA and Hibernate. (&lt;a href="http://icoloma.blogspot.com/2007/12/validate-web-forms-using-jpa.html"&gt;domain centric approach&lt;/a&gt; explained by icoloma)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Controllers are based in Spring MVC.&lt;/li&gt;&lt;li&gt;IoC with Spring (of course).&lt;/li&gt;&lt;li&gt;Layouts based in Sitemesh.&lt;/li&gt;&lt;li&gt;Also you have Web Flow with Spring Web Flow.&lt;/li&gt;&lt;li&gt;Both are a simple WAR file.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;This similars are very good for me, because I'm an old user of Appfuse and maybe can adapt Appfuse applications to Grails, I and can achive more agility.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Enterprise Ready?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;Graeme Rocher &lt;a href="http://graemerocher.blogspot.com/2008/01/re-groovy-and-jruby-enterprise-ready.html"&gt;gave  a kick ass to someone that say no&lt;/a&gt; :D. I think it's ready, you have to take care about your code like in any other language.&lt;br /&gt;&lt;br /&gt;The only thing I miss, is better support for Groovy and GSP in Eclipse (autocompletion, refactor) and &lt;a href="http://graemerocher.blogspot.com/2008/01/why-grails-doesnt-use-maven.html"&gt;manage the dependencies.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;update&lt;/span&gt;: &lt;a href="http://glaforge.free.fr/weblog/index.php?itemid=227"&gt;Guillaume Laforge thoughts&lt;/a&gt; about Enterprise Ready&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=mKKx69D"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=mKKx69D" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=U4z402D"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=U4z402D" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/5358152231508710892/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=5358152231508710892" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5358152231508710892?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5358152231508710892?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/219396540/grails-be-agile-my-friend.html" title="Grails, be agile my friend" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://dahernan.net/2008/01/grails-be-agile-my-friend.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-4617874103382719671</id><published>2007-12-02T23:17:00.000+01:00</published><updated>2007-12-11T13:40:46.453+01:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-12-11T13:40:46.453+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="scriptaculous" /><category scheme="http://www.blogger.com/atom/ns#" term="prototype" /><title type="text">Notification area with Scriptaculous</title><content type="html">This time I need a notification area in webapp, the idea is a div that appears and disappears.&lt;br /&gt;&lt;br /&gt;In &lt;a href="http://script.aculo.us/"&gt;Scriptaculous&lt;/a&gt; it's easy extend and combine effects, and the first I do is extend an Effect to do the behavior that I'm looking for.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;Effect.Notify = function(element) {&lt;br /&gt;  element = $(element);&lt;br /&gt;    return new Effect.Appear(element, &lt;br /&gt;      { afterFinishInternal: function(effect) {&lt;br /&gt;          new Effect.Fade(effect.element,{ delay: 1.6 });&lt;br /&gt;      }});&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The only thing you have to do is create a "div" with style "display: none" and invoke the Effect like this: &lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;new Effect.Notify('mydiv');&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Simple and powerful.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=wzyCjnC"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=wzyCjnC" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=bLDB2SC"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=bLDB2SC" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/4617874103382719671/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=4617874103382719671" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/4617874103382719671?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/4617874103382719671?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/198587744/noticication-area-with-scriptaculous.html" title="Notification area with Scriptaculous" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2007/12/noticication-area-with-scriptaculous.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-8506859960460713382</id><published>2007-11-12T15:44:00.000+01:00</published><updated>2007-11-17T14:10:12.478+01:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-11-17T14:10:12.478+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="ajax" /><category scheme="http://www.blogger.com/atom/ns#" term="prototype" /><title type="text">AjaxForm class for prototype</title><content type="html">Some weeks ago an old mate asked to me the best way to send a form in ajax style and put the result in "div". I think the best way is using &lt;a href="http://www.prototypejs.org/"&gt;prototype javascript framework&lt;/a&gt;.&lt;br /&gt;For one project I did a AjaxForm class, it based in an Ajax example of Spring Web Flow.&lt;br /&gt;&lt;br /&gt;Here the class:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;var AjaxForm = Class.create();&lt;br /&gt;AjaxForm.prototype = {&lt;br /&gt; initialize: function(formElementId) {&lt;br /&gt;  this.formElementId = formElementId;&lt;br /&gt;  Event.observe(formElementId, 'submit', this.handleSubmitEvent.bindAsEventListener(this), false);&lt;br /&gt; },&lt;br /&gt;&lt;br /&gt; handleSubmitEvent: function(event){&lt;br /&gt;  var formElement = $(this.formElementId);&lt;br /&gt;  if (formElement.tagName.toLowerCase() != 'form') {&lt;br /&gt;   throw 'Element ' + formElement + ' is not a FORM element!';&lt;br /&gt;  }&lt;br /&gt;  var method = formElement.method;&lt;br /&gt;  if (method == null) {&lt;br /&gt;   method = 'get';&lt;br /&gt;  }&lt;br /&gt;  var url = formElement.action;&lt;br /&gt;  if (url == null) {&lt;br /&gt;   throw 'No action defined on ' + formElement;&lt;br /&gt;  }&lt;br /&gt;  try {&lt;br /&gt;   Event.stop(event);&lt;br /&gt;   showLoadInfo(formElement);&lt;br /&gt;   var params = Form.serialize(formElement, true);&lt;br /&gt;&lt;br /&gt;   var myRequest = new Ajax.Updater(&lt;br /&gt;   { success: formElement.parentNode },&lt;br /&gt;   url,&lt;br /&gt;   {&lt;br /&gt;   method: method,&lt;br /&gt;   parameters: params,&lt;br /&gt;   evalScripts: true,&lt;br /&gt;   onFailure: errFunc&lt;br /&gt;   });&lt;br /&gt;  } finally {&lt;br /&gt;   return false;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;};&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;To use this class is very simple, you have to wrapper the form with a div, and create a new AjaxForm, like this example:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;div id="wrapperForm"&amp;gt;&lt;br /&gt; &amp;lt;form id="myAjaxForm" action="/dosomething"&amp;gt;&lt;br /&gt; ...&lt;br /&gt; ...&lt;br /&gt; &amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;    // &amp;lt;![CDATA[&lt;br /&gt; new AjaxForm('myAjaxForm');&lt;br /&gt;   // ]]&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The result of the post is put in div "wrapperForm". It's fantastic because doesn't break the MVC, remember disable decorators or tiles in the result page, because the result is in the div, not in the page.&lt;br /&gt;&lt;br /&gt;I have to update the syntax of AjaxForm class to prototype 1.6, but for example is good enought.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=dgCt4nB"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=dgCt4nB" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=67iEb7B"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=67iEb7B" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/8506859960460713382/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=8506859960460713382" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8506859960460713382?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8506859960460713382?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/186255299/ajaxform-class-for-prototype.html" title="AjaxForm class for prototype" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2007/11/ajaxform-class-for-prototype.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-6734813517905660422</id><published>2007-11-10T14:55:00.000+01:00</published><updated>2007-11-10T17:16:01.535+01:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-11-10T17:16:01.535+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="hibernate search" /><category scheme="http://www.blogger.com/atom/ns#" term="compass" /><title type="text">Compass or Hibernate Search</title><content type="html">Compass and Hibernate Search are two frameworks to provide full text search engine to your apps.&lt;br /&gt;Which one to choose? This is a &lt;a href="http://www.jroller.com/kimchy/entry/hibernate_search_lucene"&gt;large discussion&lt;/a&gt; between &lt;a href="http://blog.emmanuelbernard.com/"&gt;Emmanuel Bernard&lt;/a&gt; (Hibernate) and &lt;a href="http://www.kimchy.org/"&gt;Shay Banon&lt;/a&gt; (Compass), my conclusion is that both are really good.&lt;br /&gt;Yeah, both are really good but I have to choose one, and I choose Hibernate Search, here my reasons.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I use Hibernate API with JPA annotations and similar API seems more natural, to learn and understand.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Minimal configuration. I only have to put two properties in the config.&lt;/li&gt;&lt;li&gt;All of my searchable data are in database.&lt;/li&gt;&lt;li&gt;I think the Hibernate Search annotations fits better with JPA annotations.&lt;/li&gt;&lt;li&gt;And the last, Hibernate Search is in maven repository (Compass no).&lt;/li&gt;&lt;/ul&gt;If I used Ibatis or JDBC directly, I'd choose Compass.&lt;br /&gt;Maybe, if I had many searchable data, that aren't in database I'd choose Compass too.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=AC4GukB"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=AC4GukB" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=EgqMXcB"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=EgqMXcB" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/6734813517905660422/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=6734813517905660422" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/6734813517905660422?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/6734813517905660422?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/182735632/compass-or-hibernate-search.html" title="Compass or Hibernate Search" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://dahernan.net/2007/11/compass-or-hibernate-search.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-8439796493553918171</id><published>2007-10-01T12:39:00.000+02:00</published><updated>2007-10-01T21:52:22.273+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-10-01T21:52:22.273+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="spring" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><category scheme="http://www.blogger.com/atom/ns#" term="acegi" /><title type="text">Saving the last time login with Acegi Security</title><content type="html">This time, I'm going to explain how to save the last login time of user with &lt;a href="http://www.acegisecurity.org/"&gt;Acegi Security for Spring&lt;/a&gt;. &lt;br /&gt;It's really easy, due to Acegi publishes an autentication event in the Spring ApplicationContext (&lt;a href="http://static.springframework.org/spring/docs/2.0.x/reference/beans.html#context-functionality-events"&gt;documentation about publish/suscribe events&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;I have to create a simple class that implements ApplicationListener.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;public class LastLoginListener implements ApplicationListener {&lt;br /&gt; &lt;br /&gt; private UserManager userManager;&lt;br /&gt; &lt;br /&gt; // getter and setter ...&lt;br /&gt;&lt;br /&gt; public void onApplicationEvent(ApplicationEvent event) {&lt;br /&gt;  if (event instanceof AbstractAuthenticationEvent) {&lt;br /&gt;   &lt;br /&gt;   if (event instanceof AbstractAuthenticationFailureEvent) {&lt;br /&gt;    // log or similar&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   if ( event instanceof AuthenticationSuccessEvent ){&lt;br /&gt;    AuthenticationSuccessEvent authenticationSuccessEvent = ( AuthenticationSuccessEvent ) event;&lt;br /&gt;    String username = authenticationSuccessEvent.getAuthentication().getName();&lt;br /&gt;    User user = userManager.getUserByUsername(username);&lt;br /&gt;    user.setLastLogin(new Date());&lt;br /&gt;    userManager.saveUser(user);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In the method "onApplicationEvent" I listen the event AbstractAuthenticationEvent, that Acegi publishes. &lt;br /&gt;Next, I update the last login time, with the userManager.&lt;br /&gt;&lt;br /&gt;The last step is setup my LastLoginListener in security.xml with  the other Acegi beans.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;bean id="lastLoginListener" class="net.dahernan.common.security.LastLoginListener"&amp;gt;&lt;br /&gt;     &amp;lt;property name="userManager" ref="userManager"/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=FOkdK7ZX"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=FOkdK7ZX" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=rDrYLdEc"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=rDrYLdEc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/8439796493553918171/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=8439796493553918171" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8439796493553918171?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8439796493553918171?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/163854785/saving-last-time-login-with-acegi.html" title="Saving the last time login with Acegi Security" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2007/10/saving-last-time-login-with-acegi.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-6758271724516696296</id><published>2007-09-16T12:32:00.000+02:00</published><updated>2007-09-16T13:07:40.613+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-09-16T13:07:40.613+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tip" /><category scheme="http://www.blogger.com/atom/ns#" term="spring web flow" /><title type="text">Tip: Put result in session in Spring Web Flow</title><content type="html">So, another tip with Spring Web Flow. Sometimes it's necessary put a result of bean-action in scope session, but in SWF 1.X doesn't have this feature, but you can make a simple action to do the work.&lt;br /&gt;&lt;br /&gt;First, the flow definition:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;action-state id="saveProject"&amp;gt;&lt;br /&gt; &amp;lt;bean-action bean="projectManager" method="save"&amp;gt;&lt;br /&gt;  &amp;lt;method-arguments&amp;gt;&lt;br /&gt;  &amp;lt;argument expression="flowScope.project" /&amp;gt;&lt;br /&gt;  &amp;lt;/method-arguments&amp;gt;&lt;br /&gt;  &amp;lt;method-result name="project" scope="request"/&amp;gt;&lt;br /&gt; &amp;lt;/bean-action&amp;gt;&lt;br /&gt; &amp;lt;transition on="success" to="putInSession" /&amp;gt;     &lt;br /&gt;&amp;lt;/action-state&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;action-state id="putInSession"&amp;gt;     &lt;br /&gt; &amp;lt;action bean="putInSessionAction"&amp;gt;&lt;br /&gt;  &amp;lt;attribute name="sessionKey" value="project" /&amp;gt;      &lt;br /&gt; &amp;lt;/action&amp;gt;&lt;br /&gt; &amp;lt;transition on="success" to="finish"/&amp;gt;&lt;br /&gt;&amp;lt;/action-state&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I call a bean-action &lt;span style="font-weight:bold;"&gt;"saveProject"&lt;/span&gt; and I put the result in request with key &lt;span style="font-weight:bold;"&gt;"project"&lt;/span&gt;. Next, I execute the action &lt;span style="font-weight:bold;"&gt;"putInSession"&lt;/span&gt; and I set the attribute &lt;span style="font-weight:bold;"&gt;"sessionKey"&lt;/span&gt; with the value of the key &lt;span style="font-weight:bold;"&gt;"project"&lt;/span&gt;, this mean thay the object to save in session is in the request with this key.&lt;br /&gt;&lt;br /&gt;With this convention, here the Action implementation:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;public class PutInSessionAction implements Action{&lt;br /&gt; &lt;br /&gt; public Event execute(RequestContext context) throws Exception {&lt;br /&gt;  &lt;br /&gt;  String key = (String) context.getAttributes().get("sessionKey");&lt;br /&gt;  Object value = context.getRequestScope().get(key);  &lt;br /&gt;  context.getExternalContext().getSessionMap().put(key, value);&lt;br /&gt;&lt;br /&gt;  return new Event(this, "success");&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This simple Action gets the object from the request and puts in session.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=VDxN7Tz5"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=VDxN7Tz5" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=vLEbCyKK"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=vLEbCyKK" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/6758271724516696296/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=6758271724516696296" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/6758271724516696296?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/6758271724516696296?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/157155854/tip-put-result-in-session-in-spring-web.html" title="Tip: Put result in session in Spring Web Flow" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://dahernan.net/2007/09/tip-put-result-in-session-in-spring-web.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-4603524872712604277</id><published>2007-09-02T13:22:00.000+02:00</published><updated>2007-09-02T14:24:35.550+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-09-02T14:24:35.550+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tip" /><category scheme="http://www.blogger.com/atom/ns#" term="spring web flow" /><title type="text">Tip: Output a success message in a subflow in Spring Web Flow</title><content type="html">In Ajax applications is common output a success or error message (like Google Mail interface). With Spring Web Flow I can define subflows to do commons things and reuse parts of the application but if I want to output a success message, the natural way it's to define a view state.&lt;br /&gt;&lt;br /&gt;This tip shows other way to output a message.&lt;br /&gt;&lt;br /&gt;I have a subflow to add a new company.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;start-state idref="enterCompanyData"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;view-state id="enterCompanyData" view="people/ajax/company_add"&amp;gt;&lt;br /&gt; &amp;lt;render-actions&amp;gt;&lt;br /&gt;  &amp;lt;action bean="formAction" method="setupForm" /&amp;gt;&lt;br /&gt; &amp;lt;/render-actions&amp;gt;   &lt;br /&gt; &amp;lt;transition on="submit" to="saveCompany"&amp;gt;&lt;br /&gt;  &amp;lt;action bean="formAction" method="bindAndValidate" /&amp;gt;&lt;br /&gt; &amp;lt;/transition&amp;gt;&lt;br /&gt;&amp;lt;/view-state&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;action-state id="saveCompany"&amp;gt;&lt;br /&gt; &amp;lt;bean-action bean="companyManager" method="save"&amp;gt;&lt;br /&gt;  &amp;lt;method-arguments&amp;gt;&lt;br /&gt;   &amp;lt;argument expression="flowScope.company" /&amp;gt;&lt;br /&gt;  &amp;lt;/method-arguments&amp;gt;&lt;br /&gt; &amp;lt;/bean-action&amp;gt;&lt;br /&gt; &amp;lt;transition on="success" to="finish"&amp;gt;&lt;br /&gt;  &amp;lt;set attribute="message" value="'company.addCompany.success'" /&amp;gt;&lt;br /&gt; &amp;lt;/transition&amp;gt;&lt;br /&gt;&amp;lt;/action-state&amp;gt;&lt;br /&gt; &lt;br /&gt;&amp;lt;end-state id="finish"&amp;gt; &lt;br /&gt; &amp;lt;output-mapper&amp;gt;&lt;br /&gt;  &amp;lt;mapping source="requestScope.message" target="message" /&amp;gt;   &lt;br /&gt; &amp;lt;/output-mapper&amp;gt;&lt;br /&gt;&amp;lt;/end-state&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;When I save a company in the action state "saveCompany", I set an atttibute named "message" with a value of String 'company.addCompany.success' (with a single quotes, otherwise the expression language thinks that is a Java Bean), this value is a key for i18n.&lt;br /&gt;&lt;br /&gt;In the end state "finish", I have to map the attribute message to the output.&lt;br /&gt;&lt;br /&gt;Next, in the root flow, I have to capture the message and put in the flash scope.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;subflow-state id="companyAdd" flow="company-add-flow"&amp;gt; &lt;br /&gt; &amp;lt;attribute-mapper&amp;gt;  &lt;br /&gt; &amp;lt;output-mapper&amp;gt;&lt;br /&gt;  &amp;lt;mapping source="message" target="flashScope.message"/&amp;gt;&lt;br /&gt; &amp;lt;/output-mapper&amp;gt;&lt;br /&gt; &amp;lt;/attribute-mapper&amp;gt;&lt;br /&gt; &amp;lt;transition on="finish" to="companyList" /&amp;gt;&lt;br /&gt;&amp;lt;/subflow-state&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Putting the message in the flash scope, allow to view the message until next event.&lt;br /&gt;&lt;br /&gt;And the last step is show the message in JSP, you have to include this code, in all view states.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;c:if test="${not empty message}"&amp;gt;&lt;br /&gt;  &amp;lt;fmt:message key="${message}"/&amp;gt;&lt;br /&gt;&amp;lt;/c:if&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=seQUKRfF"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=seQUKRfF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=mrDXQhkA"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=mrDXQhkA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/4603524872712604277/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=4603524872712604277" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/4603524872712604277?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/4603524872712604277?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/151232196/tip-output-success-message-in-subflow.html" title="Tip: Output a success message in a subflow in Spring Web Flow" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2007/09/tip-output-success-message-in-subflow.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-5419320903679420213</id><published>2007-08-25T13:42:00.000+02:00</published><updated>2007-08-25T20:19:36.031+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-08-25T20:19:36.031+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="web developer" /><category scheme="http://www.blogger.com/atom/ns#" term="cost" /><category scheme="http://www.blogger.com/atom/ns#" term="maven" /><category scheme="http://www.blogger.com/atom/ns#" term="appfuse" /><title type="text">Appfuse and the cost to start a new project</title><content type="html">Long time ago that I use &lt;a href="http://appfuse.org/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;appfuse&lt;/span&gt;&lt;/a&gt; for my web applications projects, it's fantastic (thanks &lt;a href="http://raibledesigns.com/"&gt;Matt&lt;/a&gt;).&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Appfuse&lt;/span&gt; 2.0 is based in maven, and is one of the best improvements, this change add modularity to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;appfuse&lt;/span&gt;, the code of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;appfuse&lt;/span&gt; is in &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;various&lt;/span&gt; modules (jars and wars). With this changes it loose some scope about what &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;appfuse&lt;/span&gt; does and I have to run "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;mvn&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;appfuse&lt;/span&gt;:&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;fullsource&lt;/span&gt;" to view all source, and customize some classes.&lt;br /&gt;&lt;br /&gt;Although &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;appfuse&lt;/span&gt; do hard work to start, always is unavoidable make some changes to start, for example in last project I have to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Update Jetty maven &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;plugin&lt;/span&gt; for scan patterns.&lt;/li&gt;&lt;li&gt;Customize some &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Appfuse&lt;/span&gt; classes.&lt;/li&gt;&lt;li&gt;Customize some i18n features.&lt;/li&gt;&lt;li&gt;Add Spring Web Flow.&lt;/li&gt;&lt;li&gt;Customize &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;CSS&lt;/span&gt; and Layout.&lt;/li&gt;&lt;li&gt;Delete struts-menu (with a simple menu.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;jsp&lt;/span&gt; it's enough for me).&lt;/li&gt;&lt;li&gt;Update some dependencies and resources.&lt;/li&gt;&lt;li&gt;Add some maven &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;plugins&lt;/span&gt; like compress javascript and export database.&lt;/li&gt;&lt;/ul&gt;Some tasks are due to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;appfuse&lt;/span&gt; doesn't support a feature yet, and some are due to my personal requirements but the cost to start a new project it's too high yet.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=OCdN7DTl"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=OCdN7DTl" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=vtO2yls7"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=vtO2yls7" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/5419320903679420213/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=5419320903679420213" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5419320903679420213?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5419320903679420213?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/148076425/appfuse-and-cost-to-start-new-project.html" title="Appfuse and the cost to start a new project" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2007/08/appfuse-and-cost-to-start-new-project.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-59507592006580923</id><published>2007-08-15T15:45:00.001+02:00</published><updated>2007-08-15T16:10:10.201+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-08-15T16:10:10.201+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="web design" /><category scheme="http://www.blogger.com/atom/ns#" term="icons" /><category scheme="http://www.blogger.com/atom/ns#" term="inkscape" /><title type="text">Playing with Inkscape</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_y3qxkKvzxS4/RsMGCybpGzI/AAAAAAAAAAM/DHGoaZL0Nt0/s1600-h/ok.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp1.blogger.com/_y3qxkKvzxS4/RsMGCybpGzI/AAAAAAAAAAM/DHGoaZL0Nt0/s320/ok.png" alt="" id="BLOGGER_PHOTO_ID_5098925848080751410" border="0" /&gt;&lt;/a&gt;This is two samples that I have created with excelent ilustration software Inkscape.&lt;br /&gt;&lt;br /&gt;I have followed some tutorials from &lt;a href="http://inkscapetutorials.wordpress.com/"&gt;Inkscape Tutorials&lt;/a&gt; and some &lt;a href="http://screencasters.heathenx.org/"&gt;screencast&lt;/a&gt;. It's really easy create simple and elegant icons.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_y3qxkKvzxS4/RsMGCybpG0I/AAAAAAAAAAU/4eD7C24Ohxo/s1600-h/rss.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp1.blogger.com/_y3qxkKvzxS4/RsMGCybpG0I/AAAAAAAAAAU/4eD7C24Ohxo/s320/rss.png" alt="" id="BLOGGER_PHOTO_ID_5098925848080751426" border="0" /&gt;&lt;/a&gt; The design isn't incompatible with backend development&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=rZk0BoWm"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=rZk0BoWm" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=W7MD4IMQ"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=W7MD4IMQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/59507592006580923/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=59507592006580923" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/59507592006580923?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/59507592006580923?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/144408430/playing-with-inkscape.html" title="Playing with Inkscape" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp1.blogger.com/_y3qxkKvzxS4/RsMGCybpGzI/AAAAAAAAAAM/DHGoaZL0Nt0/s72-c/ok.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://dahernan.net/2007/08/playing-with-inkscape.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-2668195692412460298</id><published>2007-08-04T13:27:00.000+02:00</published><updated>2007-08-04T22:43:21.381+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-08-04T22:43:21.381+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="web 2.0" /><category scheme="http://www.blogger.com/atom/ns#" term="linkedin" /><category scheme="http://www.blogger.com/atom/ns#" term="facebook" /><category scheme="http://www.blogger.com/atom/ns#" term="social networks" /><title type="text">Are social networks useful?</title><content type="html">In other post I said that networks like &lt;a href="http://del.icio.us/"&gt;delicious&lt;/a&gt;, had changed my habits in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;internet&lt;/span&gt;. I have read some entries about the wonderful &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Linkedin&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Facebook&lt;/span&gt;, and  I have decided to test them.&lt;br /&gt;&lt;br /&gt;First, I have tested &lt;a href="http://facebook.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Facebook&lt;/span&gt;&lt;/a&gt; and tried to do contacts. I don't trust to give my email password, and I searched contacts manually but I don't felt lucky, not found any friend.&lt;br /&gt;&lt;br /&gt;Next, &lt;a href="http://linkedin.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Linkedin&lt;/span&gt;&lt;/a&gt;. I searched contacts who had worked with me and I found four contacts, but today no one has added me to his network, I don't believe that they really use &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Linkedin&lt;/span&gt;. If somebody wants to add me to his network this is &lt;a href="http://www.linkedin.com/in/dahernan"&gt;my profile in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Linkedin&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In general, the I don't have good impressions about this networks. The interface of this sites it's too complicated, there are too many options. I prefer the minimalist of delicious, maybe when I have more contacts, it could be useful, but nowadays the best network is &lt;a href="http://del.icio.us/network/dahernan"&gt;my delicious network&lt;/a&gt;.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=vNd20XPx"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=vNd20XPx" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=6XsB89Qe"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=6XsB89Qe" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/2668195692412460298/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=2668195692412460298" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/2668195692412460298?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/2668195692412460298?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/140633772/are-socials-networks-useful.html" title="Are social networks useful?" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://dahernan.net/2007/08/are-socials-networks-useful.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-5157938454297463394</id><published>2007-06-23T13:58:00.000+02:00</published><updated>2007-06-23T14:16:00.546+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-06-23T14:16:00.546+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="holidays" /><title type="text">Holidays</title><content type="html">I have three weeks!!!. One week to travel, and two weeks to be with my friends, go to the beach and whatever I want.&lt;br /&gt;Goodbye work!!!&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=62FFBNub"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=62FFBNub" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=awX1r2P5"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=awX1r2P5" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/5157938454297463394/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=5157938454297463394" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5157938454297463394?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/5157938454297463394?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/127275292/holidays.html" title="Holidays" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://dahernan.net/2007/06/holidays.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6377108869773463365.post-8418710024888296264</id><published>2007-06-10T13:56:00.000+02:00</published><updated>2007-06-10T14:43:54.347+02:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-06-10T14:43:54.347+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="web 2.0" /><category scheme="http://www.blogger.com/atom/ns#" term="delicious" /><category scheme="http://www.blogger.com/atom/ns#" term="me" /><category scheme="http://www.blogger.com/atom/ns#" term="lastfm" /><category scheme="http://www.blogger.com/atom/ns#" term="habits" /><category scheme="http://www.blogger.com/atom/ns#" term="apps" /><title type="text">My Web 2.0 favorite apps</title><content type="html">One thing I like to do is test Web 2.0 applications. &lt;a href="http://ajaxian.com/"&gt;Ajaxian&lt;/a&gt; is in my favorite feeds. But there are three applications that change my habits in the Web.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://del.icio.us/dahernan"&gt;Delicious&lt;/a&gt;. All that things that could be interesting I save in delicious. And my network is one of best source of really interesting things.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.google.com/reader/shared/user/04775928392221480832/state/com.google/starred"&gt;Google Reader&lt;/a&gt;. Previously I used to read my feeds in Thunderbird at home and work, and I had to mark as a read many many feeds in both sites. Google Reader it's very useful with two clicks on firefox I have a new feed, and I share my starred items.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.last.fm/user/dahernan"&gt;Last.fm&lt;/a&gt;. Usually, I listen many music at work, and last.fm help me to find new groups, and share with my friends. My profile tells me who are my favorite groups now. The Killers and Coldplay, are winning.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=PPwbgINV"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=PPwbgINV" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Dahernan?a=Z3nOa6xp"&gt;&lt;img src="http://feeds.feedburner.com/~f/Dahernan?i=Z3nOa6xp" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dahernan.net/feeds/8418710024888296264/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=6377108869773463365&amp;postID=8418710024888296264" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8418710024888296264?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6377108869773463365/posts/default/8418710024888296264?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/Dahernan/~3/123676355/my-web-20-favorite-apps.html" title="My Web 2.0 favorite apps" /><author><name>dahernan</name><uri>http://www.blogger.com/profile/12584392512581405386</uri><email>dahernan@gmail.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://dahernan.net/2007/06/my-web-20-favorite-apps.html</feedburner:origLink></entry></feed>
