Thursday, December 17, 2009

Thoughts on Google Wave

Lately I received an invitation to Google Wave from a colleague at the otto group (btw, thanks for that, David).

First I thought, that Wave is another way of spending my precious time. Some people say, that Google just tries to revolutionize the communication tool market with its Google Wave application and are curios if that will work given the set of existing communication tools with their broad feature set. Beside that some point out that the feature of adding arbitrary content at any location within a wave could discourage non-digital natives from using the new technology.

I fully agree that Google tries again to revolutionize a market, but I disagree with the implicated estimation that Google just adds another communication tool. Although Wave is still in beta mode, it is already visible what the driving force behind the scene is. Google does not provide us with another isolated publishing pipe like Twitter or alike but enhances our way of information exchange by combining different communication channels into an integrated application.

From my point of view, one of the main problems with today's communication tools is the fact that some of them are very famous but none of them really maps the real life way of conversation into the digital world. That again leaves us with sometimes fragmented conversations that are unnecessarily protracted because the exchanged textual informations (for the case of an email) do not fully explain the intentions of the participants. In real life we tend to support such situations with additional material from different sources, eg. maps or photos, to clarify our statements.

Google actually tries to solve what I expressed in my last statement: support a conversation with information from a variety of sources. Make no mistake about the hype Google created around Wave, the application is still under development and has more the feeling of a very active research project than an enterprise enabled communication tool. But if you strip down the initial character of its current state (by 17/12/2009) you must realize that Google heralds a new era of compelling messaging experience as for example Mozilla also tries do achieve with its Raindrop project.

Finally neither the Google nor the Mozilla approach will help us today to avoid the face-off with situations like Frank Schirrmacher wrote about: he complained that his head cannot follow the constant flow of information anymore (see www.spiegel.de, german only). But on the other hand they help us to steer into the right direction. A very tiny but important step is the traceability of a Waves conversation history which does not only help the non-digital natives to find out when a certain piece of information was inserted into a conversation and by whom.

Tuesday, December 1, 2009

Hourglass display with Richfaces

Hourglass display with Richfaces

Yesterday we started with a preliminary application test to be prepared for the final integration test next month.
Since the web based application works on large datasets which could sometimes lead to extended response times at
frontend level, one of the first things the users asked for, were a hourglass or something alike to show that the
server is still processing the request.

Since the application is based on Richfaces I searched for any feature that could help me and discovered the status tag.

The first thing I wanted to try out, was to display a message simply informing the user that the current request is still in processing mode. In order to do so, only two things needs to be done:


  • Define the message display behaviour using the status tag

  • Bind the status handler to a control that sends an ajax request to the backend



<a4j:status id="testStatus" startText="Request processing started" stopText="Request processing ended"/>
<a4j:commandButton action=".." value=".." status="testStatus"/>


The next time the user clicks on the command button a message will appear and inform him about the processing state.

Well, that kind of behaviour gives your users a slight hint on what the system is currently doing, but hey, an overlay graphic displaying a hourglass or alike is much cooler, isn't it. Therefore I continued to search for an appropriate solution to that
problem and finally found one written by Markus Kühle (in german only). Compared to my little example above, the main concept does not change. A status handler is defined as well as the binding with the command button. In order to create an overlay message, we need to work with cascade style sheets:


* html body { margin: 0; overflow-y: hidden; padding: 0; }

#globalStatusDiv {
position: relative;
left: 50%;
top: 200px;
width: 100px;

text-align: center;
margin-left: -50px;
height: 25px;
line-height: 25px;
background-color: #FFF;
padding: 2px 15px 2px 10px;
color: #000;
font-family: Verdana,Arial,Helvetica,sans-serif;
font-size: 14px;
font-weight: bold;
z-index: 10000;
}

#globalStatusDiv img {
vertical-align: middle;
}


Next, we must define a div which contains the information to be displayed and bind it to a status tag:


