Monday, April 23, 2012

A "Guicier" Apache XML-RPC

Call me old-school if you like... I guess I am. When everyone was raving about Guice, I was simply taking note of it. "Oh sure... another thing to pass other things around." However, something stuck, because the good programmer in me was referring me back to Guice when the bad programmer was whispering "static state singleton" in my ear. It did not take me long to start appreciating what Guice can do. Unfortunately, I found the Internet to be "not-so-good" for Guice examples, mainly for three reasons:
  1. The examples were too trivial to extend to real applications.
  2. The more complicated examples were doing really horrid things. (Like a singleton class that keeps the injector available for lazy and even not-so-lazy instantiations. Sorry, but why is this better? That's like taking an orange-overall crook, dressing him in a suit and calling him an honest politician. Uhh... wait... that's not what I mean...) 
  3. Guice does not lend itself well to already badly written code, hence the difficulty to find examples that deals with those situations. 
What made things a bit tricky was the Guice-rules I made for myself, either because it felt right or made understanding better (I am good with algorithm design, but find keeping a large complex system in my head a daunting task.)
  1. You have one injector and one injector only. Inject once and throw it away. The only exception I make to this is a cool trick in anonymous inner classes (more on this, later). 
  2. Keep the modules few, and put them in the same package as the program entry point. It is after-all the place where the module is used. 
  3. Do not go too far. You can easily over-guice and this DOES make matters worse. 
  4. Do not force Guice down the throat the people that will make use of your code (i.e. if you are writing a library). There is enough of that in the computer world. 
The really first challenging problem that had be baffled was Apache's immensely beautiful enigeering marvel that is XML-RPC. One of the big problems with this library is the way in which the handlers get created. Apache uses its own internal reflection approach to create the class, which cuts Guice out of the picture. Fortunately (?), in their infinite wisdom, they created a RequestProcessorFactoryFactory interface which allows you do do the creation yourself. (It sounds almost like the proverbial "I know that you know, that I know that you know I know, did you know that?)

Regardless, in order to get this working another injector needs to be passed to the servlet, violating my first rule. However... I found a workaround. I'll let the code speak for itself. Here goes:

First the main class where everything gets wired up. Simple and self-explanatory:

package gj.guice.xmlrpc;
import org.eclipse.jetty.server.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
public class SimpleServer {
private Logger logger = LoggerFactory.getLogger(SimpleServer.class);
private static final int PORT = 8081;
private Server server;
@Inject
public SimpleServer(Server server) {
this.server = server;
}
public void start() throws Exception {
server.start();
logger.debug("Server started on port: " + PORT);
}
public static void main(String[] args) throws Exception {
Injector injector = Guice.createInjector(new SimpleModule(PORT));
SimpleServer server = injector.getInstance(SimpleServer.class);
server.start();
}
}

Secondly, the servlet. This merely redirects traffic to the handler and sets the factory. Note the injection. Also note the absense of an injector:

package gj.guice.xmlrpc;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.XmlRpcHandler;
import org.apache.xmlrpc.server.PropertyHandlerMapping;
import org.apache.xmlrpc.server.RequestProcessorFactoryFactory;
import org.apache.xmlrpc.server.XmlRpcHandlerMapping;
import org.apache.xmlrpc.server.XmlRpcNoSuchHandlerException;
import org.apache.xmlrpc.webserver.XmlRpcServlet;
import com.google.inject.Inject;
public class RedirectXmlRpcServlet extends XmlRpcServlet {
private static final long serialVersionUID = 1L;
private volatile PropertyHandlerMapping mapping = new PropertyHandlerMapping();
@Inject
public RedirectXmlRpcServlet(RequestProcessorFactoryFactory factory) {
mapping.setRequestProcessorFactoryFactory(factory);
}
@Override
protected XmlRpcHandlerMapping newXmlRpcHandlerMapping() throws XmlRpcException {
return new XmlRpcHandlerMapping() {
@Override
public XmlRpcHandler getHandler(String operation) throws XmlRpcNoSuchHandlerException, XmlRpcException {
Class<?> clazz = MyHandler.class;
mapping.addHandler(clazz.getSimpleName(), MyHandler.class);
return mapping.getHandler(clazz.getSimpleName() + ".request");
}
};
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
super.doGet(request, response);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
super.doPost(request, response);
}
}

Thirdly the handler with some test injection (demonstrating that we can inject anything we want). It merely echoes the request:

package gj.guice.xmlrpc;
import java.util.Map;
import org.apache.xmlrpc.XmlRpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.google.inject.name.Named;
public class MyHandler {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Inject
public MyHandler(@Named("mystring") String value) {
logger.debug("Injected value: {}", value);
}
public Map<String, Object> request(Map<String, Object> in) throws XmlRpcException {
logger.debug("Request received...");
return in;
}
}
view raw MyHandler.java hosted with ❤ by GitHub

