Monday, July 21, 2008
A Javascript-based Generic Framework for Building Hierarchical Layouts
Description: The framework is developed as a javascript service that defines vertical / horizontal hierarchical layout method handlers. There are different handlers based on whether one wants to organize divisions (div tags), separate nodes, or node hierarchies. Apart from the structuring logic, the file also includes the rendering logic that paints the node(s) and their associated relations to build the actual hierarchy.
Now, the layouts are provided out of the box and all one requires is a nodelist (supporting composite pattern), which will then be consumed to draw the actual hierarchy. Such hierarchies can be utilized for a particular filtered view within a social networking graph.
The node definition(s) should comply to the following generic template to be able to fed and subsequently consumed properly by the framework: -
var Node = function(id) {
this.id = id;
this.coords;
this.shape;
this.text;
this.group;
this.childList = new dojox.collections.ArrayList();
}
Illustration: -
- Get a hierarchy object (pass the ultimate parent of the node hierarchy and specify the alignment [horizontal / vertical]: -
HierarchyLayout newLayout = new HierarchyLayout (document, ultimateParent, alignment);
- Invoke addNodeHierarchy: -
newLayout.addNodeHierarchy (ultimateParent, ""); // 2nd argument is yet to be utilized
This invocation would assign a value to the node coordinates (node.coords.x, node.coords.y) for each node in the hierarchy according to the passed alignment.
- Invoke renderHierarchy on a node: -
node.renderHierarchy ();
This invocation would render the immediate child nodes considering "node" as the parent.
The library can be downloaded from - Layout Lib
You can see a demo-usage @ SoNet home under "Demo" --> "Layout service demo".
Please feel free to drop a note in case you've comments / feedback.
Tuesday, July 15, 2008
A Framework Description for Dynamic Generation of XMLs
Thus, a generic XML-generation framework is desirable that could return precise XML files by consuming a schema definition(specifying generic XML structure) and an input configuration (containing information specific to a particular XML-generation instance).
Input(s) to the framework: Schema Definition (xsd), Configuration (.xml), Input Parameters (HashMap
Solution Design: The core idea is pretty straight-forward and comprises of the following steps: -
[1]. Create an in-memory parse-tree out of the given .xsd
[2]. Use the resource specification to refer the configuration and find out 'the information' specific to that particular XML-generation instance
[3]. Use the above 'information' to find out the scope of the current instance of xml generation from within the entire parse-tree
[4]. Adorn that scope with the input parameters and recursively apply 'the information' to generate the actual XML file
Description:
[1]. Create an in-memory parse-tree out of the given .xsd - For this, one can either go with any of the open-source xml-parsers, or write from scratch. Writing from scratch would generally require Element, Node, Attribute and ComplexType classes along with their respective handlers. Then, you would've a Schema Parser, which would utilize instances of those classes and generate the final tree object.
I won't elaborate further on this here; if required, please drop me a note. In essence, the only contract to be followed is that the return object should contain a parse-tree structure.
[2, 3 & 4]. To understand these, let us delve a bit into the source.
Our generator would generally need to follow something similar to the following contract: -
/**
* IXMLGenerator represents the contract that all XML generators must adhere to
* in order to support the default logic of XML genertion. Default XML generation
* contract is based on the consumption of the starting XML
element* and the
consolidatedMap of input and configuration parameters to* generate the populated response XML for that particular element.
*
* @author sushain
*
* @version 1.0
*/
public interface IXMLGenerator
{ /**
* This method takes a resource name, corresponding method and a
* parameter map and builds a request xml
* which can be consumed by the a request handler.
*
* @param resource
* @param method
* @param paramMap
*
* @return Generated request xml
*/
public static String generateXml(final String resource,
final String method, final HashMap paramMap)
throws SchemaParsingException;
}
Here, generateXml would be the main method, inherently calling the tree-creation module, and effectively completing step (1). This method would utilize the input-parameter map (HashMap containing the name-value pairs for the elements to be populated in the xml), resource (the entity for which the xml is desired) and method (the type of xml desired {system-specific}) by referring the 'Configuration' in the following manner: -
Now, I've repeatedly referred to a 'Configuration' above, lets see how that actually looks like: -
<configuration>
<resource name="<system-defined name>">
<method name="<resource access method / CRUD operation>">
<param name = "aaa" value="val1" />
<param name = "bbb" value="val2" />
<param name = "ccc" value="val3" />
<!--param name = "<complex_aaa>" value="<attr_val1>,<attr_val2>" /-->
<!--param name = "<complex_bbb>" value="<attr_val3>,<attr_val4>" /-->
</method>
.
.
.
Some key-points about the above conf are: -
- Each resource-name has a list of parameters associated with it that would define what exactly its associated XML would consist of.
- In case of complex-type params, the value consists of a list of comma-separated attributes.
- Such a definition is readable, easily extensible and configurable.
We would also have a corresponding Config class to read the above XML configuration into a Document (org.w3c.dom.Document) and build a hashMap out of it.
The structure of such a class would be similar to: -
public class Configuration {
private File configFile;
private Document configDoc;
private String resultNodeName;
public Configuration(String configText){
this.configFile = new File (configText);
this.configDoc = getConfigDocument();
}
public Document getConfigDocument() {
Document XMLDoc = XMLutils.getXMLDocument(configFile);
if (XMLDoc == null) {
System.out.println("XMLDoc null");
System.exit(-1);
}
String query = "/configuration";
NodeList nl = (NodeList) XMLutils.runXPathQuery(XMLDoc, query);
if(nl.getLength() !=1 ) {
return null;
}
Document responseObject = XMLutils.getNodeAsDocumentRoot(nl.item(0));
return (responseObject == null) ? null : responseObject;
}
public String getResultNodeName() {
return resultNodeName;
}
public HashMap getConfigurationMap (final String resourceName, final String methodName) {
HashMap
Node temp = this.configDoc.getDocumentElement().getFirstChild();
while(temp != null) {
if(temp.getNodeType() == Node.ELEMENT_NODE) {
if (temp.getAttributes().item(0).getNodeValue().trim().equals(resourceName)) {
NodeList methodList = temp.getChildNodes();
int methodListIndex = 0;
while (methodListIndex < methodList.getLength()) {
if (methodList.item (methodListIndex).getAttributes() == null) {
methodListIndex = methodListIndex + 1;
continue;
}
if (methodList.item (methodListIndex).getAttributes().item(0).getNodeValue().trim().equals(methodName)) {
NodeList paramList = methodList.item(methodListIndex).getChildNodes();
int paramListIndex = 0;
while (paramListIndex < paramList.getLength()) {
if (paramList.item(paramListIndex).getAttributes() == null) {
paramListIndex = paramListIndex + 1;
continue;
}
configObject.put(paramList.item(paramListIndex).getAttributes().item(0).getNodeValue().trim(),
paramList.item(paramListIndex).getAttributes().item(1).getNodeValue().trim());
paramListIndex = paramListIndex + 1;
}
}
methodListIndex = methodListIndex + 1;
}
}
}
temp = temp.getNextSibling();
}
return configObject;
}
}
- Once such a setup is in place, the generateXml method would then build a 'Consolidated Map' by appending ParamMap to HashMap.
- It would then read the xsd definition and get the in-memory parse tree ready using the module discussed in step (1).
- After that the actual xml generation logic would be invoked, passing the above built Consolidated Map and the resource specifiction.
- The generation logic would iterate through the tree, until it locates the resource spec
- It would then start building the XML, simultaneously referring the Consolidated Map and populating elements whenever it finds a corresponding entry in the Map. The population logic would be written in the corresponding handlers for 'simple' as well as 'complex' type nodes.
This would be something similar to: -
if(attList.size() > 0) {
XSDAttribute att = (XSDAttribute)attList.get(0);
if (consolidatedMap.containsKey(getName())) {
attributeString = consolidatedMap.get(getName()).toString();
StringTokenizer stok = new StringTokenizer (attributeString, ",");
while (stok.hasMoreTokens()) {
buffer.append("<");
buffer.append (getName() + " ");
buffer.append (att.getName());
buffer.append("=");
buffer.append("\"" + stok.nextToken() + "\"");
buffer.append(">");
if (consolidatedMap.containsKey(att.getName())) {
buffer.append (consolidatedMap.get(att.getName()));
}
buffer.append("");
buffer.append(getName());
buffer.append(">");
}
}
return buffer;
Finally, this XML would be returned to the caller and subsequently consumed by the original framework. For extension purposes, the only file to be modified later would be the configuration, which could be easily achieved due to the uniformity and structured nature of the definition. Due to a generic contract specification that only mandates an input parameter-map with name-value pairs of population-parameters, such a framework could be utilized in applications with a consuming UI-front as well as headless command-based apps. We thus saw how an effective configuration-design simplifies a seemingly difficult extension & integration problem.
If you have any suggestions, please drop a note / post.
Monday, July 7, 2008
Aggregation, Mashup Creation and Assembly Services
- alphaworks.ibm.com/tech/mashuphub
- services.alphaworks.ibm.com/damia
- services.alphaworks.ibm.com/qedwiki
^ Excellent assembly canvasses and services to create holistic aggregations and their respective interface components, and in turn giving us yet another instance of an effort towards the unification of the random segments.
Tuesday, June 10, 2008
Unified Integrated Intelligence - An instance
* We Feel Fine [ Click 'Open We Feel Fine' to view the app ]
* Twistori [ Click on any of the feelings ]
Monday, May 12, 2008
अत्यंत-सचल यातायात [a.k.a Virtual Interactive Pathfinding Intelligence]- An intelligent approach towards commuting
Everyday, we travel from our homes to our workplaces, jostling and cringing about the congested roads and unorganized traffic, coupled with the unpredictable weather and several other factors that make it very hard to commute. Everyone shares such emotions, whether using a self-owned vehicle or a public transport.
Inspired, rather provoked, by this problem, we came up with an idea to build a solution, which would help solve this problem to some extent. The Solution helps commuters identify the best path on the fly as they're traveling, given a source and destination. The system calculates the resulting path based on live traffic and weather-related feed data from an external source and display it on a geographical map in real-time. Best path, in this case, is calculated holistically; mainly by analyzing a specific live, textual RSS traffic-feed, provided by Yahoo’s Traffic API and then coupling the result with a live RSS weather or current events’ feed. Finally, these results are displayed on any freely available Map Service, like the one provided by Google, so that the user can easily view the path that he/she needs to follow.
To start with, the solution needs to be restricted to those areas, which are covered by Yahoo’s Traffic API. By doing some fundamental feasibility analysis, it was found to be practically available for the southern regions of New York and New Jersey. The assumption was that once this proof of concept is build, the dependence on the Yahoo service can be eliminated by putting a live video-feed analyzer component that doesn’t depend on the text-based feeds, leading to a generically applicable solution.
The major component of the system, the Feed Analyzer, is basically an intelligent component that acts as an Expert System. It parses the incoming XML feed and assigns severity based on the presence of some keywords, simultaneously learning and training itself to classify the future feeds in specific severity classes. This results in an analysis, which is monotonically increasing in the nature of precision. Finally, the path with least overall severity is characterized as the best path.
The other key component is a Pathfinding algorithm, which works on a connected graph, consisting of locations and roads (as nodes and points), respectively and finds the set of all possible paths between a source and a destination. After doing this, the output from the feed-analyzer is utilized to assign severities to each of these paths. Again, this algorithmic ‘manual’ component can be made redundant if there is an externally available, global and generic service or an extension to an already available service API, like Google Maps, that helps in finding all possible genuine and physical routes given two points, located by their longitude and latitudes.
Finally, as the feed analyzer is an independent component that takes XMLized feeds as input, there can be multiple and different inputs to it, or it can utilize an output from Yahoo pipes that is produced after merging many different and relevant feeds, thus increasing the possible relevance and practicality of the overall solution.
Here is a demo of the resulting proof of concept: -