<link href="/css/status.css" rel="stylesheet" />
<div id="globalStatusDiv" style="display:none;">
<img src="/images/working.gif"/> %<h:outputText value="#{generalMsg.general_loading_message}"/>
</div>
<a4j:status id="globalWaitStatus" forceId="true" layout="none"
onstart="jQuery('#globalStatusDiv').fadeIn('fast')"
onstop="jQuery('#globalStatusDiv').fadeOut('slow')" />


The binding with a command button does not differ from the simple example above:


<a4j:commandButton action=".." value=".." status="globalWaitStatus"/>

Wednesday, October 7, 2009

How to convince people of good ideas

Although I originally planned / promised to write about caching strategies and method interception in spring
applications, I decided to insert a different topic that concerns me since I gave a presentation the other day.
The main goal of that event was to show the current implementation state to the upcoming users.

The initiator of that project defined the platform in a very broad manner and with a scope that overlapped
more than one company. In doing so an integrated management process could be achieved for handling user/object
associations which would unify existing concepts that are alike for all expected participators - that implicates
that all of them currently hold and maintain individual applications for handling their own isolated process.
It's needless to mention that the unification of theses processes would lead to an economization even for
future applications. This affects the support for such a process as well as the application administration and maintenance.

Up to here the idea sounds very promising and reasonable. That's maybe why we were commissioned to implement
that piece of software. Unfortunately the project was altered within the scope of the number of participants and
thus in its importance. By reducing the scope to currently one / two partners, the whole idea was definitely
crippled. Although it's crucial to mention that the implication of such a project is the requirement for an even
bigger project that has the goal of unifying the required meta data and management concepts. On the other hand
even that project would lead to a unified concept on a more abstract level.

The question I ask myself now, is how to convince the people in charge of broadening the scope to the one formerly
defined and turn the project into an overall success? I appreciate all comments on that issue.

Tuesday, September 15, 2009

Why more software developers should write blogs

It's been a while since I wrote my last blog post and with a view to Dustin Marx comment on software developers that should write blogs, I feel to be caught red-handed.

To improve myself, I noted two topics, I would like to talk about in the upcoming posts:


      caching strategies in web applications

      method interception in spring

Sunday, September 6, 2009

Apple sauce

Today I got up and looked out of my living room window and saw that the nightly wind has torn off a large amount of apples from the tree in our garden. Since I really like to eat apple sauce as side dish, I decided to pick up some of the fruits and cook them. I found a rather simple recipe although it does not avoid the work to peel the apples:

* peel the apples and remove all decayed pieces
* cut the remaining parts into small pieces
* put 250g of apples and 6 table spoon of water into a small box that can be placed in a microwave
* heat the box for 6min in the microwave (800W)
* mash the cooked apples and mix it with sugar as you like it

Acutally I don't know how long it can be stored in the fridge.

Monday, August 31, 2009

Spring Security - Basics

During the last days I had the assignment to secure a spring based application I currently work on. Although I had no experience integration spring security into an application, I decided to use this standard technology rather than writing my own security layer.

The task to accomplish was well-defined:


  • provide a form-based login mechanism

  • authenticate the user against a local database

  • role/group information are not required since they arise from the data that will be processed by the application
  • support the user with complete and meaningful error messages



Unfortunately the documentation which is available for spring security (M3) is not very exhaustive and thus not helpful in order to reach the designated goal quickly. Thus I dug myself through various sources including forum posts, javadocs, documentation of earlier spring security versions and sourcecode. Finally I had a set of information which helped me to assemble a login module for my application.

Basic configuration


<b:beans xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd>

<security:http entry-point-ref="customAuthenticationEntryPoint"
session-fixation-protection="newSession" access-denied-page="/index.jsp">
<security:logout logout-success-url="/index.jsp" invalidate-session="true"/>
<security:anonymous username="guest" granted-authority="ROLE_ANONYMOUS"/>
<security:intercept-url pattern="/dialogs/**" access="ROLE_USER"/>
<security:intercept-url pattern="/index.jsp" access="ROLE_ANONYMOUS"/>
</security:http>


<authentication-manager alias="authenticationManager"/>

<b:bean id="customAuthenticationManager" class="CustomAuthenticationManager">
<b:property name="userService" ref="userService"/>
<b:property name="passwordEncryptionAlgorithm" value="SHA"/>
<b:property name="baseRoleName" value="ROLE_USER"/>
</b:bean>

