/* Soot - a J*va Optimization Framework * Copyright (C) 2003 Jennifer Lhotak * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package ca.mcgill.sable.soot.launching; import java.util.*; public class SootSavedConfiguration { private HashMap config; private String name; private String saved; private ArrayList saveArray; private ArrayList runArray; private HashMap eclipseDefs; private static final String SPACE = " "; private static final String COLON = ":"; private static final String DASH = "--"; /** * Constructor for SootSavedConfiguration. */ public SootSavedConfiguration(String name, HashMap config) { setName(name); setConfig(config); } /** * Constructor for SootSavedConfiguration. */ public SootSavedConfiguration(String name, String [] saveArray) { setName(name); setSaveArray(new ArrayList()); for (int i = 0; i < saveArray.length; i++){ getSaveArray().add(saveArray[i]); } } /** * Constructor for SootSavedConfiguration. */ public SootSavedConfiguration(String name, String saved) { setName(name); setSaved(saved); } // same as before (removes defs from HashMap) private void removeEclipseDefs(){ if (getEclipseDefs() == null) return; Iterator it = getEclipseDefs().keySet().iterator(); while (it.hasNext()) { String key = (String)it.next(); if (getConfig().containsKey(key)) { String needsToMatch = ""; Object val = getEclipseDefs().get(key); if (val instanceof String){ needsToMatch = (String)val; } else if (val instanceof ArrayList){ Iterator it2 = ((ArrayList)val).iterator(); while (it2.hasNext()){ if (needsToMatch.equals("")){ needsToMatch = (String)it2.next(); } else { needsToMatch = needsToMatch + "\r\n" + (String)it2.next(); } } } if (getConfig().get(key).equals(needsToMatch) || getConfig().get(key).equals(val)) { getConfig().remove(key); } } else { getConfig().put(key, getOppositeVal(getEclipseDefs().get(key)) ); } } } private Object getOppositeVal(Object val) { if (val instanceof Boolean) { if (((Boolean)val).booleanValue()) return new Boolean(false); else return new Boolean(true); } else { return ""; } } // will use addEclipseDefs to Array instead private void addEclipseDefs() { if (getEclipseDefs() == null) return; Iterator it = getEclipseDefs().keySet().iterator(); StringBuffer tempSaved = new StringBuffer(getSaved()); while (it.hasNext()) { String key = (String)it.next(); if (getSaved().indexOf((DASH+key)) != -1) { // already there don't add (implies user changed val) } else { Object val = getEclipseDefs().get(key); if (val instanceof String){ String res = (String)val; tempSaved.append(SPACE); tempSaved.append(DASH); tempSaved.append(key); tempSaved.append(SPACE); tempSaved.append(val); tempSaved.append(SPACE); } else { Iterator it2 = ((ArrayList)val).iterator(); while (it2.hasNext()){ String nextVal = (String)it2.next(); tempSaved.append(SPACE); tempSaved.append(DASH); tempSaved.append(key); tempSaved.append(SPACE); tempSaved.append(nextVal); tempSaved.append(SPACE); } } } } setSaved(tempSaved.toString()); } // will use this one in future and not addEclipseDefs private void addEclipseDefsToArray() { if (getEclipseDefs() == null) return; Iterator it = getEclipseDefs().keySet().iterator(); while (it.hasNext()) { String key = (String)it.next(); if (getSaveArray().contains(DASH+key)) { // already there don't add (implies user changed val) } else { Object val = getEclipseDefs().get(key); if (val instanceof String){ String res = (String)val; getSaveArray().add(DASH+key); getSaveArray().add(res); } else if (val instanceof Boolean){ getSaveArray().add(DASH+key); getSaveArray().add(val.toString()); } } } } public HashMap toHashMapFromArray(){ addEclipseDefsToArray(); HashMap config = new HashMap(); BitSet bits = new BitSet(getSaveArray().size()); for (int i = 0; i < getSaveArray().size(); i++){ if (((String)getSaveArray().get(i)).indexOf("--") != -1){ bits.set(i); } } int counter = 0; while (counter < getSaveArray().size()){ if ((bits.get(counter+2)) || ((counter+2) >= getSaveArray().size())){ // non phase opt // if key is already in map val = val + \n\r newVal String key = ((String)getSaveArray().get(counter)).substring(2); String val = (String)getSaveArray().get(counter+1); if (config.get(key) != null){ String tempVal = (String)config.get(key); tempVal = tempVal + "\r\n" + val; config.put(key, tempVal); } else { config.put(key,val); } counter = counter + 2; } else if ((bits.get(counter+3)) || ((counter+3) >= getSaveArray().size())){ // phase opt String key = getSaveArray().get(counter)+SPACE+getSaveArray().get(counter+1); StringTokenizer valTemp = new StringTokenizer((String)getSaveArray().get(counter+2), ":"); key = key+SPACE+valTemp.nextToken(); String val = valTemp.nextToken(); config.put(key.substring(2), val); counter = counter + 3; } } return config; } // goes from save String to HashMap public HashMap toHashMap() { // first add eclipse defs addEclipseDefs(); HashMap config = new HashMap(); String temp = getSaved(); temp = temp.replaceAll("--", "&&"); StringTokenizer st = new StringTokenizer(temp, "&&"); while (st.hasMoreTokens()) { StringTokenizer next = new StringTokenizer((String)st.nextToken()); switch (next.countTokens()) { case 2: { config.put(next.nextToken(), next.nextToken()); break; } case 3: { // phase options String key = next.nextToken()+SPACE+next.nextToken(); StringTokenizer valTemp = new StringTokenizer(next.nextToken(), ":"); key = key+SPACE+valTemp.nextToken(); String val = valTemp.nextToken(); config.put(key, val); break; } default: { //unhandled break; } } } return config; } // goes from save Array to run Array - //will use this and not toRunString in future public ArrayList toRunArray() { addEclipseDefsToArray(); if (getRunArray() == null){ setRunArray(new ArrayList()); } Iterator it = getSaveArray().iterator(); String lastKey = ""; while (it.hasNext()){ String test = (String)it.next(); String spliter = "\r\n"; if (test.indexOf("\r\n") != -1){ spliter = "\r\n"; } else if (test.indexOf('\n') != -1){ spliter = "\n"; } if (test.equals("true")){ // don't send } else if (test.equals("false")){ // don't send and also don't send key int index = getRunArray().size() - 1; getRunArray().remove(index); } else if (test.indexOf(spliter) != -1){ String [] tokens = test.split(spliter); getRunArray().add(tokens[0]); for (int i = 1; i < tokens.length; i++){ getRunArray().add(lastKey); getRunArray().add(tokens[i]); } } else { getRunArray().add(test); } lastKey = test; } return getRunArray(); } // goes from save String to run String public String toRunString() { // first add eclipse defs addEclipseDefs(); StringBuffer toRun = new StringBuffer(); String temp = getSaved(); temp = temp.replaceAll("--", "&&"); StringTokenizer st = new StringTokenizer(temp, "&&"); while (st.hasMoreTokens()) { StringTokenizer next = new StringTokenizer((String)st.nextToken()); switch (next.countTokens()) { case 2: { String key = next.nextToken(); String val = next.nextToken(); val = val.trim(); // if true its a boolean and want to send if (val.equals("true")) { toRun.append(DASH); toRun.append(key); toRun.append(SPACE); } // if false its a boolean but don't want to send else if (val.equals("false")) { } // non boolean else { toRun.append(DASH); toRun.append(key); toRun.append(SPACE); toRun.append(val); toRun.append(SPACE); } break; } case 3: { // phase options String key = next.nextToken()+SPACE+next.nextToken()+SPACE+next.nextToken(); toRun.append(DASH); toRun.append(key); toRun.append(SPACE); break; } default: { //unhandled break; } } } return toRun.toString(); } // goes from HashMap to ArrayList -> will use this and // not toSaveString in future public ArrayList toSaveArray() { if (getSaveArray() == null) { setSaveArray(new ArrayList()); } removeEclipseDefs(); Iterator keysIt = getConfig().keySet().iterator(); while (keysIt.hasNext()) { String key = (String)keysIt.next(); StringTokenizer st = new StringTokenizer(key); Object val = getConfig().get(key); switch(st.countTokens()) { case 1: { String aliasName = st.nextToken(); if (aliasName.equals("sootMainClass")) continue; if (val instanceof String) { String test = (String)val; if ((test == null) |(test.length() == 0)) { System.out.println("continuing" ); continue;} } getSaveArray().add(DASH+aliasName); if (val instanceof Boolean) { getSaveArray().add(val.toString()); } else if (val instanceof String) { String test = (String)val; String spliter = "\r\n"; if (test.indexOf("\r\n") != -1){ spliter = "\r\n"; } else if (test.indexOf('\n') != -1){ spliter = "\n"; } if (test.indexOf(spliter) != -1){ String [] tokens = test.split(spliter); getSaveArray().add(tokens[0]); for (int i = 1; i < tokens.length; i++){ getSaveArray().add(DASH+aliasName); getSaveArray().add(tokens[i]); } } else { getSaveArray().add(val); } } break; } case 3: { getSaveArray().add(DASH+st.nextToken()); getSaveArray().add(st.nextToken()); String realVal = st.nextToken()+COLON; if (val instanceof Boolean) { realVal = realVal + val.toString(); } else if (val instanceof String) { realVal = realVal + val; } getSaveArray().add(realVal); break; } default: { //unhandled non option break; } } } return getSaveArray(); } // goeas from HashMap to String - will use toSaveArray in future public String toSaveString() { // first remove eclipse defs removeEclipseDefs(); StringBuffer toSave = new StringBuffer(); Iterator keysIt = getConfig().keySet().iterator(); while (keysIt.hasNext()) { String key = (String)keysIt.next(); StringTokenizer st = new StringTokenizer(key); Object val = getConfig().get(key); switch(st.countTokens()) { case 1: { toSave.append(DASH); String aliasName = st.nextToken(); toSave.append(aliasName); toSave.append(SPACE); if (val instanceof Boolean) { toSave.append(val.toString()); } else if (val instanceof String) { if (((String)val).indexOf("\n") != -1){ StringTokenizer listOptTokenizer = new StringTokenizer((String)val, "\n"); while (listOptTokenizer.hasMoreTokens()){ String next = listOptTokenizer.nextToken(); toSave.append(next); if (listOptTokenizer.hasMoreTokens()){ toSave.append(DASH); toSave.append(aliasName); toSave.append(SPACE); } } } else { toSave.append(val); } } toSave.append(SPACE); break; } case 3: { toSave.append(DASH); toSave.append(st.nextToken()); toSave.append(SPACE); toSave.append(st.nextToken()); toSave.append(SPACE); toSave.append(st.nextToken()); toSave.append(COLON); if (val instanceof Boolean) { toSave.append(val.toString()); } else if (val instanceof String) { toSave.append(val); } toSave.append(SPACE); break; } default: { //unhandled non option break; } } } setSaved(toSave.toString()); return toSave.toString(); } /** * Returns the config. * @return HashMap */ public HashMap getConfig() { return config; } /** * Returns the name. * @return String */ public String getName() { return name; } /** * Sets the config. * @param config The config to set */ public void setConfig(HashMap config) { this.config = config; } /** * Sets the name. * @param name The name to set */ public void setName(String name) { this.name = name; } /** * Returns the saved. * @return String */ public String getSaved() { return saved; } /** * Sets the saved. * @param saved The saved to set */ public void setSaved(String saved) { this.saved = saved; } /** * Returns the eclipseDefs. * @return HashMap */ public HashMap getEclipseDefs() { return eclipseDefs; } /** * Sets the eclipseDefs. * @param eclipseDefs The eclipseDefs to set */ public void setEclipseDefs(HashMap eclipseDefs) { this.eclipseDefs = eclipseDefs; } /** * @return */ public ArrayList getSaveArray() { return saveArray; } /** * @param list */ public void setSaveArray(ArrayList list) { saveArray = list; } /** * @return */ public ArrayList getRunArray() { return runArray; } /** * @param list */ public void setRunArray(ArrayList list) { runArray = list; } }