Saturday, December 26, 2009

Grails - a decomposed application project

Hi there,

I've been looking around for ways to nicely decompose a large application (an Enterprise Application so to speak) using Grails. It turns out this platform has such a capability already build-in! Interested? Read on...

The basic building blocks of Grails are plugins. There's a plugin for everything: the ORM layer, IoC container, security, twitter access - you name it! So how is this going to help us decompose a large enterprise-grade application? Well, we're going to compose it from... plugins!

Here's a step-by-step instruction on how to create the main application along with one additional pluging. Other plugins can be added exactly the same way as the single one mentioned here.
  1. Create a grails application (we're going to name it "myapp" here) using standard Grails command grails create-app myapp
  2. Do not change the folder just yet to myapp - instead issue the following Grails command: grails create-plugin myapp-plugin
  3. cd to myapp
  4. Add the line plugins.myapp-plugin=0.1 to application.properties (that's in the main application, not in the plugin!)
  5. cd to grails-app/conf
  6. Add the following line to BuildConfig.groovy: grails.plugin.location.'myapp-plugin' = '../myapp-plugin'
  7. cd out of the application and into the myapp-plugin folder
  8. Issue grails package-plugin command to create plugin.xml
  9. cd back to your application and run it as usual using grails run-app
That's it! Whenever you make changes to your plugin they will be automatically picked up just as if they were a part of your main application which is the greatest feature ever!

Have fun!

Friday, December 25, 2009

Groovy - dumping object's properties

Marry Christmas! This is the Christmas Eve and what follows is a Christmas Present for you!

Have you ever used BeanUtils from Apache to query the properties of an object? Was that easy? Well I did that and what I ended up was completely unreadable and chaotic. But there's good news! Here's how it's doable in Groovy:
object.properties
That's it! Groovy exposes the map of properties as a predefined property called "properties". Ain't that cool? Let's see how we would go about printing all the values of object's properties along with their names:
println object.properties.collect{it}.join('\n')
Here's what it's doing: it gets the map of properties, turns it into a list (collect{it}) and joins them with a new line character.

Did you notice that "class" is also one of the properties? That's nasty! How about filtering it out?
println object.properties.findAll{it.key != 'class'}.join('\n')
Now that's much better, but good only for one or two names to filter. How about a more general solution?
def filtered = ['class', 'active']
println object.properties
.collect{it}
.findAll{!filtered.contains(it.key)}
.join('\n')

That's much much better but still, if the object has like 15 properties looking them up is a pain if they are not sorted. Let's do something about it:
def filtered = ['class', 'active']

println object.properties
.sort{it.key}
.collect{it}
.findAll{!filtered.contains(it.key)}
.join('\n')

And there it is! A list of key=value (value taken from object's toString()) separated by a new-line character for easier browsing :)

I hope this will help you out with your Groovy adventures!

Have a nice holiday!

Sunday, December 20, 2009

Deploying Grails application on Tomcat6 on Ubuntu

Hi,

I've just had a few moments of struggle deploying my Grails application onto Tomcat installed via apt-get in Ubuntu. Thanks to the Ubuntu forum it didn't morph into a war :)

After apt-get install tomcat6 and putting my application into the webapps folder I've restarted Tomcat using the usual script but could not access my application at all. The log said something like this:

SEVERE: Exception sending context destroyed event to listener instance of class org.codehaus.groovy.grails.web.util.Log4jConfigListener
java.security.AccessControlException: access denied (java.util.PropertyPermission grails.env read)

After a few minutes of search I found the answer. By default Tomcat on Debian and Ubuntu uses a security manager that prevents application to access environment variables. Why this is the case I don't know but it is. And it is easy to turn it off. Just edit the file /etc/default/tomcat6 and change the line that reads

#TOMCAT6_SECURITY=yes

into

TOMCAT6_SECURITY=no

and live is good again.

Hope this helps!

Friday, December 18, 2009

Grails - the search is over

Recently I've been crushed with the simplicity of Grails framework. For those of you who don't know what's this thing is all about please check the Grails web site - it's well worth your while!

Here are some highlights I've checked out during the evaluation process:
  • Grails combines the best open source technologies into one easy to use framework (Spring IoC, Hibernate, Spring MVC, Spring WebFlow)
  • Additional integrations are as easy as one-line plugin installation (Jabber integration, JMS integration, additional view capabilities, JavaMelody monitoring - just to name a few)
  • ActiveRecord pattern as well as dynamic finders rock!

Stay tuned for some working examples. I'll post them during the weekend.

Monday, December 7, 2009

Transcoding AVCHD using latest FFMPEG build

Recently I found myself arguing with ffmpeg to accept the fact that my template for libx264 is in fact where I know it is. Some time ago it was pretty simple - you just had to copy the template into the current directory and use the form -vpre ./preset to make ffmpeg use it. Unfortunately after last update of ffmpeg this is not the case anymore...

After some time I've finally figured it out. Due to some incompatibility between the Linux version and Win32 binary the only place where ffmpeg is actually properly looking for those templates is

%HOME%/.ffmpeg

To that end I've created the following batch script and copied the ffmpeg's x264 templates to a subfolder .ffmpeg where my ffmpeg binary lives:
@echo off
SETLOCAL
SET HOME=%~d0/
ffmpeg.exe %*
ENDLOCAL

And that's it! Now ffmpeg thinks that the home folder is where it lives and I don't have to pollute my home folder with stuff that doesn't belong there.

You can download the latest FFMPEG binaries from here (you want the "static" version for this setup).

Have fun!


Code coverage and Enum types

Hi,

I've been trying really hard to achieve 100% code coverage on one of the projects I'm working on right now. Pretty much all my business code showed the desired code coverage right up to the point where I introduced enumeration.

First let me explain why I wanted to get to the 100% in the first place.

Whenever I'm writing code that should be covered by unit tests (which is pretty much always nowadays) I'd like to be reminded (by either the code coverage results in CI or by the IDE) that some of the edge cases have not been tested yet. I know this might sound bad in the first place because I should only write as much code as required to satisfy the test I wrote but still - there are cases where the business code I produced does a little bit more than what's in the test. So it's a good idea to keep the 100% test coverage at all times so that once it drops below this magic number I'll notice immediately that something has been skipped.

Back to enumerations.

Those guys contain synthetic methods generated by the compiler (like valueOf and values) that do exist in the byte code but have no corresponding lines in the code itself. This means that there's more that meets the eye from the code's perspective but the code coverage tools I use (Cobertura and EclEmma) know only about byte code and they couldn't care less if the method they are testing came from the code itself or if it was dynamically generated by the compiler.

To that end, whenever I use an Enum the overall coverage drops like stone which simply looks awful.



But there's hope! One line of stupid test and all is green again.

MyEnum.valueOf(MyEnum.VALUE.toString());








I admit that the actual value of this test is minimum but the real reason to do that is to allow yourself the luxury to always react on the drop of coverage below 100% instead of manually checking every time if what's missing is really something we don't care about.

I hope this helps.

Wednesday, November 18, 2009

Microsoft PDC 2009 - first recordings available!

There's been the first recording made available from this year's PDC. It's the key note from day one. It looks like things are going to be very much thumbs up for the next year!

Java and Closures - own goal

Today in the morning there was an announcement made that closures (a feature long awaited in Java) will make it to version 7. Here you'll find some examples of how it will actually look like.

But...

To have an understanding of what closures really are useful for one must follow an example. Here's something written in C# for sorting a list of strings:

var list = new List<string>() {...content go here...};
list.Sort({ (s1, s2) => s1.Length - s2.Length });

And here's the equivalent in Java:

List list = ...
Collections.sort(list, #(String str1, String str2) {
return str1.length() - str2.length();
});

One can clearly see the intent of what the closure (a function being passed as parameters) looks like in both languages with the clear winner in succinctness being C# (or pretty much any other modern language out there). I know that java tends to be verbose on all possible counts but having a different approach for commonly understandable constructs is a bad thing all along.

One other thing that you can clearly see in the example above is the lack of type inference feature which makes the syntax even more verbose.

So when I said "own goal" in the title what I really meant is that the primary function, which is succinctness and clarity has been lost in transition.

Unfortunately we're facing yet another messed up implementation of a perfectly good idea (like generics with type erasure) in one of the most popular languages in the industry.
With this kind of mind set the end is near!

C ya!

Monday, September 28, 2009

Java 7 - a dissapointment

I've just been looking into the "features" available in J7 and I must say I'm mostly disappointed. Closures are out, properties are not yet implemented... I guess the code base must be to big to do any relevant changes to the language. Maybe it's time someone will admit that the language is going down and that there's time for Java++?

Tuesday, September 15, 2009

I Come to Bury Agile, Not to Praise It - by Alistair Cockburn

Hi all,

from all the presentations about programming methodologies I believe this one given by Alistair Cockburn at the InfoQ conference to be of particular value. It's mainly because of the fact that he discloses most of the actual patterns occurring during a software development process and shows probable solutions for the upcoming (or present) challenges that we might face.

Go check it out at Bury not praise agile

And please - have fun!!!

Monday, September 14, 2009

PostgreSQL and phpPgAdmin on Ubuntu Server

I was struggling to get the phpPgAdmin application to work on a virtual machine running Ubuntu 9.04 today. As it turns out phpPgAdmin's default installation is by default targeted at desktop environments which is by all intents and purposes stupid (to say the least).

So what's so "desktop-ish" about it? Well as it turns out the default configuration accepts connections from localhost only which is completely unusable in a server-like environment with no graphical environment and no web browser whatsoever.

The default behavior also manifests itself in a very non-verbose manner. At first the log entry

"GET /pgphpadmin HTTP/1.1" 403 268

is not saying very much. It'd be better if the error message said something more verbose and direct the user to change the access rules or better yet to have a configuration step during installation that asks for this rather than to have poke around some configuration files.

To change it's default behavior one has to edit the file /etc/apache2/conf.d/phppgadmin (which is a symbolic link to /etc/phppgadmin/apache.conf) and change the default access policy from 127.0.0.1/255.0.0.0 ::1/128 to all.
To do that simply comment out the line that reads

allow from 127.0.0.1/255.0.0.0 ::1/128

and remove the comment from one line below that reads

allow from all

That does the trick. Of course that opens the ability to connect to this server from the outside world, but since this is a server installation it's not uncommon to access it from far far away, is it?


Happy hunting!

Thursday, September 10, 2009

The size does not matter

I've just finished a very inspiring conversation with a friend of mine and I want to share the outcome with the rest of you.

So it started quite innocent. He talked how he liked the Flex framework with some server-side code, I talked about the discovery of Apache Wicket... Just a normal conversation between 2 fellow programmers.

Then after some time he expressed his bad feeling about dynamic languages and all. Well, I've asked if he'd like to see the waves of a WiFi transmitter where he immediately replayed that he ain't got a microscope laying around....

At that time it was quite obvious that he thinks of them as something that really is there. That they are something he can take for granted. That's an assumption even if on a very theoretical level. He made an assumption and to that end he expressed his behavior as dynamic.

This fact lead to a conclusion that human beings are in fact in their nature more suited to the dynamic part of programming languages than anything else. We choose to think about programming as a very static thing whereas it is completely dynamic in its very nature. We can never predict what the user will give for an input to our carefully design form, do we? We can never predict what kind of weather condition will be fed to our application's flight planning routine - it's just a wild guess that we can cope with all of that.

On a more structural level it's a lot better to define the actual interface required for the part in question to work as expected than to say that this part must definitely be of some special type. Hell, the duck and a canary are birds and are similar in a lot of different ways. Did they evolve from the same species? Maybe yes but, on the other hand, maybe not. The fact remains the same that we can talk about the wings of a duck as well as of the wings of a canary and we all know that they move more-less up and down to create some lift to allow the bird to fly!

At the end of the day both ideas (the static and the dynamic one) have their advantages and disadvantages. It's just takes the openness of one's mind to realize the similarities and advantages of both solution to pick the right one for the job.

Happy hunting!

Sunday, August 30, 2009

Re-encoding AVCHD video using FFMpeg

There's been some changes to how ffmpeg operates starting from revision 19459 and simply pointing out the input and output files with libx264 will not do the trick anymore. This is due to the fact that ffmpeg now recognizes the subtitles track and doesn't know how to deal with it in the resulting MKV file. To overcome this issue add the -sn to the parameters and you're done.

Also some of the x264 options don't have working default values so one must specify the preset for video encoding. Here's an example:

ffmpeg.bat -i 00001.MTS -acodec aac -ac 2 -ab 128k -sn -vcodec libx264 -deinterlace -s 1280x720 -vpre ./libx264-hq.ffpreset -crf 23 -threads 2 00001.mkv

To make it work make sure you've copied the libx264-hq.ffpreset file from ffmpeg archive into the folder with your MTS file to be re-encoded.

Also you can adjust the -crf 23 parameter to steer the final size and quality of the resulting MKV file.

Enjoy!

Joining MTS files (AVCHD)

I've been looking for a long time to find out how to join 2 consecutive MTS files from my Sony SR-11 camera. The case is simple: re-encode the recorded material into a smaller resolution and/or DVD format.

If you'd just take all the files the camera spitted out and join them afterwards a number of issues would emerge: jittered frames at the splitting points, audio desynchronization - you name it.

The solution couldn't be simplier but it was nowhere to be found directly on the net (google could have done a better job this time):

copy /b 00001.MTS + 00002.MTS + 00003.MTS output.mts

This example will join the files 00001.MTS, 00002.MTS, 00003.MTS into output.mts without doing any re-encoding, loosing synchronization or anything like that. And it's doing it extremly fast.

Enjoy!

Thursday, July 30, 2009

NHibernate and ASP.NET - UpdateModel problem

Using NHibernate as a persistence layer is fun. Not only does it hide the complexity of a database completly but also allows one to use an object model instead of playing around with database query results.
In the case of NHibernate it's even better as it provides session management for web applications so with minimum effort you can just use lazy loading from within your views very easily.

At some point though problems will emerge. One of them is using ISession.Get without specifying the type (which might be unknown at the time of querying or might depend on the actual request from the page) with Controller.UpdateModel method. Here's how it goes:

1. UpdateModel is a generic method that expects the actual type that's being mapped to as the generic parameter.
2. It then passes the processing to TryUpdateModel which is a generic method as well.
3. TryUpdateModel takes this generic parameter, retrieves it's type metadata and uses it (among other things) to fill in a ModelBindingContext structure.
4. This ModelBindingContext is then passed on to IModelBinder.BindModel method.

It's all nice and dandy if we can specify the model's type. But if we don't know the actual type it results in processing of a model of type Object and none of the properties will get mapped. Because of the fact that there's no specialized model binder for type Object it gets passed on to the DefaultModelBinder implementation held by ModelBinders.Binders.DefaultBinder.

There's however an extremly nice and easy solution to this. We're going to use the decorator pattern to wrap up the current default model binder and provide it with the necessary information from NHibernate's ISessionFactory.

Here's an example implementation of such a model binder that can provide this additional implementation. I've called it NHibernateAwareModelBinder.


public class NHibernateAwareModelBinder : IModelBinder
{
private readonly ICollection mappedClasses;
private readonly IModelBinder defaultModelBinder;

public NHibernateAwareModelBinder(
ICollection mappedClasses,
IModelBinder defaultModelBinder)
{
this.mappedClasses = mappedClasses;
this.defaultModelBinder = defaultModelBinder;
}

public object BindModel(
ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
if (bindingContext.Model != null)
{
string modelType = bindingContext.Model
.GetType().FullName;
if (mappedClasses.Contains(modelType))
{
bindingContext.ModelType =
Type.GetType(modelType);
}
}
return defaultModelBinder.BindModel(
controllerContext,
bindingContext);
}
}

And here's how you'd use this class in your Application_Start event:

ModelBinders.Binders.DefaultBinder =
new NHibernateAwareModelBinder(
SessionFactory.GetAllClassMetadata().Keys,
ModelBinders.Binders.DefaultBinder);

As you can see we're using the current default model binder as the actual binder but we're decorating it's behavior with type resolution. Nice, isn't it?

Have fun!

Saturday, July 11, 2009

Localizing ASP.NET pages using resources

Localizing ASP.NET pages using resource files is an easy thing to do. It requires just a few steps to get everything up and running but all of those steps have to be completed because otherwise it will not work.

  • Set the UICulture and Culture attributes on a page to "Auto"
  • Create an ASP.NET folder named App_LocalResources
  • In App_LocalResources create a resource file using the following pattern:
page.ext.lang-variant.resx

for example:

Default.aspx, en-us -> Default.aspx.en-us.resx
Default.aspx, pl -> Default.aspx.pl.resx

  • On the element that needs localization set the attribute meta:resourcekey to something meaningful, for example:

<asp:Label ID="LblText" Text="Hello, world!" runat="server" />

becomes

<asp:Label ID="LblText" Text="Hello, world!" meta:resourcekey="LblText" runat="server" />

  • Add resource key for the property to modify using the following pattern:

resourcekey.property

for example:

LblText.Text

  • DO NOT FORGET TO REBUILD AND RE-RUN THE APPLICATION!


Here's a complete and working solution for you to play around

ASP.NET-Localization.zip

Have fun!

Thursday, June 11, 2009

StyleCop and FxCop integration in VS 2008 Express

Recently I took interest in improving the quality of the applications I write by forcing them to be checked by StyleCop and FxCop during the build.

StyleCop was really easy to implement - just one line, well documented, nothing one would struggle with:

1. Install StyleCop using MSI installer
2. Add the following line to your project right after the line that imports C# tasks (by default it's nearly at the end of the project file!):

<Import Project="$(ProgramFiles)\MSBuild\Microsoft\StyleCop\v4.3\Microsoft.StyleCop.targets" />

FxCop on the other hand wasn't so easy to find out but it was just as easy to manage:

1. Install FxCop using MSI installer
2. Add the following task to <AfterBuild> target:

<Exec Command='"$(ProgramFiles)\Microsoft FxCop 1.36\FxCopCmd.exe" /file:"$(TargetPath)" /console'/>

That's it. Alternatively you could just add a post-build event using project options editor. This event would then look like that:

"%ProgramFiles%\Microsoft FxCop 1.36\FxCopCmd.exe" /file:"$(TargetPath)" /console

Pretty easy, ain't it?

Here you have a ready-to-check example of the above.

FxCop+StyleCop-example.zip

Enjoy!

Thursday, June 4, 2009

Mercurial - using "hg serve" to push changes

I've just discovered Mercurial. It's amazing!!! It's a distributed version control system, similar in its flows to git and others from the bunch so if you're already familiar with the concept you'll have no issues working with it.

One thing however is really amazing: it contains a built-in web user interface! Just while being inside the repository type "hg serve" and browse to http://localhost:8000. And there's more to it. "hg serve" can serve as a real server!

There's one thing worth mentioning. If you'd like to use it for hosting a repository there's one thing you have to add to .hgrc (or Mercurial.ini in case you're working in Windows) to make it work:

