Wednesday, October 14, 2009

Simplifying work with java collections using static import

Today i read article about google collections my post is simple addition to it. I will describe one tip, that I use for simpify working with java collections.
When you will create HashMap instance with some entries (often it used for unit-tests creation), you will write
in Java:


Map<String, Object> params = new HashMap<String, Object>();
params.put("age", 22L);
params.put("name", "whiter4bbit");
params.put("blog", "http://whiter4bbit.blogspot.com");

in Python :


params = {'age':22, 'name':'whiter4bbit', 'blog':'http://whiter4bbit.blogspot.com'}

Now compare it. What is pretty - yes Python is pretty:)

But in JDK 1.5 was introduced feature, that called 'static import'. You can import static methods from any class, for example:

import static java.lang.System.out;

And you can call out.println directly

This feature will very helpful. I use it to simplify work with java collections. About first example with HashMap, we can make map builder, that can help simplify map's creation:

public class MapUtils {
static class MapBuilder<K,V>{
private Map<K,V> map = new HashMap<K,V>();
public MapBuilder<K,V> $(K key, V value){
map.put(key, value);
return this;
}
public Map<K,V> map(){
return map;
}
}
//yeah, '$' - is allowed in identifiers:)
public static <K,V> MapBuilder $(K key, V value){
MapBuilder<K,V> mapBuilder = new MapBuilder<K,V>();
return mapBuilder.$(key, value);
}
}

Now we can use this class to simplyfy HashMap creation:

import static utils.MapUtils.$;
import static java.lang.System.out;

import java.util.Map;

public class TestMapUtils {
public static void main(String[] args) {
Map<String, Object> m = $("age", 22).
$("name", "Pasha").
$("blog", "http://whiter4bbit.blogspot.com").map();
for(String param : m.keySet()){
out.println(String.format("%s:%s", param, m.get(param)));
}
}
}

It is beautiful. Isn't it?:)

Wednesday, July 22, 2009

About BING search engine


So, when I use google to find information about some thing, then in first items are information actual for my region,
I enter into bing 'Visual Web Developer 2008 Express Edition download' then this engine shows me next results. It shows me download page for germany Why for germany?!


Updated: Same result when 'download' replace to 'скачать'

Tuesday, June 16, 2009

Turing Machine


import scala.collection.mutable.HashMap

class TuringMachine(_band: String, start_state: String, end_state: String) {
def walk( states: HashMap[ (String, String), (String, String, String) ] ): Unit = {
var state = start_state
var pos = 0
var band = _band
while ( state!=end_state ){
println(band)
var ch = band(pos)
var rule = states.get( state, ch.toString ).get
if (rule != Nil){
var arr = band.toArray
if (rule._2.length>0) arr(pos)=rule._2(0)
band = new String(arr)
state = rule._1
rule._3 match {
case "R" => pos+=1
case "L" => pos-=1
case _ => {}
}
}
}
}
}

def the_test: Unit = {
var mm = new HashMap[(String, String), (String, String, String)]
mm.put( ("1", "*"), ("1", "x", "R") )
mm.put( ("1", "k"), ("2", "x", ""))
var tm = new TuringMachine("****k", "1", "2")
tm.walk(mm)
}

Saturday, June 06, 2009

Multithreaded TestCases with Cactus

I need to write some stress-tests for web application. The best solution for webapplications testing is cactus - it's a junit based framework with in-box tools for servlets, filters, ejb testing. While testing, cactus for each test case cactus creates 2 cases - one for client side, second - for server side (wrapped). In fact, all tests executed on server side, client test case just sends request to server to run test and to get results ( there are sequence diagram, that represents this). So all results operated by http requests responses, and there are to many methods that can be overriten.
The problem is multithreaded testing, in pure junit there are pretty solution, that described in article "JUnit best practices" . So there 2 main ideas:
  • overwrite run method for TestCase, access to TestResult, and modify it if there are any exceptions in thread
  • for waiting while all threads done use thread joins
But in case, when I use cactus, I will to access to server side testresult, and there are no ways to access it - instance of TestCase for server side created by reflection , and there are no public access to cactus testsuite fields and methods.
So below is my solution of multithreaded test case for ServletTestCase:

public abstract class MultiThreadTest extends ServletTestCase{

protected MultiThreadTest(String s) {
super(s);
}

public void run(TestResult testResult) {
super.run(testResult);
}

/**
* all threads
*/
private Thread[] threads;

private Throwable exception;

/**
* runs all threads in array, throws exceptions, that thrown in any thread
* @param runnableTestCases
* @throws Throwable exception, that thrown by one of runnableTestCases
*/
public void runThreads(final RunnableTestCase[] runnableTestCases) throws Throwable{
threads = new Thread[runnableTestCases.length];
exception = null;
for(int i=0;i<threads.length;i++){
threads[i] = new Thread(runnableTestCases[i]);
}
for(int i=0; i<threads.length; i++){
threads[i].start();
}
try {
for(int i=0; i<threads.length; i++){
threads[i].join();
}
} catch (InterruptedException e) {
System.out.println("Thread was interrupted");
}
threads = null;
if(exception!=null){
throw exception;
}
}

/**
* interrupts all runned threads
*/
private void interruptThreads(){
if(threads!=null){
for(int i=0;i<threads.length;i++){
threads[i].interrupt();
}
}
}

/**
* represents abstract test case thread
*/
public abstract class RunnableTestCase implements Runnable{
/**
* test method
* @throws Exception
*/
public abstract void runTestCase() throws Exception;

public void run() {
try {
runTestCase();
} catch (Throwable e) {
exception = e;
interruptThreads();
}
}
}
}