Sunday, March 28, 2010

Killing an annoying warning

The most annoying warning ever has been haunting me for a while.

[javac] /home/razvanc/workspace7u6/razxml/src/razie/base/data/RiXmlUtils.java:160: warning: com.sun.org.apache.xpath.internal.objects.XObject is Sun proprietary API and may be removed in a future release


I refuse to include and move around large unnecessary libraries to deal with XML and XPATH just because Sun considers themselves the center of the universe and their internal libraries somehow more important then mine. In short, they figured there should be no way to remove this warning, although, in this case, they copied code from apache into their own libraries.

Well, the solution is rather simple. Most likely everyone has specific XML wrappers. Just put them in their own project, disable the java/scala builders. Then, build it manually, create a jar file and check it in.

Then, in all the other projects, use this jar directly. Since the jar is already compiled, the annoying warning is no more.

See for instance my xml utilities, at http://github.com/razie/razxml

What's more, I don't actually use the XML stuff directly. I wrapped it all in pretty much one single class, using XPATH for access. It's simple, fast enough and makes for very simple code:


Reg.doc(MediaConfig.MEDIA_CONFIG).xpa(
"/config/storage/host[@name='" + Agents.me().name + "']/media/@localdir"
)


For all xml data access, you should limit yourself to the xpe/xpl/xpa methods described in an earlier post (http://blog.homecloud.ca/2010/02/one-xpath-to-rule-them-all.html). So, use something like this instead: http://github.com/razie/razxml/blob/master/src/razie/base/data/XmlDoc.java

Cheers.

Saturday, March 13, 2010

The Option monad pattern thing

This informative post is consolidated in the new blog, at:

 http://www.coolscala.com/wiki/Blog:Cool_Scala/Post:The_Option_monad_pattern_thing

... where we take a closer look at the Option type of Scala, the monadic aspect of it and see how we can use it to inspire new patterns and new ways of looking at the code we write.

(Sorry - original content was removed from here, to avoid duplicates).

Monday, March 1, 2010

Scripster - interactive scala REPL using telnet, http etc

As mentioned before, I think that all apps must alllow scripted/programatic access to their objects.

I created a simple interactive gate to acces the scala REPL in any scala process. It only uses one port and supports telnet, http and swing:



The graphics are based on my 20widgets project, with the addition of a ScriptPad widget.

Content assist is only available in the telnet version (sic!). I will work to find some nice syntax-colored controls for the web version. Switch to character mode ("mode character" on ubuntu or default on windows) and use TAB to see a list of options. Right now it's a demo only, I need to find the parser's APIs to get the real content assist options ;)

You can download the single scripster-dist.jar file from my razpub project download, at http://code.google.com/p/razpub/ and run the example with this command line (replace /host/bin/scala with your $SCALA_HOME) :

java -classpath ./scripster-dist.jar:/host/bin/scala/lib/scala-library.jar:/host/bin/scala/lib/scala-compiler.jar:/host/bin/scala/lib/scala-swing.jar razie.scripster.JScalapSwing


To use it in your process, put these jars in your classpath and use this:
razie.scripster.Scripster.create(4445)
where 4445 is the port you want to use, see the razie.scripster.MainScripster for an example. To enable the swing version, use the swing jars as well and see the razie.scripster.MainSwingScripster class for an example.

For further tweaking, look at the code yourself, at http://github.com/razie/scripster/tree/master/src/razie/scripster/

If you want to keep in touch with the evolution of scripster or my other related endeavours, subscribe to the RSS feed or twitter/razie.

Scripster's main page, kept up-to-date, is at http://wiki.homecloud.ca/scripster. There's also an online live demo at http://scripster.codewitter.com.

Enjoy!

Saturday, February 6, 2010

One XPath to rule them all!

ABSTRACT: there's a million ways to access (data, objects, tables etc) these days and probably new ones are created every milisecond. What if we can figure out one that can be used anywhere?


Think about it!

/Universe/Planets/Planet[@name=='earth']/@position

XPath was created as a natural way to address elements in an XML document. One specifies the path - starting from the root node - to the element you are addressing. Conditions help you select the right nodes from many (lists) and you can address nodes or their attributes.

Extending it to addressing trees is strait-forward, so we can apply the same paradigm to any tree-structure, like Java beans...see for instance this Apache library: http://commons.apache.org/jxpath/

Come to think about it, all direct acyclical graphs fit in the same category...of course, with small differences: selecting an edge from among many possible types and lack of a root...so, some extensions are in order:

/Person[@name='John']/{hasFriends}Person

What hapens here is that the node of type Person that meets the criteria was selected as the start node and then the graph walk begins. From the many relationships tying humans together, the ones of type "hasFriends" are followed and not "hasChildren".

Yeah, you got it - even cycles are handled this way simply because as the path is walked, it reaches an end...

And... yeah, you got it again: UML domain model of classes with associations...it can describe any model you may use internally or present to clients...so we can handle pretty much any domain model described in an UML class diagram.

There.

I found myself needing four basic operations:
  • xpe : T - /** find one element */
  • xpl : List[T] - /** find a list of elements */
  • xpa : String - /** find one attribute */
  • xpla : List[String] - /** find a list of attributes */

For the sake of being concise, I will represent this new "data access interface"as either of the versions below (with explicit type and start node or implicit):

val me = XP[Person] xpe ("/Person[@areGroovy=='yeah, baby!']") from john
val minime = xpe ("/Person[@areGroovy=='yeah, baby!']")



So, why would this be useful?

Frankly, I'm growing old(er) and tired of all the non-sensical APIs that pop-up all the time everywhere: My application is unique! My domain model is complex! Everything could be an Object, but so what? I'm smarter! I know better!

My answer is: nope, your application's domain model is a class diagram and your actual objects thus form a graph. I don't need you to inven new ways to interact with your objects, over a million protocols and a million forms, when we can unify it all.

It's a very simple pattern. All it requires is that users understand basic modelling and the application's domain. The same expressions would be used by everyone...if not, at least the same pattern. No more gazillion interfaces and gazillion models.

Think about communication. Can be done in 2 ways:
1) blah blah blah can blah blah when blah blah and then some more blah blah
2) UML

You give me your domain model and, since you implement this simple no non-sense path-based model access, that's all I need to know. What you should focus on is documenting what the actual objects in your model: what they mean and what I can do with them once I have them.

This also enables generic graphical software creation. All I need is to have your domain model and then I can use a generic path composition tool (pick a node from a tree if you want).

It interactively explores the domain model, picking elements on the way.

In my integration work, I would love it if I didn't have to waste time writing stupidifying code over a miriad protocols just to get to what I needed.

If you're wondering how exactly the data should be accessed, we'll cover that in one of the next posts on this subject, in the mean time, take JOSH to heart: JSON, OSGI, Scala, Http...thank you, Gray Lens Man!


Enough for now - will continue soon...if you're interested and impatient, you can play with my prototype at http://github.com/razie/razbase/blob/master/src/razie/XP.scala