Just a little bit of space to record experiences, thoughts, anedcdotes, or even plain and simple rants about stuff. Just pieces of information on my own learning journeys.
28 October 2008
Random Thought On The Internet
I was on a work trip. One of those where you get to travel to exotic destinations but all you get to see is the office, the company cafeteria and the hotel. I was having dinner at the hotel and I started thinking of how come people have this strange need to aggregate in some area. How did people start living with other people, and how did they manage to eventually take this concept to such gigantic proportions as to create today's biggest cities, with millions and millions of individuals living close to each other.
The first reason I thought of was procreation and the continuation of the species: a certain gene pool needs a minimum degree of diversity in order to avoid extinction. Did humans in the upper palaeolithic or in the mesolithic really think along those lines? Probably not. So here I am, I'm not very good at running, hiding, or throwing spears. I can't hunt for food, but I'm good at growing legumes. If I find someone who's good at hunting, maybe we can trade food. Now, wouldn't it be easier if the two of us lived relatively close to each other instead of a half-day walking distance? I haven't studied anthropology, archaeology or any related branches, but that kind of makes sense to me.
Without going that far back in time, just think that a hundred years ago a grain of black pepper needed to travel for months to reach Europe, from south west India to Italy, but people could still find black papper in grocery shops, because they lived in human settlements where specialisation of roles could support a complex social infrastructure: different people can do different things and provide different needs, but they need to be in relatively close proximity in order to maximise their reciprocal advantage.
In physics, this is equivalent to a system trying to find its equilibrium by minimising its energy. An electron in an excited atom "prefers" to drop to a lower energy level if that level is not already full. This is what the electron thinks: what's the point in doing so much work just to keep running like mad in a "higher orbit", when I could just cruise casually around a "lower orbit"? So the electron "drops down" an energy level and sheds the excess energy in a flash of light. And no, I haven't studied much physics either, but that kind of makes sense to me.
Extrapolating the principle of minimising a system's energy, here's what a human might think instead: what's the point in spending half a day travelling to buy some food, load up enough food to last me a while (because it's not like I'll do this again tomorrow, or the day after), then carry all that food back home and manage its storage, when I could just move downtown and simply pop down to the corner shop whenever I need to?
The real achievement in moving downtown, in really fancy terms, is not that I have found a low-energy equilibrium. My half-day walk has become a two-minute stroll. The 20 kilometers between the shop and my house have become less than 100 metres. By moving downtown I have effectively compressed space and time.
Today, as a human living in the remote countryside, I don't actually need to move at all, but I can still compress space and time. How? With Internet, of course. I don't need to live in relatively close proximity to other humans and human structures: I need to move to wherever there is an Internet connection and a postal service, and these might well exist in the remote countryside as well as downtown. So will internet reverse the process of urbanisation, or at least will it make such reversal possible? I think so. Virtual offices, internet videoconferencing, voice-over-IP, news streaming, bla bla bla... it's all there already. The recent hype of "going green" even encourages to great extents to stay where you are, avoid travelling, avoid lighting up an entire office or unnecessarily loading the public transport system if you can work from home. The fascination for "going downtown", perhaps, will eventually be confined only to touristic attractions. I'm not saying people will have no more reasons for sticking together in organised physical conglomerates: I'm just saying, IMHO, that there will be a lot less of a motivation to do so in the future.
M.
23 October 2008
Expressions in IceFaces Navigation Targets
I've been working on an exception handling mechanism for a JSF-based application using IceFaces, and I was thinking... "why oh why can't we dynamically navigate to error pages using a navigation rule?"
Navigation rules in the faces-config.xml look like this:
<navigation-rule>That is fine but very limiting for my navigation purposes. What if I want to navigate to a different page according to the actual error code? In other words, I want to be able to do this:
<from-view-id>/somePage.xhtml</from-view-id>
<navigation-case>
<from-outcome>error</from-outcome>
<to-view-id>/errorPage.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>Well, it seems that I can't do that with the Sun JSF RI or IceFaces, so I decided to make it happen. I figured that if I wanted to add expression evaluation in a navigation target URL I needed to write a view handler. With IceFaces, the application view handler is com.icesoft.faces.facelets.D2DFaceletViewHandler, which is reponsible for setting up the direct-to-DOM rendering etc, so I needed to extend that class and find what methods I needed to override in order to get me to where I wanted to be. After a bit of experimentation I found there are two scenarios:
<from-view-id>/somePage.xhtml</from-view-id>
<navigation-case>
<from-outcome>error</from-outcome>
<to-view-id>/#{errorBean.errorCode}.xhtml</to-view-id>
</navigation-case> </navigation-rule>
Scenario #1: Navigation Rule With Redirection
This is where the navigation rule has a <redirect/> tag. The method in D2DFaceletViewHandler that handles this is
public String getActionURL(FacesContext context, String viewId)Scenario #2: Navigation Rule Without Redirection
This is where the navigation rule does not have a <redirect/> tag. The method in D2DFaceletViewHandler that handles this is
public void renderView(FacesContext context, UIViewRoot viewToRender)The way I decided to process the expression is very simple, almost elementary:
- Parse the URL/ViewId looking for a sub-string that begins with '#{' or '${' and ends with '}'
- capture the sub-string and create a value binding to evaluate the expression
- Replace the expression in the URL/ViewId with the actual value
- Process the newly evaluated URL/ViewId
Before I get any comments on step 1... no, I don't like regex because my brain just doesn't get it, and it takes me considerably longer to figure out a regex pattern to capture such a simple substring than to actually write a few lines of code to do the parsing.
So here's my (edited) code.
/**To use my spanking new view handler I just have to change the application section in the faces-config.xml file:
* Constructor
*/
public MyViewHandler(ViewHandler delegate) {
super(delegate);
}
/**
* Processes a view id that may contain an expression, by evaluating the
* expression and replacing the expression tag in the original view id with
* the expression result.
*
* @param context The faces context.
* @param viewId The view id to process.
* @return The processed view id.
*/
private String processViewId(FacesContext context, String viewId) {
String processedViewId = viewId;
int startExpression = processedViewId.indexOf("{") - 1;
if (startExpression > 0) {
char expChar = processedViewId.charAt(startExpression);
// expressions start with # or $
if ((expChar == '#') || (expChar == '$')) {
int endExpression = processedViewId.indexOf("}", startExpression);
if (endExpression > startExpression) {
// viewId contains an expression
String expression = processedViewId.substring(startExpression, endExpression + 1);
try {
ValueBinding vb = context.getApplication().createValueBinding(expression);
if (vb != null) {
String evaluatedExpression = vb.getValue(context).toString();
// replace the expression tag in the view id
// with the expression's actual value
processedViewId = processedViewId.replace(expression, evaluatedExpression);
}
}
catch (ReferenceSyntaxException ex) {
// do nothing: processedViewId = viewId;
}
}
}
}
return processedViewId;
}
/**
* Used to process a URL that may contain an expression. If a navigation
* rule in the faces configuration file has a <redirect> tag, this
* method will be used to process the URL specified in the
* <to-view-id> tag
*
* @see javax.faces.application.ViewHandler#getActionURL(FacesContext, String)
*/
@Override
public String getActionURL(FacesContext context, String viewId) {
String processedViewId = super.getActionURL(context, viewId);
processedViewId = this.processViewId(context, processedViewId);
return processedViewId;
}
/**
* If a navigation rule in the faces configuration file does not have a
* <redirect> tag, this method will be used to process the URL
* specified in the <to-view-id> tag
*
* @see com.icesoft.faces.application.D2DViewHandler#renderView(FacesContext,
* UIViewRoot)
*/
@Override
public void renderView(FacesContext context, UIViewRoot viewToRender)
throws IOException, NullPointerException {
String viewId = this.processViewId(context, viewToRender.getViewId());
viewToRender.setViewId(viewId);
super.renderView(context, viewToRender);
}
<faces-config>M.
<application>
...
...
<view-handler>
<!--
com.icesoft.faces.facelets.D2DFaceletViewHandler
-->
myViewHandler
</view-handler>
</application>
</faces-config>
21 October 2008
Finding Kokkyu
16 October 2008
2309
sorridi |
smile | |
canta |
sing | |
vola |
fly | |
ecco un artista! |
here is an artist! | |
adesso |
and now | |
luceran |
the stars |
20 September 2008
Architectural Agility - Part 1
In the life of a ten year old, this might take the form of climbing a tree for the first time, ascending to seemingly unreachable altitudes with a non-zero probability of following that up with weeks of hospitalisation.
In the life of a programmer, this might be the result of producing thousands of lines of code under deadlines that you never considered even remotely realistic.
Let's face it: the feeling of impending doom is just great.
In the life of an architect, the main perverse sense of doom and destruction originates from the fact that you are supposed to shape the system in your head, then somehow implant that picture in the heads of over 50 developers, and pray that you've been clear enough with your specifications.
The uninitiated might rightfully ask "Why? Just write the darn specs and pass them on: if they're good developers, they'll work them out..." Alternatively, "Ever heard of agile?".
Well, I don't know about the rest of the world, but in my projects I've never managed to do either. Usually, the situation involves very vague or even yet-to-be-discovered requirements, and only one or two agile developers in a team of 50-plus. So how have I managed so far? Well, it's surely a continuous learning for me, and I still discover something new almost on a daily basis, but here are some points that I have picked up along the way and found very valuable.
#1 : Learn how to produce on-the-fly specs
Why? Because on one hand I have this very hazy and almost monochromatic picture of the requirements, on the other hand I have 50 developers expecting fairly detailed specifications of what they are going to produce, and somewhere in the middle I have a bunch of reasons for being unable to cultivate an agile team.
#2 : Learn how to be ALWAYS available for the team
Why? Perhaps it's just me, but on-the-fly specs are NEVER good enough.
#3 : Learn how to monitor progress all the time
This doesn't mean to become a control freak, but rather to understand the dynamics of the project and minimise the risk of producing the wrong thing due to sub-optimal specifications. Why? Because 50 developers, over (officially) 8 working hours in a day, makes 400 hours/day of code writing and testing time. In one week, that's at least 2000 hours, or about one developer/year worth of effort. That means that failing to convey an architectural concept for the system and leaving 50 developers alone for a whole week translates into seriously refactoring one developer/year worth of code, which is not something you usually do in your spare time. It's like steering the proverbial oil tanker: one mistake in plotting the route, and it will take considerable effort trying to get it back on the right track if you don't spot the mistake right away.
#4 : Functional refactoring is inevitable
Why? Well, due to all of the above. However, I tend to view refactoring as falling into one of three categories: architectural, functional, and schematic.
Architectural refactoring is serious: that is what happens when we change parts of the architecture , for example when half way through the project we realise we need a caching framework for our web application.
Functional refactoring is somewhat less serious and could be considered a minor version of architectural refactoring: that happens when we change some of the application's behavior, for example when we move hard-coded values to some configuration file, and surely when we are bugfixing.
Schematic refactoring is standard routine: that is when the application's functionality is unaffected while changing its internal structure, for example when we abstract common functionality from several classes into one parent class, or formalise common class contracts into interfaces. I'm now learning to shape functional refactoring into an agile project in its own right, and probably write some considerations on that in another post.
M.
14 September 2008
The Eternal Beginner
Hi There
I'm starting this blog to share my personal views on different subjects.
In other words, these are my experiences, and these are the ways I've travelled my own path.
It's just a bunch of information that someone might or might not find useful. In the end, if only one person finds any of this stuff useful in any way, then I will have done something good with my time. Enjoy. M.