package com.ericsson.tic.vi; import java.util.LinkedList; import com.sun.opengl.util.texture.Texture; import com.sun.opengl.util.texture.TextureIO; import java.awt.Color; import javax.swing.ImageIcon; import java.util.Hashtable; import java.io.BufferedReader; import java.io.FileReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.File; import java.util.ListIterator; import java.net.UnknownHostException; import java.net.SocketException; // uncomment for windows version (requires jgoodies plugin) // you also need to uncomment in the main() method in this file. // search for JGOODIESCOMMENT // import com.jgoodies.looks.plastic.Plastic3DLookAndFeel; // import javax.swing.UIManager; /** * VI holds the main method, all globally accessed static variables and * constants as well as some static methods used for the initialization. * * @author Sami Matilainen * @version 1.0 (2008-12-04) */ public class VI { /** The size of the socket input buffer size. */ public static int socketBufferSize; /** Enables better lighting. */ public static boolean betterLightingOn = false; /** True if fog is turned on. */ public static boolean fogOn = false; /** True if bar shading is turned on. */ public static boolean barShadingOn = false; /** True if node shading is turned on. */ public static boolean nodeShadingOn = false; /** True if line shading is turned on. */ public static boolean lineAAOn = false; /** True if the skybox is turned on. */ public static boolean skyboxOn = false; /** The current buildnumber of this software. Used to identify if a savefile is compatible with the current build. */ private static final int build = 1000; /// used by various parts of the software to keep track of states /** If true, no prior initialization has ocurred */ public static boolean startup = true; /** If true, the startup dialog is running. */ public static boolean startupDialogRunning = false; /// Data gathered from the system running this program /** The resolution of currentTimeInMillis() method */ //public static long timerResolution = Long.MAX_VALUE; /// Database DEFAULT settings /** The default port number used for accessing the MySQL database. */ //public static final int DEFAULT_DB_PORT = 3306; /** The default host of the MySQL database. */ //public static final String DEFAULT_DB_HOST = "localhost"; /** The default password for the MySQL database. */ //public static final String DEFAULT_DB_PASS = "ericsson"; /** The default database name (schema) for the MySQL database. */ //public static final String DEFAULT_DB_SCHEMA = "tic_ynode_db_pa0"; /** The default username for the MySQL database. */ //public static final String DEFAULT_DB_USR = "vi"; /// UDP DEFAULT settings /** The default port number used for incoming messages from the TIC. */ public static final int DEFAULT_UDPIN_PORT = 8601; /** The default port on which the TIC is assumed to listen for messages from the VI ynode */ public static final int DEFAULT_UDPOUT_PORT = 8701; /** The default host where the TIC listens for incoming messages. */ public static final String DEFAULT_UDPOUT_HOST = "localhost"; /// Database custom settings /** The default port number used for accessing the MySQL database. */ //public static int dbPort = 0; /** The default host of the MySQL database. */ //public static String dbHost = ""; /** The default password for the MySQL database. */ //public static String dbPass = ""; /** Not settable in the interface for some reason. */ /** The default database name (schema) for the MySQL database. */ //public static String dbSchema = DEFAULT_DB_SCHEMA; /** Not settable in the interface for some reason. */ /** The default username for the MySQL database. */ //public static String dbUsr = DEFAULT_DB_USR; /// UDP custom settings /** The default port number used for incoming messages from the TIC. */ public static int udpInPort = 0; /** The default port on which the TIC is assumed to listen for messages from the VI ynode */ public static int udpOutPort = 0; /** The default host where the TIC listens for incoming messages. */ public static String udpOutHost = ""; /** The default port on which the TIC is assumed to listen for messages from the VI ynode */ public static int keepAlivePort = 0; /** The default host where the TIC listens for incoming messages. */ public static String keepAliveHost = ""; /** A list of commands. */ public static Command[] commandArr; /** An image. */ public static ImageIcon leftArrowIcon; /** An image. */ public static ImageIcon downArrowIcon; /** An image. */ public static ImageIcon brushOnIcon; /** An image. */ public static ImageIcon brushOffIcon; /** The default window title. */ public static String windowTitle = "The VI"; /** Grey (80%). As a 3f value. */ public static final float[] greyColor = {0.8f, 0.8f, 0.8f}; /** White. As a 3f value. */ public static final float[] whiteColor = {1.0f, 1.0f, 1.0f}; /** Red. As a 3f value. */ public static final float[] redColor = {1.0f, 0.0f, 0.0f}; /** Green. As a 3f value. */ public static final float[] greenColor = {0.0f, 1.0f, 0.0f}; /** Blue. As a 3f value. */ public static final float[] blueColor = {0.0f, 0.0f, 1.0f}; /** The default dealy time (in tics) for "movement inertia" */ public static final int GLOBE_MOVE_DELAY = 60; /** The default zoom distance. */ public static final float GLOBE_ZOOM_DEFAULT = 3.0f; /** The maximum zoom distance. Note that the skybox is the limit. Get it? "sky is the limit"?*/ public static final float GLOBE_ZOOM_MAX = 12.0f; /** The minimum allowed zooming distance. */ public static final float GLOBE_ZOOM_MIN = 1.5f; /** The default zoom distance. */ public static final float PLANE_ZOOM_DEFAULT = 3.0f; /** The maximum zoom distance. Note that the skybox is the limit. Get it? "sky is the limit"?*/ public static final float PLANE_ZOOM_MAX = 5.0f; /** The minimum allowed zooming distance. */ public static final float PLANE_ZOOM_MIN = 0.3f; /** The maximum x-panning distance. */ public static final float PLANE_PAN_X_MAX = 2.6f; /** The maximum y-panning distance. */ public static final float PLANE_PAN_Y_MAX = 1.8f; /** Controls the decay rate of the zoom. */ public static final float ZOOM_DECAY = 5.0f; /** Controls the decay rate of rotational movement. */ public static final float SPEED_DECAY_ROT = 20.0f; /** Controls the decay rate of tiliting movement. */ public static final float SPEED_DECAY_TILT = 5.0f; /** The default tilt-angle. */ public static final float GLOBE_TILT_ANGLE_DEFAULT = 0.0f; /** The default rot-angle. */ public static final float GLOBE_ROT_ANGLE_DEFAULT = 0.0f; /** If true, tilting continues if the mouse is released. */ public static boolean tiltMoveDelayOn = false; /** If true, panning continues if the mouse is released. */ public static boolean panMoveDelayOn = false; /** If true, panning and tilting is not separated. */ public static boolean ignoreShift = true; /** If true, tilting continues for eternity. */ public static boolean infiniteMoveDelayOn = false; /** pause the GUI. */ public static boolean pauseGUI = false; /** Automatic globe rotation. */ public static boolean globeRotationOn = true; /** Automatic skybox rotation. */ public static boolean skyboxRotationOn = true; /** If shift is pressed. */ public static boolean shiftPressed = false; /** If m-key is pressed. */ public static boolean mPressed = false; /** If focus is in view. */ public static boolean focusInView = true; /** If globe view is on. */ public static boolean globeViewOn = false; /** If brushing is on. */ public static boolean brushingOn = false; /** */ public static int brushedCategory = 0; /** The primary brushing color. */ public static final Color BRUSHING_PRIMARY_COLOR_DEFAULT = Color.GREEN; /** The secondary brushing color. */ public static final Color BRUSHING_SECONDARY_COLOR_DEFAULT = Color.YELLOW; /** Brushing Suppressed color. */ public static final Color BRUSHING_OFF_COLOR_DEFAULT = Color.GRAY; /** The primary brushing color. */ public static Color brushingPrimaryColor = BRUSHING_PRIMARY_COLOR_DEFAULT; /** The secondary brushing color. */ public static Color brushingSecondaryColor = BRUSHING_SECONDARY_COLOR_DEFAULT; /** Brushing Suppressed color. */ public static Color brushingOffColor = BRUSHING_OFF_COLOR_DEFAULT; /** Suggested update frequenzy for the OpenGL rendering engine. */ public static int viewRefreshRate = 30; /** Enable vertical sync. */ public static int verticalSync = 0; // 0 = off 1 = on /** If true, the core is running. */ public static boolean coreRunning = false; /** If true, server messages are printed to the console. */ public static boolean printServerMessages = false; /** A list of view panels. */ public static LinkedList viewList = new LinkedList(); /** A list of console panels. */ public static LinkedList consoleList = new LinkedList(); /** A list of top level windows. */ public static LinkedList windowList = new LinkedList(); /** A list of regions. */ //public static LinkedList regionList = new LinkedList(); /** A list of regions as an array. */ //public static Region[] regionArr = null; // an easier to use alternative to the LinkedList /** A list of graph nodes. */ public static LinkedList nodeList = new LinkedList(); /** A list of graph nodes as an array. */ public static GraphNode[] nodeArr = null; // an easier to use alternative to the LinkedList /** A list of node relations. */ public static LinkedList nodeRelList = new LinkedList(); /** A list of node relations as an array. */ public static GraphNodeRel[] nodeRelArr = null; // an easier to use alternative to the LinkedList /** A list of categories as an array. */ public static LinkedList categoryList = new LinkedList(); /** A list of categories. */ public static Category[] categoryArr = null; // an easier to use alternative to the LinkedList /** A list of data */ public static Data[] dataArr = null; /** A list of singular node data */ public static LinkedList nodeSingularDataList = new LinkedList(); /** A list of multidimensional node data */ public static LinkedList nodeMultiDataList = new LinkedList(); /** A list of data tied to relations. */ public static LinkedList relsDataList = new LinkedList(); /** A list of singular node data */ public static Data[] nodeSingularData = null; /** A list of multidimensional node data */ public static Data[] nodeMultiData = null; /** A list of data tied to relations. */ public static Data[] relsData = null; /** Strings used by the GUI to display node-singular data. */ public static String[] nodeSingularDataStrings = null; /** Strings used by the GUI to display node-multideimensional data. */ public static String[] nodeMultiDataStrings = null; /** Strings used by the GUI to display relation data. */ public static String[] relsDataStrings = null; /** A hashtable containing an ID, hostname pair. */ public static Hashtable nodeID = new Hashtable(); /** A hashtable containing an ID, hostname pair. */ public static Hashtable relID = new Hashtable(); /** A hashtable containing an ID, hostname pair. */ public static Hashtable catID = new Hashtable(); /** A hashtable containing an ID, data set name pair. */ public static Hashtable dataID = new Hashtable(); /** The latest WindowID. */ private static int wid; /** The latest ViewID. */ private static int vid; /** World map texture. */ public static Texture worldTex; /** World map texture. */ public static Texture blankTex; /** Skybox texture. */ public static Texture skyboxTexTop; /** Skybox texture. */ public static Texture skyboxTexBottom; /** Skybox texture. */ public static Texture skyboxTexSide1; /** Skybox texture. */ public static Texture skyboxTexSide2; /** Skybox texture. */ public static Texture skyboxTexSide3; /** Skybox texture. */ public static Texture skyboxTexSide4; /** If true, the predefined textures are loaded. */ public static boolean texturesLoaded = false; /** The size of the console input buffer */ public static final int CONSOLE_INPUT_CAPACITY = 8; /** */ //public static final int STANDARD_INPUT_CAPACITY = 8; /** */ //public static final int MESSAGE_INPUT_CAPACITY = 256; /** The maximum size of incoming messages. */ public static final int MESSAGE_MAX_WIDTH = 1024; /** A buffer used for storing user input messages. */ public static RawBuffer consoleInputBuffer; /** */ //public static RawBuffer standardInputBuffer; /** */ //public static RawBuffer messageInputBuffer; //public static StandardInputListener standardInputListener; /** The console. Use VI.d.d("debug"); to print text. */ public static ConsolePanel d; /** Maintains a connection to the database. */ //public static DBCom dbcon; /** Parsing strategy. */ public static int STRAT_NODE_HOST_VALUE = 0; /** Parsing strategy. */ public static int STRAT_NODE_HOST_CAT_VALUE = 1; /** Parsing strategy. */ public static int STRAT_NODE_HOST_CAT_VALUE_N = 2; /** Parsing strategy. */ public static int STRAT_REL_HOST_VALUE = 3; /** Parsing strategy. */ public static int STRAT_REL_HOST_VALUE_2 = 4; /** The null category. */ public static int NULL_CATEGORY = 0; /** A space character. */ public static final String SPACE = " "; /** An underscore. */ public static final String UNDERSCORE = "_"; /** A null character. */ public static final String NULL_CHAR = "\0"; /** The current time. */ public static long currentTimeStamp = 0; /** If this value is set to zero, time out time is assumed to be infinite. */ public static long timeOut = 0; /** The default value used for the timeout. */ public static float defaultValue = 0.0f; /** The current bar type. */ public static int barType = 0; /** An array of nodes. */ public static NodeType[] nodeTypeArr; /** * Calculate the normalized color from a normalized value and a color range. * Note: Uses linear scaling. * * @param c1 A color RGB triple. Start color of the gradient. * @param c2 A color RGB triple. End color of the gradient. * @param vn A normalized value in the range [0.0 1.0]. * @return the normalized color. */ public static float[] normalizedColor(float[] c1, float[] c2, float vn) { float[] ret = new float[3]; ret[0] = c1[0] + (c2[0] - c1[0]) * vn; ret[1] = c1[1] + (c2[1] - c1[1]) * vn; ret[2] = c1[2] + (c2[2] - c1[2]) * vn; return ret; } /** * Request a new window ID. This method is thread safe. * * @return The requested window ID. */ public static synchronized int requestWindowID() { wid++; return wid; } /** * Request a new view ID.This method is thread safe. * * @return The requested view ID. */ public static synchronized int requestViewID() { vid++; return vid; } /** * Read a save file and load the settings into a view panel. * @param file A save file. * @param view A view panel. */ public static void readSave(File file, ViewPanel view) { int v = 0; int labelCount = 0; int subsetCount = 0; int[] subsetArr = null; String[] token = null; try { BufferedReader reader = new BufferedReader(new FileReader(file)); String input = null; if ((input = reader.readLine()) != null) { try { // 900 = 0.9 and forward if (900 <= Integer.parseInt(input)) { VI.d.def("The save file is not compatible with this version."); return; } } catch (NumberFormatException e) { e.printStackTrace(); } } input = null; if ((input = reader.readLine()) != null) { try { subsetCount = Integer.parseInt(input); } catch (NumberFormatException e) { e.printStackTrace(); } } input = null; subsetArr = new int[subsetCount]; for (int i = 0; i < subsetCount; i++) { if ((input = reader.readLine()) != null) { try { subsetArr[i] = Integer.parseInt(input); } catch (NumberFormatException e) { e.printStackTrace(); } } } input = null; if ((input = reader.readLine()) != null) { labelCount = 0; token = input.split(" "); if (token[0].equals("view")) { try { //Integer.parseInt(token[1]); view.barsOn = Boolean.parseBoolean(token[2]); view.brushingMarkersOn = Boolean.parseBoolean(token[3]); view.graphNodesOn = Boolean.parseBoolean(token[4]); view.graphRelationsOn = Boolean.parseBoolean(token[5]); view.texturesOn = Boolean.parseBoolean(token[6]); view.viewTitleOn = Boolean.parseBoolean(token[7]); view.labelsOn = Boolean.parseBoolean(token[8]); view.subsetOn = Boolean.parseBoolean(token[9]); view.subsetEmpty = Boolean.parseBoolean(token[10]); view.defaultNodeColorsOn = Boolean.parseBoolean(token[11]); view.levelNodeShadingOn = Boolean.parseBoolean(token[12]); labelCount = Integer.parseInt(token[13]); } catch (NumberFormatException e) { e.printStackTrace(); } input = null; if ((input = reader.readLine()) != null) { token = input.split(" "); if (token[0].equals("nodeData")) { try { view.nodeData = Integer.parseInt(token[1]); view.nodeSelectedIndex = Integer.parseInt(token[2]); } catch (NumberFormatException e) { e.printStackTrace(); } } } input = null; if ((input = reader.readLine()) != null) { token = input.split(" "); if (token[0].equals("relData")) { try { view.relData = Integer.parseInt(token[1]); view.relSelectedIndex = Integer.parseInt(token[2]); } catch (NumberFormatException e) { e.printStackTrace(); } } } input = null; if ((input = reader.readLine()) != null) { token = input.split(" "); if (token[0].equals("barData")) { int count = 0; try { count = Integer.parseInt(token[1]); } catch (NumberFormatException e) { e.printStackTrace(); } for (int j = 0; j < count; j++) { input = null; if ((input = reader.readLine()) != null) { token = input.split(" "); try { view.barData[j] = Integer.parseInt(token[0]); view.barsSelectedIndex[j] = Integer.parseInt(token[1]); } catch (NumberFormatException e) { e.printStackTrace(); } } } } } input = null; if ((input = reader.readLine()) != null) { token = input.split(" "); if (token[0].equals("histData")) { int count = 0; try { count = Integer.parseInt(token[1]); } catch (NumberFormatException e) { e.printStackTrace(); } for (int j = 0; j < count; j++) { input = null; if ((input = reader.readLine()) != null) { token = input.split(" "); try { view.histData[j] = Integer.parseInt(token[0]); view.histSelectedIndex[j] = Integer.parseInt(token[1]); } catch (NumberFormatException e) { e.printStackTrace(); } } } } } input = null; if ((input = reader.readLine()) != null) { token = input.split(" "); if (token[0].equals("nodeOfTypeOn")) { int count = 0; try { count = Integer.parseInt(token[1]); } catch (NumberFormatException e) { e.printStackTrace(); } for (int j = 0; j < count; j++) { try { view.nodeOfTypeOn[j] = Boolean.parseBoolean(token[2+j]); } catch (NumberFormatException e) { e.printStackTrace(); } } } } for (int j = 0; j < labelCount; j++) { input = null; if ((input = reader.readLine()) != null) { token = input.split(" "); try { view.nodeArrFull[j].highlighted = Boolean.parseBoolean(token[0]); view.nodeArrFull[j].label.xPlane = Float.parseFloat(token[1]); view.nodeArrFull[j].label.yPlane = Float.parseFloat(token[2]); view.nodeArrFull[j].label.zPlane = Float.parseFloat(token[3]); view.nodeArrFull[j].label.xGlobe = Float.parseFloat(token[4]); view.nodeArrFull[j].label.yGlobe = Float.parseFloat(token[5]); view.nodeArrFull[j].label.zGlobe = Float.parseFloat(token[6]); view.nodeArrFull[j].label.x = Float.parseFloat(token[7]); view.nodeArrFull[j].label.y = Float.parseFloat(token[8]); view.nodeArrFull[j].label.z = Float.parseFloat(token[9]); } catch (NumberFormatException e) { e.printStackTrace(); } } } view.nodeArr = view.nodeArrFull; } else { VI.d.def("The save file is corrupt."); return; } } reader.close(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } view.createSubset(subsetArr); } /** * Writes the viewsettings to file. * @param file a file to write to. * @param view a view. */ public static void writeSave(File file, ViewPanel view) { try { BufferedWriter writer = new BufferedWriter(new FileWriter(file)); String output = ""; writer.write("" + build); // build number writer.newLine(); writer.write("" + view.nodeArrSubset.length); writer.newLine(); for (int i = 0; i < view.nodeArrSubset.length; i++) { writer.write("" + view.nodeArrSubset[i].id); writer.newLine(); } output = "view " + view.id + " "; output = output + view.barsOn + " "; output = output + view.brushingMarkersOn + " "; output = output + view.graphNodesOn + " "; output = output + view.graphRelationsOn + " "; output = output + view.texturesOn + " "; output = output + view.viewTitleOn + " "; output = output + view.labelsOn + " "; output = output + view.subsetOn + " "; output = output + view.subsetEmpty + " "; output = output + view.defaultNodeColorsOn + " "; output = output + view.levelNodeShadingOn + " "; output = output + view.nodeArr.length + " "; writer.write(output); writer.newLine(); output = "nodeData " + view.nodeData + " " + view.nodeSelectedIndex; writer.write(output); writer.newLine(); output = "relData " + view.relData + " " + view.relSelectedIndex; writer.write(output); writer.newLine(); output = "barData " + view.barData.length; writer.write(output); writer.newLine(); for (int i = 0; i < view.barData.length; i++) { output = view.barData[i] + " " + view.barsSelectedIndex[i]; writer.write(output); writer.newLine(); } output = "histData " + view.histData.length; writer.write(output); writer.newLine(); for (int i = 0; i < view.histData.length; i++) { output = view.histData[i] + " " + view.histSelectedIndex[i]; writer.write(output); writer.newLine(); } /* output = "nodeOfLevelOn " + view.nodeOfLevelOn.length + " "; for (int i = 0; i < view.nodeOfLevelOn.length; i++) { output = output + view.nodeOfLevelOn[i] + " "; } writer.write(output); writer.newLine(); */ output = "nodeOfTypeOn " + view.nodeOfTypeOn.length + " "; for (int i = 0; i < view.nodeOfTypeOn.length; i++) { output = output + view.nodeOfTypeOn[i] + " "; } writer.write(output); writer.newLine(); for (int i = 0; i < view.nodeArrFull.length; i++) { output = view.nodeArrFull[i].highlighted + " "; output = output + view.nodeArrFull[i].label.xPlane + " "; output = output + view.nodeArrFull[i].label.yPlane + " "; output = output + view.nodeArrFull[i].label.zPlane + " "; output = output + view.nodeArrFull[i].label.xGlobe + " "; output = output + view.nodeArrFull[i].label.yGlobe + " "; output = output + view.nodeArrFull[i].label.zGlobe + " "; output = output + view.nodeArrFull[i].label.x + " "; output = output + view.nodeArrFull[i].label.y + " "; output = output + view.nodeArrFull[i].label.z + " "; writer.write(output); writer.newLine(); } writer.flush(); writer.close(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } /** * Reads topology information from a file pointed to by the xml-file. The file should have the following formatting: *
	 * C
	 * nodeID nodeTypeID nodeTypeName nodeHierarchyName Xpos Ypos
	 * ...
	 * relationID nodeAID nodeBID
	 * ...
	 * 
	 * Example:
	 * 
 	 * 1
	 * 1 1 xnode 11b 0.4 1.102
	 * 2 2 ynode 11b 0.11 -0.3
	 * rID 1 2
	 * 