<b:bean id="customizedUrlAuthenticationFailureHandler" class="CustomAuthenticationFailureHandler">
<b:property name="defaultFailureUrl" value="/index.jsp"/>
</b:bean>

<b:bean id="customizedFormLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter" >
<security:custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>
<b:property name="authenticationManager" ref="customAuthenticationManager"/>
<b:property name="allowSessionCreation" value="true"/>
<b:property name="authenticationFailureHandler" ref="customizedUrlAuthenticationFailureHandler"/>
</b:bean>

<b:bean id="customAuthenticationEntryPoint" class="CustomAuthenticationEntryPoint">
<b:property name="loginFormUrl" value="/index.jsp"/>
</b:bean>


</b:beans>


security:http

The first block configures the security layer as such. It defines the entry point into the layer (customAuthenticationEntryPoint) where all requests will be redirected to, the urls to secure (intercept-url) and the logout behavior (logout-success-url).

customAuthenticationManager

The customAuthenticationManager bean implements the core authentication behavior. Incoming requests that belong to an user session which has not passed the security layer before are handled by this bean. It overrides the authenticate method and performs the necessary principal and credentials checks.

customizedUrlAuthenticationFailureHandler

The customizedUrlAuthenticationFailureHandler defines the steps to carry out in case the authentication fails. In this case I created a new one next to the standard implementation since I had the requirement to implement a special error handling.

customizedFormLoginFilter

The customizedFormLoginFilter defines that the application uses the basic username / password scheme to authenticate new users. Spring security also provides implementations for open id authentication or CAS.

customAuthenticationEntryPoint

The customAuthenticationEntryPoint defines the class that provides the implementation of the authentication entry point of the security layer. All incoming requests will be directed into this class. I use the commence method to remove all previous error messages.

As you can see, the configuration (and implementation) of a custom spring security login filter is straight forward. Since I did not want to overflow the blog with source code, I omitted it. If you are interested in it, feel free to contact me.

Friday, August 21, 2009

FileUpload with Richfaces

The other day I had an assignment to write a CSV upload and download interface for a JSF (Richfaces) based web application. On first sight, that isn't a really tricky task since it was realised many times before by a lot of people - including me. Therefore I was quite confident to implement that feature quite quickly ... until it came to the point where I tried out what I implemented. Unfortunately, the file was not uploaded although my code wrote the correct filename to the log output. This is my sourcecode:

public void uploadListener(final UploadEvent uploadEvent) {
UploadItem uploadItem = uploadEvent.getUploadItem();
String fileName = uploadItem.getFileName();
String csvFile = new String(uploadItem.getData());
...
}

The method signature follows the requirements set by richfaces in order for a method to receive incoming upload events. Usually the upload item variable should contain all required information, especially the required file data.

The reason why the upload item is not filled as expected, is the AJAX filter option createTempFile which is set to true by default. Under these circumstances the uploaded file data will not be made available to the upload item variable, but is written into a temporary file on disk. To change this behavior, its necessary to switch the config option of org.ajax4jsf.Filter to true in the web.xml.


Initial Commit

Hello everybody and welcome to my new blog. I guess most people starting a blog have thoroughly planned the topics they want to write about. Actually I did the same, but writing an inital post to introduce the blog and its author is much harder than expected. I could write a long essay about me, my work and how I made the decision to start this blog - probably most people would be bored beyond belief. Therefore I omit that and give you a quick summary about me and the topics you can expect from the upcoming posts.

Who am I?
My name is Christian Kreutzfeldt and I work as a software engineer in Hamburg / Germany. Mainly I deal with a lot of topics that are associated with the development of enterprise software written in JAVA. Actually I work on a project that deals with the definition and implementation of a role and permission management.

What can you expect?
As you can read in the nice textare that covers my face in the page header, I stumble upon a lot of interesting topics during my day-by-day work. I plan to use this blog as a kind of reference book for myself as well as an information assembly for others. Most topics that I will cover will be associated with J2EE in the one or another way.