--- /dev/null
+package com.example.lede2;\r
+\r
+import android.app.ProgressDialog;\r
+import android.content.Context;\r
+import android.support.design.widget.Snackbar;\r
+import android.support.v7.app.AppCompatActivity;\r
+import android.util.Log;\r
+import android.util.Pair;\r
+import android.util.SparseBooleanArray;\r
+import android.view.View;\r
+import android.widget.ArrayAdapter;\r
+import android.widget.Button;\r
+import android.widget.ListView;\r
+import android.widget.Spinner;\r
+import android.widget.Toast;\r
+\r
+import com.jcraft.jsch.HASH;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Properties;\r
+import java.util.Scanner;\r
+import java.util.Set;\r
+\r
+\r
+/**\r
+ * Created by Brian on 4/27/2018.\r
+ */\r
+\r
+public class ApplicationWithRelations extends AppCompatActivity implements View.OnClickListener {\r
+ protected HashMap<String, ArrayList<String>> addedSetList; //list of sets that is currently being added and their values\r
+ protected int numFields;\r
+ protected Properties prop;\r
+ protected HashMap<String, HashSet<Pair<String, String>>> addedRelations;\r
+ protected HashMap<String, HashSet<String>> addedIndependentSets;\r
+ protected Context context;\r
+ protected HashMap<String, Pair<String, String>> relations;\r
+ protected HashMap<String, String> setHashMap;\r
+ protected Spinner relationNameSpinner;\r
+ protected Spinner relationLeftSpinner;\r
+ protected Spinner relationRightSpinner;\r
+ protected Spinner setOrRelationSpinner;\r
+ protected Button addRelationButton;\r
+ protected Button doneRelationButton;\r
+ protected Button deleteRelationButton;\r
+ protected HashMap<String, String> independentSetList;\r
+ protected ArrayList<String> independentSetNames;\r
+ protected boolean hasIndependentSets;\r
+ protected boolean hasRelations;\r
+ ArrayList addedRelationsArrayList;\r
+ ProgressDialog dialog;\r
+ protected Scanner scanner;\r
+ ArrayAdapter adapter;\r
+ ListView addRelationsListView;\r
+ protected HashSet<String> applicationSetList; //list of all sets that should be used\r
+\r
+\r
+\r
+\r
+ protected void deleteFromSet(String device){\r
+ Set<String> keyset = addedSetList.keySet();\r
+ for(String s: keyset){\r
+ ArrayList<String> tempSet = addedSetList.get(s);\r
+ tempSet.remove(device);\r
+ }\r
+ }\r
+\r
+ protected void addSSHResultsToConfig(List<String> results, String filename) {\r
+ ConfigFileIO.writeToNewFile(filename,"", this );\r
+ File dir = getFilesDir();\r
+ File file = new File(dir, filename);\r
+ file.delete();\r
+ for (int i = 0; i < results.size(); i++) {\r
+ ConfigFileIO.writeToFile(filename, results.get(i), this);\r
+ }\r
+ }\r
+\r
+ protected void callSSHCommandAddComm(){\r
+ //default already in bin/installer (RELATION)\r
+ String installCommPatternCommand = "";\r
+ for(int i = 0; i < numFields; i++){\r
+ if(prop.getProperty("FIELD_TYPE_" + i).equals("IoTRelation")){\r
+ String writeToRelConfigFileCommand = "";\r
+ writeToRelConfigFileCommand += this.getString(R.string.changeToSQLConfigFileLocation);\r
+\r
+ String filename = prop.getProperty("FIELD_CONFIG_FILENAME_"+i);\r
+ HashSet<Pair<String,String>> tempSet = addedRelations.get(prop.getProperty("FIELD_" + i));\r
+\r
+ //insert roomCameraReal.config writing\r
+ writeToRelConfigFileCommand += "echo \"" + "SELECT RELATION FROM\n"+\r
+ "FIRST\n" +\r
+ prop.getProperty("FIELD_CLASS_0_" + i) + "\n" +\r
+ "OTHER\n" +\r
+ prop.getProperty("FIELD_CLASS_1_" + i) + "\n" +\r
+ "WHERE\n"; //need to add where clauses for each case\r
+ int counter = 0;\r
+ //iterates through all of the added relations under the current relationName\r
+ //ex all relations under roomCameraRel\r
+ for(Pair<String, String> pair: tempSet){\r
+ int size = tempSet.size();\r
+ Scanner scanner = new Scanner(pair.first);\r
+ String typeFirst = scanner.next();\r
+ String idFirst = scanner.next();\r
+ typeFirst += idFirst;\r
+ scanner = new Scanner(pair.second);\r
+ String typeSecond = scanner.next();\r
+ String idSecond = scanner.next();\r
+ typeSecond += idSecond;\r
+\r
+ writeToRelConfigFileCommand += "(TYPE_SOURCE='" + typeFirst + "' AND TYPE_DESTINATION='" + typeSecond + "')";\r
+\r
+\r
+ installCommPatternCommand += this.getString(R.string.changeToCommConfigFileLocation) + "echo \"" + idFirst + " " + typeFirst + "\n" +\r
+ idSecond + " " + typeSecond + "\n" +\r
+ "WRITE\" > " + filename + ";" +\r
+ "java -cp .:..:/usr/share/java/* iotinstaller.IoTInstaller -install_comm " + filename + ";" +\r
+ "rm " + filename + ";";\r
+\r
+ //if this is the last item, finish it by writing it into file\r
+ if(counter == size-1){\r
+ writeToRelConfigFileCommand += "\n;\" > " + prop.getProperty("FIELD_" + i) + ".config; \n";\r
+ installCommPatternCommand = writeToRelConfigFileCommand + installCommPatternCommand;\r
+ System.out.println("COMM" + installCommPatternCommand);\r
+ }\r
+\r
+ //if it is not the last item, concatenate or and continue\r
+ else{\r
+ writeToRelConfigFileCommand += "\nOR\n";\r
+ System.out.println(installCommPatternCommand);\r
+ }\r
+\r
+ SSH_MySQL ssh_mySQL = new SSH_MySQL();\r
+ List<String> results = new ArrayList<>();\r
+ try {\r
+ ssh_mySQL.execute(installCommPatternCommand);\r
+ Thread.sleep(1000);//To execute asyntask in ssh object, we have to sleep main thread\r
+ results = ssh_mySQL.getResultLines();\r
+ while(results.size() == 0){\r
+ Thread.sleep(500);\r
+ results = ssh_mySQL.getResultLines();\r
+ System.out.println(results);\r
+ }\r
+ System.out.println(results);\r
+ } catch (Exception e) {\r
+ Log.d("Sleep exception", "exception at getSetsAndRelations");\r
+ }\r
+ installCommPatternCommand = "";\r
+ counter++;\r
+ }\r
+\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ protected HashMap<String, ArrayList<String>> createSetList(String filename){\r
+ HashMap<String, ArrayList<String>> setListHashMap = new HashMap<>();\r
+ String setData = ConfigFileIO.readFromFile(filename, context);\r
+ Scanner scanner = new Scanner(setData);\r
+ while (scanner.hasNextLine()){\r
+ String temp = scanner.nextLine();\r
+ if(temp.equals("START")){\r
+ String setName = scanner.nextLine();\r
+ temp = scanner.nextLine();\r
+ ArrayList<String> availableDevices = new ArrayList<>();\r
+ while (!temp.equals("END")){\r
+ availableDevices.add(temp);\r
+ temp = scanner.nextLine();\r
+ }\r
+ setListHashMap.put(setName, availableDevices);\r
+ }\r
+ }\r
+ return setListHashMap;\r
+ }\r
+\r
+\r
+ //relationofTwoItems comes in form of ex: RoomSmart,LightBulbSmart. Splits them by commma and adds them to hashmap\r
+ protected void addPair(String name, String relationOfTwoItems){\r
+ String firstItem = relationOfTwoItems.substring(0, relationOfTwoItems.indexOf(","));\r
+ String secondItem = relationOfTwoItems.substring(relationOfTwoItems.indexOf(",")+1, relationOfTwoItems.length());\r
+ Pair<String, String> pair = new Pair<>(firstItem, secondItem);\r
+ relations.put(name,pair);\r
+ }\r
+\r
+ protected ArrayList<String> removeDuplicates(ArrayList<String> list){\r
+ HashSet<String> set = new HashSet<>();\r
+ set.addAll(list);\r
+ ArrayList<String> noDups = new ArrayList<>();\r
+ noDups.addAll(set);\r
+ return noDups;\r
+ }\r
+ protected String generateSQLQuery(String setName, ArrayList<String> listOfDevices){\r
+ String query = "";\r
+ query = "SELECT * FROM\n" +\r
+ setName + "\n" +\r
+ "WHERE\n";\r
+ for(int i = 0; i < listOfDevices.size(); i++){\r
+ Scanner scanner = new Scanner(listOfDevices.get(i));\r
+ String type = scanner.next();\r
+ String id = scanner.next();\r
+ query += "(TYPE='" + type + "' AND ID='" + id + "')";\r
+ if(i == listOfDevices.size() -1){\r
+ query +="\n;";\r
+ }\r
+ else{\r
+ query += "\nOR\n";\r
+ }\r
+ }\r
+ return query;\r
+ }\r
+\r
+ protected String generateSSHCommandRelation(){\r
+ String command = "";\r
+ //move to directory where the sql file should be located (SET)\r
+ command += this.getString(R.string.changeToSQLConfigFileLocation);\r
+ //go through all sets, and find their set type.\r
+ Set<String> keySet = setHashMap.keySet();\r
+ for(String s: keySet){\r
+ String setType = setHashMap.get(s);\r
+ ArrayList<String> list = addedSetList.get(setType);\r
+ list = removeDuplicates(list);\r
+ command += "echo \"" + generateSQLQuery(setType, list) + "\" > " + s + ".config" + ";";\r
+ }\r
+\r
+ keySet = addedIndependentSets.keySet();\r
+ for(String s:keySet){\r
+ String setType = independentSetList.get(s);\r
+ ArrayList<String> list = new ArrayList<>();\r
+ HashSet<String> set = addedIndependentSets.get(s);\r
+ list.addAll(set);\r
+ command += "echo \"" + generateSQLQuery(setType, list) + "\" > " + s + ".config" + ";";\r
+ }\r
+\r
+ return command;\r
+ }\r
+\r
+ @Override\r
+ public void onClick(View view) {\r
+ if(view == addRelationButton){\r
+ if(setOrRelationSpinner.getSelectedItem().toString().equals("RELATIONS")) {\r
+ //adding the user selected relation into a relationset\r
+ String leftValue = relationLeftSpinner.getSelectedItem().toString();\r
+ String rightValue = relationRightSpinner.getSelectedItem().toString();\r
+ Pair<String, String> pair = new Pair<>(leftValue, rightValue);\r
+ if ((addedRelations.get(relationNameSpinner.getSelectedItem().toString())) == null) {\r
+ HashSet<Pair<String, String>> tempSet = new HashSet<>();\r
+ tempSet.add(pair);\r
+ addedRelations.put(relationNameSpinner.getSelectedItem().toString(), tempSet);\r
+ adapter.notifyDataSetChanged();\r
+ } else {\r
+ (addedRelations.get(relationNameSpinner.getSelectedItem().toString())).add(pair);\r
+ adapter.notifyDataSetChanged();\r
+ }\r
+\r
+ //adding selected Objects into their respective sets\r
+ String relationName = relationNameSpinner.getSelectedItem().toString();\r
+ //get the left hand side of the generic selected relation\r
+ // ex: IoTRelation<RoomSmart, CameraSmart> roomCameraRel, get "RoomSmart"\r
+ Pair<String, String> tempPair = relations.get(relationName);\r
+ ArrayList<String> tempArrayList = addedSetList.get(tempPair.first);\r
+ //add the selected Left Value to RoomSmart set\r
+ if (tempArrayList == null) {\r
+ tempArrayList = new ArrayList<>();\r
+ tempArrayList.add(leftValue);\r
+ addedSetList.put(tempPair.first, tempArrayList);\r
+ } else {\r
+ tempArrayList.add(leftValue);\r
+ addedSetList.put(tempPair.first, tempArrayList);\r
+ }\r
+\r
+ //repeat for the right side\r
+ tempArrayList = addedSetList.get(tempPair.second);\r
+ //ex: add to the selected Right Value CameraSmart set\r
+ if (tempArrayList == null) {\r
+ tempArrayList = new ArrayList<>();\r
+ tempArrayList.add(rightValue);\r
+ addedSetList.put(tempPair.second, tempArrayList);\r
+ } else {\r
+ tempArrayList.add(rightValue);\r
+ addedSetList.put(tempPair.second, tempArrayList);\r
+ }\r
+ addedRelationsArrayList = new ArrayList<>();\r
+ Set<String> relationTypes = addedRelations.keySet();\r
+ for (String s : relationTypes) {\r
+ for (Pair<String, String> temp : addedRelations.get(s)) {\r
+ addedRelationsArrayList.add(temp.first + " " + temp.second);\r
+ }\r
+ }\r
+ if(hasIndependentSets){\r
+ Set<String> keys= addedIndependentSets.keySet();\r
+ for (String s : keys) {\r
+ for (String temp : addedIndependentSets.get(s)) {\r
+ addedRelationsArrayList.add(temp);\r
+ }\r
+ }\r
+ adapter = new ArrayAdapter(context, android.R.layout.simple_list_item_multiple_choice, addedRelationsArrayList);\r
+ addRelationsListView.setAdapter(adapter);\r
+ }\r
+ else {\r
+ adapter = new ArrayAdapter(context, android.R.layout.simple_list_item_multiple_choice, addedRelationsArrayList);\r
+ addRelationsListView.setAdapter(adapter);\r
+ }\r
+\r
+ }\r
+ else {\r
+ //user is adding to independent sets (sets that are not part of a relation)\r
+ String leftValue = relationLeftSpinner.getSelectedItem().toString();\r
+ if ((addedIndependentSets.get(relationNameSpinner.getSelectedItem().toString())) == null) {\r
+ HashSet<String> tempSet = new HashSet<>();\r
+ tempSet.add(leftValue);\r
+ addedIndependentSets.put(relationNameSpinner.getSelectedItem().toString(), tempSet);\r
+ adapter.notifyDataSetChanged();\r
+ } else {\r
+ (addedIndependentSets.get(relationNameSpinner.getSelectedItem().toString())).add(leftValue);\r
+ adapter.notifyDataSetChanged();\r
+ }\r
+ addedRelationsArrayList = new ArrayList<>();\r
+ Set<String> relationTypes = addedRelations.keySet();\r
+ for (String s : relationTypes) {\r
+ for (Pair<String, String> temp : addedRelations.get(s)) {\r
+ addedRelationsArrayList.add(temp.first + " " + temp.second);\r
+ }\r
+ }\r
+ Set<String> keys= addedIndependentSets.keySet();\r
+ for (String s : keys) {\r
+ for (String temp : addedIndependentSets.get(s)) {\r
+ addedRelationsArrayList.add(temp);\r
+ }\r
+ }\r
+ adapter = new ArrayAdapter(context, android.R.layout.simple_list_item_multiple_choice, addedRelationsArrayList);\r
+ addRelationsListView.setAdapter(adapter);\r
+\r
+ }\r
+ }\r
+\r
+ if(view == doneRelationButton){\r
+\r
+ boolean allSetsHaveEntry = true;\r
+ for(String s: applicationSetList){\r
+ ArrayList<String> list = addedSetList.get(s);\r
+ if(list== null || list.size() == 0){\r
+ allSetsHaveEntry = false;\r
+ System.out.println("NOT ALL RELATIONS HAVE ENTRIES");\r
+ Toast t = Toast.makeText(ApplicationWithRelations.this, "Insufficient Entries",Toast.LENGTH_SHORT);\r
+ t.show();\r
+ continue;\r
+ }\r
+ }\r
+ if(hasIndependentSets) {\r
+ for (int i = 0; i < independentSetNames.size(); i++) {\r
+ if (addedIndependentSets.get(independentSetNames.get(i)) == null ||\r
+ (addedIndependentSets.get(independentSetNames.get(i))).size() == 0) {\r
+ allSetsHaveEntry = false;\r
+ System.out.println("NOT ALL SETS HAVE ENTRIES");\r
+ continue;\r
+ }\r
+ }\r
+ }\r
+ System.out.println("all sets have entry" + allSetsHaveEntry);\r
+ if(allSetsHaveEntry){\r
+\r
+ //the ssh execution is within the following command. Add comm patterns to database\r
+ callSSHCommandAddComm();\r
+\r
+ //adding relations and their derived sets, add to localconfig/mysql files\r
+ String command = generateSSHCommandRelation();\r
+ //System.out.println(command)\r
+ SSH_MySQL addConfigFiles = new SSH_MySQL();\r
+ addConfigFiles.execute(command);\r
+ try {\r
+ Thread.sleep(1500);\r
+ List<String> result = addConfigFiles.getResultLines();\r
+ for (int i = 0; i < result.size(); i++) {\r
+ System.out.println("result" + result.get(i));\r
+ }\r
+ }\r
+ catch (Exception e){\r
+ e.printStackTrace();\r
+ }\r
+\r
+\r
+\r
+\r
+ //add independent sets to their respective localconfig/mysql files\r
+ finish();\r
+ }\r
+\r
+ }\r
+ if (view == deleteRelationButton) {\r
+ //SparseBooleanArray's data is True or False\r
+ SparseBooleanArray checkedItems = addRelationsListView.getCheckedItemPositions();//to check which devices are checked in listview(check -> true, no check -> false)\r
+ int count = adapter.getCount();//number of items in listview\r
+ for (int i = count - 1; i >= 0; i--) {//scan from back\r
+ //i : index of IoT device which will be removed in tmp array\r
+ if (checkedItems.get(i)) {//if check\r
+ System.out.println("delete relation: " + i);\r
+ String selectedValue = (String)addRelationsListView.getItemAtPosition(i);\r
+ scanner = new Scanner(selectedValue);\r
+ String left = scanner.next() + " " + scanner.next();\r
+\r
+ if(scanner.hasNext()) {\r
+ String right = scanner.next() + " " + scanner.next();\r
+ Pair<String, String> pair = new Pair<>(left, right);\r
+ //remove from user-selected relations\r
+ Set<String> relationTypes = addedRelations.keySet();\r
+ for (String s : relationTypes) {\r
+ if (addedRelations.get(s).contains(pair)) {\r
+ addedRelations.get(s).remove(pair);\r
+ }\r
+ }\r
+ //remove from displaying on the check list\r
+ String temp = pair.first + " " + pair.second;\r
+ addedRelationsArrayList.remove(temp);\r
+ adapter.notifyDataSetChanged();\r
+ //remove from addedsetlist\r
+ deleteFromSet(left);\r
+ deleteFromSet(right);\r
+ }\r
+ else{\r
+ System.out.println("only has one word");\r
+ Set<String> keySet = addedIndependentSets.keySet();\r
+ for(String s: keySet){\r
+ HashSet<String> tempSet = addedIndependentSets.get(s);\r
+ tempSet.remove(left);\r
+ }\r
+ addedRelationsArrayList.remove(left);\r
+ adapter.notifyDataSetChanged();\r
+ }\r
+ }\r
+ }\r
+\r
+ //update\r
+ adapter.notifyDataSetChanged();\r
+ //delete checked mark in listview\r
+ addRelationsListView.clearChoices();\r
+\r
+ }\r
+\r
+ }\r
+}\r