[web]
allow_push = *
push_ssl = false

Otherwise while trying to push the changes you'll get a message saying something SSL and stuff.

And like I said - Mercurial is great - go check it out!

Sunday, May 31, 2009

Flexigrid

Did you ever wanted to have an all-in-one solution for grids in your application? One that does Ajax refreshes, supports sorting, filtering and pagination out of the box. How about an API that's actually usable?

I've got some good news for you - it's there! It is called Flexigrid and is in fact a plugin for jQuery.

For the purpose of demonstration I've put together an example that does pretty much everything I've mentioned above.

FlexigridExample.zip

Here are some points worth noticing in the provided example:

1. The CSS in Internet Explorer is trashed. I don't know how to fix it.
2. The real power that feeds the data is to be found in BookController and is well documented.
3. Since there's not much documentation for Flexigrid itself I suggest taking a look at the list of options in flexigrid.js.

Enjoy this fantastic library!

Wednesday, May 20, 2009

Creating custom controls in ASP.NET MVC

Today I've been going over the process of creating a simple ASP.NET MVC control. At the first glance it might seem unnecessary since we have the HtmlHelper class. However the main difference is that MVC Controls have superior design time support!

Let's get down to business, shall we?

First you need to import Microsoft.Web.Mvc.dll assembly to your project.
Next you create a class that inherits from Microsoft.Web.Mvc.Controls.MvcControl. I put my controls into Controls folder in my solution so my controls are in the namespace (for example) MvcApplication1.Controls.
The actual creation of the control is really simple: you override the Render method and use the writer object to pass on some text to the rendering pipeline.
Here's a ready-to-use example:

