Tuesday, September 30, 2008

Format groovy StreamingMarkupBuilder XML

Playing with groovy this week, and specifically the MarkupBuilder and StreamingMarkupBuilder classes to create XML documents. MarkupBuilder is simple but doesn't handle namespaces in a DSL friendly way. StreamingMarkupBuilder handles namespaces nicely but doesn't pretty-print format the xml in the output. And finding information on how to pretty print xml from StreamingMarkupBuilder is rather difficult on Google and the like, so here is the solution that I found using the Transformer class that ships with the JDK.


String indentXml(xml) {
def factory = TransformerFactory.newInstance()
factory.setAttribute("indent-number", 2);

Transformer transformer = factory.newTransformer()
transformer.setOutputProperty(OutputKeys.INDENT, 'yes')
StreamResult result = new StreamResult(new StringWriter())
transformer.transform(new StreamSource(new ByteArrayInputStream(xml.toString().bytes)), result)
return result.writer.toString()
}

xml is the output from the .bind call on StreamingMarkupBuilder. And the setAttribute call on TransformerFactory is needed to get around a JDK bug.

Sunday, August 17, 2008

Fix Twitter RSS in Google Reader

Here's an awesome fix to read a Twitter RSS feed with Google Reader. I just had to share because it took too long for me to find a work around to twitter's authenticated RSS feed that Google Reader couldn't show.

Thursday, July 31, 2008

Use Plugin Classpath with Openfire Plugin

When creating an Openfire plugin, some classes cannot be found by the default classpath. This is a result of the way that Openfire loads plugins and their jars into the classpath. For me, specifically, I got a ClassNotFoundException when trying to create an IntialContext with WLIntialContextFactory, even though the weblogic.jar was in my plugin lib folder. One solution is to move everything from the plugin/lib folder into openfire/lib. But this is messy at best.

Luckily, I found a solution from someone trying to use
GWT in an Openfire Plugin.

First, set a PluginClassLoader on your Plugin class. Here is my trimmed example:

...
private PluginClassLoader pluginClassLoader = null;
...
public void initializePlugin(PluginManager pManager, File pluginDirectory) {
pluginClassLoader = pManager.getPluginClassloader(this);
}
...
public PluginClassLoader getPluginClassLoader() {
return pluginClassLoader;
}


Then, in my class that attempts to load a Context, before loading it I do this:

MyPlugin myPlugin = (MyPlugin) XMPPServer.getInstance()
.getPluginManager().getPlugin("myplugin");
if (myPlugin != null && myPlugin.getPluginClassLoader() != null) {
Thread.currentThread().setContextClassLoader(
myPlugin.getPluginClassLoader().getClassLoader());
}

Wednesday, July 30, 2008

Enum Serialization with Weblogic EJB Client

I was trying to setup an ejb client to connect to an ejb running on a Weblogic 9 app server. I could connect fine, but kept getting a Mismatched serialization uids error on a Java 5 Enum class. After some digging I found
a fix on JavaRanch. For whatever reason using the wlclient.jar will not work when serializing enums, but using the full blown weblogic.jar is fine. I'm going to ignore the details on this one and just move along, but maybe someone else understands the problem/workaround/fix better?

Tuesday, July 22, 2008

Custom servlet in Openfire plugin

I've been working on creating a plugin for our Openfire server, which is currently on version 3.3.3. The Plugin developer guide is a little help, and so are the message boards, but there is still some detail missing.

Situation: I want to have a custom servlet that is available on the same url:port as our admin server. I don't want to have to login to the admin server to reach this url, and the output from this servlet should not be wrapped by the openfire sitemesh template.

First, I registered the servlet in a web-custom.xml, but I could not get my servlet to appear. I had a url like http://localhost:9090/plugins/myplugin/CustomServlet. I couldn't find an answer on the message boards so I pulled down the source and started debugging. Turns out that the PluginServlet class does a toLower on the servlet url. So changing the url pattern from /CustomServlet to /customservlet in the web-custom.xml fixed the problem.

Next, to remove the security for hitting the servlet, I used the information from this post. Adding AuthCheckFilter.addExclude("CustomServlet") to the initializePlugin method fixed it up.

Lastly, as mentioned here and here, adding <meta name='decorator' content='none'/> tells sitemesh to not use the normal openfire template.

Hopefully this info will help me remember this stuff down the line...

Thursday, February 28, 2008

Custom sort key with Ext JS Grids

I've begun using Ext JS in the last few days. I'm very impressed by the professionalism and api documentation, but there is still a lot to be desired as far as installation and initial setup docs.

Anyway... I spent a couple hours trying to track down a way to sort a column in my GridPanel by a value other than its text. That is, I want the column to sort on a keyed index that is different than just alphabetically sorting the text value. This seemed like something that should be built into the framework, like with Displaytag, but unfortunately it is not!

Finally, after digging through the API docs, google searches, and ext forum searches, I found a solution.

Basically you have to define a custom sortType on the Record. Here is my example code that sorts cities on an arbitrary "FavoriteCity" index:

function sortFavoriteCities(cityName) {
var sortOrder = {'New York':0, 'London':1, 'Chicago':2, 'Paris':3};
return sortOrder[cityName];
}

var reader = new Ext.data.ArrayReader({}, [
{name: 'city', sortType: sortFavoriteCities},
{name: 'state'},
{name: 'country'}
]);


I just hope that this helps someone else save a few hours! And, it would be very nice if the Ext JS developers would add a helper method where we could just pass the "sortOrder" array into the sortType field as a custom sort order.
{name: 'city', sortType: {'New York':0, 'London':1, 'Chicago':2, 'Paris':3}}
Or extend that a step farther and allow sortType to use a different record as the sort key, like
{name: 'city', sortType: 'cityIndex'}, {name: 'cityIndex'}

Sunday, January 27, 2008

Using Eclipse for C++ with GLUT on Windows

For my latest grad school class at UNO, cs8626 Computer Graphics (yeah, its an easy elective for this semester), I need to develop some code using OpenGL. In my 10 years as a Java web app developer I haven't had any need for OpenGL before now, so my knowledge of it is around "beginner" to "sounds like something cool to learn". I can get by with C/C++/Make and the like, but until now I've either used A) Visual Studio back in college, B) a random linux box, or C) Cygwin to do any of my coding. But since I use Eclipse for my Java coding I thought I would tryout the C++ support that it offers on this Windows XP machine.

And, of course, it is next to impossible to navigate and deduce the steps needed to set this all up from the Eclipse website and wiki pages.

Thankfully, after only a few hours and random searches, I found Paul Solt's GLUT Setup Tutorial with Eclipse CDT on Windows. It goes step by step to get everything installed and running. Note: before finding Paul's page, I had already gone through Brian Lee's steps to install MinGW, and I couldn't get to the Max Berger page that Paul links to; so your results to his step #2 may vary. MinGW is a simple way to install the g++ compiler and its dependencies without using cygwin.

I'm all setup with my first GLUT hello world app for my first assignment now. Hopefully this post will help someone else do the same in the future.