package lawyer; import java.net.*; import java.io.*; import java.util.*; import java.awt.*; import java.awt.event.*; import java.applet.*; // custom classes import exercise.DatabaseBroker; /** *

This class is the Applet that runs each lesson. The applet reads * in the majority (all but image) of the information from text files, whose * location are given to it.

* *

The soundfiles must be in .au format, with MuLaw compression [Note: is * this correct? Talk to Joel]

* *

There are six different kinds of ASCII files that the applet reads in. *

  1. The header file *
  2. Dialog files *
  3. The brief file *
  4. New state files (text with choices following the text) *
  5. The data file *
  6. Finishing files
* Below are the syntax specifications for each kind of file.

* *

The Header File

*

The header file is an ASCII file composed of headings, followed by tags. * All of the headings must be on their own line, and prefixed by a '#'. All * of the tags following a heading are for that section, and must be of the * form tag=value. With the exception * of the panellinks tag, all file locations should be given * relative to the codeBase of the applet. The * panellinks values should be absolute URLs. If * the tag accepts multiple values (e.g., soundfile), the values can be on * multiple successive lines, provided all but the last line end in a ';'. * Otherwise each tag/value pair must be on the same line, and each pair must * be its own line. * Comment lines can be added to the header file; they must have an '!' as the * first character. Below are the headings (bold), the valid tags for each, * and the syntax for the values ("Val:"), if there are specific * requirements:

* * *

Dialog Files

*