using System;
using System.Web.Mvc;
using Microsoft.Web.Mvc.Controls;

namespace MvcApplication1.Controls {
public class Status : MvcControl {
public String Key { get; set; }

protected override void Render(System.Web.UI.HtmlTextWriter writer) {
TagBuilder tag = new TagBuilder("span");
String data = String.Empty;
if (!DesignMode)
data = ViewData[Key] != null ? ViewData[Key].ToString() : "";
else
data = "#" + Key;
tag.SetInnerText(data);
writer.Write(tag.ToString());
}
}
}

Remember to compile your project before moving on to the next step!!!

Next you need to do one thing to get your controls to the page:

Register your namespace with prefix for ASP.NET WebForms engine by adding the following line to your Web.config file in section system.web/pages:

<add tagPrefix="custom"
namespace="MvcApplication1.Controls"
assembly="MvcApplication1"/>

From now on (after a few moments when VS/VWD thinks if your control is worth using :D) you'll get the IntelliSense support for your new control with all the public properties it has.

Here's an example usage of the control described above:

<custom:Status runat="server" Key="Example" />

As you can see this control is rendered by the server (runat="server") and has one property (or rather an attribute) called Key. Taking a look at the code reveals that the actual meaning of this field is that it serves as a key in ViewData map.

Bye!

