tag:blogger.com,1999:blog-178608412024-03-07T22:22:49.810-05:00Bumping my Head on the WallFrancisco Assis Rosa on software development tips and tricks, processes, languages and life in generalFrancisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.comBlogger46125tag:blogger.com,1999:blog-17860841.post-11388008926563292982009-01-20T10:52:00.006-05:002009-01-21T09:56:51.836-05:00Tizra Publisher DemoThis is why I have been so quiet...the Tizra Publisher platform has evolved immensely during the last couple of months...which of course means a pretty busy time...and fun for that matter...And we are now posting a video tour of Tizra Publisher...<br /><br /><object height="250" width="408"><param name="movie" value="http://www.youtube.com/v/MkVdGQAqHR8&hl=en&fs=1"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/MkVdGQAqHR8&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="250" width="408"></embed></object><br /><br />For a higher resolution demo tour, try <a href="http://www.tizra.com/tour">this</a>.<br /><br />Oh...and since we went self-service, you can try a free plan for Tizra Publisher by subscribing for your free site <a href="https://secure.agilepdf.com/">here</a>.Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-49528037628808111912008-07-21T22:10:00.001-04:002008-07-25T13:06:49.754-04:00My Essential Firefox Add-ons<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFJu55MBRrXGIWthRruAuqP1gXY49tN-QtjZEI0HdDuIrOdLAey1uAqEyCsFvC4Ipi5fXo7gESD5wkLRq4aB9LmU0fYu_X8iqtoZTkDaa6L7ksoJTH6z0Xl5Yy4YHvfnMiWuphcQ/s1600-h/firefox.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFJu55MBRrXGIWthRruAuqP1gXY49tN-QtjZEI0HdDuIrOdLAey1uAqEyCsFvC4Ipi5fXo7gESD5wkLRq4aB9LmU0fYu_X8iqtoZTkDaa6L7ksoJTH6z0Xl5Yy4YHvfnMiWuphcQ/s400/firefox.png" alt="" id="BLOGGER_PHOTO_ID_5225547873142091522" border="0" /></a>Been too long since I last wrote here. Tizra has been pretty busy picking up a ton of enthusiasm from customers and prospects (see <a href="http://tizra.blogspot.com/">Tizra Blog</a>). That means, of course, a pretty busy time... :-)<br /><br />I recently had to do a complete reinstall of my development environment. My laptop went dead and I had to get a new one...so that leads to the typical "absolutely essential" lists...today I reinstalled all my Firefox Add-ons. The good thing about reinstalls is that you cut the fat accumulated throughout the years and the absolute musts get installed first. Here is my list of absolute musts (in no particular order):<br /><br /><ul><li><a href="http://selenium-ide.openqa.org/">Selenium IDE</a>: if you're doing any kind of serious development, you want to have a good test coverage. Selenium is a really cool tool to allow you to build automated UI and system integration testing. Selenium IDE makes your life *a whole lot easier* (although not dead-simple). You still have to tweak a lot of the generated code but hey, it's a really great start. And if you have not seen Selenium yet, you have to go <a href="http://selenium.openqa.org/">take a look</a>. It is not necessarily simple to get into but well worth it!<br /></li><li><a href="https://addons.mozilla.org/en-US/firefox/addon/59">User Agent Switcher</a>: really nice for that kind of testing that involves user agent detection...you can even "roll your own" agent identification for test purposes.<br /></li><li><a href="https://addons.mozilla.org/en-US/firefox/addon/60">Web Developer</a>: a really essential set of tools for web development. CSS inspection, changing, DOM information, source viewing, browser resizing, you name it, it's probably here.<br /></li><li><a href="http://livehttpheaders.mozdev.org/">Live HTTP Headers</a>: a nice tool to let you see the header flow from and into your browser. Sometimes essential for analysis of behavior.<br /></li><li><a href="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug</a>: you can't say you do web development and not know about Firebug. Simply brilliant. If you have not seen it yet, tell no one about that and <a href="http://getfirebug.com/">go check it out for yourself</a>.<br /></li><li><a href="https://addons.mozilla.org/en-US/firefox/addon/3615">Delicious Bookmarks</a>: currently addicted to <a href="http://del.icio.us/">del.icio.us</a>. You can see my bookmarks <a href="http://del.icio.us/fassisrosa">here</a>.</li></ul>I'm always open to suggestions on new add-ons...Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com1tag:blogger.com,1999:blog-17860841.post-55981666155997955272008-03-18T09:36:00.006-04:002008-03-18T12:15:53.970-04:00Google APIs, XML, Ajax and some pretty cool pictures!<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU8soUnkRV1h5V4u5UoizToBgzOHWQQ0Sp719t4PQ6oNp354lxV1TUS3XmDdLC58yuVht2jECvxRMZr312PFOKTwhvF9S0ogsiJfu8Xs-7wXPl6n-74Rngy7WPHnZSQgl59sS16w/s1600-h/brazilpics.gif"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU8soUnkRV1h5V4u5UoizToBgzOHWQQ0Sp719t4PQ6oNp354lxV1TUS3XmDdLC58yuVht2jECvxRMZr312PFOKTwhvF9S0ogsiJfu8Xs-7wXPl6n-74Rngy7WPHnZSQgl59sS16w/s320/brazilpics.gif" alt="" id="BLOGGER_PHOTO_ID_5179075796922157346" border="0" /></a>This is what happens when you join in a single "package" an artist and a techie...Marcelino Martins had already assembled a pretty cool site filled with really impressive pictures (see <a href="http://mmartins.com/">here)</a>. With <a href="http://brazilpictures.net/">Brazil Pictures</a>, Marcelino joins his photographic artistic talent to his techie talent...he has already developed some pretty cool packages like <a href="http://www.treemenu.net/">Treeview</a>...Now he's been playing the Google APIs, XML, Ajax...the result is the really interesting <a href="http://brazilpictures.net/">Brazil Pictures</a>. And take a look at his <a href="http://brazilpictures.net/brazilpictures/about.asp">implementation notes</a> for a very interesting read.<br /><br />Very nice....Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-45137113959887251162008-01-22T14:11:00.000-05:002008-01-23T09:46:56.408-05:00AgilePDF is live!I am pretty excited to see the first set of AgilePDF sites go live...we (<a href="http://www.tizra.com/">Tizra</a>) are indeed live at this point. You can now see the results of this effort at the following sites.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Sg0ue4cWDdENjzK8dcX-JqOYrwD6tNjFDCrnRNacEhp39gdoKPJkCqXRemkhXG21p4zKl9xZ11Vh060vVlV8vICAo6nO9wJTvZklFgU4v1hXm-i28Udnz9XUUIWmNDyPwOFM0Q/s1600-h/fp.gif"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Sg0ue4cWDdENjzK8dcX-JqOYrwD6tNjFDCrnRNacEhp39gdoKPJkCqXRemkhXG21p4zKl9xZ11Vh060vVlV8vICAo6nO9wJTvZklFgU4v1hXm-i28Udnz9XUUIWmNDyPwOFM0Q/s200/fp.gif" alt="" id="BLOGGER_PHOTO_ID_5158404962450665186" border="0" title="Click for full screen"/></a><a href="http://francisco-pubs.assisrosa.com/">Francisco Assis Rosa's Publications</a>. Now, would I not be eating my own dog food ? I honestly find the system pretty cool and am publicly using it to store and offer my publications online. Privately I keep a copy of the system on an internal network where I keep all my favorite tech reading. It is really handy to be able to search through the full collection of my favorite texts and get relevant results *to the page*....nice.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeJQNXGmqMiJa3DI8RyZckIAA0dBP-5v5e6RTZhiJL2XtvIAsKZC_IDOLhhkCmauRnjdj0U8l-deijGWO-3CRgvyZK7hUTJ2aG4JS7_wSKTa0PYAsE7CLadX6Iob7ZRPB5vFH9SQ/s1600-h/es.gif"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeJQNXGmqMiJa3DI8RyZckIAA0dBP-5v5e6RTZhiJL2XtvIAsKZC_IDOLhhkCmauRnjdj0U8l-deijGWO-3CRgvyZK7hUTJ2aG4JS7_wSKTa0PYAsE7CLadX6Iob7ZRPB5vFH9SQ/s200/es.gif" alt="" id="BLOGGER_PHOTO_ID_5158405181493997298" border="0" title="Click for full screen"/></a><a href="http://eatshop.site.agilepublisher.com/">eat.shop guides</a>. Some pretty cool eating and shopping guides...smartly written, gorgeously presented.<br /><br /><p><br /></p><p><br /></p><p><br /></p><p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6hI0icwg2yjxlyW8K7XtvQJfACiF5b-lHXbeeE5klYzg3lIh3gejb9GsfySTUUQjeF6EA83oweZ4WXZOJGsZfN-mGgNVSPcG-mU2IJLDHi3mTjgcwNSV96k4zUEd2VdNqyeyEaQ/s1600-h/rig.gif"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6hI0icwg2yjxlyW8K7XtvQJfACiF5b-lHXbeeE5klYzg3lIh3gejb9GsfySTUUQjeF6EA83oweZ4WXZOJGsZfN-mGgNVSPcG-mU2IJLDHi3mTjgcwNSV96k4zUEd2VdNqyeyEaQ/s200/rig.gif" alt="" id="BLOGGER_PHOTO_ID_5158405331817852674" border="0" title="Click for full screen" /></a><a href="http://liveaccess.rateitgreen.com/">Rate It Green</a>. Live access digital edition to "Green Building 101".<br /></p><br /><br /><br /><br /><p><br /></p><p><br /></p><p>Why do I feel so excited about this ?<br /></p><ul><li>These customers were able to hop on online without any significant investment. We are talking days instead of months between agreement and go live (and that with full design customization!), we're talking about revenue from online selling in the first couple of days. Yup, they did not have to wait six months to see a dollar, or even more to get their money back from the site building investment.<br /></li><li>The technology set used in this system is a pretty exciting technology allowing us to take advantage of a lot that's good out there...</li><li>I could see a nice use for personal users like me that have some content that want to distribute online. Either free or for sale...you name it.<br /></li></ul>As far as system features go, these are some of the items that make me believe AgilePDF is cool:<br /><ul><li>End-user page-at-time PDF rendering, allowing for getting back web usability that was taken back by the placement of unwieldy PDFs online (50Mb PDF downloads to read *one* page anyone? Make that over slow connections ?).</li><li>Full text search over the content of the site/sub-site/single document with results returned at the page level (again, instead of result pointing at full PDF).</li><li>Full fledged configurable access control over your content.<br /></li><li>Full ecommerce configurability. Whoever owns the site can create their own products (including products resulting from combinations of pages from different documents in the site), create their own selling offers and just put it out for the test. We allow hooking up to <a href="https://www.paypal.com/">PayPal</a> and <a href="http://www.authorize.net/">Authorize.Net</a> right now but as requests come in we will be expanding the list of payment fulfillers.</li><li>Full site design configurability. We offer some out-of-the-box designs you can use but you can change all the look of your site by dragging and dropping site blocks around your pages...and if you really want to go crazy on your design, just upload your CSS and you can do what you want (just compare <a href="http://francisco-pubs.assisrosa.com/">Francisco Assis Rosa's Publications</a> to <a href="http://liveaccess.rateitgreen.com/">Rate It Green</a> to <a href="http://eatshop.site.agilepublisher.com/">eat.shop guides</a>!).</li><li>Full site structure configurability. Via the administration web interface you can create sub-sites based on filtering of meta data in your documents. When I said "full site design configurability" in the previous item I really meant it, you can even have these sub-sites look completely different from the main site and/or other sub-sites.<br /></li><li>Google crawling, analytics and adsense integration...speaks for itself! ;-)<br /></li></ul>And...you can always <a href="mailto:frosa@tizra.com?subject=I%20Want%20to%20use%20AgilePDF">drop me a line</a> if you wish to use something like this...<br /><br />This is just our first release...we are and will continue to work on this...<br /><br />We are live! :-)<br /><br />I'm still alive! ;-) ;-) ;-)<br /><p></p>Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com1tag:blogger.com,1999:blog-17860841.post-33609179969373451202007-09-11T08:58:00.001-04:002008-06-26T12:31:42.402-04:00Unit Testing Struts 2.0 (Part 3)Like <span style="font-style: italic;">Dan</span> commented on the <a href="http://fassisrosa.blogspot.com/2007/03/unit-testing-struts-20-part-2.html">Unit Testing Struts 2.0 (Part 2)</a> post, Struts 2.0 has changed it's API enough to make my previous code not work on latest version. So, in response to his comment, here is what I am using right now. Credit where it's due, the setup code is the one that <a href="http://arsenalist.com/">The Arsenalist</a> pointed out on his blog post <a href="http://arsenalist.com/2007/06/18/unit-testing-struts-2-actions-spring-junit/">Unit Testing Struts 2 Actions wired with Spring using JUnit</a>. Again, credit where it's due...my thanks go to "The Arsenalist" for posting his solution.<br /><pre><br />/**<br />* Class for easier support of Struts related<br />* testing. Takes care of all the configuration details<br />* that allow test classes to create beans (Spring),<br />* actions (Struts), intercepted actions (Struts).<br />* Class is singleton to minimize hit of initializing<br />* Struts and related infrastructure (e.g. Hibernate).<br />*<br />* Adapted from code from "The Arsenalist" (http://arsenalist.com/),<br />* see http://arsenalist.com/2007/06/18/unit-testing-struts-2-actions-spring-junit/<br />*/<br />public class StrutsTestCaseSupport {<br /><br /> /**<br /> * Singleton variable<br /> */<br /> public static StrutsTestCaseSupport _theInstance = null;<br /><br /> /**<br /> * Servlet context<br /> */<br /> private ServletContext servletContext = null;<br /><br /> /**<br /> * Request dispatcher<br /> */<br /> private Dispatcher dispatcher = null;<br /><br /> /**<br /> * Singleton access<br /> */<br /> public static synchronized StrutsTestCaseSupport getInstance()<br /> throws Exception {<br /> if ( _theInstance == null ) {<br /> _theInstance = new StrutsTestCaseSupport();<br /> }<br /> return _theInstance;<br /> }<br /><br /> /**<br /> * Class constructor, take care of Struts initializations<br /> */<br /> private StrutsTestCaseSupport ()<br /> throws Exception {<br /> String[] config = new String[] { "/WEB-INF/applicationContext.xml" };<br /><br /> // Link the servlet context and the Spring context<br /> servletContext = new MockServletContext(new FileSystemResourceLoader());<br /> XmlWebApplicationContext appContext = new XmlWebApplicationContext();<br /> appContext.setServletContext(servletContext);<br /> appContext.setConfigLocations(config);<br /> appContext.refresh();<br /> servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, appContext);<br /><br /> // Use spring as the object factory for Struts<br /> StrutsSpringObjectFactory ssf = new StrutsSpringObjectFactory(null, null, servletContext);<br /> ssf.setApplicationContext(appContext);<br /> StrutsSpringObjectFactory.setObjectFactory(ssf);<br /><br /> // Dispatcher is the guy that actually handles all requests. Pass in<br /> // an empty Map as the parameters but if you want to change stuff like<br /> // what config files to read, you need to specify them here<br /> // (see Dispatcher's source code)<br /> dispatcher = new Dispatcher(servletContext, new HashMap());<br /> dispatcher.init();<br /> Dispatcher.setInstance(dispatcher);<br /> }<br /><br /> /**<br /> * create a bean from the object factory (all wired up from Spring)<br /> *<br /> * @param beanName the name of the bean to get from the object factory<br /> * @param extraContent any extra content information to pass along to the bean building<br /> * process<br /> * @return the object factory created bean<br /> * @throws Exception on processing, configuration errors, test failure<br /> */<br /> public Object createBean ( String beanName, Map<object,object> extraContext )<br /> throws Exception {<br /> ObjectFactory objectFactory = dispatcher.getContainer().getInstance(ObjectFactory.class);<br /> return objectFactory.buildBean(beanName,extraContext);<br /> }<br /><br /> /**<br /> * create an action proxied by it's interceptor stack<br /> *<br /> * @param actionName the name/id for the action<br /> * @param actionNameSpace the namespace for the action<br /> * @return the proxyed action<br /> * @throws Exception on processing, configuration errors, test failure<br /> */<br /> public ActionProxy createActionProxy ( String actionName, String actionNamespace )<br /> throws Exception {<br /> // create a proxy class which is just a wrapper around the action call.<br /> // The proxy is created by checking the namespace and name against the<br /> // struts.xml configuration<br /> ActionProxy proxy = dispatcher.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(actionNamespace, actionName, null, true, false);<br /><br /> // by default, don't pass in any request parameters<br /> proxy.getInvocation().getInvocationContext().setParameters(new HashMap());<br /><br /> // by default, pass along an empty session map<br /> proxy.getInvocation().getInvocationContext().setSession(new HashMap<object,object>());<br /><br /> // set the actions context to the one which the proxy is using<br /> ServletActionContext.setContext(proxy.getInvocation().getInvocationContext());<br /> MockHttpServletRequest request = new MockHttpServletRequest();<br /> MockHttpServletResponse response = new MockHttpServletResponse();<br /> ServletActionContext.setRequest(request);<br /> ServletActionContext.setResponse(response);<br /> ServletActionContext.setServletContext(servletContext);<br /><br /> // set proper URI<br /> request.setRequestURI(actionNamespace + "/" + actionName);<br /><br /> return proxy;<br /> }<br /><br /> /**<br /> * create an action proxied by it's interceptor stack<br /> *<br /> * @param actionName the name/id for the action<br /> * @param actionNameSpace the namespace for the action<br /> * @param sessionMap the request/invocation session map (for http session map mocking)<br /> * @return the proxyed action<br /> * @throws Exception on processing, configuration errors, test failure<br /> */<br /> public ActionProxy createActionProxy ( String actionName, String actionNamespace, Map<object,object> sessionMap )<br /> throws Exception {<br /><br /> // create an action proxy as usual<br /> ActionProxy actionProxy = createActionProxy(actionName,actionNamespace);<br /><br /> // set the session map in the action proxy's invocation<br /> actionProxy.getInvocation().getInvocationContext().setSession(sessionMap);<br /><br /> return actionProxy;<br /> }<br /><br /> /**<br /> * create an action object, bypass all it's stacks. Have it properly injected<br /> * according to configurations.<br /> *<br /> * @param actionName the name/id for the action<br /> * @param actionNameSpace the namespace for the action<br /> * @return the properly injected action<br /> * @throws Exception on processing, configuration errors, test failure<br /> */<br /> public Object createAction ( String actionName, String actionNamespace )<br /> throws Exception {<br /> ActionProxy actionProxy = createActionProxy(actionName,actionNamespace);<br /> return actionProxy.getAction();<br /> }<br /><br /> /**<br /> * Access to the proxy's response content as a string<br /> * @param proxy the proxy to get the string response for<br /> * @return the proxy's response content as a string<br /> */<br /> public static String getResponseContentAsString ( ActionProxy proxy )<br /> throws java.io.UnsupportedEncodingException {<br /> return ((MockHttpServletResponse)ServletActionContext.getResponse()).getContentAsString();<br /> }<br /><br /> /**<br /> * Set a hostname in proxy request<br /> * @param proxy the proxy to set hostname to<br /> * @param serverName the server name to set for this proxy's call<br /> */<br /> public static void setRequestServerName ( ActionProxy proxy, String serverName ) {<br /> ((MockHttpServletRequest)ServletActionContext.getRequest()).setServerName(serverName);<br /> }<br />}<br /></object,object></object,object></object,object></pre><br /><br />Like mentioned in previous postings, using this class is pretty straightforward, within your test you just do for beans:<br /><br /><pre><br /> YourClass yourInstance = (YourClass)StrutsTestCaseSupport.getInstance().createBean("yourBeanId",new HashMap());<br /></pre><br /><br />For Actions:<br /><pre><br /> ActionProxy proxy = StrutsTestCaseSupport.getInstance().createActionProxy(yourActionId,yourContextPath);<br /> MyActionClass myActionInstance = (MyActionClass)StrutsTestCaseSupport.getInstance().createAction(yourActionId,yourContextPath);<br /></pre><br /><br />This code is currently being used with Struts 2.0.8.Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com19tag:blogger.com,1999:blog-17860841.post-68041404893529713452007-08-29T18:49:00.000-04:002007-08-29T18:55:34.748-04:00Return of the Stuff!<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5970/1732/1600/nfjs_logo200.gif"><img style="FLOAT: left; MARGIN: 0pt 10px 10px 0pt; CURSOR: pointer" alt="" src="http://photos1.blogger.com/blogger/5970/1732/200/nfjs_logo200.gif" border="0" /></a>Here we go again, it's that time of the year where good things are about to happen. September is marked by two major events: the <a href="http://www.halo3.com/">release of Halo 3</a> ;-) and the return of the <a href="http://www.nofluffjuststuff.com/">No Fluff Just Stuff conference</a> (now called the New England Software Symposium). I have written about this even before but it does not hurt to repeat it...this is a really impressive conference and a must if you live around the Boston area. It takes place during a Friday afternoon and over the weekend. This is actually a great decision since it simplifies a lot the "need to be out of work" argument with your bosses. Sure it takes over your weekend but, if you're in this business you are most probably hooked enough to this stuff for this not to be a problem. The attendance to this event is capped at around 250 which is another great feature since it does allow you to be in those rooms listening to the presentations in a much close environment. You get to interact with the presenters both during the talks and during the breaks by mingling in lunch tables or just approaching them directly. The topics are amazing and, like I mentioned before (see <a href="http://fassisrosa.blogspot.com/2006/10/no-fluff-just-stuff-impressions.html">here</a>), the really annoying part of the even is choosing which sessions to go to. The price for the event is really a find...pretty affordable even if, like me, you do not get your company to sponsor you<br />and pay out of your own pocket.</p><p><br />This fall, the Boston even takes place on the 14th (PM), 15th and 16th of September in Framingham, Massachusetts. For all the details, check out the <a href="http://www.nofluffjuststuff.com/conference/boston/2007/09/index.html">event site</a>.</p><p><br />I got my place already booked, what are you waiting for ?<br /></p>Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-6559574744397151662007-07-06T09:57:00.000-04:002007-07-06T10:09:27.201-04:00Problems with Keyboard Mapping when Running vncviewer on UbuntuIn the hope that this adds to the list of solutions out there that can actually help people...<br />If you are having keyboard mapping issues when trying to connect via vncviewer to a machine running vncserver on Ubuntu Feisty (7.04) with gnome, try this:<br /><br />Create a ~/.vncrc file and add to it:<br /><pre> $vncStartup = "<your_home_dir_here>/.vnc/xstartup"; </pre><br />Create a ~/.vnc/xstartup file (or edit) and make sure it contains:<br /><pre> xrdb $HOME/.Xresources<br /> gnome-wm &<br /> gnome-panel &<br /> nautilus --no-default-window &<br /> gnome-cups-icon &amp;<br /> gnome-volume-manager &<br /> cd ~<br /> xterm &</pre><br /><br />Solved the problem for me. Credit where it belongs, found the solution here: <a href="http://ubuntuforums.org/showthread.php?t=382441">http://ubuntuforums.org/showthread.php?t=382441</a><br /><br />My take on it, posts do help find solutions, here is my contribution to try helping others find a solution quicker.Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com9tag:blogger.com,1999:blog-17860841.post-76423403397389786772007-05-05T08:27:00.000-04:002007-05-05T12:52:56.562-04:00Pity the User<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpIrT-hYA4IT9ECfAQPl5ihyphenhyphenexBnwaKLc75YReqiJKTp24zrGgO_XW8NohQDCDKgvUzRLwr-jzAo_KHn1-VGk7pN1cumV75B9bZ1cc_CuYtUBGSlivtjoQo0qH1KQv6XfRM3kL5Q/s1600-h/ubuntu-vs-vista.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpIrT-hYA4IT9ECfAQPl5ihyphenhyphenexBnwaKLc75YReqiJKTp24zrGgO_XW8NohQDCDKgvUzRLwr-jzAo_KHn1-VGk7pN1cumV75B9bZ1cc_CuYtUBGSlivtjoQo0qH1KQv6XfRM3kL5Q/s320/ubuntu-vs-vista.png" alt="" id="BLOGGER_PHOTO_ID_5061060533461691826" border="0" /></a>I have recently got the opportunity to get my hands on a copy of <a href="http://www.microsoft.com/windows/products/windowsvista/editions/ultimate/default.mspx">Vista Ultimate</a> at MS employee prices. I jumped at the opportunity and, as soon as I ensured all my crucial apps actually ran on Vista (<a href="http://www.vmware.com/products/ws/">VMWare Workstation</a> in particular), proceeded to install it on my laptop. I spend my working hours (and others for that matter) using this laptop so, although I surely did not get to explore all the niceties of Vista, I got the daily use experience of running it. The first impression was the "Wow" that MS advertises so much. It is indeed an eye-candy-filled OS. It looks awesome and all the UI interactions have been tuned to please the eye, Windows Aero is indeed really enticing. But...the niceties of a new UI only last so much...My daily work is spent mostly on another OS environment. All my work is done on Linux and I had been used to depend on VMWare Workstation to be able to get the best of both worlds and jump around as needed. My experience with XP and VMWare Workstation had been impeccable and I could not recommend it more...Then came Vista...oh well...Suddenly my Pentium 4 3.4Ghz with Hyperthreading, 2Gb RAM started grinding to a halt. Although a year old now, this is not (I believe) a run-of-the-mill laptop...A laptop with these specs should be able to handle this OS plus the apps that I needed to run on top of it! My frustration grew when looking at memory usage on Vista...Just starting up brought me to 600Mb usage, with VMWare I was up to 1.6Gb...this on a 2Gb RAM machine...And I started looking through the nice UI and thinking seriously that I could not work daily with this...The initial "Wow" turned into "Wow, this is unbearable!". So, after some serious consideration I decided it was time to byte the bullet and wipe out my system and replace it by something more snappy that actually made good use of my hardware...<a href="http://www.ubuntu.com/">Ubuntu 7.04</a> to the rescue! Ok, I am not religious about the OS war and am one of the people who tries to take advantage of whatever each has to offer so, being the gamer that I am, I left Vista on a dual boot setup alongside Ubuntu (I still have hopes of playing Halo 2 on Vista someday to <a href="http://gamerconnect.blogspot.com/2007/04/be-achiever.html">get my achievements</a>! ). Now I am running Linux as a first OS...my life became a lot less stressing...and I can still run Windows XP or Win 2K on a VMWare Workstation virtual host for all the testing I need to do...The best of both worlds I would say...<br /><br />With this Windows Vista we are bound to see a new need to get new hardware where once what you had was just fine...and, to be honest, without any real *day to day* real important enhancements that I can see (again, I stress the *day to day*... you might do cool and important things on Vista but I'm betting these are completely irrelevant for the common user).<br /><br />But I believe Ubuntu 7.04 (and Linux in general) is still not there as well...I had to jump through some serious loops to get my Wireless card and my sound card to work on my laptop...It has evolved immensely no doubts. I still remember the old Linux installations of the early nineties where you really had to be courageous and curious to even try it. But good as it is this is hardly mass user ready...<br /><br />Pity the user indeed!Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com1tag:blogger.com,1999:blog-17860841.post-12037576977906358382007-03-29T20:46:00.000-04:002007-09-18T11:54:40.255-04:00Unit Testing Struts 2.0 (Part 2)<span style="font-weight:bold;"><span style="font-style:italic;">Edit: for latest on this see <a href="http://fassisrosa.blogspot.com/2007/09/unit-testing-struts-20-part-3.html">recent post</a>.<br /></span></span><br /><br />In response to a comment made to <a href="http://fassisrosa.blogspot.com/2006/11/unit-testing-struts-20.html">Unit Testing Struts 2.0</a>, here is the updated, complete code for Struts 2.0 testing. Hope this is useful. Have questions ? Want to discuss any of this ? Just drop me a line...Read on, includes support class code, small snippets for creation of Spring beans, Struts 2.0 actions, Struts 2.0 action proxies.<br /><br /><pre><br />import com.opensymphony.xwork2.ActionContext;<br />import com.opensymphony.xwork2.ActionProxy;<br />import com.opensymphony.xwork2.ActionProxyFactory;<br />import com.opensymphony.xwork2.ObjectFactory;<br />import com.opensymphony.xwork2.config.ConfigurationManager;<br />import com.opensymphony.xwork2.config.entities.ActionConfig;<br /><br />import org.apache.struts2.StrutsConstants;<br />import org.apache.struts2.StrutsStatics;<br />import org.apache.struts2.config.Settings;<br />import org.apache.struts2.config.StrutsXmlConfigurationProvider;<br />import org.apache.struts2.dispatcher.Dispatcher;<br />import org.apache.struts2.impl.StrutsActionProxyFactory;<br />import org.apache.struts2.spring.StrutsSpringObjectFactory;<br />import org.apache.struts2.views.freemarker.FreemarkerManager;<br /><br />import org.springframework.core.io.FileSystemResourceLoader;<br />import org.springframework.mock.web.MockServletContext;<br />import org.springframework.mock.web.MockHttpServletRequest;<br />import org.springframework.mock.web.MockHttpServletResponse;<br />import org.springframework.web.context.ConfigurableWebApplicationContext;<br />import org.springframework.web.context.WebApplicationContext;<br />import org.springframework.web.context.support.XmlWebApplicationContext;<br /><br />import java.lang.reflect.Method;<br /><br />import java.net.URLEncoder;<br /><br />import java.util.HashMap;<br />import java.util.Map;<br /><br />import javax.servlet.ServletContext;<br /><br /><br />/**<br /> * Class for easier support of Struts related<br /> * testing. Takes care of all the configuration details<br /> * that allow test classes to create beans (Spring),<br /> * actions (Struts), intercepted actions (Struts).<br /> * Class is singleton to minimize hit of initializing<br /> * Struts and related infrastructure (e.g. Hibernate).<br /> *<br /> * @author Francisco Assis Rosa<br /> */<br />public class StrutsTestCaseSupport {<br /><br /> /**<br /> * Singleton variable<br /> */<br /> public static StrutsTestCaseSupport _theInstance;<br /><br /> /**<br /> * Singleton access<br /> */<br /> public static synchronized StrutsTestCaseSupport getInstance() {<br /> if ( _theInstance == null ) {<br /> _theInstance = new StrutsTestCaseSupport();<br /> }<br /> return _theInstance;<br /> }<br /><br /> /**<br /> * Application context class (encapsulation of applicationContext.xml)<br /> */<br /> ConfigurableWebApplicationContext _applicationContext;<br /><br /> /**<br /> * Configuration Manager object, to allow for encapusulation of struts.xml,<br /> * creation of actions and their proxied counterparts, creation of<br /> * servlet context from this application context<br /> */<br /> ConfigurationManager _configurationManager;<br /><br /> /**<br /> * Class constructor, take care of Struts initializations<br /> */<br /> private StrutsTestCaseSupport () {<br /><br /> // create the struts+spring integrated object factory<br /> // set spring autowiring by name for spring object factory<br /> Settings.set(StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_AUTOWIRE,"name");<br /> StrutsSpringObjectFactory objectFactory = new StrutsSpringObjectFactory();<br /><br /> // set system object facory<br /> ObjectFactory.setObjectFactory(objectFactory);<br /><br /> // set action proxy factory<br /> ActionProxyFactory.setFactory(new StrutsActionProxyFactory());<br /><br /> // create a web application context instance (for spring configuration)<br /> _applicationContext = new XmlWebApplicationContext();<br /><br /> // get ahold of a servlet context to use in the creation of the application context<br /> ServletContext servletContext = createOneServletContext(_applicationContext);<br /> // complete application context initialization, pass in servlet<br /> // context and config file location, force reading of config (via refresh)<br /> _applicationContext.setServletContext(servletContext);<br /> _applicationContext.setConfigLocations(new String[] {"WEB-INF/applicationContext.xml"});<br /> _applicationContext.refresh();<br /><br /> // initialize the object factory with the mock servlet context, application context<br /> objectFactory.init(servletContext);<br /> objectFactory.setApplicationContext(_applicationContext);<br /><br /> // add a default dispatcher to the system<br /> Dispatcher du = new Dispatcher(servletContext);<br /> Dispatcher.setInstance(du);<br /><br /> // pass over to the configuration manager location where struts-default.xml,<br /> // struts-plugin.xml and struts.xml can be found, force reading all<br /> _configurationManager = new ConfigurationManager();<br /> _configurationManager.addConfigurationProvider( new StrutsXmlConfigurationProvider("struts-default.xml", false));<br /> _configurationManager.addConfigurationProvider( new StrutsXmlConfigurationProvider("struts-plugin.xml", false));<br /> _configurationManager.addConfigurationProvider( new StrutsXmlConfigurationProvider("struts.xml", false));<br /> _configurationManager.reload();<br /> }<br /><br /> /**<br /> * create a servlet context useable for a specific action<br /> *<br /> * @param applicationContext the application context to use in the servlet context<br /> * @return the created servlet context<br /> */<br /> protected ServletContext createOneServletContext (ConfigurableWebApplicationContext applicationContext) {<br /> // create a servlet context for this action, use FileSystemResourceLoader for<br /> // context to find configuration files<br /> ServletContext servletContext = (ServletContext) new MockServletContext(new FileSystemResourceLoader());<br /><br /> // initialize freemarker manager config parameter to null (let FreemarkerManager figure<br /> // out configuration location out of ServletContext)<br /> Settings.set(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8");<br /> servletContext.setAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY,null);<br /><br /> // hand over application context to servlet context<br /> servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext);<br /><br /> return servletContext;<br /> }<br /><br /> /**<br /> * Build one action context for an accessmethod and an access url<br /> *<br /> * @param serverName the hostname that the request will need to hook up to<br /> * @param accessMethod http method to use (e.g. 'get', 'post', 'put', etc)<br /> * @param accessUrl the url to access<br /> * @return the map for the action's context<br /> * @throws Exception on processing, configuration errors, test failure<br /> */<br /> public Map<Object,Object> buildActionContext ( String serverName, String accessMethod, String accessUrl, Map<String,String> requestParamMap )<br /> throws Exception {<br /> // get ahold of a brand new servlet context<br /> ServletContext servletContext = createOneServletContext(_applicationContext);<br /><br /> // create fake request and response objects<br /> MockHttpServletRequest request = new MockHttpServletRequest(servletContext,accessMethod,accessUrl);<br /> MockHttpServletResponse response = new MockHttpServletResponse();<br /><br /> // set request server name<br /> request.setServerName(serverName);<br /><br /> // add request parameters<br /> if ( "get".equals(accessMethod) ) {<br /> for ( String oneParamName : requestParamMap.keySet() ) {<br /> request.addParameter(oneParamName,requestParamMap.get(oneParamName));<br /> }<br /> } else if ( "post".equals(accessMethod) ) {<br /> String requestBody = "";<br /> for ( String oneParamName : requestParamMap.keySet() ) {<br /> if ( requestBody.length() > 0 ) {<br /> requestBody += "&";<br /> }<br /> requestBody += oneParamName + "=" + URLEncoder.encode(requestParamMap.get(oneParamName),"UTF-8");<br /> }<br /> request.setContent(requestBody.getBytes());<br /> }<br /><br /> // add context, request and response to an action context map<br /> Map<Object,Object> actionContext = new HashMap<Object,Object>();<br /> actionContext.put(StrutsStatics.SERVLET_CONTEXT,servletContext);<br /> actionContext.put(StrutsStatics.HTTP_REQUEST,request);<br /> actionContext.put(StrutsStatics.HTTP_RESPONSE,response);<br /> actionContext.put(ActionContext.DEV_MODE,new Boolean(false));<br /> // add request parameters to action context<br /> Map<Object,Object> actionContextParams = new HashMap<Object,Object>();<br /> for ( String oneParamName : requestParamMap.keySet() ) {<br /> String[] paramValue = new String[1];<br /> paramValue[0] = requestParamMap.get(oneParamName);<br /> actionContextParams.put(oneParamName,paramValue);<br /> }<br /> actionContext.put(ActionContext.PARAMETERS,actionContextParams);<br /><br /> return actionContext;<br /> }<br /><br /> /**<br /> * create a bean from the object factory (all wired up from Spring)<br /> *<br /> * @param beanName the name of the bean to get from the object factory<br /> * @param extraContent any extra content information to pass along to the bean building<br /> * process<br /> * @return the object factory created bean<br /> * @throws Exception on processing, configuration errors, test failure<br /> */<br /> public Object createBean ( String beanName, Map<Object,Object> extraContext )<br /> throws Exception {<br /> return ObjectFactory.getObjectFactory().buildBean(beanName,extraContext);<br /> }<br /><br /> /**<br /> * create an action proxied by it's interceptor stack<br /> *<br /> * @param actionName the name/id for the action<br /> * @param actionNameSpace the namespace for the action<br /> * @param actionContext the action context for creating the proxy (created from buildActionContext)<br /> * @return the proxyed action<br /> * @throws Exception on processing, configuration errors, test failure<br /> */<br /> public ActionProxy createActionProxy ( String actionName, String actionNamespace, Map<Object,Object> actionContext)<br /> throws Exception {<br /> return createActionProxy(actionName,actionNamespace,actionContext,new HashMap<Object,Object>());<br /> }<br /><br /> /**<br /> * create an action proxied by it's interceptor stack<br /> *<br /> * @param actionName the name/id for the action<br /> * @param actionNameSpace the namespace for the action<br /> * @param actionContext the action context for creating the proxy (created from buildActionContext)<br /> * @param sessionMap the request/invocation session map (for http session map mocking)<br /> * @return the proxyed action<br /> * @throws Exception on processing, configuration errors, test failure<br /> */<br /> public ActionProxy createActionProxy ( String actionName, String actionNamespace, Map<Object,Object> actionContext, Map<Object,Object> sessionMap )<br /> throws Exception {<br /> ActionProxy actionProxy = ActionProxyFactory.getFactory().createActionProxy(_configurationManager.getConfiguration(),actionNamespace,actionName,actionContext);<br /><br /> // set the session map in the action proxy's invocation<br /> actionProxy.getInvocation().getInvocationContext().setSession(sessionMap);<br /><br /> return actionProxy;<br /> }<br /><br /> /**<br /> * create an action object, bypass all it's stacks. Have it properly injected<br /> * according to configurations.<br /> *<br /> * @param actionName the name/id for the action<br /> * @param actionNameSpace the namespace for the action<br /> * @param actionContext the action context for creating the proxy (created from buildActionContext)<br /> * @return the properly injected action<br /> * @throws Exception on processing, configuration errors, test failure<br /> */<br /> public Object createAction ( String actionName, String actionNamespace, Map<Object,Object> actionContext )<br /> throws Exception {<br /> // get ahold of the action's configuration via the XWorkConfigRetriever class<br /> ActionConfig actionConfig = _configurationManager.getConfiguration().getRuntimeConfiguration().getActionConfig(actionNamespace,actionName);<br /><br /> // create one instance of the action to test using the object factory, pass in action config and context<br /> return ObjectFactory.getObjectFactory().buildAction(actionName, actionNamespace, actionConfig, actionContext);<br /> }<br /><br /></pre><br /><br />And using it to create any bean:<br /><br /><pre><br /> MyClass myObject = (MyClass)StrutsTestCaseSupport.getInstance().createBean("myBeanName",new HashMap());<br /></pre><br /><br />Or to do a full fledged Struts 2.0 action proxy test:<br /><br /><pre><br /> // create action for ActionSearchTest<br /> Map<String,String> requestParameters = new HashMap<String,String>();<br /> requestParameters.put("searchMode","quick");<br /> requestParameters.put("searchText","Testing");<br /> Map<Object,Object> actionContext = StrutsTestCaseSupport.getInstance().buildActionContext("struts.assisrosa.com","get","/search/results",requestParameters);<br /><br /> // create the proxy for the action, this encapsulates all<br /> // the interception stack up to the real action<br /> ActionProxy proxy = StrutsTestCaseSupport.getInstance().createActionProxy("results","/search",actionContext);<br /><br /> // let the full stack run<br /> String result = proxy.execute();<br /><br /> // confirm result, any exception thrown will cause test to fail<br /> assert result.equals("success");<br /><br /></pre><br /><br />Or a Struts 2.0 action test (no proxy in front of it):<br /><br /><pre><br /> MyAction myAction = (MyAction) StrutsTestCaseSupport.getInstance().createAction("hello","/site",actionContext);<br /> String result = myAction.execute();<br /> assert result.equals("myExpectedResult");<br /></pre>Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com5tag:blogger.com,1999:blog-17860841.post-68655391422627772362007-02-12T09:35:00.000-05:002007-02-08T08:19:11.610-05:00Continous IntegrationContinuous integration is a practice introduced by Extreme Programming (XP) that brings in the idea that developers should check in their code often and that their work should be continuously integrated and tested to ensure that no error goes unnoticed (see <a href="http://www.martinfowler.com/articles/continuousIntegration.html">article by Martin Fowler</a>). The practice is tightly integrated with the concepts of source control, unit testing and automated building as these are the privileged means of bringing the code together and running tests on it. Continuous integration (CI) not only works nicely but does enforces some pretty important habits to developers.<br /><ul><li>Developers working on a CI project will be required to use source control for their code. Sounds like a basic tool for any development project but I've seen too many projects where source control is completely absent...CI simply requires it...nice.</li><li>Developers working on a CI project will be rewarded by putting in place as many unit tests as possible. How ? By seeing that less errors will sneak by because of the existence of this safety net of testing. It is pretty cool to see that you avoid putting mistakes into production because of this first line of defense. Better our CI screaming at us than our clients right ?</li><li>Developers working on a CI project get used to the concept of automated building and the concept of building from scratch. Again, often have I seen in the past cases where code that is not rebuilt regularly from scratch becomes too entangled in dependencies that prevent it from building from a clean slate.</li></ul>All these make for pretty strong points in favor of CI. And it is not that hard to put it in place...There is a significant amount of tools that joined together make for a great CI platform. Just look around. A winning combination for me, developing in Java, has been:<br /><br /><ul><li><a href="http://cruisecontrol.sourceforge.net/">Cruise Control</a>. A CI framework that glues together all the components to provide a pretty decent CI setup. From HTML reporting to email notification of success failures of builds, this is a pretty cool tool to use.</li><li><a href="http://subversion.tigris.org/">Subversion</a>. A version control system that addresses a lot of the typical weak spots of other version control systems (e.g. <a href="http://www.nongnu.org/cvs/">CVS</a>).</li><li><a href="http://ant.apache.org/">Ant</a>. An automated build tool for Java. I doubt anyone working in Java never heard of Ant.</li><li><a href="http://testng.org/doc/">TestNG</a>. A really cool testing framework for Java. Check it out...<br /></li></ul>All of the above are free tools that you can get and play with, together they make up for a pretty strong CI.<br /><br />CI takes a step ahead when talking about Continuous Database Integration (CDBI). <a href="http://www.testearly.com/category/duvall/">Paul Duvall</a> at <a href="http://www.testearly.com/">Test Early</a> has been doing some pretty interesting <a href="http://www.nofluffjuststuff.com/speaker_topic_view.jsp?topicId=349">presentations </a>on it. It does bring a new level of testing to your database-driven apps. One which enforces the cooperation between developers and database administrators and builds a structure that ensures that you can deploy your application at any point in time. If you ever seen a project where to redeploy in a new system you have to go chasing for the DB schema required to deploy a clean system, you know the kind of sorrows CDBI can save you from.<br /><br />I simply *guarantee you* that if you ever start using CI, you will not want to work again without it.Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-62464199833189735812007-02-07T21:05:00.000-05:002007-02-07T22:04:04.267-05:00Javascript: The Definitive Guide<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWO8qr9f67EJ5aJRWThJPCb9afHf9w_9UYOJwg9m9bEM1rY0vVsiloNsC3aFXRNHqZtN9C63ErGyUD76OBn_2-E0eBay0yJRJlAlrYVKFf2Q0y2HAfaosA7em9bK5oLGafb5QI_g/s1600-h/js_def_guide.gif"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWO8qr9f67EJ5aJRWThJPCb9afHf9w_9UYOJwg9m9bEM1rY0vVsiloNsC3aFXRNHqZtN9C63ErGyUD76OBn_2-E0eBay0yJRJlAlrYVKFf2Q0y2HAfaosA7em9bK5oLGafb5QI_g/s320/js_def_guide.gif" alt="" id="BLOGGER_PHOTO_ID_5028979104242554386" border="0" /></a>The title does sound presumptuous but after reading it you can only agree that if there is any Javascript book worth reading, this is it. David Flanagan does a most excellent work of introducing the Javascript language and of exploring all the kinks and nice features that you can take from it.<br /><br />Having known Javascript for sometime I could not avoid being wowed in some chapters by some cool features that I really did not know existed in the language.<br /><br />This 5<span class="blsp-spelling-error" id="SPELLING_ERROR_0">th</span> edition is well worth it even if you read previous editions. I did have a previous version and found that this new edition brings a significant amount of new content worth spending your budget in.<br /><br />The book is well structure dividing it's presentation in core javascript and client-side javascript. Something I really liked seeing.<br /><br />The core Javascript section presents pretty successfully crucial aspects of the language like closures and <span class="blsp-spelling-corrected" id="SPELLING_ERROR_1">prototyping</span> (among many others)...Even if you already know Javascript you should give it a try...I'm almost sure you will learn something from it.<br /><br />The client-side Javascript is where this book gets even more of its value... from a fantastic <span class="blsp-spelling-error" id="SPELLING_ERROR_2">CSS</span> reference chapter (I do not believe you need much more than this to get you rolling with <span class="blsp-spelling-error" id="SPELLING_ERROR_3">CSS</span>), to even handling, DOM navigation, XML handling and scripting with Java, Flash, charting with Javascript and <span class="blsp-spelling-error" id="SPELLING_ERROR_4">CSS</span> (way cool). A really interesting read.<br /><br />Like I said before, if you're out to get just one (or your first) Javascript book, I believe this is it! An interesting and absolutely essential read for any web developer these days.<br /><br />5 stars!Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com6tag:blogger.com,1999:blog-17860841.post-33643341397904536752006-12-05T20:36:00.000-05:002007-01-27T21:50:39.110-05:00DNS Analysis and Debugging<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAtvT5ST2i8x5gg0KICitQypfzmpYjxo5L9qhgT5qAqJ3winvvbBofBvCm2kXXQjmnW9mJikZhpj9E2WOkjG-tId8gjcJCoxqiBpRBe2w1vikYN95aO5xaa_UW7WMHeyKEB_1m4g/s1600-h/dnsstuff.gif"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAtvT5ST2i8x5gg0KICitQypfzmpYjxo5L9qhgT5qAqJ3winvvbBofBvCm2kXXQjmnW9mJikZhpj9E2WOkjG-tId8gjcJCoxqiBpRBe2w1vikYN95aO5xaa_UW7WMHeyKEB_1m4g/s320/dnsstuff.gif" alt="" id="BLOGGER_PHOTO_ID_5005222144494066818" border="0" /></a>If you have to deal with any DNS configuration or want to do some analysis on any other existing DNS, <a href="http://www.dnsstuff.com/">DNSstuff.com</a> might just do the trick for you...Including analysis such as DNS reporting (pretty useful since it can point out any errors you might have in your DNS entries), spam database lookups, DNS record retrieval, among many others, this is a time-saver and a great find. Another tool for my tool belt.<br /><br />Revision: since I put up this post, DNSstuff is no longer free. A shame since this was a way cool and useful service.Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com2tag:blogger.com,1999:blog-17860841.post-58373799118241450852006-11-19T23:45:00.000-05:002007-09-18T11:55:27.951-04:00Unit Testing Struts 2.0<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger2/2281/2180/1600/42738/struts2_unit.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/x/blogger2/2281/2180/320/475158/struts2_unit.png" alt="" border="0" /></a><br /><span style="font-weight:bold;"><span style="font-style:italic;">Edit: for latest on this see <a href="http://fassisrosa.blogspot.com/2007/09/unit-testing-struts-20-part-3.html">recent post</a>.<br /></span></span><br /><br />Unit testing is now (or should be) an established step of the development process in any project. If you're not writing unit tests, you are pretty much leaving yourself ready to commit errors over and over again. Granted there is a category of testing other than unit testing that can be put in place to give you that safety net (see <a href="http://webtst.sourceforge.net/">WebTst </a>;-) ) but unit testing has it's well deserved place in the must do list.<br /><br />Testing however will only happen, let's face it, if it becomes dead easy (or close to that) for developers to write tests. Crunch time has the tendency to make developers drop their testing efforts and if putting them up is in any way hard or cumbersome, it will not happen.<br /><br />So I started looking at simplifying unit testing for <a href="http://struts.apache.org/2.x/">Struts 2.0</a> (recently merged from <a href="http://www.opensymphony.com/webwork/">WebWork</a>). This is, IMHO, a pretty smart and elegant web framework (topic for another post maybe) that if you have not seen, should take a look at. I am using <a href="http://testng.org/">TestNG </a>for my testing framework (again, a topic for another post maybe, again a pretty smart framework). One of the selling points of WebWork and Struts 2.0 was the idea that testing your actions should be pretty simple due to the nature of the framework. Dependency injection would be a good step to achieve simplicity in testing and allow you to detach yourself from the need of a servlet container to run your tests.<br /><br />And so I dived into trying to add unit testing to my Struts 2.0 actions. Here is what I would like to do ideally to test my actions purely:<br /><pre><br />Action myAction = getAction("myActionUrl");<br />String actionResult = myAction.execute();<br /></pre>and to test my actions with the interceptor chain in front of them, something which I believe should be pretty important to test in the context of Struts 2.0:<br /><br /><pre><br />ActionProxy myActionProxy = getActionProxy("myActionUrl");<br />String result = myActionProxy.execute();<br /></pre><br /><br />I would then like to do testing on results coming out for execution of the actions. Both testing on result strings and testing on HTML returned in the case of the action proxy where we can get access to the fully processed response. Ideally I would like to make it as simple as above, could make it a bit more involved in some cases...but it should always be dead-easy to write a test. So the answer (to me) is a support class to help with writing unit tests. Ready for code dump ? Here it goes, snipped in the non-relevant aspects. Class implements the singleton pattern and relevant methods for Struts testing are:<br /><br /><pre><br />/**<br /> * Class constructor, take care of Struts initializations<br /> */<br />private StrutsTestCaseSupport () {<br /><br /> // create the struts+spring integrated object factory<br /> // set spring autowiring by name for spring object factory<br /> Settings.set(StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_AUTOWIRE,"name");<br /> StrutsSpringObjectFactory objectFactory = new StrutsSpringObjectFactory();<br /><br /> // set system object facory<br /> ObjectFactory.setObjectFactory(objectFactory);<br /><br /> // set action proxy factory<br /> ActionProxyFactory.setFactory(new StrutsActionProxyFactory());<br /><br /> // create a web application context instance (for spring configuration)<br /> _applicationContext = new XmlWebApplicationContext();<br /><br /> // get ahold of a servlet context to use in the creation of the application context<br /> ServletContext servletContext = createOneServletContext(_applicationContext);<br /><br /> // complete application context initialization, pass in servlet<br /> // context and config file location, force reading of config (via refresh)<br /> _applicationContext.setServletContext(servletContext);<br /> _applicationContext.setConfigLocations(new String[] {"WEB-INF/applicationContext.xml"});<br /> _applicationContext.refresh();<br /><br /> // initialize the object factory with the mock servlet context, application context<br /> objectFactory.init(servletContext);<br /> objectFactory.setApplicationContext(_applicationContext);<br /><br /> // add a default dispatcher to the system<br /> Dispatcher du = new Dispatcher(servletContext);<br /> Dispatcher.setInstance(du);<br /><br /> // pass over to the configuration manager location where struts-default.xml,<br /> // struts-plugin.xml and struts.xml can be found, force reading all<br /> _configurationManager = new ConfigurationManager();<br /> _configurationManager.addConfigurationProvider( new StrutsXmlConfigurationProvider("struts-default.xml", false));<br /> _configurationManager.addConfigurationProvider( new StrutsXmlConfigurationProvider("struts-plugin.xml", false));<br /> _configurationManager.addConfigurationProvider( new StrutsXmlConfigurationProvider("struts.xml", false));<br /> _configurationManager.reload();<br />}<br /><br />/**<br /> * create a servlet context useable for a specific action<br /> *<br /> * @param applicationContext the application context to use in the servlet context<br /> * @returns the created servlet context<br /> */<br />protected ServletContext createOneServletContext (ConfigurableWebApplicationContext applicationContext) {<br /> // create a servlet context for this action, use FileSystemResourceLoader for<br /> // context to find configuration files<br /> ServletContext servletContext = (ServletContext) new MockServletContext(new FileSystemResourceLoader());<br /><br /> // initialize freemarker manager config parameter to null (let FreemarkerManager figure<br /> // out configuration location out of ServletContext)<br /> Settings.set(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8");<br /> servletContext.setAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY,null);<br /><br /> // hand over application context to servlet context<br /> servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext);<br /><br /> return servletContext;<br />}<br /><br />/**<br /> * Build one action context for an accessmethod and an access url<br /> *<br /> * @param serverName the hostname that the request will need to hook up to<br /> * @param accessMethod http method to use (e.g. 'get', 'post', 'put', etc)<br /> * @param accessUrl the url to access<br /> * @returns the map for the action's context<br /> */<br />public Map<object,object> buildActionContext ( String serverName, String accessMethod, String accessUrl, Map<string,string> requestParamMap ) {<br /> // get ahold of a brand new servlet context<br /> ServletContext servletContext = createOneServletContext(_applicationContext);<br /><br /> // create fake request and response objects<br /> MockHttpServletRequest request = new MockHttpServletRequest(servletContext,accessMethod,accessUrl);<br /> MockHttpServletResponse response = new MockHttpServletResponse();<br /><br /> // set request server name<br /> request.setServerName(serverName);<br /><br /> // add request parameters<br /> for ( String oneParamName : requestParamMap.keySet() ) {<br /> request.addParameter(oneParamName,requestParamMap.get(oneParamName));<br /> }<br /><br /> // add context, request and response to an action context map<br /> Map<object,object> actionContext = new HashMap<object,object>();<br /> actionContext.put(StrutsStatics.SERVLET_CONTEXT,servletContext);<br /> actionContext.put(StrutsStatics.HTTP_REQUEST,request);<br /> actionContext.put(StrutsStatics.HTTP_RESPONSE,response);<br /> actionContext.put(ActionContext.PARAMETERS,new HashMap());<br /> actionContext.put(ActionContext.DEV_MODE,new Boolean(true));<br /><br /> return actionContext;<br />}<br /><br />/**<br /> * create a bean from the object factory (all wired up from Spring)<br /> *<br /> * @param beanName the name of the bean to get from the object factory<br /> * @param extraContent any extra content information to pass along to the bean building<br /> * process<br /> * @returns the object factory created bean<br /> */<br />public Object createBean ( String beanName, Map<object,object> extraContext )<br />throws Exception {<br /> return ObjectFactory.getObjectFactory().buildBean(beanName,extraContext);<br />}<br /><br />/**<br /> * create an action proxied by it's interceptor stack<br /> *<br /> * @param actionName the name/id for the action<br /> * @param actionNameSpace the namespace for the action<br /> * @param actionContext the action context for creating the proxy (created from buildActionContext)<br /> * @returns the proxyed action<br /> */<br />public ActionProxy createActionProxy ( String actionName, String actionNamespace, Map<object,object> actionContext)<br />throws Exception {<br /> return createActionProxy(actionName,actionNamespace,actionContext,new HashMap<object,object>());<br />}<br /><br />/**<br /> * create an action proxied by it's interceptor stack<br /> *<br /> * @param actionName the name/id for the action<br /> * @param actionNameSpace the namespace for the action<br /> * @param actionContext the action context for creating the proxy (created from buildActionContext)<br /> * @param sessionMap the request/invocation session map (for http session map mocking)<br /> * @returns the proxyed action<br /> */<br />public ActionProxy createActionProxy ( String actionName, String actionNamespace, Map<object,object> actionContext, Map<object,object> sessionMap )<br />throws Exception {<br /> ActionProxy actionProxy = ActionProxyFactory.getFactory().createActionProxy(_configurationManager.getConfiguration(),actionNamespace,actionName,actionContext);<br /><br /> // set the session map in the action proxy's invocation<br /> actionProxy.getInvocation().getInvocationContext().setSession(sessionMap);<br /><br /> return actionProxy;<br />}<br /><br />/**<br /> * create an action object, bypass all it's stacks. Have it properly injected<br /> * according to configurations.<br /> *<br /> * @param actionName the name/id for the action<br /> * @param actionNameSpace the namespace for the action<br /> * @param actionContext the action context for creating the proxy (created from buildActionContext)<br /> * @returns the properly injected action<br /> */<br />public Object createAction ( String actionName, String actionNamespace, Map<object,object> actionContext )<br />throws Exception {<br /> // get ahold of the action's configuration via the XWorkConfigRetriever class<br /> ActionConfig actionConfig = _configurationManager.getConfiguration().getRuntimeConfiguration().getActionConfig(actionNamespace,actionName);<br /><br /> // create one instance of the action to test using the object factory, pass in action config and context<br /> return ObjectFactory.getObjectFactory().buildAction(actionName, actionNamespace, actionConfig, actionContext);<br />}<br /><br /></object,object></object,object></object,object></object,object></object,object></object,object></object,object></object,object></string,string></object,object></pre>With this support class, I can now write my tests:<br /><pre> // create action context for my action, feed<br /> // into the action context all request parameters<br /> Map<string,string> requestParameters = new HashMap<string,string>();<br /> requestParameters.put("param1","param1-value");<br /> requestParameters.put("param2","param2-value");<br /> Map actionContext = StrutsTestCaseSupport.getInstance().buildActionContext("my.hostname.com","get","/myActionNamespace/myActionName",requestParameters);<br /><br /> // create the proxy for the action, this encapsulates all<br /> // the interception stack up to the real action<br /> ActionProxy proxy = StrutsTestCaseSupport.getInstance().createActionProxy("myActionName","myActionNameSpace",actionContext);<br /> // if needed be, get ahold of particular action underlying proxy and<br /> // inject parameters as required<br /><br /> // let the full stack run<br /> String result = proxy.execute();<br /><br /> // confirm result<br /> assert result.equals("myTestResponseString");<br /><br /> // look into mock HttpServletResponse, do whatever<br /> // tests I need to do: returned HTML, returned headers,<br /> // cookies, etc...<br /> String responseXml = ((MockHttpServletResponse)actionContext.get(StrutsStatics.HTTP_RESPONSE)).getContentAsString();<br /> assert responseXml.indexOf("<status>success</status>") != -1;<br /></string,string></string,string></pre>Or test unproxyed actions directly:<br /><pre> // create action for my action<br /> Map<string,string> requestParameters = new HashMap<string,string>();<br /> requestParameters.put("param1","param1-value");<br /> requestParameters.put("param2","param2-value");<br /> Map actionContext = StrutsTestCaseSupport.getInstance().buildActionContext("my.hostname.com","get","/myActionNamespace/myActionName",requestParameters);<br /><br /> // create the proxy for the action, this encapsulates all<br /> // the interception stack up to the real action<br /> Action myAction = StrutsTestCaseSupport.getInstance().createAction("myActionName","myActionNameSpace",actionContext);<br /> // if needed be, get ahold of particular action underlying proxy and<br /> // inject parameters as required<br /><br /> // let the full stack run<br /> String result = myAction.execute();<br /><br /> // confirm result<br /> assert result.equals("myTestResponseString");<br /></string,string></string,string></pre>So testing became *a lot* simpler to me...my support class deals with all infrastructure hooking up and my test is simplified...and more tests get written... ;-)Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com9tag:blogger.com,1999:blog-17860841.post-74186045831296434682006-11-15T09:22:00.000-05:002006-11-15T16:13:34.924-05:00iPodaholic<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2281/2180/1600/ipod2.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger2/2281/2180/400/ipod2.png" alt="" border="0" /></a>Last year I dove into the iPod addiction...Maybe not very typically, I really did not get into it because of music but because of technical podcasts. Music I can do in a number of other ways but the amount of technical podcasts that are out there for free is just overwhelming and it can be a fantastic source for free training and technical news feed. I have not regretted diving into it yet and am currently in a iPodaholic state. This is a fantastic way to make your commute useful and pleasurable. Ironically I now think my commute is just too short (got me an <a href="http://www.griffintechnology.com/products/itrip/">iTrip FM transmitter</a> to hook it up to my car radio). :-) Podcast shows are getting more and more interesting and show durations are getting longer with deeper more involved content coming in. To any developer these days I say that listening to podcasts is now an essential way to keep up to date, in addition to book reading, playing with cool stuff after-hours, magazines and blogs (and I wonder where time goes!?!!?). I should also be saying that podcasting is not only about technical podcasts.....there is pretty much a podcast for any thing you might think of.<br /><br />Anyway, these are the must-have-on-my-iPod podcasts:<br /><ul><li><a href="http://www.javaposse.com/">The Java Posse</a>: in my opinion, the best podcast out there on Java development. These guys do news info update, analysis of tools, overall software development discussions. Absolutely top of my list.</li><li><a href="http://softwareas.com/">Software as She Developed</a>: pretty interesting podcast on software development. The author Michael Mahemoff is the author of the <a href="http://www.amazon.com/Ajax-Design-Patterns-Michael-Mahemoff/dp/0596101805/sr=8-1/qid=1163601557/ref=pd_bbs_sr_1/002-7918864-5573664?ie=UTF8&s=books">Ajax Design Patterns</a> book so you can expect this podcast to bring in a good amount of that experience.</li><li><a href="http://www.ajaxian.com/">Audible Ajax</a>: name says all, a really good podcast on Ajax.</li><li><a href="http://www.se-radio.net/">Software Engineering Radio</a>: good presentations on software engineering in general. Covering topics like agile development, SOA, development processes, etc.</li><li><a href="http://javapolis.libsyn.com/rss.xml">Javapolis</a>: one of the best Java conferences around. You can find podcast feeds for some of the presentations in here. A free way to "be" at the conference.</li><li><a href="http://talkcrunch.com/">TalkCrunch</a>: a really interesting podcast on web 2.0 companies.</li><li><a href="http://www.venturevoice.com/">Venture Voice</a>: talks and discussions on entrepreneurship.</li><li><a href="http://www.podtech.net/entrepreneurship/">PodTech's Entrepreneurship Podcast</a>: talks and discussions on entrepeneurship.</li></ul>If you have not tried the podcasting listening experience I would say you <span style="font-weight: bold;">need </span>to try it! You can try it before you buy your player just by getting <a href="http://www.apple.com/itunes/">iTunes </a>for instance...<br /><br />And...if you have any other interesting tech podcast please drop me a line! I want more! :-)Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com2tag:blogger.com,1999:blog-17860841.post-67957347014129251482006-10-13T09:45:00.000-04:002006-10-13T09:54:13.173-04:00Tizra Blog is alive!<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2281/2180/1600/tizraLogo.0.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger2/2281/2180/320/tizraLogo.jpg" alt="" border="0" /></a>Tizra's blog is now alive! In there you should hope to find the Tizra's team ramblings on the web publishing world...technical hints, development process observations, geekly comments and cool notes on what is going on. The blog is alive at <a href="http://tizra.blogspot.com/">http://tizra.blogspot.com/</a>. I will be splitting some of my blogging time between this blog and the new Tizra blog, but putting on the new blog some more focus on what we are doing at Tizra and practices that worked there. Check it out!Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-65723863627398974462006-10-01T23:00:00.001-04:002006-10-01T23:00:12.006-04:00TiddlyWiki<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2281/2180/1600/tiddlyWiki.1.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger2/2281/2180/200/tiddlyWiki.jpg" alt="" border="0" /></a>Wikis should now hold, I believe, a crucial place in every development team's utility belt. Information sharing, knowledge transmission, they all represent fundamental aspects of the development process within a team. There are a ton of wikis out there (e.g. see <a href="http://jspwiki.org/">JSPWiki </a>for instance) that provide the full features that will allow for this information knowledge base repository to be implemented.<br /><br />Now, sometimes wouldn't it be nice to have a small personal wiki to jot your thoughts, todo lists, tips and tricks ? Something that you probably would not want to store on a shared wiki. <a href="http://www.tiddlywiki.com/">TiddlyWiki </a>gives you just that. For starters it is pretty impressive the ease in which you can start doing something with it....You just download a single html file (loaded with javascript functionality) drop it into a directory on your disk and access it via a browser. That's it. no more installation steps/tools/servers required! You're up-and-running ready to start writing. How cool is that ? And bringing features like tagging, RSS this brings an even more useful experience to the mix.<br /><br />Yet another tool in my tool belt (will probably need a new belt sometime soon...mine is getting too crowded...;-) ).<br /><br />P.S.<br />Another tip picked up at the <a href="http://www.nofluffjuststuff.com/">No Fluff Just Stuff</a> conference. :-)Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-90504139098429959432006-10-01T22:59:00.000-04:002006-10-01T23:00:01.422-04:00No Fluff Just Stuff Impressions<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5970/1732/1600/nfjs_logo200.gif"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/5970/1732/200/nfjs_logo200.gif" alt="" border="0" /></a>Damn you Jay Zimmerman for making my life so hard during the <span style="font-style: italic;">No Fluff Just Stuff </span>conference days ;-). For two and a half days you made me go through the excruciating pain of having to choose one presentation for each time slot...I mean...you could have put boring, uninteresting sessions in there to make my life easier but nooooooo...you had to give us a choice of absolutely fascinating topics presented by brilliant speakers. And pretty much at all time slots ? Come on....I came back refreshed and enthusiastic from the presentations, exhausted from the selection process.<br /><br />Now seriously (in case you have not picked up *yet* that I'm joking), the <span style="font-style: italic;">No Fluff Just Stuff </span>conference was simply fantastic. The organization, and Jay Zimmerman in particular, did a fantastic job of putting this together. The place was pretty well setup, the materials were really good and organized, the topics impressive (I would have gone to all of them could I clone myself!), the speaker list really overwhelming. You would get to hear the presentations in decently sized rooms (not huge theater like places like other conferences), you would get to interact with the speakers (in and out of the sessions) to ask questions and just exchange ideas. And there were even nice goodies raffled among the audience (I was not one of the lucky ones to get a prize but hey, that was not what I went there for ... obviously still trying to rationalize! ;-) )<br /><br />In short...count me in for the next one! This is a hidden gem of a conference!<br /><br />And, if you could not make it, you can still get the <a href="http://www.amazon.com/Fluff-Stuff-Anthology-Pragmatic-Programmers/dp/0977616665/sr=8-1/qid=1159980524/ref=pd_bbs_1/002-7918864-5573664?ie=UTF8&s=books">No Fluff Just Stuff Anthology</a> from any shelf of any good tech bookstore (or amazon if you also consider virtual shelves for that matter).Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-50357520416035858252006-09-16T23:39:00.000-04:002006-09-16T23:56:35.989-04:00Blogger Enhancements and Tizra AgilePDF Boasting<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2281/2180/1600/logo100.gif"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger2/2281/2180/320/logo100.gif" alt="" border="0" /></a>Now we're cooking! Last week I upgraded my Blogger blogs to the new Blogger Beta...This new beta adds a couple of new features that I consider to be crucial for a useful and rich blog.<br /><ul><li>You are now able to add tags to my blog entries (have you checked my right navigation bar since then ? ;-) ) thus effectively achieving category grouping of these entries.</li><li>You can now create private blogs. And why would I want that you may ask ? For small teams it is often useful to have a repository of shared information and/or comments. While for some things the use of a Wiki (see <a href="http://en.wikipedia.org/wiki/Wiki">Wikipedia entry for Wiki</a>) fits the bill of storing and sharing knowledge, for others the use of a blog can be more appropriate (not impossible to do via a Wiki, just a bit more awkward). Recent news of interest, cool interesting things out there, these all fall more into the info better usable in a blog.</li><li>It provides a drag-and-drop interface for blog template management, provides an enhanced set of blogger tags for simpler layout management.<br /></li><li>It provides an enhanced user interface for some of the blog's visual components, take a look for instance at the new archive navigation tree, pretty cool.</li></ul>At this point I will have to boast a bit and put in my shameless plug...;-)<br /><br /><span style="font-weight: bold;"><br /><shamelessPlug></span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2281/2180/1600/agilepdf1.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger2/2281/2180/200/agilepdf1.jpg" alt="Defining page layout structure" title="Defining page layout structure" border="0" /></a>If you like what you see in terms of control of the appearance of your blog, you should *really* see what we are doing at <a href="http://www.tizra.com/">Tizra</a>...We are building a web tool for pdf content publishers, the AgilePDF product, that gives the admin user total control over all aspects of their site including presentation, content management, search, access control, creation and selling of admin defined products. The layout definition component in particular is a component that currently really overwhelms what the Blogger page editor is offering, if you liked that one, you should see ours! ;-) It offer the means to change the presentation of the site by providing a pretty nifty drag-and-drop interface for site structuring definition and CSS definition interface.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2281/2180/1600/agilepdf2.jpg"><img style="margin: 0pt 10px 10px 0pt; float: right; cursor: pointer;" src="http://photos1.blogger.com/blogger2/2281/2180/200/agilepdf2.jpg" alt="Publishing Content" title="Publishing Content" border="0" /></a>The Publishing experience makes use of currently available rich client technologies thus eliminating the typical "Push and Pray" experience of a good number of publisher applications out there making it possible for people to *actually know* what is going on when interacting with the system.<br /><br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2281/2180/1600/agilepdf3.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger2/2281/2180/200/agilepdf3.jpg" alt="Published and looking just like you wanted!" title="Published and looking just like you wanted!" border="0" /></a>At the end of the day, a nice looking (actually as nice as you might want to make it! ;-) we offer nice looking canned solutions that might get you started towards a nice looking site but you are free to do whatever you want with it, including make it look ugly if for nothing else to make a statement! :-) ), site is out there with your content properly presented, giving you a nice web-like experience to content that usually is not very web-friendly.<br /><br /><span style="font-weight: bold;"><br /></shamelessPlug></span><br /><br /><br />If Blogger was already a nice tool for bloggers and small companies, it becomes even more so after these nice enhancements. I'll keep drilling through the new beta...blogging...Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-4257008393058737642006-09-15T17:55:00.001-04:002006-09-15T17:55:40.034-04:00Computer Science Talks<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2281/2180/1600/sptm133.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger2/2281/2180/320/sptm133.jpg" alt="" border="0" /></a>If you are looking for some computer science talks/presentations, <a href="http://www.researchchannel.org/prog/">Research Channel</a> is a nice gathering place for a whole number of interesting presentations on a number of different topics (and other non CS related topics for that matter). The <a href="http://www.cs.washington.edu/news/colloq.info.html">University of Washington Computer Science and Engineering site</a> also presents a pretty cool list of colloquiums available for public viewing. Spanning a whole slew of CS subjects, from <a href="http://norfolk.cs.washington.edu/htbin-post/unrestricted/colloq/details.cgi?id=437">Distributed Storage Systems</a> to <a href="http://norfolk.cs.washington.edu/htbin-post/unrestricted/colloq/details.cgi?id=105">Google's Linux Cluster</a>, the list is just too big to reproduce here....<br /><br />All in all a pretty cool resource for getting to learn a bit more....Fair warning: you could be in there for some serious time...;-)Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-1153318204886397432006-07-19T10:02:00.000-04:002006-07-19T10:12:01.213-04:00No Fluff Just Stuff<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5970/1732/1600/nfjs_logo200.gif"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/5970/1732/200/nfjs_logo200.gif" alt="" border="0" /></a>The No Fluff Just Stuff Symposium has been doing the rounds for sometime now...This is an excellent event for Java developers, architects, testers, etc... It usually displays an impressive list of presentations covering a good range of Java and/or Software Development topics and usually brings some pretty interesting names of the Java development community for the presentations. The symposium goes around the country so there is a good chance you might get one close to you...If you have not heard about it, check it out at the <a href="http://www.nofluffjuststuff.com/index.jsp">No Fluff Just Stuff site</a>.<br /><br />My registration to the <a href="http://www.nofluffjuststuff.com/show_view.jsp?showId=69">Boston NFJS symposium</a> Sep. 29 - Oct. 1 2006 is already in...See you there! :-)Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-1153238454931581682006-07-18T11:52:00.000-04:002006-07-18T12:03:51.326-04:00Free books online!<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5970/1732/1600/MasteringEJB.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/5970/1732/200/MasteringEJB.jpg" alt="" border="0" /></a><br />Not a pitch...they are really free. <a href="http://www.theserverside.com/">TheServerSide</a>, which happens to be a really good site for java related technical content (got my RSS feed reader hooked up to it, read through the feed always with eager anticipation), is offering a couple of books in PDF format for free. All Java related these include:<br /><br /><br /><br /><br /><br /><ul><li><a href="http://www.theserverside.com/tt/books/wiley/masteringEJB3/index.tss">Mastering Enterprise JavaBeans 3.0</a> </li><li><a href="http://www.theserverside.com/tt/books/wiley/masteringEJB/index.tss">Mastering Enterprise JavaBeans 3rd edt (EJB 2.1)</a></li><li><a href="http://www.theserverside.com/tt/books/DVTPress/J2EEArchitectsHandbook/index.tss">The J2EE Architect's Handbook<span style="font-weight: bold;"></span></a></li><li><a href="http://www.theserverside.com/tt/books/addisonwesley/ServletsJSP/index.tss">Servlets and JavaServer Pages: The J2EE Technology Web Tier</a></li><li><a href="http://www.theserverside.com/tt/books/prenticeHall/JavaTestingAndDesign/index.tss">Java Testing and Design</a></li><li><a href="http://www.theserverside.com/tt/books/sourcebeat/JakartaStrutsLive/index.tss">Jakarta Struts Live</a></li><li><a href="http://www.theserverside.com/tt/books/wiley/EJBDesignPatterns/index.tss">EJB Design Patterns</a></li></ul>You need to register on the site to "get the goodies" but it is worth it. Pretty interesting stuff, yet again, from <a href="http://www.theserverside.com/">TheServerSide</a>.Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-1152798209130884712006-07-13T09:38:00.000-04:002006-07-13T09:43:29.130-04:00JavaOne 2006 Sessions Online<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5970/1732/1600/java.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/5970/1732/320/java.jpg" alt="" border="0" /></a>Sun has posted the JavaOne conference technical content online. These can be found at the <a href="http://developers.sun.com/learning/javaoneonline/">Sun Developer Network site</a> in PDF and multimedia format (audio + slides). Really interesting information in there.Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0tag:blogger.com,1999:blog-17860841.post-1152711823886078522006-07-12T09:35:00.000-04:002006-07-12T10:10:47.673-04:00Getting organized!<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5970/1732/1600/airset.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/5970/1732/320/airset.jpg" alt="" border="0" /></a>When you work on several things at time it becomes really important for you to track what you need to do, when you need to do it and to be "nudged" when it is time to do them...And along come things like <a href="http://www.google.com/calendar">Google Calendar</a> and <a href="http://www.airset.com/">Airset </a>(among tons of others!). I have personally been using <a href="http://www.airset.com/">Airset </a>for quite sometime (long before <a href="http://www.google.com/calendar">Google Calendar</a> showed up) and have been pretty impressed with what they have. With such an application I can keep separate calendars for my private life and my work. Even within the work information we can keep separate events from different activities (e.g. management roles activities, development activities, staff vacation). Nicest thing, you can have separate views or integrated views....easy enough to provide people synchronization since some of those calendar sections (tabs in their nomenclature) can be made shareable effectively allowing for people to know what each other is doing. And....for people like me that like to be "nudged" you can have as many warnings as you want on an event that is about to happen...<br /><br />So.....no more excuses...Get organized!Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com3tag:blogger.com,1999:blog-17860841.post-1149863874792347792006-06-09T10:37:00.000-04:002006-07-11T22:40:25.243-04:00Sharing initialization across Unit TestsIn principle unit tests should be isolated from each other to ensure that running one unit test does not influence another. There is however, I believe, a case where having a shared initialization between unit tests can make a lot of sense. Whenever a time consuming initialization needs to take place, and when one can ensure that the state of the initialized environment does not influence in any way the tests, then it is really important to share initialization. One of the goals of unit testing is to make it easy to test, to promote a test-often approach and that will conflict with long initialization times. An initialization that takes a couple of seconds, although very acceptable for a running application is not acceptable at all for unit testing. If you do follow the test-often approach, you will be building a large number of tests (not hard to admit you will have several dozens, hundreds of tests). Multiply that by the initialization cost and testing becomes unbearable.<br /><br />Example of the above. I have been working for sometime with <a href="http://www.opensymphony.com/webwork/">WebWork</a>+<a href="http://www.springframework.org/">Spring</a>+<a href="http://www.hibernate.org/">Hibernate </a>and using <a href="http://www.junit.org/index.htm">JUnit </a>for unit testing integrated in the build/deployment process via <a href="http://ant.apache.org/">Ant</a>. The startup time for the system is around 8 seconds (still way lower than a full J2EE application server startup time ;-)...but after even a mere 12 tests it becomes impossible to have to wait for a simple test run. By isolating the initialization of WebWork+Spring+Hibernate in a shared initialization class, I was able to reduce the overall tests run time by a huge factor. Somewhere from 104s to 12s in my simple (very simple) case of 12 tests.<br /><br />The solution for me, I create a singleton class that isolates all shared initialization then I make sure all tests run via ant using the task batchtest with forking enabled and with forkmode set to 'perBatch' (see <a href="http://ant.apache.org/manual/OptionalTasks/junit.html">http://ant.apache.org/manual/OptionalTasks/junit.html</a>) and voila, I get shared initialization and a huge reduction in test running.<br /><br />After looking online for similar issues, I found the link <a href="http://beust.com/weblog/archives/000082.html">http://beust.com/weblog/archives/000082.html</a> that talks a bit about this same issue confirming my worries and validating this approach.<br /><br />My belief in unit testing restored, I continue my development with my nice safety net in place...Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com3tag:blogger.com,1999:blog-17860841.post-1149687749176951332006-06-07T09:42:00.000-04:002006-07-07T09:55:33.000-04:00FireBug<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5970/1732/1600/firebug.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/5970/1732/320/firebug.jpg" alt="" border="0" /></a>Every developer "carries" his bag of tools around when doing their work...This bag of tools can represent a precious advantage since a good tool applied at the right moment can bring speed and quality to the development effort. It is quite unlikely you will find a tool that "fits all" (a tool for each job) and the developer does need to know enough of the tool and problem to solve to make it useful (it is not the weapon that makes the warrior, it is the warrior that makes the weapon). But sure enough, some tools are just too good and should be in every developer's bag. A tool which I found to be a must for any serious web developer doing from just regular HTML coding to AJAX development is the <a href="http://www.joehewitt.com/software/firebug/">Firebug </a>Firefox extension (you are using Firefox right?!?! ;-) ). The tool allows you (among other functionality) to:<br /><br /><ul><li>Inspect HTML, by moving your mouse around you can get to see the HTML snippet relevant to the element highlighted on the browser.</li><li>Inspect properties like positioning, styles on inspected HTML elements.</li><li>Inspect events happening in your pages.</li><li>Inspect the DOM of your page.<br /></li><li>Perform Javascript debugging.</li><li>Show all AJAX interactions between your page and the underlying server.</li><li>Show all kinds of errors (e.g. CSS, Javascript, etc)</li></ul>In short, if you are doing web development and have not seen Firebug in action before, you should spend sometime looking at it...It will save you hours in any future development. It sure is in my bag of tools to stay. :-)Francisco Assis Rosahttp://www.blogger.com/profile/12855998998098058553noreply@blogger.com0