- Grid now tries to persists it's values, asynchronously, on given databases. Currently MongoDB is the default but this would be pluggable.
- I have tried various scripting languages for the console. I was not very happy with Groovy because it had too many dependencies and kind of a overkill for my needs. I replaced it with "JavaScript" which is by default available with sun JDK6. Not 100% happy though since it may not be available by default on other platforms.
- To minimize the dependencies I moved to java.util.logging from log4j and commons-logging. I replaced the commons-logging with a little module I named 'yala', which stands for 'yet another logging api'. My two cents to java logging hell...
- Since I release less often, from now on I decided to name my versions as M1, M2 and so on...
Tuesday, January 10, 2012
QMass M1
It has been a while since I wrote anything on QMass. Here are the updates :
Monday, November 28, 2011
Recognizing The Letters as Being Drawn With The Mouse
While playing-out with a Kinect device, I think I will be writing more about this later, I had an idea. I could detect letters being drawn with the mouse and convert them to key presses enabling the user, use the mouse like a keyboard. It's basically same problem like they do with these pens.
So while drawing the above with the mouse my app. prints "BABA" on where the cursor is. There are two parts to this problem, hard part is obviously recognizing what actually is written. Easy part is producing the key presses. Here are the libraries I used :
java.awt.Robot
A Robot is actually created with automating tests in mind. It has the methods for moving, clicking the mouse, producing key presses and capturing the screen.
java.awt.MouseInfo
MouseInfo class gives you the location of the mouse. Unfortunately with just Java I couldn't find a way to tell if any of the mouse key's are being pressed out side the java application window. Here are some discussions on that. Apparently one would have to use a native library. Anyway I didn't really need to handle clicks at the beginning anyway.
How to Recognize The Characters
My approach is capturing the changes in the movement of 'x' and 'y' axis.
Here is how 'x' and 'y' axis moves while a the letter 'A' is being drawn :
One might also choose to compare the values of increases and decreases in order to eliminate some false matches.
I use 90ms mouse position samples to compute the differences from the previous location. If the differences are less than 10 pixel I ignore them.
Here is how the 'B' recognition function looks like :
I found this approach working quite well even with not taking account if the mouse button is pressed, though that would be required to match some simpler characters like 'I' or '.'.
java.awt.Robot
A Robot is actually created with automating tests in mind. It has the methods for moving, clicking the mouse, producing key presses and capturing the screen.
java.awt.MouseInfo
MouseInfo class gives you the location of the mouse. Unfortunately with just Java I couldn't find a way to tell if any of the mouse key's are being pressed out side the java application window. Here are some discussions on that. Apparently one would have to use a native library. Anyway I didn't really need to handle clicks at the beginning anyway.
How to Recognize The Characters
My approach is capturing the changes in the movement of 'x' and 'y' axis.
Here is how 'x' and 'y' axis moves while a the letter 'A' is being drawn :
One might also choose to compare the values of increases and decreases in order to eliminate some false matches.
I use 90ms mouse position samples to compute the differences from the previous location. If the differences are less than 10 pixel I ignore them.
Here is how the 'B' recognition function looks like :
@Override
public void execute(Double x, Double y) {
if (state == 0 && (y < 0 || (y == 0 && prevY < 0))) {
state++;
} else if (state == 1 && x > 0 && y > 0) {
state++;
} else if (state == 2 && x < 0 && y > 0) {
state++;
} else if (state == 3 && x > 0 && y > 0) {
state++;
} else if (state == 4 && x < 0 && y > 0) {
state++;
} else {
state = 0;
setIndex(saveI);
saveI++;
}
if (state == 5) {
setResult(getIndex());
breaked();
}
prevY = y;
}
This function is continuously fed with ordered X and Y axis values. State variable is increased if the difference is expected, reseted otherwise. When the state 5 is reached than we know that it's a 'B'.I found this approach working quite well even with not taking account if the mouse button is pressed, though that would be required to match some simpler characters like 'I' or '.'.
Monday, October 31, 2011
Hot R&D Topics At Itea 2011 co-summit
Last week I attended the Itea2/Artemis co-summit. It's a showcase of Itea funded R&D projects.
This year apparently most projects are focused on embeded software (Artemis), M2M Networks and Green Energy.
There are several projects that focus on M2M architecture/applications, including ours A2Nets, which would allow M2M devices to connect and exchange information with each other. Notable applications would be determining when your bus will be at the bus stop or cars passing by sharing traffic data with each other.
It seems, at least in europe, smart readers will be more common in the future. There are numerous projects trying to build and manage different metering networks such as electric and gas metering.
MetaVerse1 was also an interesting project which attempts to enable interoperability among virtual worlds. One of the products of the project is the MPEG-V standard.
This year apparently most projects are focused on embeded software (Artemis), M2M Networks and Green Energy.
There are several projects that focus on M2M architecture/applications, including ours A2Nets, which would allow M2M devices to connect and exchange information with each other. Notable applications would be determining when your bus will be at the bus stop or cars passing by sharing traffic data with each other.
It seems, at least in europe, smart readers will be more common in the future. There are numerous projects trying to build and manage different metering networks such as electric and gas metering.
MetaVerse1 was also an interesting project which attempts to enable interoperability among virtual worlds. One of the products of the project is the MPEG-V standard.
Friday, September 23, 2011
Creating a JSF2 Console Component
Since most of the people coming to my site are still looking for JSF how-to's here is one more. This is an how-to on creating a console component, like the one here, with just the JSF2 api.
A shell like console's basic requirements look like this ;
A shell like console's basic requirements look like this ;
- Should prompt the user to enter a command.
- Evaluate the command and print the result.
- Should limit the text to be entered only on the prompt line limiting the movement of the caret.
- The new command line should be empty for user to enter a new command.
- Should support AJAX
Since all a JSF component does is rendering HTML and managing state we should actually find a way to implement this with HTML and JavaScript.
Here are two options I could think of ;
- Render a textarea, try to limit the movement of the caret through JavaScript.
- Render a input text for the user command. Print outputs within a 'div'. Blend them together using CSS.
I chose the second approach since JavaScript needed for he first approach is a bit tricky to implement.
Now to implement these as a JSF component we need these :
- A taglib defining our component.
- A State manager component that manages inputs and outputs of the component and beans.
- A Renderer that will output the html depending on components state
The taglib is actually quite simple :
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">
<namespace>http://mca.org/qmass</namespace>
<tag>
<tag-name>console</tag-name>
<component>
<component-type>UIConsole</component-type>
<renderer-type>UIConsole</renderer-type>
</component>
</tag>
</facelet-taglib>
We will refence this taglib through our xhtml's using namespace and our component tag. Component-type references to what I called state-manager and renderer-type references to the renderer.
The state manager :
Lastly the renderer :
Finally here is how I use the component on a xhtml :
Cheers
The state manager :
@FacesComponent(value = "UIConsole")
public class UIConsole extends UICommand {
public String getCommand() {
return (String) getStateHelper().eval("command");
}
public void setCommand(String command) {
getStateHelper().put("command", command);
getValueExpression("command").setValue(FacesContext.getCurrentInstance().getELContext(), command);
}
public String getOutput() {
return (String) getStateHelper().eval("output");
}
public void setOutput(String output) {
getStateHelper().put("output", output);
}
@Override
public String getFamily() {
return "qmass.jsf.Console";
}
}
Above code does not do much but actually doing it is a bit trickier. We mark this class as a JSF component, and give it an id with @FacesComponent annotation. The means to access your components inputs and outputs are defined with in this class. Get/Set command is for the command that our shell will implement. The output is for printing the result of our shell. And since we will need to perform an action we are extending from UICommand and use it's bindings.Lastly the renderer :
@FacesRenderer(rendererType = "UIConsole", componentFamily = "qmass.jsf.Console")
@ResourceDependencies({
@ResourceDependency(name = "qconsole.css", library = "org.mca.qmass", target = "head"),
@ResourceDependency(name = "jsf.js", library = "javax.faces", target = "body")})
public class ConsoleRenderer extends Renderer {
@Override
public void decode(FacesContext context, UIComponent component) {
UIConsole console = (UIConsole) component;
String val = context.getExternalContext().getRequestParameterMap().get(getCommandId(console));
console.setCommand(val);
console.queueEvent(new ActionEvent(component));
}
private String getCommandId(UIConsole console) {
return console.getClientId() + "_in";
}
@Override
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
UIConsole comp = (UIConsole) component;
String inId = getCommandId(comp);
String lines = comp.getOutput();
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", null);
writer.writeAttribute("id", comp.getClientId(), null);
writer.writeAttribute("name", comp.getClientId(), null);
writer.writeAttribute("class", "qconsole", null);
writer.writeAttribute("onmouseover", "document.getElementById('" + inId + "').focus();", null);
String[] lineRay = lines.split("\n");
for (int i = 0; i < lineRay.length; i++) {
writer.startElement("div", null);
writer.writeAttribute("class", "qconsolerow", null);
writer.write(lineRay[i].replaceAll(" ", " "));
if (i + 1 == lineRay.length) {
writer.startElement("input", null);
writer.writeAttribute("id", inId, null);
writer.writeAttribute("name", inId, null);
writer.writeAttribute("onkeypress",
"if(event.keyCode == 13){" +
"jsf.ajax.request(this,event,{execute:'" + comp.getClientId() + "'," +
"render:'" + comp.getClientId() + "'," +
"onevent:function(e) {if(e.status=='success')" +
"document.getElementById('" + inId + "').focus();}});" +
"return false;" +
"}",
null);
writer.writeAttribute("class", "qconsole", null);
writer.writeAttribute("autocomplete", "off", null);
writer.writeAttribute("type", "text", null);
writer.endElement("input");
}
writer.endElement("div");
}
}
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.endElement("div");
}
}
We start by defining this class as a Faces Renderer and specify the necessary resources it needs. We need he ajax library and css for custom look. Decode method both sets the new command entered by the user and schedules the action listener attached for execution if necessary. Encode part outputs the HTML we use.Finally here is how I use the component on a xhtml :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:q="http://mca.org/qmass">
...
<q:console id="q" output="#{consoleBean.output}" command="#{consoleBean.input}"
actionListener="#{consoleBean.handleCommand}"/>
...
</html>
You can find out the full source code available here as a part of the QMass project here.Cheers
Saturday, August 27, 2011
QMass, P2P Communication over TCP
I have done significant refactoring and added new features to QMass :
- P2P, TCP communication, UDP for cluster discovery code
- A new console app working online or at command shell
- Significant performance improvements
You may try out the console at http://qmass.cloudfoundry.com , which spans 8 instances.
And here is my new logo :
Tuesday, June 7, 2011
QMass as an Data Grid
Memcached defines it's self as in-memory object system. Hazelcast defines it's self as a distributed data grid. What they mean is there is cluster of instances that form a data grid, where a key value pair is hold on only one instance.
I started developing QMass with cache data in mind. Particularly for use with Hibernate 2nd level cache where "a key value pair is hold on only one instance" approach is not that useful where there are too many access on the cache creating to many network trips. So the cache I designed broke that rule.
While that was useful, forming a data-grid used as a in-memory db also is. So there starts the QMass Data Grid Service where you can do that. There is also a console app. where you can fire up multiple instances and test your grid whit put, get and remove.
And more to come :)
QMass Project page, Wiki, Downloads
I started developing QMass with cache data in mind. Particularly for use with Hibernate 2nd level cache where "a key value pair is hold on only one instance" approach is not that useful where there are too many access on the cache creating to many network trips. So the cache I designed broke that rule.
While that was useful, forming a data-grid used as a in-memory db also is. So there starts the QMass Data Grid Service where you can do that. There is also a console app. where you can fire up multiple instances and test your grid whit put, get and remove.
And more to come :)
QMass Project page, Wiki, Downloads
Tuesday, May 24, 2011
QMass for Sharing Sessions
I have just committed code that adds session sharing support to QMass.
By defining a filter QMass will share session attributes amongst cluster. It serializes/deserializes the values and does not work synchronously just yet.
QMass project page, QMass wiki
By defining a filter QMass will share session attributes amongst cluster. It serializes/deserializes the values and does not work synchronously just yet.
QMass project page, QMass wiki
Subscribe to:
Posts (Atom)