"Error creating control" in VS and VWD

There's a nasty bug in VisualStudio 2008 SP1 and Visual Web Developer 2008 SP1 that makes the usage of custom controls virtually impossible. Everytime you try to set a property (via Properties or directly in code) you'll get a gray error message saying that the value of your property cannot be set.

This is a known issue and there's a simple remedy to that. Close VS/VWD, install this hotfix, start VS/VWD again and you're good to go.

http://code.msdn.microsoft.com/KB961847/Release/ProjectReleases.aspx?ReleaseId=2646

Happy coding!

Monday, May 11, 2009

JSF Nonsenses

Hi,

As you have probably noticed I'm not the biggest JSF supporter out there. In fact JSF has been driving me mad for quite some time now and I've decided to take revange.

So here it is: JSF Nonsenses

Jump in from time to time if you want to - if you don't that's fine by me. I just need a place where I can publicly discredit the ideas behind declarative-only and I'll do it all for you approach.

If you feel the same way I do please share! If you don't and you think I'm nuts please share your opinion as well.

MVC RuLeZ!

Colose encounters with J2EE/JSF

Hi,

One of the projects I work on involves heavy JSF usage. Along with other tools to make our life "easier" (Facelets for example) the project runs quite smoothly. Right up to the point where a little bit more "custom" solution is required...

