Monday, August 3, 2009
Suppress mouse events on child components - Flex3
I use it when i want to catch a mouse event on a container, regardless of the component within that container that was exactly under the mouse.
There is no way under the heavens to guess this is the functionality of a property with such a name.
Thanks Liran.
Saturday, July 18, 2009
Down the rabbits hole with neo4j (Part 1)
While standing on one foot, I would say that the neo4j project is an implementation for an embedded java graph database. Unlike the traditional relation databases, the graph database has no table structure for storing its data. Instead it uses a more dynamic (unstructured) network composition. Using mathematical terminology, a network of nodes is called a graph.
I’ll put my other foot down now.
Applications use an object data structure in order to describe and abstract the business domain they address. Stitching together the object oriented structure onto the table oriented data structure of a relational database is a major part of the time consumed in server side programming. This price has been, and still is willingly paid because of the absolute reliability of the traditional relational data structures.
Truth to be said, there are implementations that make much more sense when persisted using tables. However, I would dare to argue that when querying becomes complex and cumbersome, it just might be a sign that the persisting method isn’t appropriate.
The unstructured graph database leads the field when it comes to implementing an ad-hoc structure that is prone to runtime changes.
I decided to give it a try after watching Emil Efirem’s demonstration on the web and I’m sharing my experience as I played around with three aspects of use:
- Part 1: Converting plain java data objects into persisted neo nodes
- Part 2: Managing lookups
- Part 3: Experimenting With Transactions
Setting up a neo4j environment
The neo4j jars are available on: http://neo4j.org/download, under which there are two packages;
- The apoc package includes some extra utility jars, i.e. the indexing jar, the shell jar and some examples
- The kernel package includes the bare minimum, i.e. neo and jta jars
My example project’s source code is also available here, compatible for eclipse and intelliJ.
Part 1: Converting POJO into neo
In my mind’s eye I saw a plain old java data objects that would define my domain data structure. These objects would be passed to some kind of neo facilitating mechanism that would take care of the persistence for me.
Using annotations
Java annotations are a wonderful tool; I use Annotations to load metadata on class elements, when the metadata is not intended to be part of the primary business course of the class.
In this example, I have a type representing a person that has a couple of properties and lists of friends and foes. I annotated the fields with the hinting I needed to ease the conversion into neo.
Note that the conversion is handled at runtime so the annotation retention policy is set appropriately.
Here is the annotation declaration:
@Retention(RetentionPolicy.RUNTIME)public @interface Persistance {Type type() default Type.Property;Peers relationType() default Peers.NA;public static enum Type {Property, Peer}}
The annotated POJO, representing my person data is as follows:
And so on…public enum Peers implements RelationshipType {Friend, Foe, NA}public class Person {@Persistance(type = Persistance.Type.Property)public String name;@Persistance(type = Persistance.Type.Property)public String nickname;@Persistance(type = Persistance.Type.Peer, relationType = Peers.Friend)public List<Person> friends;@Persistance(type = Persistance.Type.Peer, relationType = Peers.Foe)public List<Person> foes;
The conversion to the neo nodes
The neo world speaks in two basic terms, the node and the relation. Each can bear its own properties.The nodes have no typing, which I think is a shame, but relationships do require typing. I went along with the recommendations and defined my relationship as an enum.
The snippet for the relationship type:The persistence mechanism is a recursive breakdown of the POJO graph (the person and all this friends etc.) according to the hints I get on the annotations.public enum Peers implements RelationshipType {Friend, Foe, NA}
Within a neo transaction I call the converting method by passing the object I want to persist onto it:
Transaction tx = neo.beginTx();Node node = null;try {node = objectToNode(object, null);tx.success();return node.getId();} catch (Exception e) {tx.failure();e.printStackTrace();} finally {tx.finish();}
The method objectToNode(..) is the recursive part and I load it with a stack map to prevent the recursive calls from looping forever on objects that were already processed.
if (stack == null) {stack = new HashMap<Object, Node>();} else if (stack.containsKey(object)) {return stack.get(object);}Node node = neo.createNode();stack.put(object, node);Class cls = object.getClass();Field[] fields = cls.getDeclaredFields();for (Field field : fields) {// only persisting the fields that have my special annotationif (field.isAnnotationPresent(Persistance.class)) {processFieldData(node, object, field, stack);}}return node;
The method processFieldData(..) is where the annotations are processed. Properties are loaded on the nodes and hints for relationships invoke the recursive call that handles the linked objects as independent nodes.
if (annotation instanceof Persistance) {Persistance p = (Persistance) annotation;log("processing annotation: " + p.type() + " "+ p.relationType());if (p.type().equals(Persistance.Type.Property)) {// TODO: verify that the property is actually a primitiveObject value = field.get(object);log("setting property: " + field.getName() + " " + value);// here is a neo setting of a propertynode.setProperty(field.getName(), value);} else if (p.type().equals(Persistance.Type.Peer)) {Object value = field.get(object);log("setting peer: " + field.getName() + " " + value);if (value instanceof List) {for (Object item : (List) value) {// here is another neo bit, where a new Node is// created by recursively calling on the converting// method with the child object// after the new node is handed back, i create the// relationship between the twoNode otherNode = objectToNode(item, stack);node.createRelationshipTo(otherNode, p.relationType());}
Wednesday, July 1, 2009
Factory Implementation in Flex AS3
The closest thing i could find for implementing a simple factory in Flex is by using the getDefinitionByName function.
Usage:
import flash.utils.getDefinitionByName;private static const basePath:String = "..path to implementation..";
private var a:SomeClassImp;
private var b:OtherClassImp;
public static function getRendrer(className:String):Object{
var classFullName:String = basePath+ className;
var objClass:Class = getDefinitionByName( classFullName ) as Class;
return new objClass();
}
Note: The classes that the factory is suppose to generate in run time have to be explicitly stated as var’s in the factory class. this is for the compiler to know to add them into the compilation product.
Sunday, June 14, 2009
Bazooka Developer
It is so told, that there should come a time for every developer, when he be faced with the challenge of coding in the sky. A situation like this happens when a client is faced with a critical problem and needs an immediate solution. The solution provider decides to give it a go, sends out a repair man, for a fast, cowboy style solution, and cashes in the check.
When my turn came, I was handed the assignment along with the flight tickets and a brief rundown of the functionality I had to deliver. The functionality took about an hour for him to describe.
This kind of positive thinking often reminds me of the ‘Bazooka Joe’ bubblegum fortune, telling me that by the age of 21 I would probably land on the moon.
Keeping that same positive thinking in mind, I realized it would be a nice opportunity for setting my agile development skills to the test. I preach agility all the time. I preach it to my colleges and to my developers. I even preach it to my boss. There was no way I was about to turn ‘cowboy’ on all that.
The entire time frame for this task was less than a standard agile heart beat, but I stuck with the principles, and used them to guide me.
My first task was to deliver functionality. So I set to inquire whatever I could about the requirements. There was the way my boss envisioned it and there were some correspondence with the customer that preceded the request. I swept through the mail exchanges, to find out how the customer wanted it to work and how it ought to be fitted in the surrounding landscape of the other systems. I came out with a detailed feature list, reflecting the functionality requirements, an outline sketch of the interfaces and a high level cubistic design with a short list of would be obstacles (i.e. outstanding issues yet to be resolved).
Meeting the bare minimum to enable testability: I wrote a mock up interface invoker (two actually, that know how to talk to each other in a session like manner). Just like in the real world, my module was going to be ‘stuck’ right in between the two mockups, doing so I could have a convenient testing envelope where I can gradually grow my functionality.
I felt I was ready for some hard core coding.
Fortune: you will not get much sleep the next few nights.
I developed in short cycles. I used my short list of suspected pickles to define the steps for development. After coding a new solution that was suppose to address a particular issue, I ran the module against the testing facilities, with all the scenarios I had so far, and a new scenario that would test the solution. This got me through debugging and I made sure that I was not disrupting previously developed features (i.e. regression testing).
I know, I know, I was sprinting or whatever. In any case it kept me focused on my goals and constantly in check with working functionality.
I sprinted at the office, I sprinted at home, I sprinted at night, in the airport and on the airplane.
It so happened that by the time I got to the site, I was far from done, but I did have a prototype that was solid enough and being as it was, I had it installed on one of the development environment there.
I made use of the customer. The customer in this case was a respectable American corporate. I met there with the IT team that held everything together. Right at the beginning, they brought into my attention that they had four sets of environments. This was an important point to note since there were differences in application versions between them. The version differences meant that every time I got environmentally promoted, I had to adjust to the changes in protocol and behavior.
Fortune: an overnight success is the result of years of preparations
At this stage, I could have my testing cycles run up against real applications and not the mockup applications I prepared myself. The people from the IT team helped me learn about the extreme scenarios and together we were able to devise a meticulous testing plan. Together we defined the scope for load testing.
During the working hours, I ran tests on the various environments that were available and spent the nights at the hotel for code fixing and optimization. This was not an easy time for me. By the end of the first week we have conducted a few cycles of testing and amendment, and we were already deep into the load testing.
Fortune: the love you give is equal to the love you get
I was also able to cater for some extra requests for changes. These were minor modifications that had to do with logging and configuration options, but it made customer happy. The help I got from the customer staff I met there was absolutely essential in making the delivery and having the module go into production.
A month after I flew back, my module was set into production. Of course there were some more bugs identified and some new feature requests as well. But all in all, the customer was satisfied.
Fortune: don’t let it go up to your head
Friday, June 12, 2009
Flex MDI, Always On Top window
So how does one go about and opens an “Always On Top” window, using the FlexMDI (on flexlib)?
Sadly, I wasn’t able to find any nice solution for this problem and when such frustration comes, I resort to tricks.
My trick in this case was to wrap the MDICanvas with a class of my own, and in it I had two MDI canvases one on top of the other.
I added a nice utility method for opening a window, and according to an indicator on that method I either open it in bottom layer, or the top one; hence the “always on top”.
Not perfect, but working.
Tuesday, June 9, 2009
Flex loads with a blank screen
no error was printed out in the consul. it appeared that flex was loading but wasn't loading my application.
if this happens to you too, check your code to see if you are embedding a file as XML:
[Embed(source="...data.xml")]
private static var xmlData:Class;
if you are, and the file happens to be malformed (some mistake in the XML structure) you are not going to see any error from the compiler or the runtime(!)
just a peaceful, zen like, blank page.
bugger