...and lastly, the module. The magic happens in the getRequestProcessorFactoryFactory provider. Have you ever had the need to write an anonymous local inner class within yet another anonymous local inner class? Well, now you do. I call it the Russion-doll pattern (anti-pattern?) Guice has access to the injector so you can merely inject it here as well:

package gj.guice.xmlrpc;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.XmlRpcRequest;
import org.apache.xmlrpc.server.RequestProcessorFactoryFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import com.google.inject.Binder;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Provides;
import com.google.inject.name.Names;
public class SimpleModule implements Module {
private final int port;
public SimpleModule(int port) {
this.port = port;
}
@Override
public void configure(Binder binder) {
binder.bind(MyHandler.class);
binder.bindConstant().annotatedWith(Names.named("mystring")).to("See it works!");
}
@Provides
public Server getServer(final ServletContextHandler handler) {
Server server = new Server();
Connector connector = new SelectChannelConnector();
connector.setHost("0.0.0.0");
connector.setPort(port);
server.setConnectors(new Connector[] { connector });
server.setHandler(handler);
return server;
}
@Provides
public ServletContextHandler getServletHandler(RequestProcessorFactoryFactory factory) {
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.addServlet(new ServletHolder(new RedirectXmlRpcServlet(factory)), "/*");
return context;
}
@Provides
@SuppressWarnings("unchecked")
public RequestProcessorFactoryFactory getRequestProcessorFactoryFactory(final Injector injector) {
return new RequestProcessorFactoryFactory() {
@Override
public RequestProcessorFactory getRequestProcessorFactory(final Class pClass) throws XmlRpcException {
return new RequestProcessorFactory() {
@Override
public Object getRequestProcessor(XmlRpcRequest pRequest) throws XmlRpcException {
return injector.getInstance(pClass);
}
};
}
};
}
}

So, the order of creation. The main class gets an instance of the SimpleServer, which needs an instance of a ServletContextHandler, which needs a RequestProcessorFactoryFactory which needs an injector to inject an instance of a new handler. Basically boils down to lazy instantiation which is set up in the module.

Wednesday, April 18, 2012

Doto

I've always had an issue with code like this: (event though I do it all the time)

Map map = new HashMap(); //you're forced to create a temporary variable
map.put(1, "one");
map.put(2, "two"); //because you can't chain these void method calls(mutators)
...
return map;
view raw nodoto.java hosted with ❤ by GitHub

Nothing wrong with it, but wouldn't it be nice to be able to chain those calls and avoid declaring that local variable?

I am currently reading "The Joy of Clojure" and came across the doto macro in clojure, which enables you to do the above like so: 
   (doto (new java.util.HashMap) ; or just (java.util.HashMap.)  
         (.put 1 "One")  
         (.put 2 "Two"))  
Nice!  But alas, I am forced to use Java by day so I tried to figure out the best approach to do this.  The first one comes to mind is this:
 new HashMap<Integer, String>(){{  
     put(1, "one");  
     put(2, "Two");  
   }};  

Which works perfectly except that it assumes you are the one constructing the object.  So I tried a more functional approach:
public static <K> Doto<K> doto(K k){
return new Doto(k);
}
public static class Doto<T>{
private T t;
private Doto(T t){
this.t = t;
}
public T DO(FVoid<T> f){
f.apply(t);
return t;
}
}
public interface FVoid<T>{
public void apply(T t);
}
//Which can be used like so :
doto(Maps.<Integer, String>newHashMap()).DO(new FVoid<HashMap<Integer, String>>(){
public void apply(HashMap<Integer, String> map){
map.put(1, "one");
map.put(2, "Two");
}
});
view raw doto.java hosted with ❤ by GitHub


I believe I've gone and made it worse :(

I also tried a js implementation, which is pretty redundant for maps/objects as object literals are built in:
function doto(m, f){f(m); return m;}
//var result = {1: "One", 2: "Two"}
var result = doto({}, function(m){ m[1] = "One"; m[2] = "Two"});
view raw doto.js hosted with ❤ by GitHub


I would love to see some alternate solutions/improvements or maybe event implementations in other languages!  


Friday, April 13, 2012

These Steps

We all can probably agree that there are too many to-do lists and step applications, websites, browser plugins, IDE plugins, etc.

I have had a look at a few, but I always end up with a notepad list or "//Todo" entries in my code.

Here is another one with a collaborative, documentary and multiple integration future:

Some features include:
  • A hierarchy of steps, with current edge steps ordered, unordered, tabs and options with leaf steps youtube, image, code.
  • Sharing of steps via a link or to another registered user.
  • Exporting to PDF.
  • Reference steps from other areas in the hierarchy.
  • Editing: copy, cut and paste steps (nodes).
  • Keyboard shortcuts for navigation and editing.
Some features that are in the works:
  • Exporting to Json.
  • Websockets for real time collaboration.
Some suggested features being considered for future implementation:
  • Cucumber support, such that steps are confined to the structure of a cucumber file, this would be awesome for collaboration between the developers and clients.
  • Gist support, such that a leaf step can reference a gist.
It is still under development but it looks promising, give it a try!