Here's the problem: I need to call a method that will return some JSON that will be evaluated by the client and according to the result of this operation some action must be taken.

As long as I wanted to use the rather limited XMLHttpRequest capabilities provided by Ajax4JSF I was fine. Now I need a little bit more control and flexibility over the actual flow and I am screwed. I'm not really interested in the whole life-cycle of a JSF page and all that statefull crap JSF provides - all I need is a simple call to a method and return a little bit of text - that's all.'

As it turns out there's no such thing in JSF directly. There's however a big honky machine to actually hide the inner-workings of JavaScript from an evil developer like me. I can almost hear the creators of Ajax4JSF saying "no no.. that's not allowed here, nigther is that, and oh that's because of X and that's because of Y and that's because it is like that, period". I'm sick and tired of this miserable framework.

So far I've not found a single thing that I like about JSF (MyFaces and RichFaces in particular). To start a project it's a configuration nightmare (if you want to have more than one JSF component library like RichFaces and Tomahawk), some things are simply incompatible. RichFaces force me to use stone-age version of jQuery (my favorite and better with each release), mix things that don't really come together (like server-side code being "executed" by so called "client actions" for example). The whole beautiful stateless nature of the web is gone with the wind in the worst possible style. And last but definitely not least: there's no control whatsoever over the generated markup, nada, zipp, null... And let me tell you, it's huge!

Apparently the designers of RichFaces (and other JSF-related frameworks) didn't follow the news and in their urge to "define" every damn thing they have forgotten that it actually matters in what way you define the layouts. Doing it with multi-level tables is probably the worst thing ever about the generated HTML, but it's definitely not the only horror you'll see. Constant 'styles' and 'script' blocks, intrusive JavaScript and the like are just standard. How can something so bad have become so popular? Oh I get it: scriptlets are the source of all evil in the enterprise application world... How could I forget that mantra. Apparently URLs are also evil as they have no damn meaning in JSF. Posting a form (or however its called in the JSF world) reveals the concept of ghost-urls: you're seeing the next page but the URL didn't get the memo yet. Whatta heck???

No wonder that MVC-based solutions (Spring MVC, ASP.NET MVC, Rails, Django) are getting more and more popular. Those are actually non-hammer tools to get the job done without 100-line exception messages getting in a way.

And don't get me wrong: I'm sure JSF is good for something - it just so happens it's not the creation of highly interactive, flexible and customizable Web 2.0-enabled enterprise applications.

"Close encounters my a..." - John Criton / Farscape.

RadioTaxi Manager gone OpenSource!

RadioTaxi Manager is one of those projects that I've created a long long time ago and that has actively been in use for the better part of last 10 years. Finally after all those years since I really can't find the time to develop it further (and there are new requirements coming!) I've decided to go OpenSource.

The code base is full of legacy stuff, polish variable/procedure/table names and a lot of other stuff that will most probably make it very hard to work with.

Anyways, here it is: http://code.google.com/p/rtmgr

I've also setup a mailing list for this project at http://groups.google.com/group/rtmgr-dev.

Should you be willing to participate drop me a note. I'm sure we can work something out!


Have fun!

Tuesday, May 5, 2009

ASP.NET MVC scaffolding

I've been recently playing a bit with the scaffolding capability in ASP.NET MVC tooling support. Being it all nice and dandy it's still a lot of work to be done to get a simple CRUD operation working with any kind of data access technology.

As a result I've started a code/view generator that will allow for bottom-up scaffolding of all the typical layers in a web application: the entity being persisted, data access using NHibernate, a pass-through service layer, the controller with default CRUD actions and a set of views supporting the controller.

As a matter of fact the basic idea behind this tool came from the Rails framework. In there you can scaffold an entity with a page and all the default CRUD behavior from the command-line. This tool will allow for exactly that but instead of taking advantage of the field:type syntax it'll use the NHibernate hbm.xml mapping files to describe an entity and its relation to other entities.

Here's a link in case you want to monitor the progress or (if you feel up to it) to join the effort:

MVCGen

Have fun!

EDIT on 21/06/2011: since I'm no longer working with .NET (or ASP.NET MVC for that matter) the project is dead.

Tuesday, April 28, 2009

