-package iotruntime.brillo;
-
-// Java libraries
-import java.io.BufferedWriter;
-import java.io.PrintWriter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.ProtocolException;
-import java.net.URL;
-import java.lang.Class;
-import java.lang.reflect.*;
-import java.util.Map;
-
-// Google APIs
-import com.google.api.services.clouddevices.model.CommandDefNew;
-import com.google.api.services.clouddevices.model.Device;
-
-
-/** IoTBrilloWeaveCodeGenerator class that connects to
- * Google Brillo/Weave server based on user's credentials
- * and creates user's class and interface
- * <p>
- * Steps:
- * 0) Compile iotruntime
- * 1) Run this code generator
- * - go to $(IOTJAVA_CLASSPATH)/iot/bin/iotruntime/brillo/
- * - run this class with this command line:
- * java -cp .:../../:../../../jars/brillo/*:../../../jars/brillo/libs/* iotruntime.brillo.IoTBrilloWeaveCodeGenerator -help
- * - follow the instructions to generate codes
- * 2) If credentials_cache.json hasn't been created then one will be created
- * 3) Both interface and implementation java API source files will be created
- * 4) We can move them to the right directories with the credentials_cache.json
- * - move the interface java file into folder "interfaces"
- * - create a folder in "iot/benchmarks/drivers" with the class name and put
- * the class java file there; don't forget to create <class>.config file
- * and modify the Makefile
- * 5) A device driver can be created based on the created API's
- *
- * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
- * @version 1.0
- * @since 2016-06-09
- */
-public class IoTBrilloWeaveCodeGenerator {
-
- /**
- * IoTBrilloWeaveCodeGenerator properties
- */
- private PrintWriter pw;
- private String strInterfaceName;
- private String strClassName;
- private IoTBrilloWeaveCloudConnection iotBrillo;
-
- /**
- * Constructor
- */
- public IoTBrilloWeaveCodeGenerator(String[] strArgs) {
-
- this.strInterfaceName = strArgs[0];
- this.strClassName = strArgs[1];
- this.iotBrillo = new IoTBrilloWeaveCloudConnection(strArgs[2], strArgs[3], strArgs[4]);
- this.iotBrillo.connectionSetup(strArgs[5]);
- }
-
-
- /**
- * Generate interface
- *
- * @return void
- */
- public void generateInterface() throws IOException {
-
- // Initialize FileWriter and PrintWriter
- FileWriter fwInterface = new FileWriter(strInterfaceName + ".java");
- this.pw = new PrintWriter(new BufferedWriter(fwInterface));
- // Write the interface header
- generateInterfaceImports();
- println("");
- println("public interface " + strInterfaceName + " extends Remote {");
- println("");
- generateInterfaceBody(this.iotBrillo.getDeviceObject());
- println("");
- //Close interface
- println("}");
- pw.close();
- }
-
-
- /**
- * Generate interface import statements
- *
- * @return void
- */
- public void generateInterfaceInit() {
- println("public void init() throws RemoteException;");
- }
-
-
- /**
- * Generate interface init method
- *
- * @return void
- */
- public void generateInterfaceImports() {
- println("package iotcode.interfaces;");
- println("");
- println("import java.rmi.Remote;");
- println("import java.rmi.RemoteException;");
- }
-
-
- /**
- * Generate interface body
- *
- * @param device Device object that contains JSON parameters
- * @return void
- */
- private void generateInterfaceBody(Device device) {
-
- generateInterfaceInit();
- Map<String,Map<String,CommandDefNew>> mapCommand = device.getCommandDefs();
- for(String strCmd : mapCommand.keySet()) {
- Map<String,CommandDefNew> mapSubCommand = mapCommand.get(strCmd);
- for(String strSubCmd : mapSubCommand.keySet()) {
- print("public void " + strCmd + "_" + strSubCmd + "(");
- CommandDefNew cmd = mapSubCommand.get(strSubCmd);
- if (cmd.getParameters() != null) {
- // If we have parameters ...
- int iParamCount = 0;
- Map<String,Map<String,Object>> mapParam = cmd.getParameters();
- for (String strParamName : mapParam.keySet()) {
- iParamCount++;
- Map<String,Object> mapParamProp = mapParam.get(strParamName);
- for (String strParamProp : mapParamProp.keySet()) {
- if (strParamProp.equals("type")) {
- print(getJavaType(mapParamProp.get(strParamProp).toString()) + " ");
- if (iParamCount == mapParam.size())
- println(strParamName + ") throws RemoteException;");
- else
- print(strParamName + ", ");
- }
- }
- }
- } else {
- // If we don't have parameters ...
- println(") throws RemoteException;");
- }
- }
- }
- }
-
-
- /**
- * Type translator from JSON syntax to Java
- *
- * @return String
- */
- private String getJavaType(String strJsonType) {
-
- if (strJsonType.equals("string")) {
- return "String";
- } else if (strJsonType.equals("integer")) {
- return "Integer";
- } else if (strJsonType.equals("boolean")) {
- return "Boolean";
- } else if (strJsonType.equals("number")) {
- return "Float";
- } else { // NULL is returned when type is not recognized
- return null;
- }
- }
-
-
- /**
- * Generate class
- *
- * @return void
- */
- public void generateClass() throws IOException {
-
- // Initialize FileWriter and PrintWriter
- FileWriter fwClass = new FileWriter(strClassName + ".java");
- this.pw = new PrintWriter(new BufferedWriter(fwClass));
- // Write the import statements
- generateImports();
- println("");
- println("public class " + strClassName +
- " extends IoTBrilloWeave" +
- " implements " + strInterfaceName + " {");
- println("");
- generateAtConfigs();
- println("");
- generateConstructor();
- println("");
- generateInit();
- println("");
- generateClassAPIs(this.iotBrillo.getDeviceObject());
- //Close class
- println("}");
- pw.close();
- }
-
-
- /**
- * Generate @config statements for IoTDeviceAddress
- *
- * @return void
- */
- public void generateAtConfigs() {
-
- println("@config private IoTSet<IoTAddress> GoogleAccountAddress;");
- println("@config private IoTSet<IoTAddress> GoogleAPIsAddress;");
- }
-
-
- /**
- * Generate init method
- *
- * @return void
- */
- public void generateInit() {
-
- println("public void init() {");
- println("Iterator itr = GoogleAccountAddress.iterator();");
- println("IoTAddress address = (IoTAddress)itr.next();");
- println("super.setAuthScope(address.getHostName());");
- println("}");
- }
-
-
- /**
- * Generate class APIs
- *
- * @param device Device object that contains JSON parameters
- * @return void
- */
- private void generateClassAPIs(Device device) {
-
- // Generate method header
- Map<String,Map<String,CommandDefNew>> mapCommand = device.getCommandDefs();
- for(String strCmd : mapCommand.keySet()) {
- Map<String,CommandDefNew> mapSubCommand = mapCommand.get(strCmd);
- for(String strSubCmd : mapSubCommand.keySet()) {
- print("public void " + strCmd + "_" + strSubCmd + "(");
- CommandDefNew cmd = mapSubCommand.get(strSubCmd);
- boolean doesParamExist = false;
- if (cmd.getParameters() != null) {
- // If we have parameters ...
- doesParamExist = true;
- int iParamCount = 0;
- Map<String,Map<String,Object>> mapParam = cmd.getParameters();
- for (String strParamName : mapParam.keySet()) {
- iParamCount++;
- Map<String,Object> mapParamProp = mapParam.get(strParamName);
- for (String strParamProp : mapParamProp.keySet()) {
- if (strParamProp.equals("type")) {
- print(getJavaType(mapParamProp.get(strParamProp).toString()) + " ");
- if (iParamCount == mapParam.size())
- println(strParamName + ") {");
- else
- print(strParamName + ", ");
- }
- }
- }
- } else {
- // If we don't have parameters ...
- println(") {");
- }
- generateMethodBody(cmd, doesParamExist, strCmd, strSubCmd);
- generateCommandInsertionAndException();
- println("}");
- println("");
- }
- }
- }
-
-
- /**
- * Generate method body
- *
- * @param cmd Object CommandDefNew that contains information about the command
- * @param doesParamExist Boolean that tracks if the method has parameters
- * @param strCmd String that contains the main command name
- * @param strSubCmd String that contains the sub command name
- * @return void
- */
- private void generateMethodBody(CommandDefNew cmd, boolean doesParamExist, String strCmd, String strSubCmd) {
-
- if (doesParamExist) {
- // If we have parameters ...
- //int iParamCount = 0;
- println("Map<String, Object> parameters = new HashMap<String, Object>();");
- Map<String,Map<String,Object>> mapParam = cmd.getParameters();
- for (String strParamName : mapParam.keySet()) {
- //iParamCount++;
- Map<String,Object> mapParamProp = mapParam.get(strParamName);
- for (String strParamProp : mapParamProp.keySet()) {
- if (strParamProp.equals("type")) {
- //print(getJavaType(mapParamProp.get(strParamProp).toString()) + " ");
- println("parameters.put(\"" + strParamName + "\", " + strParamName + ");");
- }
- }
- }
- }
- println("Command command = new Command()");
- println("\t.setName(\"" + strCmd + "." + strSubCmd + "\")");
- if (doesParamExist)
- println("\t.setParameters(parameters)");
- println("\t.setDeviceId(device.getId());");
- }
-
-
- /**
- * Generate command insertion and exception statements
- *
- * @return void
- */
- private void generateCommandInsertionAndException() {
- println("try {");
- println("command = apiClient.commands().insert(command).execute(); }");
- println("catch (IOException e) {");
- println("throw new RuntimeException(\"Could not insert command\", e); }");
- println("");
- println("try {");
- println("System.out.println(\"Sent command to the device:\" + jsonFactory.toPrettyString(command)); }");
- println("catch (IOException e) {");
- println("throw new RuntimeException(e); }");
- }
-
-
- /**
- * Generate import statements
- *
- * @return void
- */
- private void generateImports() {
-
- println("package iotcode." + strClassName + ";");
- println("");
- println("import com.google.api.client.json.jackson2.JacksonFactory;");
- println("import com.google.api.services.clouddevices.CloudDevices;");
- println("import com.google.api.services.clouddevices.model.Command;");
- println("import com.google.api.services.clouddevices.model.Device;");
- println("");
- println("import java.io.IOException;");
- println("import java.util.HashMap;");
- println("import java.util.Iterator;");
- println("import java.util.Map;");
- println("");
- println("import iotcode.interfaces.LEDFlasher;");
- println("import iotruntime.brillo.IoTBrilloWeave;");
- println("import iotruntime.brillo.IoTBrilloWeaveCloudConnection;");
- println("import iotruntime.slave.IoTAddress;");
- println("import iotruntime.slave.IoTSet;");
- println("import iotchecker.qual.*;");
- }
-
-
- /**
- * Generate constructor
- *
- * @return void
- */
- private void generateConstructor() {
- // Write the constructor
- println("public " + strClassName +
- "(String _clientId, String _clientSecret, String _apiKey, String _deviceId) {");
- println("super(_clientId, _clientSecret, _apiKey, _deviceId);");
- println("}");
- }
-
-
- /**
- * Display help message
- *
- * @return void
- */
- public static void displayHelpMessage() {
- System.out.println();
- System.out.println("Please use this code generator in the following syntax:");
- System.out.print("java -cp <classpath> IoTBrilloWeaveCodeGenerator <interface_name> ");
- System.out.println("<class_name> <client_id> <client_secret> <api_key> <device_id>");
- System.out.println("e.g.");
- System.out.print("java -cp .:../clouddevices/*:../clouddevices/libs/* IoTBrilloWeaveCodeGenerator ");
- System.out.print("LEDFlasherTest LEDFlasherTestImplementation 627170482755-4l2gd5m3lf6ej674vqr8sdc14gmeva3e.apps.googleusercontent.com ");
- System.out.println("Yhj6QzCxeO2B0i25JHqYShsi AIzaSyDcYp9RQAV2ELZWxVIjPBAzIPGiXAAORs0 77173ed5-3303-4c54-f852-b8f51fb7b31f");
- System.out.println();
- System.out.println("To show this help message: java IoTBrilloWeaveCodeGenerator --help");
- System.out.println();
- }
-
-
- /**
- * Helper functions that help print to files
- */
- boolean newline=true;
- int tablevel=0;
-
- private void print(String str) {
- if (newline) {
- int tab=tablevel;
- if (str.equals("}"))
- tab--;
- for(int i=0; i<tab; i++)
- pw.print("\t");
- }
- pw.print(str);
- updatetabbing(str);
- newline=false;
- }
-
- private void println(String str) {
- if (newline) {
- int tab = tablevel;
- if (str.equals("}"))
- tab--;
- for(int i=0; i<tab; i++)
- pw.print("\t");
- }
- pw.println(str);
- updatetabbing(str);
- newline = true;
- }
-
- private void updatetabbing(String str) {
- tablevel += count(str,'{') - count(str,'}');
- }
-
- private int count(String str, char key) {
- char[] array = str.toCharArray();
- int count = 0;
- for(int i=0; i<array.length; i++) {
- if (array[i] == key)
- count++;
- }
- return count;
- }
-
-
- /**
- * Call main function for file generations
- *
- * @param args[0] Interface name
- * @param args[1] Class name
- * @param args[2] Client ID
- * @param args[3] Client secret
- * @param args[4] API key
- * @param args[5] Device ID
- */
- public static void main(String[] args) throws IOException {
-
- if(args.length < 6 || args[0].contains("help")) {
- displayHelpMessage();
- } else {
- IoTBrilloWeaveCodeGenerator iotBrilloCodeGen = new IoTBrilloWeaveCodeGenerator(args);
- iotBrilloCodeGen.generateInterface();
- iotBrilloCodeGen.generateClass();
- }
- }
-}