package org.myrobotlab.codec; import java.io.IOException; import java.net.URI; import java.net.URLDecoder; import org.myrobotlab.framework.Message; import org.myrobotlab.framework.TypeConverter; import org.myrobotlab.logging.LoggerFactory; import org.myrobotlab.service.interfaces.ServiceInterface; import org.slf4j.Logger; public class CodecUri { public final static Logger log = LoggerFactory.getLogger(CodecUri.class); public static Message decodeURI(URI uri) throws IOException { log.info(String.format("authority %s", uri.getAuthority())); // gperry:blahblah@localhost:7777 log.info(String.format(" host %s", uri.getHost())); // localhost log.info(String.format(" port %d", uri.getPort())); // 7777 log.info(String.format(" path %s", uri.getPath())); log.info(String.format(" query %s", uri.getQuery())); // /api/string/gson/runtime/getUptime log.info(String.format(" scheme %s", uri.getScheme())); // http log.info(String.format(" userInfo %s", uri.getUserInfo())); // gperry:blahblah Message msg = decodePathInfo(uri.getPath()); return msg; } /** * FIXME - this method requires the class to be loaded for type conversions * !!! Decoding a URI or path can depend on Context & Environment part of * decoding relies on the method signature of an object - therefore it has to * be loaded in memory, but if the ability to send messages from outside this * system is desired - then the Message must be able to SPECIFY THE DECODING * IT NEEDS !!! - without the clazz available !!! * * URI path decoder - decodes a path into a MRL Message. Details are here * http://myrobotlab.org/content/myrobotlab-api JSON is the default encoding * * @param pathInfo * - input path in the format - * /{api-type}(/encoding=json/decoding=json/)/{method}/{param0}/{ * param1}/... * @return * @throws IOException */ // FIXME - reconcile with WebGUIServlet public static final Message decodePathInfo(String pathInfo) throws IOException { // FIXME optimization of HashSet combinations of supported encoding instead // of parsing... // e.g. HashMap<String> supportedEncoding.containsKey( // refer to - http://myrobotlab.org/content/myrobotlab-api String[] parts = pathInfo.split("/"); // String trailingCharacter = pathInfo.substring(pathInfo.length() - 1); // synchronous - blocking // Encoder.invoke(Outputs = null, "path"); // search for //: for protocol ? // api has functionality .. // it delivers the next "set" of access points - which is the services // this allows the calling interface to query if (!CodecUtils.PREFIX_API.equals(parts[1])) { throw new IOException(String.format("/api expected received %s", pathInfo)); } // FIXME INVOKING VS PUTTING A MESSAGE ON THE BUS Message msg = new Message(); if (parts.length > 3) { msg.name = parts[2]; msg.method = parts[3]; } else if (parts.length == 3) { // lazy runtime method call msg.method = parts[2]; // FIXME - NOT GOOD - the encoder SHOULD NOT NEED OR DEPEND ON ANY RUNTIME // OR // INSTANCE INFO !! // precedence - // 1. Runtime method /* * if (Runtime.getInstance().getMessageSet().contains(msg.method)){ * * } // 2. get named instance of service if () */ } else { // lazy runtime help msg.method = "help"; return msg; } if (parts.length > 4) { // FIXME - ALL STRINGS AT THE MOMENT !!! String[] jsonParams = new String[parts.length - 4]; // System.arraycopy(parts, 4, jsonParams, 0, parts.length - 4); // FIXME - this is a huge assumption of type of encoding ! - needs to be // dynamic ! for (int i = 0; i < jsonParams.length; ++i) { String result = URLDecoder.decode(parts[i + 4], "UTF-8"); jsonParams[i] = result; } ServiceInterface si = org.myrobotlab.service.Runtime.getService(msg.name); if (si == null){ si = org.myrobotlab.service.Runtime.getInstance(); } // FIXME - this is a huge assumption of type of encoding ! - needs to be // dynamic ! msg.data = TypeConverter.getTypedParamsFromJson(si.getClass(), msg.method, jsonParams); } return msg; } }