*/ public static void readTopologyFromFile(String fileName) { int C = 0; int nID = 0; int nodeTypeID = 0; String nodeTypeName = ""; String nodeHierarchyName = ""; float nodeX = 0; float nodeY = 0; int rID = 0; int nodeA = 0; int nodeB = 0; try { BufferedReader reader = new BufferedReader(new FileReader(fileName)); String input = null; if ((input = reader.readLine()) != null) { try { C = Integer.parseInt(input); } catch (NumberFormatException e) { e.printStackTrace(); } } input = null; while ((input = reader.readLine()) != null) { String[] token = input.split(" "); if (token[0].equals("node")) { try { nID = Integer.parseInt(token[1]); nodeTypeID = Integer.parseInt(token[2]); nodeTypeName = token[3]; nodeHierarchyName = token[4]; nodeX = Float.parseFloat(token[5]); nodeY = Float.parseFloat(token[6]); } catch (NumberFormatException e) { e.printStackTrace(); } GraphNode node = new GraphNode( nID, nodeTypeArr[nodeTypeID], nodeTypeName + nodeHierarchyName, nodeX, nodeY, 0.0f); nodeList.add(node); nodeID.put(nodeTypeName + nodeHierarchyName, new Integer(nID)); } else if (token[0].equals("rel")) { try { rID = Integer.parseInt(token[1]); nodeA = Integer.parseInt(token[2]); nodeB = Integer.parseInt(token[3]); } catch (NumberFormatException e) { e.printStackTrace(); } GraphNode nA = null; GraphNode nB = null; ListIterator iter = nodeList.listIterator(); GraphNode nU = null; while (iter.hasNext()) { nU = (GraphNode)iter.next(); if (nU.id == nodeA) { nA = nU; } if (nU.id == nodeB) { nB = nU; } } nodeRelList.add(new GraphNodeRel(rID, nA, nB)); relID.put(nA.title + "_" + nB.title, new Integer(rID)); } } reader.close(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } /** * Prepares all global data structures. */ public static void prepareDataStructures() { // the order in which nodes, categories and relations are // fetched is bound by some dependencies in the datastructures // so it is adviced you do not change the order of the code beyond this point. try { udpOutPort = Integer.parseInt(XMLInterface.masterPort); } catch (NumberFormatException e) { System.out.println("VI.java > master port number is not an integer!"); System.exit(1); } try { udpInPort = Integer.parseInt(XMLInterface.inputPort); } catch (NumberFormatException e) { System.out.println("VI.java > input port number is not an integer!"); System.exit(1); } try { keepAlivePort = Integer.parseInt(XMLInterface.keepAlivePort); } catch (NumberFormatException e) { System.out.println("VI.java > keep alive port number is not an integer!"); System.exit(1); } VI.udpOutHost = XMLInterface.masterHost; VI.keepAliveHost = XMLInterface.keepAliveHost; VI.windowTitle = XMLInterface.windowTitle; VI.defaultValue = XMLInterface.defaultValue; VI.timeOut = XMLInterface.timeOut; VI.barType = XMLInterface.defaultBarType; nodeTypeArr = new NodeType[XMLInterface.totalNodeTypes]; for (int i = 0; i < XMLInterface.totalNodeTypes; i++) { if (i == 0) { nodeTypeArr[i] = new NodeType(0, "null", -1); } else { nodeTypeArr[i] = new NodeType( XMLInterface.topologyNodeTypeId[i-1], XMLInterface.topologyNodeTypeName[i-1], XMLInterface.topologyNodeTypeLevel[i-1], XMLInterface.topologyNodeTypeNullColor[i-1]); } } for (int i = 0; i < XMLInterface.totalCategories; i++) { if (i == 0) { CategoryItem[] arr = new CategoryItem[1]; arr[0] = new CategoryItem(0, "null", "null"); categoryList.add(new Category(i, arr, "Null Category")); catID.put("null", new Integer(0)); } else { LinkedList categoryItemList = new LinkedList(); CategoryItem[] categoryItemArr = null; for (int k = 0; k < XMLInterface.totalCategoryItems[i-1]; k++) { CategoryItem item = new CategoryItem( k+1, XMLInterface.categoriesCategoryCategoryItemName[i-1][k], XMLInterface.categoriesCategoryCategoryItemParseName[i-1][k]); item.color = XMLInterface.categoriesCategoryCategoryItemColor[i-1][k][0]; categoryItemList.add(item); catID.put( XMLInterface.categoriesCategoryCategoryItemParseName[i-1][k], new Integer(k+1)); } categoryItemArr = categoryItemList.toArray(new CategoryItem[0]); VI.categoryList.add(new Category(i, categoryItemArr, XMLInterface.categoriesCategoryName[i-1])); } } // read the topology from the save file. VI.readTopologyFromFile(XMLInterface.topologyFileName); categoryArr = categoryList.toArray(new Category[0]); nodeArr = nodeList.toArray(new GraphNode[0]); nodeRelArr = nodeRelList.toArray(new GraphNodeRel[0]); dataArr = new Data[XMLInterface.totalData]; // if the naming conventions seems confusing... // consult the file: XMLInterface.java for (int i = 0; i < XMLInterface.totalData; i++) { dataArr[i] = new Data( XMLInterface.dataDataSetId[i], XMLInterface.dataDataSetName[i], XMLInterface.dataDataSetPName[i], XMLInterface.dataDataSetSet[i], categoryArr[XMLInterface.dataDataSetCat[i]], XMLInterface.dataDataSetParseStrat[i], XMLInterface.dataDataSetDimension[i], nodeTypeArr[XMLInterface.dataDataSetNodeType[i]], XMLInterface.dataDataSetMax[i], XMLInterface.dataDataSetMin[i], XMLInterface.dataDataSetColor[i]); } commandArr = new Command[XMLInterface.totalCommands]; for (int i = 0; i < XMLInterface.totalCommands; i++) { commandArr[i] = new Command( XMLInterface.commandsCommandId[i], XMLInterface.commandsCommandName[i], XMLInterface.commandsCommandMessagePrefix[i], XMLInterface.commandsCommandMessage[i]); } for (int i = 0; i < dataArr.length; i++) { if ( dataArr[i].category.id == 0 && dataArr[i].set == Data.SET_NODES) { nodeSingularDataList.add(dataArr[i]); } if ( dataArr[i].category.id == 0 && dataArr[i].set == Data.SET_REL) { relsDataList.add(dataArr[i]); } if (dataArr[i].set == Data.SET_NODES) { nodeMultiDataList.add(dataArr[i]); } } nodeSingularData = nodeSingularDataList.toArray(new Data[0]); nodeMultiData = nodeMultiDataList.toArray(new Data[0]); relsData = relsDataList.toArray(new Data[0]); nodeSingularDataStrings = new String[VI.nodeSingularData.length]; nodeMultiDataStrings = new String[VI.nodeMultiData.length]; relsDataStrings = new String[VI.relsData.length]; for (int i = 0; i < VI.nodeSingularData.length; i++) { nodeSingularDataStrings[i] = VI.nodeSingularData[i].name; } for (int i = 0; i < VI.nodeMultiData.length; i++) { nodeMultiDataStrings[i] = VI.nodeMultiData[i].name; } for (int i = 0; i < VI.relsData.length; i++) { relsDataStrings[i] = VI.relsData[i].name; } for (int i = 0; i < nodeRelArr.length; i++) { nodeRelArr[i].createControlPoints(); } for (int i = 0; i < dataArr.length; i++) { dataID.put(dataArr[i].parseName, new Integer(dataArr[i].id)); } consoleInputBuffer = new RawBuffer( MESSAGE_MAX_WIDTH, CONSOLE_INPUT_CAPACITY); } /** * Clones an array of nodes. * * @return An array of nodes. */ public static GraphNode[] cloneNodeArr() { GraphNode[] ret = new GraphNode[nodeArr.length]; for (int i = 0; i < nodeArr.length; i++) { try { ret[i] = (GraphNode)nodeArr[i].clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } return ret; } /** * Clones an array of relations. * *@param gNode An array of nodes. * @return An array of relations. */ public static GraphNodeRel[] cloneNodeRelArr(GraphNode[] gNode) { GraphNodeRel[] ret = new GraphNodeRel[nodeRelArr.length]; for (int i = 0; i < nodeRelArr.length; i++) { try { ret[i] = (GraphNodeRel)nodeRelArr[i].clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } ret[i].a = gNode[nodeRelArr[i].a.id-1]; ret[i].b = gNode[nodeRelArr[i].b.id-1]; } return ret; } /** * Initialize the environment and start the GUI. * * @param args Not used. */ public static void main(String[] args) { // uncomment for windows version (requires jgoodies plugin) // you also need to uncomment the import statement // at the top of this file. search for JGOODIESCOMMENT // try { UIManager.setLookAndFeel(new Plastic3DLookAndFeel()); } // catch (Exception e) { e.printStackTrace(); } // 1. read the xml-file and prepare all of the datastructures XMLInterface.readConfiguration(); VI.prepareDataStructures(); // 2. start reading the input socket and user input from the commandline try { BufferReader bufferReader = new BufferReader(udpInPort); } catch (SocketException e) { e.printStackTrace(); System.out.println("VI.main > Unable to open a socket! Exiting..."); System.exit(1); } // 3. start the time-out timer if and only if the timeout is a positive integer if (VI.timeOut > 0) { TimeOutTimer timer = new TimeOutTimer(); } // 4. start the main GUI window and add it to the list of windows GUI window = new GUI(); VI.windowList.add(window); // 5. (optional) start the KeepAlive class which gives feedback about the current // up-state of the VI so that the server knows if it is any point // sending any data. try { new KeepAlive(udpInPort, keepAliveHost, keepAlivePort); } catch (UnknownHostException e) { e.printStackTrace(); } } }