package org.ut.biolab.medsavant.client.controller; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.ut.biolab.medsavant.client.api.Listener; import org.ut.biolab.medsavant.client.settings.DirectorySettings; import org.ut.biolab.medsavant.client.view.login.MedSavantServerInfo; import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Semaphore; import java.util.logging.Level; import java.util.logging.Logger; /** * Created by mfiume on 2/3/2014. */ public class ServerController { private final ArrayList<Listener<ServerController>> listeners; Log LOG = LogFactory.getLog(ServerController.class); List<MedSavantServerInfo> servers; MedSavantServerInfo tmpServer; private final String SERVER_FILE_NAME = ".servers"; private static final String KEY_SETTING_LASTSERVER_NICKNAME = "server-nickname"; private static ServerController instance; private MedSavantServerInfo currentServer; //private final Semaphore semaphore = new Semaphore(1, true); //private static final Object initializationLock = new Object(); public synchronized static ServerController getInstance() { if (instance == null) { instance = new ServerController(); } return instance; } private ServerController() { listeners = new ArrayList<Listener<ServerController>>(); loadServers(); String serverNickName = SettingsController.getInstance().getValue(KEY_SETTING_LASTSERVER_NICKNAME); if (serverNickName != null) { MedSavantServerInfo server = getServerWithName(serverNickName); if (server != null) { setCurrentServer(server); } } else { if (servers.size() > 0) { setCurrentServer(servers.get(0)); } } } public void setCurrentServer(MedSavantServerInfo server) { currentServer = server; if (server == null) { SettingsController.getInstance().setValue(KEY_SETTING_LASTSERVER_NICKNAME, null); } else { SettingsController.getInstance().setValue(KEY_SETTING_LASTSERVER_NICKNAME, server.getNickname()); LOG.info("Setting server to " + server.getNickname()); } notifyListeners(); } private void notifyListeners() { for (Listener l : listeners) { l.handleEvent(null); } } private MedSavantServerInfo getServerWithName(String serverNickName) { for (MedSavantServerInfo s : servers) { if (s.getNickname().equals(serverNickName)) { return s; } } return null; } private File getServerFile() { return new File(DirectorySettings.getMedSavantDirectory(), SERVER_FILE_NAME); } public void addServer(MedSavantServerInfo server) { LOG.info("Adding server " + server.getNickname() + " count is " + servers.size()); servers.add(server); saveServers(); } public void addTemporaryServer(MedSavantServerInfo server) { tmpServer = server; saveServers(); } public synchronized void saveServers() { saveServers(true); } public synchronized void saveServers(boolean notifyListeners) { //LOG.info("Serializing " + servers.size() + " servers"); FileOutputStream fileout = null; Writer out = null; // remove passwords before saving List<MedSavantServerInfo> serversWithPasswordsRemoved = new ArrayList<MedSavantServerInfo>(); for (MedSavantServerInfo s : servers) { MedSavantServerInfo clone = new MedSavantServerInfo(s); if (!clone.isRememberPassword()) { clone.setPassword(""); } //LOG.info("Saved " + clone.getNickname()); serversWithPasswordsRemoved.add(clone); } try { fileout = new FileOutputStream(getServerFile()); out = new OutputStreamWriter(fileout,"UTF-8"); Gson gson = new GsonBuilder().create(); gson.toJson(serversWithPasswordsRemoved, out); out.close(); fileout.close(); LOG.info("Saved " + serversWithPasswordsRemoved.size() + " servers"); } catch (Exception ex) { LOG.error("Problem saving servers", ex); ex.printStackTrace(); } finally { try { out.close(); } catch (Exception ex) { } try { fileout.close(); } catch (Exception ex) { } } if (notifyListeners) { notifyListeners(); } } private synchronized void loadServers() { FileInputStream filein = null; Reader in = null; try { // create the server file if (!getServerFile().exists()) { servers = new ArrayList<MedSavantServerInfo>(); saveServers(); // load the server file } else { filein = new FileInputStream(getServerFile()); in = new InputStreamReader(filein); LOG.info("Deserializing servers"); try { Gson gson = new GsonBuilder().create(); java.lang.reflect.Type type = new TypeToken<List<MedSavantServerInfo>>(){}.getType(); servers = gson.fromJson(in, type); // happens if the server class changes, nuke the file and start again } catch (Exception e) { LOG.info("Corrupted server file, recreating " + e); getServerFile().delete(); servers = new ArrayList<MedSavantServerInfo>(); saveServers(); } in.close(); filein.close(); } LOG.info("Loaded " + servers.size() + " servers"); } catch (Exception ex) { LOG.error("Problem loading servers", ex); servers = new ArrayList<MedSavantServerInfo>(); } finally { try { in.close(); } catch (Exception ex) { } try { filein.close(); } catch (Exception ex) { } } } public void removeServer(MedSavantServerInfo server) { LOG.info("Removing server " + server.getNickname() + " count is " + servers.size()); servers.remove(server); if (currentServer == server) { setCurrentServer(null); } saveServers(); } public MedSavantServerInfo getServerNamed(String name) { for (MedSavantServerInfo s : servers) { if (s.getNickname().equals(name)) { return s; } } return null; } public MedSavantServerInfo getCurrentServer() { return currentServer; } public void addListener(Listener<ServerController> serverListener) { listeners.add(serverListener); } public List<MedSavantServerInfo> getServers() { return servers; } public boolean isServerNamed(String name) { return getServerNamed(name) != null; } }