Small reminder for my readers
If you want to comment on my articles, please do so. However, all comments need to be approved by me, so please adhere to the following rules:
- Use a valid email address
- No profanity or name calling ("YOU SUCK!!!" falls under that category)
- No spamming
If you follow these rules, I'll approve even the most disagreeing comments (please read this if you want to disagree in style: DH levels).
Stepping away from MySQL
MySQL is a dead product walking. I know it, people around me are starting to realize it and Monty sure as hell knows it. For those not familiar with MySQL's roots, Monty Widenius is one of the founder of MySQL.
Recently, Monty has staged an all-out attack on the Sun-Oracle merger, due to the promises that Oracle made towards the MySQL product that apparently it has no intention to keep.
Luckily, we (MySQL users) have a great alternative: MariaDB. MariaDB is a fully compatible MySQL fork, once again backed by Monty. And it has all the features MySQL has and then some. Better multicore support, better performance, more storage engines, ... If you're planning on using MySQL for any project, consider using MariaDB instead. For the Ubuntu users out there, there are APT repositories available for MariaDB, and they are updated frequently.
Now if only Monty was able to rebuild the client libraries for MySQL to remove that pesky GPL license...
Code Kata: BBCode
Here's a nice code kata: convert BBCode to HTML. So [b]test[/b] becomes <strong>test</strong>, etc... Provide tags for all the basic BBCode tags: i, u, b, img, url, li, ol, ul and newlines.
For you cheaters, here's my implementation, using regex:
import org.springframework.web.util.HtmlUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BBCodeConverter {
public static String convertString(String bbCodeString)
{
bbCodeString = HtmlUtils.htmlEscape(bbCodeString);
for(BBCodeTag tag : BBCodeTag.values())
{
bbCodeString = tag.convert(bbCodeString);
}
return bbCodeString;
}
private enum BBCodeTag
{
B("\\[b\\](.*?)\\[/b\\]", "<strong>$1</strong>"),
I("\\[i\\](.*?)\\[/i\\]", "<em>$1</em>"),
U("\\[u\\](.*?)\\[/u\\]", "<span style=\"text-decoration:underline\">$1</span>"),
NEWLINE("\n", "<br/>"),
IMG("\\[img\\](.*?)\\[/img\\]", "<img src=\"$1\"></img>"),
URL("\\[url=(.*?)\\](.*?)\\[/url\\]", "<a href=\"$1\">$2</a>"),
UL("\\[ul\\](.*?)\\[/ul\\]","<ul>$1</ul>"),
OL("\\[ol\\](.*?)\\[/ol\\]","<ol>$1</ol>"),
LI("\\[li\\](.*?)\\[/li\\]","<li>$1</li>"),
SIZE("\\[size=(.*?)\\](.*?)\\[/size\\]","<span style=\"font-size:$1%\">$2</span>"),
COLOR("\\[color=(.*?)\\](.*?)\\[/color\\]","<span style=\"color:$1\">$2</span>")
;
private String tagPattern;
private String htmlConversion;
private BBCodeTag(String tagPattern, String htmlConversion) {
this.htmlConversion = htmlConversion;
this.tagPattern = tagPattern;
}
public String convert(String bbCodeTag)
{
Pattern pattern = Pattern.compile(tagPattern);
Matcher matcher = pattern.matcher(bbCodeTag);
String replaced = matcher.replaceAll(htmlConversion);
return replaced;
}
}
}
Compiling JasperReports with Maven
For those working with JasperReports, this is the plugin config you can use to compile jrxml files:
...
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>target/generated-jasper</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jasperreports-maven-plugin</artifactId>
<version>1.0-beta-2</version>
<executions>
<execution>
<goals>
<goal>compile-reports</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.directory}/generated-jasper</outputDirectory>
</configuration>
<dependencies>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>3.7.2</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
...
If you're using groovy as a template language in your JasperReport reports, don't forget to add the groovy-all 1.5.5 dependency to your plugin and add this to your plugin configuration:
<compiler>net.sf.jasperreports.compilers.JRGroovyCompiler</compiler>
Have fun reporting!
Software companies are modelled like armies… but are missing a thing
When you think of it, a large software company can easily be compared to an army. Let's see if we can cover the ranks.
Infantry soldiers
This one is easy. These are the mainstream software developers. Like soldiers, some have specialities, other are just plain cannon fodder. As in the army, they can move up the ladder.
Lieutenants
These are your senior developers. They have experience, or have had more schooling which enables them to enter the company higher on the ladder. They should be able to cope with responsibility and make decisions that affect the performance of those they manage.
Senior officers
Like any organisational structure, the higher one goes up the ladder, the fewer in numbers. These senior officers are the management within the company. You'll find majors (unit managers), colonels (divisions manangers) up to generals (CEO's) and any rank in between. These are the guys that should be able to make the hard decisions. It's impossible to enter the army with these ranks without experience, just like a company. You won't start your career as a CEO (unless you start your own small firm, but then this article doesn't really apply anymore).
Intelligence
In the army, intelligence can mean the difference between success and failure. In software companies, intelligence can be seen as the analysts. They build the blueprints that ultimately will decide if a project will succeed or not. As with intelligence, most of the work is done up front. Once the operation (project) begins, their main objective is to provide steering and updates to the situation at hand.
Engineers
In the army, the engineers pave the way and provide logistical support to the army. In a software company, these are your system administrators. They make sure the hardware keeps running and provide logistical support where and if needed.
I think that covers about all the positions within a company. However, software companies are lacking something crucial. The US Army has the 75th Ranger Regiment, the US Navy has the SEALs. We need something like that.
Rangers and SEALs are the elite. They are deployed when all other options have been depleted and the situation demands for a quick and professional intervention. When they go in, they get the job done.
In my opinion, every large software company needs one of more elite teams, depending on the size. The decision to deploy these elites should not be taken lightly: it's expensive. As it should be. These are experts in their field and are a force to be reckoned with. When they make a decision, there shouldn't be any second guessing (client or company). You'll be giving these guys carte blache to reach the objective. In other words: you shouldn't use these guys for putting out a small brushfire. No, you deploy these guys when the whole forest is on fire. You'll be counting on them to put the fire out, utilising all and any resources they have (including all of the above ranks). Like the army elites, you won't be using these guys when there's no crisis. Like, say, transferring them to an active unit because otherwise they're just costing the company money (that said, given a large enough software company, they'll be occupied just about always). No. You make these guys train. Hard. You make sure they keep being the best of the best. You do regular checks to weed out those who shouldn't be in the elite corps anymore and make it very clear among the members of that team that they shouldn't take their place for granted. Even worse, you make dismissal a very public affair within the company. You make sure they are instantly deployable, anytime, anywhere. When the job is under control, you bring them back and let the main army handle the rest. You don't keep these guys around for the fun of it. At most, you'll leave a couple of elites behind a bit longer so they can make sure a second intervention won't needed.
The client also be aware of the capabilities of such a unit. It's very tempting for a client to always demand the use of such a unit once he knows it exists. After all, all the clients want the best team to get the job done. However, and this should be made very clear, the use of the elites should be at the discretion of the company, not the client. Their job is to defuse a situaton.
Why don't companies do this? It costs a lot of money and most think they don't need such a team since all their developers are elites. I would say 'keep dreaming'. Any software company large enough needs teams like this. But maintaining these teams is expensive and hard. You'll be paying for a lot of training, not to mention the wages. You'll have to be at the top of your game to retain these guys and keep them happy.
All in all, I think it's a nice idea I would love to see being used in real-life. If you work in a company that has such a team, feel free to share your experiences.
Doing RPC with REST
RPC doesn't really rhyme with REST. REST revolves around the concept of resources, and the basic methods offered by the HTTP protocol (being GET, PUT, POST, DELETE and some others). Now, sometimes you're confronted with something outside the scope of those methods. Say, for example, you want to be able to send a client's data to the ERP system by simply doing 1 REST call.
Option 1 is to create an URL template like this: http://host/client/{id}/sendToERP. But that isn't REST. sendToERP isn't a resource, it's an action. So that one's gone.
Option 2 is to create an URL template like this: http://host/client/{id}?action=sendToERP. Better, but to which HTTP method will you bind this. Is it a GET? A PUT? Not really sure. You're not really altering the client, but you're not asking for the data either...
So that brings us to option 3: the command pattern. Assume we have a URL template like this: http://host/client/{id}/command. Doing a get on this will return all the possible commands for that client. In our case this might be:
<commands>
<command id="1">
<type>sendToERP</type>
</command>
<command id="2">
<type>updateFromERP</type>
</command>
</commands>
So now we can do this to execute the sendToERP command: GET http://host/client/{id}/command/1. What does this return? Well, it can for example return the result of the command, like this:
<commandResult>
<result>
OK
</result>
</commandResult>
Code snippet: replacing java.util.Logger by SLF4J
This simple piece of code adapts all JUL statement to be forwarded to SLF4J:
java.util.logging.Logger rootLogger = LogManager.getLogManager().getLogger("");
Handler[] handlers = rootLogger.getHandlers();
for (Handler handler : handlers) {
rootLogger.removeHandler(handler);
}
SLF4JBridgeHandler.install();
The first 5 lines are needed because otherwise JUL will still log to System.err.