Wednesday, May 11, 2011

Spring ACL with UUID

Attempt 1


  1. Change acl_object_identity.object_id_identity field to varchar.
  2. Start application. Expecting error.
  3. App started normally (before any page call)
  4. Browse page, error come up. (Yes~!)
  5. java.lang.String cannot be cast to java.math.BigInteger
  6. Error at existing ACL entry.
Attempt 2
  1. Try insert an object with UUID as PK.
  2. And this is what I'm waiting for: java.lang.NumberFormatException: For input string: "741d25fe-f281-4747-95ef-229c1ba60000"
Attempt 3
  1. Create a Java Project in eclipse
  2. Import from spring-security-acl-3.0.5.RELEASE-sources.jar
  3. Modify (trial-and-error) BasicLookupStrategy.java and ObjectIdentityImpl.java (mostly change long to String)
  4. And it works, for now...

Monday, May 2, 2011

Swing Component Data Binding

I wrote a simple class to bind value change of a component to my bean. Someone must have done it many x 10000... times before. :p
Hope it helps.
Require: common-beanutils

package com.dummy;

import java.lang.reflect.InvocationTargetException;

import javax.swing.JSpinner;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.JTextComponent;

import org.apache.commons.beanutils.BeanUtils;

public class BeanBinder {

 public static void bind(final JSpinner jSpinner, final Object object,
   final String attribute) {
  jSpinner.addChangeListener(new ChangeListener() {

   @Override
   public void stateChanged(ChangeEvent arg0) {
    try {
     BeanUtils.setProperty(object, attribute,
       jSpinner.getValue());
     System.out.println(object);
    } catch (IllegalAccessException e) {
     e.printStackTrace();
    } catch (InvocationTargetException e) {
     e.printStackTrace();
    }
   }
  });
 }

 public static void bind(final JTextComponent textComponent,
   final Object object, final String attribute) {
  textComponent.addCaretListener(new CaretListener() {

   @Override
   public void caretUpdate(CaretEvent arg0) {
    try {
     BeanUtils.setProperty(object, attribute,
       textComponent.getText());
     System.out.println(object);
    } catch (IllegalAccessException e1) {
     e1.printStackTrace();
    } catch (InvocationTargetException e1) {
     e1.printStackTrace();
    }
   }
  });
 }

}
Usage:

Saturday, April 9, 2011

Java Event Listener for Console Application

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class EventListener {

private static Map eventInstances = new HashMap();
private static Map eventRegistry = new HashMap();

/**
*
* @param eventName
* @param instance - instance of the class
* @param method - method of the class
*/
public static void registerEvent(String eventName, Object instance, Method method) {
eventRegistry.put(eventName, method);
eventInstances.put(eventName, instance);
}

public static void triggerEvent(String eventName, Object... eventData) {
Method method = eventRegistry.get(eventName);
Object instance = eventInstances.get(eventName);
if(method != null) {
try {
method.invoke(instance, eventData);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}

}

Monday, January 3, 2011

Drools 5.1 Human Task Example

It has been a while seen my last post. Lately I have been working on BPMS and Drools. I try to create a simple app using Drools Flow and Human task and now have some small success.
While learning and creating my simple app, looking for example online was difficult. Try google "Drools 5.1 Human Task Example" and see what you will get. So I decide to put more example online for reference. It may not be as complete but I'll show the parts that is working.

What I try to do is like this.
I start a flow, then it will run Action 1, then the Human Task, where it need human/external interaction, then Action 2 and finish.
Action 1 and Action 2 will just print some text on the screen. (System.out.println(...))
Human Task has these properties:
The ActorId "mina" is just a value. I think (haven't try) we can either set it at design time or run time.

I use eclipse (with Drools plugin (core and task)) to create a new drools project. I end up having these libraries in the project. Can still be clean up a bit but... let's continue.



[tricky part: Error is main-1.4.jar is missing.]
Ok. now we start with a simple java class with a main function. In the class, we have:

 private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("human_task_flow.bpmn"), ResourceType.BPMN2);
return kbuilder.newKnowledgeBase();
}
In the main function,


  try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();

EntityManagerFactory emf =
Persistence.createEntityManagerFactory( "org.drools.task" );
Environment env = KnowledgeBaseFactory.newEnvironment();
env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );

SystemEventListener systemEventListener = SystemEventListenerFactory.getSystemEventListener();

TaskService taskService = new TaskService(emf, systemEventListener);

TaskServiceSession taskSession = taskService.createSession();

taskSession.addUser(new User("Administrator"));
taskSession.addUser(new User("mina"));

MinaTaskServer server = new MinaTaskServer( taskService );
Thread thread = new Thread( server );
thread.start();

StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

WSHumanTaskHandler handler = new WSHumanTaskHandler();

ksession.getWorkItemManager().registerWorkItemHandler("Human Task", handler);

KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
// start a new process instance
ksession.startProcess("HumanTaskSample");

// ksession.fireAllRules();

logger.close();
} catch (Throwable t) {
t.printStackTrace();
}

Now we run the app and you will notice a lot of stuff printed out in the console. Hopefully there is no error. :p
[tricky part: You need to create the default user "Administrator", OR ELSE...]

To know what is happening, use the Drools Audit View to view the log.

You can see that Action 1 and Human Task were triggered.
At this stage, a Task is created and saved in the database. (lazy to explain how)
Now we use Human Task View (from Drools Task plugin) to lookup for the task using UserId "mina". You will see the task with Status Reserved.

You can now select the task and complete it (click the "Complete" button).

Stage 1 works, but what if I want to programmaticly complete the task? So I also written some task client code.

package com.geneoz.drools;

import java.util.List;

import org.drools.SystemEventListenerFactory;
import org.drools.task.User;
import org.drools.task.query.TaskSummary;
import org.drools.task.service.TaskClient;
import org.drools.task.service.mina.MinaTaskClientConnector;
import org.drools.task.service.mina.MinaTaskClientHandler;
import org.drools.task.service.responsehandlers.BlockingTaskOperationResponseHandler;
import org.drools.task.service.responsehandlers.BlockingTaskSummaryResponseHandler;

public class GeneozTaskClient {

public static void main(String... args) {
TaskClient client = new TaskClient(new MinaTaskClientConnector("mina",
new MinaTaskClientHandler(
SystemEventListenerFactory.getSystemEventListener())));
try {
client.connect("127.0.0.1", 9123);
BlockingTaskSummaryResponseHandler summaryHandler = new BlockingTaskSummaryResponseHandler();
client.getTasksAssignedAsPotentialOwner("mina", "en-UK",
summaryHandler);
List tasks = summaryHandler.getResults();
TaskSummary task = null;
for (TaskSummary taskSummary : tasks) {
System.out.println(taskSummary.getId() + " : "
+ taskSummary.getName());
task = taskSummary;
}
   if (task != null) {
BlockingTaskOperationResponseHandler operationHandler = new BlockingTaskOperationResponseHandler();
client.release(task.getId(), "mina", operationHandler);
client.claim(task.getId(), "Administrator", operationHandler);
operationHandler.waitTillDone(10000);

operationHandler = new BlockingTaskOperationResponseHandler();
client.start(task.getId(), "Administrator", operationHandler);
operationHandler.waitTillDone(10000);

operationHandler = new BlockingTaskOperationResponseHandler();
client.complete(task.getId(), "Administrator", null, operationHandler);
operationHandler.waitTillDone(10000);

}

} catch (Exception e) {
e.printStackTrace();
} finally {
try {
client.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);

}
}
}
Some explanation:
1. Create a Mina Task Client
2. Connect to default MinaTaskServer
3. Find tasks belong to "mina"
4. Release the task (from "Reserved" state to "Ready" state) so that it can be claimed by other user.
5. Start and complete the task.

And now you will have Human Task completed and Action 2 triggered.

So this is where I am currently at for the moment. Hope to discover more stuff as I move on.
Hope this example can be helpful. Sorry for the bad English. :p


Saturday, August 7, 2010

iPad Scroll with jQuery

Yeah~! I did it. After pressure from my boss, I finally get some prototype done. Please see it here.
Yes!! Yes!!! Yes!!!!

Friday, May 7, 2010

Convert POJO to JSON

Face this issue many times.


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class POJO2JSON {

public static JSONArray convert(Class cls, List list) {

Method[] methods = cls.getDeclaredMethods();

String className = cls.getSimpleName();
className = className.substring(0,1).toLowerCase() + className.substring(1);

JSONArray jsonarray = new JSONArray();
for (Object object : list) {
JSONObject json = new JSONObject();

for (Method method : methods) {
if(method.getName().startsWith("get")) {
String fieldName = method.getName().substring(3);
fieldName = fieldName.substring(0,1).toLowerCase() + fieldName.substring(1);

try {
Object result = method.invoke(object, null);
// System.out.println(fieldName + " = " + result);
json.put(fieldName, result);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
jsonarray.put(json);
}
return jsonarray;
}

public static JSONObject convert(Class cls, Object obj) {


Method[] methods = cls.getDeclaredMethods();

String className = cls.getSimpleName();
className = className.substring(0,1).toLowerCase() + className.substring(1);

JSONObject json_class = new JSONObject();

JSONObject json = new JSONObject();

for (Method method : methods) {
if(method.getName().startsWith("get")) {
String fieldName = method.getName().substring(3);
fieldName = fieldName.substring(0,1).toLowerCase() + fieldName.substring(1);

try {
Object result = method.invoke(obj, null);
// System.out.println(fieldName + " = " + result);
json.put(fieldName, result);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
try {
json_class.put(className, json);
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
}

See http://www.json.org/java/ for JSONObject