ASP.NET MVC template with Spark

What it Spark?

Spark is a view engine for Asp.Net MVC and Castle Project MonoRail frameworks. The idea is to allow the html to dominate the flow and the code to fit seamlessly.

Here's an ASP.NET MVC template that you can put into your "Visual Studio 2008\Templates\ProjectTemplates\Visual Web Developer" folder and start using Spark as view engine.

MvcWebApplicationSparkProjectTemplatev1.cs.zip

All the views as well as the user control used to display log on information has been translated!

Enjoy!

Monday, April 27, 2009

Installing Oracle XE on Ubuntu

I've faced a dilemma today. I need an instance of Oracle XE datababase. The question however is "should I install the windows version on my box?". Since this is not the first time I've been doing it the answer was quite obvious: NEVER EVER DO THAT!

VMware Player to the rescue!

You might ask why wouldn't I install Oracle XE on my Windows box. The answer is plain and simple: I use my notebook for more than just data serving and allowing the Oracle to spread throughout the available resources would be a perfect waste of hardware.
So I did as follows: I've installed Ubuntu 9.04 server (very nice linux distribution indeed!!!), installed the necessary stuff I can't live without (openssh-server, tomcat6, mc, htop), used this tutorial to install Oracle XE, used this tutorial to configure web access to Oracle database manager for external hosts and that's it! It took an hour to get it to work from scratch and the time is really well spent!

One must not forget to allocate quite a lot of swap memory during installation. Automatic disk partitioning is out of the question here. I've created my swap partition to be 1.5 GB in size and that was enough to install Oracle XE.

The final product is 3.5 GB in size, has VMware Tools installed (taken from VMware Server) and performs extraordinary well! Long live virtualization!!!

See ya!

Saturday, April 25, 2009

VirtualPathProvider example

Hi there,

did you ever wonder if you can retrieve ASP.NET MVC views from another storage than a file on disk? For example from the database? This is where the VirtualPathProvider comes into play!

VirtualPathProviderExample.zip

