ValidationSuiteServer.java
001 package com.flat502.rox.demo.validation;
002 
003 import java.io.FileOutputStream;
004 import java.net.InetAddress;
005 import java.util.Date;
006 import java.util.Map;
007 
008 import com.flat502.rox.log.Level;
009 import com.flat502.rox.log.LogFactory;
010 import com.flat502.rox.log.SimpleLogFactory;
011 import com.flat502.rox.log.StreamLog;
012 import com.flat502.rox.marshal.NopFieldNameCodec;
013 import com.flat502.rox.server.XmlRpcProxyingRequestHandler;
014 import com.flat502.rox.server.XmlRpcServer;
015 
016 /**
017  * An implementation of the suite of methods defined by
018  * the <a href="http://www.xmlrpc.com/validator1Docs">XML-RPC validation suite</a>.
019  */
020 public class ValidationSuiteServer implements IValidationSuite {
021   public int arrayOfStructsTest(MoeLarryAndCurly[] list) {
022     int total = 0;
023     for (int i = 0; i < list.length; i++) {
024       total += list[i].curly;
025     }
026     return total;
027   }
028 
029   public EntityInfo countTheEntities(String str) {
030     EntityInfo result = new EntityInfo();
031     for (int i = 0; i < str.length(); i++) {
032       switch (str.charAt(i)) {
033       case '<':
034         result.ctLeftAngleBrackets++;
035         break;
036       case '>':
037         result.ctRightAngleBrackets++;
038         break;
039       case '&':
040         result.ctAmpersands++;
041         break;
042       case '\'':
043         result.ctApostrophes++;
044         break;
045       case '"':
046         result.ctQuotes++;
047         break;
048       }
049     }
050     return result;
051   }
052 
053   public int easyStructTest(MoeLarryAndCurly struct) {
054     return struct.curly + struct.larry + struct.moe;
055   }
056 
057   public Map echoStructTest(Map struct) {
058     return struct;
059   }
060 
061   public Object[] manyTypesTest(Integer n, Boolean b, String s, Double d,
062       Date dt, byte[] b64) {
063     return new Object[] { n, b, s, d, dt, b64 };
064   }
065 
066   public String moderateSizeArrayCheck(String[] list) {
067     return list[0+ list[list.length - 1];
068   }
069 
070   public int nestedStructTest(Map calendar) {
071     Map months = (Mapcalendar.get("2000");
072     Map days = (Mapmonths.get("04");
073     Map buriedStruct = (Mapdays.get("01");
074     Integer moe = (IntegerburiedStruct.get("moe");
075     Integer larry = (IntegerburiedStruct.get("larry");
076     Integer curly = (IntegerburiedStruct.get("curly");
077     return moe.intValue() + larry.intValue() + curly.intValue();
078   }
079 
080   public MultipliedStruct simpleStructReturnTest(int n) {
081     return new MultipliedStruct(n);
082   }
083 
084   /**
085    * Start an instance of this demo server.
086    @param args
087    *   A list of parameters indicating
088    *   the <code>host/address</code> and
089    *   <code>port</code> to bind to. These default to 
090    *   <code>localhost</code> and <code>8080</code> if
091    *   not specified.
092    */
093   public static void main(String[] args) {
094     try {
095       String host = "localhost";
096       int port = 8080;
097 
098       if (args != null && args.length > 0) {
099         host = args[0];
100         if (args.length > 1) {
101           port = Integer.parseInt(args[1]);
102         }
103       }
104       System.out.println("Starting server on " + host + ":" + port);
105 
106       LogFactory.configure(new SimpleLogFactory(new StreamLog(new FileOutputStream("validation.log"), Level.TRACE)));
107       XmlRpcServer server = new XmlRpcServer(InetAddress.getByName(host), port);
108 
109       // By default RoX expects hyphenated struct member names. The XML-RPC
110       // validation suite uses camelCase. This can be changed by passing
111       // RoX an unmarshaller configured with a different FieldNameDecoder.
112       // 
113       // The encoding (marshalling) side is up to the request handler.
114       // In this case we're using the proxying request handler provided by
115       // Rox, which accepts a FieldNameEncoder as an optional constructor
116       // parameter.
117       //
118       // The NopFieldNameCodec returns the field name unchanged.
119       NopFieldNameCodec fieldNameCodec = new NopFieldNameCodec();
120       
121       // We don't use registerProxyingHandler() here because
122       // we want to provide a custom FieldNameCodec.
123       // registerProxyingHandler() is just a convenience method
124       // consisting of the next few lines of code anyway.
125       String namePattern = "^validator1\\.(.*)";
126       XmlRpcProxyingRequestHandler proxy = new XmlRpcProxyingRequestHandler(
127           namePattern, new ValidationSuiteServer(), fieldNameCodec);
128       server.registerHandler(null, namePattern, proxy, proxy);
129       server.start();
130     catch (Exception e) {
131       e.printStackTrace();
132     }
133   }
134 }