Dialog files contain only dialog, and are used for the initial parts of * the lesson. Each speech by a character must begin with the character's * name (or one of the abbreviations given below), followed by a ':'. This * tells the parser that it is a new speech, instead of simply the person's * name. "Personalizing" codes (e.g., that insert the lawyer's name) can be * inserted directly into the text. The abbreviations and codes are given * below:

* * *

The Brief File

*

The brief file contains the brief which the students will fill out. * A section of text is followed by the specification of the options. * There is one option displayed per page (i.e., finishing an option signifies * the end of a page). The following "HTML-like" tags are used to separate * out the options and the choices within them.

* * *

New State Files

*

New state files contain both the text and options for sections after * the brief is submitted. All of the dialog text should be followed by the * options (there can be as many of them as you want, but they cannot be * interwoven with the dialog). Within the new state text, you can use the same * abbreviations and personalizing codes as in the dialog files. In the * options section, you should use the same "pseudo-HTML" tags as in the * brief file.

* *

The Data File

*

The data file contains the data and reference for the table to be * displayed by the statistician. Any text outside of the <data>, and * </data> tags is considered part of the reference. Within the * <data> section, the following conventions apply:

* * *

Finishing Files

*

These are the files that contain the text for the finishes (when the * student wins, loses, or is found incompetent). Each of the finishes should * have its own file. However, all of finishes of a particular type (e.g., * all of the winning finishes) should be within a single file. Within the * file, the text of each finish should be enclosed in <#> * and </#> tags. The number in the tag corresponds to the * finish named in the "If" statements. E.g., finish w3 is the * text within the winning textfile that is enclosed by <3> * and </3>. Within the text, you can use the same * abbreviations and personalizing codes as in the dialog files.

* *

HTML Parameters

*

There are five parameters that can be set in the HTML. They are: *

    *
  1. "student": The name of the student *
  2. "sex": The student's gender *
  3. "lesson codebase": The directory (below the LessonManager.class * file) that the lesson is in *
  4. "header": The lesson header file *
  5. "online": An optional tag indicating whether we're online (T and * F are the recognized values) *

* * @author David Danks * @version 0.9; Mar 9, 1999 * @see BriefPanel * @see DataTableFrame * @see ImageCanvas * @see SoundPlayer * @see TextCanvas * @see DatabaseBroker */ public class LessonManager extends Applet implements ActionListener { // general lesson variables /** @serial */ protected URL lessonUrl; /** @serial */ protected String lessonTitle; /** @serial */ protected int clientSex; /** @serial */ protected boolean soundOn = false; // this is temporary /** @serial */ protected int lawyerSex; /** @serial */ protected String lawyerName; // file locations /** @serial */ protected URL soundFile[][][]; // lawyerSex, scene, number /** @serial */ protected URL finishSound[][][]; // lawyerSex, result, number /** @serial */ protected URL textFile[]; /** @serial */ protected URL dataFile; /** @serial */ protected URL choiceFile[]; /** @serial */ protected URL incompFile; /** @serial */ protected URL loseFile; /** @serial */ protected URL winFile; // panel information /** @serial */ protected String panelLinkTitle[]; /** @serial */ protected URL panelLink[]; // flow information /** @serial */ protected Hashtable briefResult; /** @serial */ protected String[][] text; /** @serial */ protected String[][][] options; /** @serial */ protected Hashtable responseResult; /** @serial */ protected String stateVector; /** @serial */ protected int finalResult; // magic numbers for the possible results static final int INCOMPETENT = 1000; static final int LOSE = 2000; static final int WIN = 3000; static final String IM = "images/"; static final String FEMIM = "images/female_lawyer/"; static final String MALIM = "images/male_lawyer/"; static final int FEMALE = 0; static final int MALE = 1; static final int PAIR = 2; static final int INSET = 30; // image information /** @serial */ private URL beginIm[]; // images /** @serial */ private URL introIm[][][]; // lawyer, client, image /** @serial */ private URL dataCollIm[][]; // lawyer, image /** @serial */ private URL statIm[][]; // lawyer, image /** @serial */ private URL courtIm[][]; // lawyer, image /** @serial */ private URL finishIm[][][]; // lawyer, outcome, images // general variables /** @serial */ GridBagLayout gbl; /** @serial */ Checkbox on; /** @serial */ TextField loginName; /** @serial */ java.awt.List panel; /** @serial */ URL classList; /** @serial */ Checkbox[] optBoxes; /** @serial */ ImageCanvas pict; /** @serial */ TextCanvas tc; /** @serial */ Button next; /** @serial */ Button skip; /** @serial */ Component[] keep; /** @serial */ DataTableFrame dtf; /** @serial */ SoundPlayer sound; /** @serial */ BriefPanel bp; /** @serial */ DatabaseBroker db; /** @serial */ boolean isLocal = false; /** @serial */ String lessonBase; /** * The default constructor simply initializes the Frame, when it is not * run as an Applet */ public LessonManager () { super(); gbl = new GridBagLayout(); this.setLayout(gbl); } /** * This constructor initializes the Frame, and then loads in the lesson, * when it is not run as an Applet * * @param lessonName The relative filename of the lesson */ public LessonManager (String lessonName) { this(); loadLesson(lessonName); } /** * This init() method starts up the LessonManager when it is run as an * Applet */ public void init() { String header = getParameter("header"); lessonBase = getParameter("lesson codebase"); if (lessonBase == null) lessonBase = ""; String sex = getParameter("sex"); if (sex.equals("F")) lawyerSex = FEMALE; else lawyerSex = MALE; lawyerName = getParameter("student"); String online = getParameter("online"); db = new DatabaseBroker("lawyer", header); if ((online == null) || (online.startsWith("F"))) { db.setOnline(false); isLocal = true; } else db.setOnline(true); loadLesson(lessonBase+header); runIntro(); } /** * actionPerformed is called whenever the student hits a button to move to the * next section. Sometimes, this method only sets the readyToAdvance variable * before moving on. Other times, it actually stores some information. */ public void actionPerformed (ActionEvent a) { // exercise wanted if (a.getSource() == panel) { int ind = panel.getSelectedIndex(); this.getAppletContext().showDocument(panelLink[ind], panelLinkTitle[ind]); } // in one of the script pages else if (a.getActionCommand().startsWith("next:")) { int sec; int ind; try { sec = Integer.parseInt(a.getActionCommand().substring(5, a.getActionCommand().indexOf(","))); ind = Integer.parseInt(a.getActionCommand().substring(a.getActionCommand().indexOf(",")+1)); } catch (NumberFormatException n) { System.err.println("Problem with changing script pages!"); return; } displayScript(sec, ind); return; } // run Data Collection else if (a.getActionCommand().equals("rundatacollect")) { this.removeAll(); if (textFile[1] != null) runDataCollect(); else if (textFile[2] != null) runStatistics(); else if (textFile[3] != null) runBrief(); return; } // run Statistics else if (a.getActionCommand().equals("runstats")) { this.removeAll(); if (textFile[2] != null) runStatistics(); else if (textFile[3] != null) runBrief(); return; } // run Brief else if (a.getActionCommand().equals("runbrief")) { this.removeAll(); runBrief(); return; } // move to next Brief section else if (a.getActionCommand().startsWith("nextbrief:")) { int resp = bp.getSelectedIndex(); if (resp == -1) return; stateVector += String.valueOf(resp) + ","; int nex = 0; try { nex = Integer.parseInt(a.getActionCommand().substring(10)); } catch (NumberFormatException n) { System.err.println("problem with the brief transition"); return; } if (nex == 1) { skip.setEnabled(true); } skip.setActionCommand("backbrief:"+String.valueOf(nex-1)); if (nex == text.length-1) { next.setActionCommand("submitbrief"); next.setLabel("Submit Brief"); } else next.setActionCommand("nextbrief:"+String.valueOf(nex+1)); bp.displayPage(nex); return; } // move to previous Brief section else if (a.getActionCommand().startsWith("backbrief:")) { int bac = 0; try { bac = Integer.parseInt(a.getActionCommand().substring(10)); } catch (NumberFormatException n) { System.err.println("problem with the brief transition"); return; } if (bac == 0) { stateVector = ""; skip.setEnabled(false); } else { String temp = stateVector.substring(0, stateVector.lastIndexOf(",", stateVector.length()-2)+1); stateVector = temp; skip.setActionCommand("backbrief:"+String.valueOf(bac-1)); } if (bac == text.length-2) next.setLabel("Next Section"); else next.setActionCommand("nextbrief:"+String.valueOf(bac+1)); bp.displayPage(bac); return; } // done with Brief else if (a.getActionCommand().equals("submitbrief")) { int resp = bp.getSelectedIndex(); if (resp == -1) return; stateVector += String.valueOf(resp); if (briefResult.containsKey(stateVector)) { db.submitGrade("brief", stateVector); Integer nextState = (Integer)briefResult.get(stateVector); this.removeAll(); runCourt(nextState.intValue()); } else System.err.println("key not found:"+stateVector); return; } // next new state text else if (a.getActionCommand().startsWith("newnext:")) { int ind; try { ind = Integer.parseInt(a.getActionCommand().substring(8)); } catch (NumberFormatException n) { System.err.println("Problem with the new state transition"); return; } if (ind == tc.getNumDialogs()) { removeAll(); displayOptions(0); } else displayNewState(ind); } // forward in a new state's options else if (a.getActionCommand().startsWith("nextopt:")) { for (int i=1; i= WIN) { db.submitGrade("finish", "100"); runWinFinish((nextState % WIN)); } else if (nextState >= LOSE) { db.submitGrade("finish", "50"); runLoseFinish((nextState % LOSE)); } else if (nextState >= INCOMPETENT) { db.submitGrade("finish", "0"); runIncompetentFinish((nextState % INCOMPETENT)); } else runNewState(nextState); } /** * runNewState is called when the student's choices lead to a different state * (i.e., not court or a final result) * * @param newState The index of the new state we should display */ public synchronized void runNewState(int newState) { pict = new ImageCanvas(courtIm[lawyerSex]); BufferedReader ns = openFile(textFile[newState]); String[][] script = parseNewState(ns); stateVector = String.valueOf(newState)+","; tc = new TextCanvas(script, getFont(), getSize().width-pict.getPreferredSize().width, pict.getPreferredSize().height-INSET); displayNewState(0); if (soundOn) { sound.stopSound(); sound = new SoundPlayer(soundFile[lawyerSex][newState], this); sound.playSound(0); } } /** * runIncompetentFinish runs the finish when the lawyer performs incompetently * * @param scene The index of the incompetent finish we should display */ public synchronized void runIncompetentFinish(int scene) { finalResult = INCOMPETENT; pict = new ImageCanvas(finishIm[lawyerSex][0]); keep = new Component[1]; keep[0] = pict; tc = new TextCanvas(parseFinish(0, scene), getFont(), getSize().width-pict.getPreferredSize().width, pict.getPreferredSize().height-INSET); displayScript(9, 0); if (soundOn) { sound.stopSound(); sound = new SoundPlayer(finishSound[lawyerSex][0], this); sound.playSound(scene-1); } } /** * runLoseFinish runs the finish when the lawyer loses the case * * @param scene The index of the losing finish we should display */ public synchronized void runLoseFinish(int scene) { finalResult = LOSE; pict = new ImageCanvas(finishIm[lawyerSex][1]); keep = new Component[1]; keep[0] = pict; tc = new TextCanvas(parseFinish(1, scene), getFont(), getSize().width-pict.getPreferredSize().width, pict.getPreferredSize().height-INSET); displayScript(9, 0); if (soundOn) { sound.stopSound(); sound = new SoundPlayer(finishSound[lawyerSex][1], this); sound.playSound(scene-1); } } /** * runWinFinish runs the finish when the lawyer wins the case * * @param scene The index of the winning finish we should display */ public synchronized void runWinFinish(int scene) { finalResult = WIN; pict = new ImageCanvas(finishIm[lawyerSex][2]); keep = new Component[1]; keep[0] = pict; tc = new TextCanvas(parseFinish(2, scene), getFont(), getSize().width-pict.getPreferredSize().width, pict.getPreferredSize().height-INSET); displayScript(9, 0); if (soundOn) { sound.stopSound(); sound = new SoundPlayer(finishSound[lawyerSex][2], this); sound.playSound(scene-1); } } /** * parseFinish reads in the finishing text from whichever finish it actually * is. * * @param result The value of the finish, which tells us which file to open * @param scene The index of the finish we should display * @return An array of arrays of Strings, encoded as * String[individual's_speech][line_of_dialog] */ private synchronized String[][] parseFinish(int result, int scene) { BufferedReader input; switch (result) { case 0: input = openFile(incompFile); break; case 1: input = openFile(loseFile); break; case 2: input = openFile(winFile); break; default: return new String[][] {{}}; } String textTemp[][] = new String[20][30]; int paraNum = -1; int lineNum = 0; boolean reading = false; String line = ""; while (true) { try { line = input.readLine(); } catch (IOException i) { System.err.println("Problem reading in the ending file"); return new String[][] {{}}; } if (line == null) break; else if (line.equals("")) continue; else if (line.startsWith(""))); } catch (NumberFormatException n) { System.err.println("bad index tag!"); return new String[][] {{}}; } if (opt == scene) reading = true; } else if (reading) { if (line.startsWith("Judge:")) { paraNum++; lineNum = 0; textTemp[paraNum][lineNum] = replaceCodes(line); lineNum++; } else if (line.startsWith("J:")) { paraNum++; lineNum = 0; StringBuffer temp = new StringBuffer(line); temp.insert(1, "udge"); textTemp[paraNum][lineNum] = replaceCodes(temp.toString()); lineNum++; } else if (line.startsWith("Opposing:")) { paraNum++; lineNum = 0; textTemp[paraNum][lineNum] = replaceCodes(line); lineNum++; } else if (line.startsWith("O:")) { paraNum++; lineNum = 0; StringBuffer temp = new StringBuffer(line); temp.insert(1, "pposing"); textTemp[paraNum][lineNum] = replaceCodes(temp.toString()); lineNum++; } else { textTemp[paraNum][lineNum] = replaceCodes(line); lineNum++; } } } String[][] script = new String[paraNum+1][]; for (int i=0; i= 2*max(rowMax, colMax) int nameNum = 0; String attrib[] = new String[15]; int lineNum = 0; String line = ""; boolean inData = false; while (true) { try { line = input.readLine(); } catch (IOException i) { System.err.println("Problem reading in the data file"); return; } if (line == null) break; else if (line.equals("")) continue; else if (line.startsWith("")) { inData = true; } else if (line.startsWith("")) { inData = false; } else if (inData) { if (Character.isWhitespace(line.charAt(0))) { // column names boolean inName = false; for (int i=0; i"))); } catch (NumberFormatException n) { System.err.println("problem with choice number"); return new String[][] {{}}; } line = line.substring(line.indexOf(">")+1); lineNum = 0; optionsTemp[optNum][choNum][lineNum] = line; lineNum++; } else { if (inText) { textTemp[paraNum][lineNum] = replaceCodes(line); lineNum++; } else { optionsTemp[optNum][choNum][lineNum] = replaceCodes(line); lineNum++; } } } String[][] script = new String[paraNum+1][]; for (int i=0; i 0) { String temp = orig.substring(0, num); temp += lawyerName; temp += orig.substring(num+8, orig.length()); orig = temp; num = orig.indexOf("##name##"); } num = orig.indexOf("##pronoun##"); while (num > 0) { String temp = orig.substring(0, num); if (lawyerSex == FEMALE) { temp += "s"; } temp += "he"; temp += orig.substring(num+11, orig.length()); orig = temp; num = orig.indexOf("##pronoun##"); } return orig; } /** * removeAllExcept removes all of the Components except the ones in the * argument array. * * @param keep The array of Components to keep */ private synchronized void removeAllExcept(Component keep[]) { Component inCont[] = this.getComponents(); CHECK: for (int i=0; i"); try { choNum = Integer.parseInt(line.substring(1, end)); } catch (NumberFormatException n) { System.err.println("choice number not valid!"); return; } lineNum = 0; optionsTemp[optNum][choNum][lineNum] = line.substring(3); lineNum++; } else if (line.startsWith(" -1) { if (delimitInd == newLine.length()-1) { try { soundTemp[MALE][header][fileNum] = new URL(getCodeBase()+lessonBase+ newLine.substring(eqInd, delimitInd)); } catch (MalformedURLException m) { System.err.println("bad soundfile URL: "+ m.toString()); return; } inMSoundFile = true; continue LOAD; } else { try { soundTemp[MALE][header][fileNum] = new URL(getCodeBase()+lessonBase+ newLine.substring(eqInd, delimitInd)); } catch (MalformedURLException m) { System.err.println("bad soundfile URL: "+ m.toString()); return; } eqInd = delimitInd; fileNum++; delimitInd = newLine.indexOf(";", eqInd); } } try { soundTemp[MALE][header][fileNum] = new URL(getCodeBase()+lessonBase+ newLine.substring(eqInd)); } catch (MalformedURLException m) { System.err.println("bad soundfile URL: "+m.toString()); return; } inMSoundFile = false; continue LOAD; } // FEMALE SOUNDFILE if (newLine.startsWith("fsoundfile=") || inFSoundFile) { int delimitInd = newLine.indexOf(";"); int fileNum = 0; // get to the first null space in the temp array for (int i=0; i -1) { if (delimitInd == newLine.length()-1) { try { soundTemp[FEMALE][header][fileNum] = new URL(getCodeBase()+lessonBase+ newLine.substring(eqInd, delimitInd)); } catch (MalformedURLException m) { System.err.println("bad soundfile URL: "+ m.toString()); return; } inFSoundFile = true; continue LOAD; } else { try { soundTemp[FEMALE][header][fileNum] = new URL(getCodeBase()+lessonBase+ newLine.substring(eqInd, delimitInd)); } catch (MalformedURLException m) { System.err.println("bad soundfile URL: "+ m.toString()); return; } eqInd = delimitInd; fileNum++; delimitInd = newLine.indexOf(";", eqInd); } } try { soundTemp[FEMALE][header][fileNum] = new URL(getCodeBase()+lessonBase+ newLine.substring(eqInd)); } catch (MalformedURLException m) { System.err.println("bad soundfile URL: "+m.toString()); return; } inFSoundFile = false; continue LOAD; } // TEXTFILE if (newLine.startsWith("textfile=")) { if (header == 110) { try { incompFile = new URL(getCodeBase()+newLine.substring(eqInd)); } catch (MalformedURLException m) { System.err.println("bad incompetent ending URL: "+ m.toString()); return; } } else if (header == 111) { try { loseFile = new URL(getCodeBase()+lessonBase+ newLine.substring(eqInd)); } catch (MalformedURLException m) { System.err.println("bad losing ending URL: "+ m.toString()); return; } } else if (header == 112) { try { winFile = new URL(getCodeBase()+lessonBase+ newLine.substring(eqInd)); } catch (MalformedURLException m) { System.err.println("bad winning ending URL: "+ m.toString()); return; } } else { try { textTemp[header] = new URL(getCodeBase()+lessonBase+ newLine.substring(eqInd)); } catch (MalformedURLException m) { System.err.println("bad textfile URL: "+m.toString()); return; } } continue LOAD; } // DATAFILE if (newLine.startsWith("datafile=")) { try { dataFile = new URL(getCodeBase()+lessonBase+ newLine.substring(eqInd)); } catch (MalformedURLException m) { System.err.println("bad datafile URL: "+m.toString()); return; } continue LOAD; } // CHOICES if (newLine.startsWith("choices=")) { // initialize (possibly too largely) the choices array choices = new int[newLine.length()-eqInd]; int j = 0; int curr = 0; for (int i=eqInd; i < newLine.length(); i++) { if (Character.isDigit(newLine.charAt(i))) { curr *= 10; curr += Character.digit(newLine.charAt(i), 10); } else if (curr != 0) { choices[j] = curr; curr = 0; j++; } } continue LOAD; } // PANELLINKS if (newLine.startsWith("panellinks=") || inPanelLinks) { int delimitInd = newLine.indexOf(">"); int linkNum = 0; for (int i=0; i", delimitInd+1); linkNum++; if (delimitInd < 0 && eqInd > 0) { inPanelLinks = true; continue LOAD; } } // now copy them over to the actual arrays panelLinkTitle = new String[linkNum]; System.arraycopy(titleTemp, 0, panelLinkTitle, 0, linkNum); panelLink = new URL[linkNum]; System.arraycopy(linkTemp, 0, panelLink, 0, linkNum); inPanelLinks = false; continue LOAD; } // IF if (newLine.startsWith("if")) { // determine what the result of the 'if' is int result = 0; if (eqInd != 0) { // it's an actual result eqInd++; try { result = Integer.parseInt(newLine.substring(eqInd)); } catch (NumberFormatException n) { System.err.println("bad result num: "+n.toString()); return; } char type = newLine.charAt(eqInd-1); if ((type == 'i') || (type == 'I')) result += INCOMPETENT; else if ((type == 'l') || (type == 'L')) result += LOSE; else if ((type == 'w') || (type == 'W')) result += WIN; else System.err.println("Unrecognized finish type: "+type); } else { // it's a new state eqInd = newLine.indexOf("goto ") + 5; String stateName = newLine.substring(eqInd); int i; // figure out which one... for (i=0; i < numOfNewStates; i++) { if (newStates[i].equals(stateName)) { result = i + 4; break; } } // ...or add it to the newStates array if (i == numOfNewStates) { newStates[i] = stateName; result = i + 4; numOfNewStates++; } } Integer value = new Integer(result); // now we need to figure out which vectors to assign the // result to, depending on the header number. int vecSt = newLine.indexOf("<"); vecSt++; if (header == 3) { // we're in the Brief section int vector[] = new int[choices.length]; int vecInd = 0; boolean neg = false; while (true) { int val = 0; if (newLine.charAt(vecSt) == '>') break; else if (newLine.charAt(vecSt) == '*') { vector[vecInd] = 1000; vecInd++; } else if (newLine.charAt(vecSt) == '~') neg = true; else if (Character.isDigit(newLine.charAt(vecSt))) { while (Character.isDigit(newLine.charAt(vecSt))) { val *= 10; val += Character.digit(newLine.charAt(vecSt), 10); vecSt++; } vecSt--; vector[vecInd] = val; if (neg) { vector[vecInd] *= -1; neg = false; } vecInd++; } vecSt++; } String keys[] = new String[1000]; int numOfVectors = 0; // have to create the "starter" string(s) if (vector[0] == 1000) { for (int i=0; i < choices[0]; i++) { keys[i] = String.valueOf(i+1); } numOfVectors = choices[0]; } else if (vector[0] > 0) { keys[0] = String.valueOf(vector[0]); numOfVectors = 1; } else if (vector[0] < 0) { int not = Math.abs(vector[0]) - 1; for (int i=0; i < choices[0]; i++) { if (i != not) keys[i] = String.valueOf(i+1); } numOfVectors = choices[0] - 1; } // now we add on the elements for (int i=1; vector[i] != 0; i++) { if (vector[i] == 1000) { // make the right number of copies for (int j=1; j < choices[i]; j++) { for (int k=0; k < numOfVectors; k++) { keys[numOfVectors*j + k] = keys[k]; } } // then add on the elements for (int j=0; j < choices[i]; j++) { for (int k=0; k < numOfVectors; k++) { keys[numOfVectors*j + k] += ","+String.valueOf(j+1); } } numOfVectors *= choices[i]; } else if (vector[i] > 0) { for (int j=0; j < numOfVectors; j++) { keys[j] += ","+String.valueOf(vector[i]); } } else { int not = Math.abs(vector[i]); // make the right number of copies for (int j=1; j < choices[i] - 1; j++) { for (int k=0; k < numOfVectors; k++) { keys[numOfVectors*j + k] = keys[k]; } } // then add on the elements boolean passed = false; for (int j=0; j < choices[i]; j++) { if ((j+1) == not) { passed = true; continue; } for (int k=0; k < numOfVectors; k++) { if (passed) { keys[numOfVectors*(j-1) + k] += ","+String.valueOf(j+1); } else { keys[numOfVectors*j + k] += ","+String.valueOf(j+1); } } } numOfVectors *= choices[i] - 1; } } for (int i=0; i < numOfVectors; i++) { if (briefResult.containsKey(keys[i])) { ; } else briefResult.put(keys[i], value); } } else { // we're in one of the new states String vector = String.valueOf(header); while(newLine.charAt(vecSt) != '>') { int val = 0; while (Character.isDigit(newLine.charAt(vecSt))) { val *= 10; val += Character.digit(newLine.charAt(vecSt), 10); vecSt++; } if (val != 0) { vector += ","+String.valueOf(val); vecSt--; } vecSt++; } responseResult.put(vector, value); } continue LOAD; } } // this closes the while(true) loop // need to transfer the temp data to the final arrays soundFile = new URL[2][numOfNewStates + 4][]; for (int h=0; h