This simplistic example shows how to implement retrieval of data from a predefined string (ugly long string but that's not the point here). You can use some other backing store (database, ftp or even web service!) to get the content.

Enjoy!

Friday, April 24, 2009

Thursday, April 23, 2009

New NUnit template for ASP.NET MVC

Hi,

I've been doing a little bit research in the area of mocking frameworks for different platforms and picked in total 3 clear winners:

- Java: Mockito
- .Net: NUnit (it's there anyway...) and Moq

Here you'll find the new NUnit test template for ASP.NET MVC that also contains a reference to Moq for convenience. Other than that it's the same template as the previous one. However expect that to change in the near future as I'll be porting the manual mocks in AccountControllerTest to Moq.

ASP.NET-MVC-NUnitAndMoqTemplate.zip


Have fun!

Splitting an ASP.NET MVC application into modules

I've been playing a little bit with the concept of splitting an ASP.NET MVC application into some sort of modules so that the final product can be developed separately and (possibly) reused.

Splitting the code into class libraries is easy - you just reference the class library from your main project and that's it. The tricky part is to get the pages into the main project in some usable way.

To solve this riddle I've first created an example ASP.NET MVC application and a class library in the same solution. The class library has been given the following dependencies:

- System.Web.Abstractions
- System.Web.Mvc

and by doing so I was able to effectively create controllers in my class library.

As for the pages I've created a folder called Views in the same way it's done in a regular ASP.NET MVC application but this time in the class library itself. The content of this folder is pretty much the same as with the regular application (\Views\controllername\viewname.aspx).
To get the pages copied to the main project I've used the AfterBuild target as follows:

<Target Name="AfterBuild">
<Exec Command="xcopy /Y /E /R /I Views ..\MVCPluginExample\Plugins\Views" />
</Target>

Hint: to get IntelliSense to work I needed to copy the Web.config from main project to the root of the class library. It works like a charm!

Furthermore I didn't want the "plugin" (so to speak) to be directly referenced from the main project (so that I can really plug'n'run additional parts of the application as needed). To achieve that I've created additional Exec tasks in the AfterBuild target:

<Target Name="AfterBuild">
<Exec Command="xcopy /Y /I /R $(OutputPath)$(AssemblyName).dll ..\MVCPluginExample\bin" />
<Exec Command="xcopy /Y /I /R $(OutputPath)$(AssemblyName).pdb ..\MVCPluginExample\bin" />
<Exec Command="xcopy /Y /E /R /I Views ..\MVCPluginExample\Plugins\Views" />
</Target>

With that at hand I'm able to debug the code in the class library because of the presence of .pdb file and all my views are nicely packaged in separate plugin projects.

But that's not all. To be able to use the views from controllers contained in the library (and to have them in a separate location so that I can easily clean up the main project) I was forced to use constructs as follows:

public ActionResult Index() {
return View("~/Plugins/Views/Home/Index.aspx");
}

Naturally it's a mess and one should never need to specify the full path to the view. It just doesn't make any sense.

It turns out that the list of locations where the MVC engine looks for views is stored in three fields: MasterLocationFormats, ViewLocationFormats and PartialViewLocationFormats (as per WebFormViewEngine.cs lines 23, 28 and 35). Since all we want to do is to instruct the engine to look for views in one more location (~/Plugins/Views/...) all we have to do is to inherit from WebFormViewEngine class and create a constructor that will provide this information. Here's the piece of code that does just that:

public class PluginAwareWebFormViewEngine : WebFormViewEngine {
public PluginAwareWebFormViewEngine() : base() {
ViewLocationFormats = new[] {
"~/Plugins/Views/{1}/{0}.aspx",
"~/Plugins/Views/{1}/{0}.ascx",
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx",
"~/Views/Shared/{0}.ascx"
};

PartialViewLocationFormats = ViewLocationFormats;
}
}

Now we can finally get back to providing view names instead of file names in the controller action methods:

public ActionResult Index() {
return View("Index");
}

or even

public ActionResult Index() {
return View();
}

To register this new ViewEngine add the following line to Application_Start event handler in Global.asax.cs

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new PluginAwareWebFormViewEngine());

What this does is it makes sure that there's only one view engine that is in fact modified by us.

Here you can download the complete solution.

mvc-plugin-example.zip


Have fun!

Saturday, April 18, 2009

Visual Studio Web Developer Server and PHP

Today I've been looking for a solution that would allow me to serve PHP pages from my web application. Unfortunately it turns out there's no default handler for CGI applications. However Ziya Suzen has already created an IHttpHandler that does the job.

Remember: all the credits for this solution go to Ziya Suzen


PHP-Example.zip

Here you can find a complete solution that does just that: when executed from within Visual Web Developer it shows a list of files in a browser and when you select index.php you'll get a nice text "Hello, world!" that's being generated by PHP.

A few notes about the modifications I've made:

1. The php-cgi.exe executable has a fixed path build in. It's X:\programs\php\php-cgi.exe.
2. For some (yet) unknown reason the PHP script processor complains when the REQUEST_METHOD variable is set so I've commented it out.

Have fun!

PHP on MS platform???

Hi,

it looks like that MS is hitting at the PHP web page developers out there by providing a unified installer for PHP and PHP-based applications in their web-platform installer. Check it out here

Enjoy!

Friday, April 17, 2009

DynamicData cleanup

Last time I've described a way of merging the DynamicData capability with an ASP.NET MVC application. This time I'll show you how to make the DynamicData part be stored in the right place.

First of all it's kind of awkward to have the Site.css, Site.master and the rest in the root folder. Let's face it: this sucks! It'd be nice if we could have those DynamicData-related stuff inside the DynamicData folder where they could live happily ever after.

It's not impossible but there are two small glitches that you need to be aware of. But first things first.

Step 1. Grab the Site.css, Site.master in solution explorer and drag them to the DynamicData folder.

Step 2. Open the DynamicData\Site.master file and change the

<img alt="Back to home page" runat="server" src="DynamicData/Content/Images/back.gif" />

with

<img alt="Back to home page" runat="server" src="~/DynamicData/Content/Images/back.gif" />

Node the Tilda addition in the image src attribute!

Step 3: Change the master page for pages. In the folder DynamicData\PageTemplates you'll find templates for all the generated pages. Open them one by one (there are 5 of them: Details.aspx, Edit.aspx, Insert.aspx, List.aspx and ListDetails.aspx) and change the MasterPageFile attribute from

MasterPageFile="~/Site.master"

to

MasterPageFile="~/DynamicData/Site.master"

That's it! There's nothing more to it. From now on your application structure is cleaner and there's noting polluting the clear ways of the ASP.NET MVC project!


Have fun!

Adding DynamicData to an ASP.NET MVC application

In my previous post I've pointed you to a place that contains a ready-to-use solution on how to use DynamicData with ASP.NET MVC. In this post I'll describe the manual way of doing that so that you can see that there's no mystery hiding behind the scenes.

I'm going to assume that you have an up-and-running project created using ASP.NET MVC Application template.

Step 1: Create a separate DynamicData project. Call it whatever you want - we're going to need a few files from that project.

Step 2: Copy the following files from the DynamicData project right into the MVC application and include them in the MVC project:

  • /Site.css

  • /Site.master

  • /Site.master.cs

  • /Site.master.designer.cs

  • /DynamicData (the whole folder!)


Step 3: We need to register the DynamicData engine in our application. To do that copy the following lines from the Web.config file in DynamicData project into the Web.config file in ASP.NET MVC project:

  • from \\configuration\system.web\compilation\assemblies
    <add assembly="System.Web.DynamicData, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

  • from \\configuration\system.web\pages\controls
    <add tagPrefix="asp" namespace="System.Web.DynamicData" assembly="System.Web.DynamicData, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

Step 4: Add a reference to System.Web.DynamicData to the MVC project.

Step 5: Register routes in Global.asax.cs. Depending on the context you'll have to adjust the context registration. Here I'm using the Northwind data context:

MetaModel model = new MetaModel();
model.RegisterContext(
typeof(MvcApplication1.Models.NorthwindDataContext),
new ContextConfiguration() {
ScaffoldAllTables = true
});
routes.Add(
new DynamicDataRoute("DD/{table}/{action}.aspx") {
Constraints = new RouteValueDictionary(
new { action = "List|Details|Edit|Insert" }),
Model = model
});

Make sure you add the proper using statement to System.Web.DynamicData and your models!

Step 6: Add a listing of all the tables to your Views/Home/Index.aspx:

<% foreach (MetaTable table in MetaModel.Default.Tables) { %>
<li>
<a href="<% =table.GetActionPath("List") %>">
<% =table.DisplayName %>
</a>
</li>
<% } %>


Done!

Run your application. On the initial page you should see a clickable list of all the tables from your database.

Enjoy!

DynamicData with ASP.NET MVC

Recently while browsing the web for interesting resources I've stumbled upon a blog entry talking about DynamicData. Since I've had no idea what that was I've dug a little bit into it and found out that it poses a fantastic opportunity to complement an otherwise complete site with a nice browser/editor for the whole database.

Since it was all nice and dandy I've dug a little bit more trying to integrate this technology with the ASP.NET MVC framework. And as it turns out there's a great example here that provides an end-to-end solution.

Since I've had some trouble running this example out-of-the-box I though I'd share what I've done to make it work:

1. Open the ~/Views/Shared/Site.Master
2. Add the following line right after the page declaration:

<%@ Import Namespace="System.Web.Mvc.Html" %>


That's it! Just hit F5 and observe the beauty of the DynamicData integrated with ASP.NET MVC :D

Have fun!

Linking resources in ASP.NET MVC

Working on web sites that have dynamic URLs (like the ones in ASP.NET MVC or JSF) poses one difficulty: you never know where to look for resources such as images or CSS files. This is due to the fact that the same view can have more than one address. Let me give you an example:

/Demo/ -> this should render the default controller (HomeController) with the default view (Index.aspx).
/Demo/Home -> this should render the specified controller (again HomeController) with the default view (Index.aspx)
/Demo/Home/Index -> this should render the specified controller (again HomeController) with the specified view (Index.aspx)

So how do you go about specifying an URL for resources in this case? Well there are different ways to do that.

1. You could create and use an Html helper method to do that.
2. You could hard-code the absolute paths (like /Demo/Content/Index.css for example)
3. You could make use of the runat attribute and use relative paths.

I personally dislike the first and second options. They tend to introduce mess to my otherwise clear code. The third option is in my opinion the best one.
Here's an example of how you'd create a link to a CSS:


<link type="text/css" href="~/Content/Site.css" runat="server" />


Happy coding!

Wednesday, April 15, 2009

NUnit template for ASP.NET MVC

Hi there,

I've been struggling a bit with the automatic addition of NUnit unit tests to ASP.NET MVC project in Visual Web Developer. I wanted to have it the same way it works with the VisualStudio unit test framework that is being shown over and over again on the net.

So here's the complete solution: just unzip it, run install.bat and enjoy!

ASP.NET-MVC-NUnitTemplate.zip

Additionally to the standard files you'd expect to be in place there's a NUnit project file called UnitTests.nunit. It's already configured and ready to go. To open it with the NUnit test runner do a right click on it, select "Open with...", add a new program by using the "Add" button, select the nunit.exe file, click ok, highlight NUnit in the list, click "Set as Default" and click OK. From now on everytime you double-click on it you'll run the NUnit GUI test runner which is pretty much what you'd expect.

Padcom.

Sunday, March 8, 2009

Running JSP/Servlets under .NET in C#

Hi there,

Recently I've been amazed by the things you can accomplish by using the IKVM library. I took me quite a while to realize the actual potential that hides behind this kind of integration that IKVM provides (which is kind of stupid as I'm working in both technologies, just not at the same time).

Let's get to the point!

Here's a line that will compile jetty (tried with version 6.1.11) into a .NET assembly with everything required to start writing and hosting JSP and servlets:

ikvmc -target:library jetty-6.1.11.jar jetty-util-6.1.11.jar servlet-api-2.5-6.1.11.jar jsp-2.1\core-3.1.1.jar jsp-2.1\ant-1.6.5.jar jsp-2.1\jsp-2.1.jar jsp-2.1\jsp-api-2.1.jar

That produces a .NET assembly called jetty-6.1.11.dll which you should include along with IKVM.OpenJDK.ClassLibrary.dll and IKVM.Runtime.dll to make it work.

And now for the fun stuff! Here's a code snippet (actually it's a complete application) that starts up jetty, creates 2 contexts (one for the servlet under /servlet and one for the example web application in JSP under /jsp) and starts the server:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using java.io;
using java.lang;
using javax.servlet.http;
using org.mortbay.jetty;
using org.mortbay.jetty.servlet;
using org.mortbay.jetty.webapp;

namespace JettyServletAndJSPExample {
class Program {
static void Main(string[] args) {
Server server = new Server(8080);

// see: http://localhost:8080/servlet/whatever
Context servletContext = new Context(server, "/servlet", Context.SESSIONS);
servletContext.addServlet(new ServletHolder(new TestServlet()), "/*");

// see: http://localhost:8080/jsp/hello.jsp
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/jsp");
webapp.setWar("../../webapps/test");
webapp.setDefaultsDescriptor("../../etc/webdefault.xml");
server.addHandler(webapp);

server.start();
}
}

class TestServlet : HttpServlet {
protected override void doGet(HttpServletRequest req, HttpServletResponse resp) {
resp.setContentType("text/html");
PrintWriter o = resp.getWriter();
o.println("<h1>hello, world!</h1>");
o.close();
}
}
}


After that you have a full fledged, java-like (very much alike) server that can hosts servlets written in C# for .NET platform and at the same time to host applications written in pure JSP.

The obvious next step will be to extract the rendering engine alone to be used with ASP.NET MVC framework thus enriching the seamless integration between Java and the .NET world.

If you're lazy enough you can download the whole package here and start exploring it immediately.

Have fun!

Tuesday, January 13, 2009

Spring - a "brief" introduction

Hi there,

I was looking for a "getting started", "hello-world" or something of that sort for Spring. Imagine my surprise when I found this:

SPR-101: Getting Started With Spring Training
Submitted by class editor on Mon, 12/22/2008 - 16:16.

Getting Started With Spring is a two-day training course focused toward experienced Java and JEE developers who need a brief, yet comprehensive, course to get them “up and running “ and writing Spring-powered applications in as little time as possible.


OMG! 2 days of study needed just to get me started on one library?! WTF!!!