ExpresserLauncher.java :  » Math » migen » uk » ac » lkl » migen » system » Java Open Source

Java Open Source » Math » migen 
migen » uk » ac » lkl » migen » system » ExpresserLauncher.java
package uk.ac.lkl.migen.system;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.MissingResourceException;

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;


import org.restlet.Client;
import org.restlet.data.Method;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.resource.Representation;

import uk.ac.lkl.common.util.LoggingUtilities;
import uk.ac.lkl.common.util.RobotUtilities;
import uk.ac.lkl.common.util.SubversionUtilities;
import uk.ac.lkl.common.util.config.ConfigurationException;
import uk.ac.lkl.common.util.config.ConfigurationOutOfSyncException;
import uk.ac.lkl.common.util.datafile.AbstractDataFileManager;
import uk.ac.lkl.common.util.datafile.BasicDataFileManager;
import uk.ac.lkl.common.util.datafile.DataFile;
import uk.ac.lkl.common.util.datafile.SettableDataFileManager;
import uk.ac.lkl.common.util.restlet.RestletException;
import uk.ac.lkl.common.util.value.IntegerValue;

import uk.ac.lkl.migen.system.expresser.LoggerConfigurator;
import uk.ac.lkl.migen.system.expresser.model.AvailableTileColors;
import uk.ac.lkl.migen.system.expresser.model.ExpresserModel;
import uk.ac.lkl.migen.system.expresser.model.event.CreationEventManager;
import uk.ac.lkl.migen.system.expresser.model.exception.ColorSpecificationException;
import uk.ac.lkl.migen.system.expresser.ui.ActivityMaker;
import uk.ac.lkl.migen.system.expresser.ui.BlockShapeCanvasPanel;
import uk.ac.lkl.migen.system.expresser.ui.ExpresserModelPanel;
import uk.ac.lkl.migen.system.expresser.ui.MasterSlaveUniverseMicroworldPanel;
import uk.ac.lkl.migen.system.expresser.ui.MultiUniverseTabbedPanel;
import uk.ac.lkl.migen.system.expresser.ui.ObjectCanvasFrame;
import uk.ac.lkl.migen.system.expresser.ui.ObjectSetCanvas;
import uk.ac.lkl.migen.system.expresser.ui.ecollaborator.ActivityDocument;
import uk.ac.lkl.migen.system.expresser.ui.ecollaborator.ActivityDocumentXMLString;
import uk.ac.lkl.migen.system.expresser.ui.event.ClientCreationEventListener;
import uk.ac.lkl.migen.system.server.Gender;
import uk.ac.lkl.migen.system.server.MiGenServerCommunicator;
import uk.ac.lkl.migen.system.server.OfflineUser;
import uk.ac.lkl.migen.system.server.User;
import uk.ac.lkl.migen.system.server.UserSet;
import uk.ac.lkl.migen.woztools.intervention.InterventionDisplayerImpl;

/**
 * The main point of entry for the stand-alone version of the eXpresser.
 * 
 * @author $Author: sergut $
 * @version $Revision: 9203 $
 * @version $Date: 2011-04-21 16:34:45 -0700 (Thu, 21 Apr 2011) $
 */
public class ExpresserLauncher extends MiGenLauncher {

    // to provide access when closing the window
    private static InterventionDisplayerImpl wizardOfOzFeedbackServer = null;
    private static MultiUniverseTabbedPanel modelCopyTabbedPane;
    private static ObjectCanvasFrame<IntegerValue> mainExpresserFrame;
    private static boolean rearrangingPanels = false;

    // hack: so can share between methods -- need to clean up this class a lot!!
    private static SettableDataFileManager taskConfigsFileManager = null;
    private static BasicDataFileManager tasksFileManager = null;
    private static BasicDataFileManager messagesFileManager = null;
    
    private static boolean savedActivityDocumentLoadPending;

    private static Runnable repaintRunnable = new Runnable() {
  public void run() {
      if (mainExpresserFrame != null) {
    mainExpresserFrame.repaint();
      }
      repaintPending = false;
  }};

    private static boolean repaintPending = false;

    private static UserSet userSet = null;
    
    private static List<User> allUsers = new ArrayList<User>();

    private static long startTime = 0;

    private static HomepageFrame homepageFrame = null;

    private static SetupFrame setupFrame = null;
    
    private static String configFilename = null;
    
    public static void main(String[] args) throws RestletException, ConfigurationException {
  if (args.length > 1)
      usage();

  configFilename = (args.length == 1) ? args[0] : "migen.ini";
  try {
      init();
      initialiseFileManagers();
      processConfiguration(configFilename);
      Boolean enableServer = MiGenConfiguration.isConnectedToServer();
      if (enableServer) {
    createServerCommunicator(args);
      }
      String userName = MiGenConfiguration.getUserName();
      initialiseUserSet(userName);
      launchStartFrame();
  } catch (ConfigurationOutOfSyncException e) {
      errorShutdown(e, e.getMessage(), ExitStatus.CONFIGURATION_SYNC);
  } catch (ConfigurationException e) {
      errorShutdown(e, "Invalid configuration: " + e.getMessage(), ExitStatus.CONFIG_ERROR);
  } catch (MissingResourceException e) {
      errorShutdown(e, "Missing resource", ExitStatus.NO_MESSAGE_BUNDLE_FOUND);
  } catch (RestletException e) {
      errorShutdown(e, "Server Unavailable", ExitStatus.CONNECTION_ERROR);
  }
    }

    private static void usage() {
  System.out.println("USAGE: ExpresserLauncher [<file.ini>]");
  shutdown(ExitStatus.WRONG_CMD_LINE_ARG);
   }

    // convenience for clarity
    private static void errorShutdown(Exception e, String msg, ExitStatus exitStatus) {
  e.printStackTrace();
  JOptionPane.showMessageDialog(null, msg, "System Error", JOptionPane.ERROR_MESSAGE);
  shutdown(exitStatus);  
    }

    private static void createServerCommunicator(String[] args) throws RestletException, ConfigurationException {
  if (MiGenContext.isServerCommunicatorEnabled())
      return;
  
  String serverName = MiGenConfiguration.getServerName();
  if (serverName == null)
      throw new ConfigurationException("No server defined.");
  
  int serverPort = MiGenConfiguration.getServerPort();
  MiGenServerCommunicator serverCommunicator = new MiGenServerCommunicator(serverName, serverPort);
  MiGenContext.setServerCommunicator(serverCommunicator);
  checkServerStatus(serverName, serverPort);
    }

    private static boolean isServerCommunicatorEnabled(MiGenServerCommunicator serverCommunicator) {
  if (serverCommunicator == null)
      return false;
  
  return serverCommunicator.isEnabled();
    }
    
    private static void launchStartFrame() {
  printTime("Start");
  Integer choice = null;
  if (MiGenConfiguration.isUsingHomePageOnly()) {
      choice = 1;
  } else if (MiGenConfiguration.isUsingSetupFrameOnly()) {
      choice = 0;
  }
  if (choice == null) {
      // old interface
      File file = new File("ChooseStartFrame");
      if (file.exists()) {
    choice = JOptionPane.showOptionDialog(
      null,
      "Please choose start frame:", "Start Frame Chooser",
      JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
      null, new String[] { "Setup", "Homepage" }, "Setup");
    if (choice == JOptionPane.CLOSED_OPTION) {
        shutdown(ExitStatus.NO_ERROR);
    }
      }
  }
  if (choice == null)
      launchHomepageFrame();
  else if (choice == 0)
      launchSetupFrame();
  else if (choice == 1)
      launchHomepageFrame();
    }

    public static void printTime(String message) {
  if (startTime == 0) {
      return; // don't want to instrument this run
  }
  long now = System.currentTimeMillis();
  if (startTime < 0) {
      startTime = now;
  }
  System.out.println(">>>Time is " + (now-startTime )*.001 + " seconds. " + message);  
    }

    // todo: put this somewhere more central and check name of entity layer
    private static void checkServerStatus(String server, int port) throws RestletException {
  Client client = new Client(Protocol.HTTP);
  Reference reference = new Reference("http://" + server + ":" + port);
  Request request = new Request(Method.GET, reference);
  Response response = client.handle(request);
  Status status = response.getStatus();
  if (status.isError())
      throw new RestletException("Server is not available");
  
  Representation representation = response.getEntity();
  try {
      String responseText = representation.getText();
      System.out.println(status.getName() + "\n" + responseText);
  } catch (IOException e) {
      throw new RestletException("Unable to get server check response text");
  }
    }

    private static void launchSetupFrame() {
  List<AbstractDataFileManager<?>> dataFileManagers = initialiseFileManagers();
  setupFrame = new SetupFrame(dataFileManagers);
  setupFrame.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
    DataFile currentTaskConfigFile = taskConfigsFileManager.getCurrentFile();
    startTask(currentTaskConfigFile);
      }});
  setupFrame.setVisible(true);
    }

    private static void launchHomepageFrame() {
  homepageFrame  = new HomepageFrame();
  homepageFrame.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
    printTime("Home Page button pressed.");
    ConfigHandle selectedTaskConfigHandle = homepageFrame.getSelectedConfigHandle();
    DataFile taskConfigFile = selectedTaskConfigHandle.getDataFile();
    JList savedActivityDocumentsList = homepageFrame.getSavedDocumentsList();
    if (savedActivityDocumentsList != null) {
        Object selectedValue = savedActivityDocumentsList.getSelectedValue();
        if (selectedValue != null) {
      SavedActivityDocumentHandle handle = (SavedActivityDocumentHandle) selectedValue;
      final ExpresserModel modelHandle = handle.getModelHandle();
      if (modelHandle != null) {
          savedActivityDocumentLoadPending = true;
          if (startTask(taskConfigFile)) {
        Runnable loadSavedDocument = new Runnable() {

            @Override
            public void run() {
          MiGenServerCommunicator serverCommunicator = MiGenContext.getServerCommunicator();
          ActivityDocumentXMLString activityDocumentXMLString;
          activityDocumentXMLString = serverCommunicator.getActivityDocumentXMLString(userSet, modelHandle);
          if (activityDocumentXMLString != null) {
              ActivityDocument activityDocument = activityDocumentXMLString.getActivityDocument();
              activityDocument.installActivityDocument(true);
          }
            }
        };
        SwingUtilities.invokeLater(loadSavedDocument);
          } else {
        homepageFrame.setVisible(true);
          }
      } else {
          savedActivityDocumentLoadPending = false;
          if (!startTask(taskConfigFile)) {
        homepageFrame.setVisible(true);
          }
      }
        }
    } else {
        startTask(taskConfigFile);
    }
      }}
  );
  homepageFrame.setVisible(true);
    }

    public static List<AbstractDataFileManager<?>> initialiseFileManagers() {
  if (taskConfigsFileManager == null) {
      taskConfigsFileManager = 
    new SettableDataFileManager("Configs", "data", "configs", "txt");
  }
  if (tasksFileManager == null) {  
      tasksFileManager = 
    new BasicDataFileManager("Pre-Saved Models", "data", "tasks", "xml");
  }
  if (messagesFileManager == null) {  
      messagesFileManager = 
    new BasicDataFileManager("Messages", "data", "messages", "properties");
  }
  List<AbstractDataFileManager<?>> dataFileManagers = new ArrayList<AbstractDataFileManager<?>>();
  dataFileManagers.add(taskConfigsFileManager);
  dataFileManagers.add(tasksFileManager);
  dataFileManagers.add(messagesFileManager);
  return dataFileManagers;
    }

    private static boolean startTask(DataFile taskConfigFile) {
  printTime("startTask called");
  try {
      MiGenConfiguration.resetToSystemDefault();
      processConfiguration(configFilename);
      processConfiguration(taskConfigFile);
  } catch (ConfigurationException e) {
      e.printStackTrace();
      JOptionPane.showMessageDialog(
        null, 
        "Error in activity configuration file: " + e.getMessage(), 
        "Activity Configuration Error", 
        JOptionPane.ERROR_MESSAGE);  
      return false;
  }
  setJavaAWTToolkitDesktopProperty("DnD.gestureMotionThreshold", MiGenConfiguration.getPixelsToStartDrag());
  initialiseUserSet(null);
  String errorFileName = MiGenConfiguration.getErrorFileName();
  MiGenServerCommunicator serverCommunicator = MiGenContext.getServerCommunicator();
  CreationEventManager.addCreationEventListener(new ClientCreationEventListener(serverCommunicator, getUserSet()));
  UserSet userSet = getUserSet();
  /*
   * FIXME: This is a hack to connect eGen to the DB while ActivityMaker
   * is being used.
   */
  ActivityMaker.setUserSet(userSet);
  /* ************************************* */
  if (errorFileName != null && !errorFileName.isEmpty()) {
      try {
    String fullFileName = 
        errorFileName + "_"
      + LoggingUtilities.getUserName() + "_"
      + LoggingUtilities.formatTime() + "_"
      + SubversionUtilities.getCoreVersion().replace(":", "-")
      + ".log";
    FileOutputStream os = new FileOutputStream(
      new File("log", fullFileName));
    FileOutputStream os2 = new FileOutputStream(
      new File("log", "out_" + LoggingUtilities.getUserName()
        + "_" + LoggingUtilities.formatTime() + "_"
        + SubversionUtilities.getCoreVersion().replace(":", "-")
        + ".log"));
    PrintStream ps = new PrintStream(os);
    PrintStream ps2 = new PrintStream(os2);
    System.setErr(ps);
    System.setOut(ps2);
      } catch (FileNotFoundException e) {
    e.printStackTrace();
      }
  }
  try {
      AvailableTileColors.initialiseDefaultColors();
  } catch (ColorSpecificationException e) {
      e.printStackTrace();
  }
  launchMainExpresserInterface(userSet);
  // hack maybe need to configure this
  sendStartKeys();
  return true;
    }

    /**
     * initialises allUsers
     * @throws RestletException 
     */
    private static void initialiseUserSet(String defaultName) {
  MiGenServerCommunicator serverCommunicator = MiGenContext.getServerCommunicator();
  if (allUsers.isEmpty()) {
      if (MiGenContext.isServerCommunicatorEnabled()) {
    User user = createOnlineUser(serverCommunicator, defaultName);
    if (user != null && !allUsers.contains(user)) {
        allUsers.add(user);
    }
      } else {
    allUsers.add(new OfflineUser());
      }
  }
  userSet = getUserSet(serverCommunicator, allUsers);
  if (userSet == null) {
      userSet = createUserSet(serverCommunicator, allUsers);
  }
  System.out.println("UserSet: " + userSet);
  printTime("User set computed");
    }

    /**
     * Attempts to get a User instance with the given username from the server.
     * 
     * Note that if the communicator is disabled, this method returns null
     * immediately.
     * 
     * This method also returns null if the user is not found on the list of
     * users on the server.
     * 
     * This method is very inefficient in principle since it gets the entire
     * list of users and iterates through them. This is best done through the
     * appropriate query on the server. This improvement will come ASAP. In the
     * meantime, this workaround is robust and since the number of users we will
     * have is low, does not have a huge impact on efficiency.
     * 
     * @param serverCommunicator
     * @param username
     * @return
     */
    public static User getUser(MiGenServerCommunicator serverCommunicator, String username) {
  if (!isServerCommunicatorEnabled(serverCommunicator))
      return null;

  List<User> users = serverCommunicator.getUserList();
  for (User user : users) {
      if (user.getUsername().equals(username))
    return user;
  }
  return null;
    }

    /**
     * Creates a User instance and posts it on the server (if enabled).
     * 
     * If the communicator is disabled, this method creates a User instance with
     * the given username and dummy firstname/lastname and returns this instance
     * immediately. If the communicator is enabled, the user is added to the set
     * of users known to the system after requesting that they enter their name.
     * 
     * Note that the Gender and BirthDate of the user is hard-wired here (!).
     * This is a temporary hack that will do for now.
     * 
     * @param serverCommunicator
     * @param username
     * @return
     */
    public static User createUser(MiGenServerCommunicator serverCommunicator, String username) {
  if (!isServerCommunicatorEnabled(serverCommunicator))
      return createOfflineUser(username);

  return createOnlineUser(serverCommunicator);
    }
    
    private static User createOfflineUser(String username) {
  return new User(username, username, "", Gender.MALE);
    }
    
    private static User createOnlineUser(MiGenServerCommunicator serverCommunicator) {
  return createOnlineUser(serverCommunicator, null);
    }

    private static User createOnlineUser(MiGenServerCommunicator serverCommunicator, String defaultUserName) {
  String[] nameParts;
  if (defaultUserName == null || defaultUserName.length() == 0) {
      nameParts = inputName();
      if (nameParts == null) {
    return null;
      }
  } else {
      nameParts = defaultUserName.split(" +");
  }
  String firstName = nameParts[0];
  String lastName = nameParts[1];
  // TODO: see discussion of Issue 1043
  String userName = generateUserName(firstName, lastName);
  User user = new User(userName, firstName, lastName, Gender.MALE);
  User existingUser = getUser(serverCommunicator, userName);
  if (existingUser == null) {
      int response = JOptionPane.showConfirmDialog(mainExpresserFrame, firstName + " " + lastName + " is not registered. Register now?", "New user?", JOptionPane.YES_NO_OPTION);
      if (response == JOptionPane.YES_OPTION) {
    serverCommunicator.addUser(user);
    return user;
      } else {
    return createOnlineUser(serverCommunicator);
      }
  } else {
      return existingUser;
  }
    }

    public static String generateUserName(String firstName, String lastName) {
  return firstName.substring(0,1) + lastName.charAt(0) + (firstName + lastName).hashCode();
    }

    private static String[] inputName() {
  boolean nameOk = false;
  String[] parts = null;
  do {
      String name = JOptionPane.showInputDialog("Please enter your first name and last name: ");
      if (name != null) {
    parts = name.split(" +");
    if (parts.length == 2) {
        nameOk = true;
    }
      } else {
    // user cancelled the log in
    // Does this make sense if cancelling the addition of user to form a group?
    return null;
      }
  } while (!nameOk);
  parts[0] = cannonicaliseName(parts[0]);
  parts[1] = cannonicaliseName(parts[1]);
  if (parts[0].isEmpty() || parts[1].isEmpty() ) {
      return inputName();
  }
  return parts;
    }

    private static String cannonicaliseName(String name) {
  name = name.replaceAll("\\W", "");
  name = name.toLowerCase();
  name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
  return name;
    }

    public static void addUserToUserSet() throws RestletException {
  if (!MiGenContext.isServerCommunicatorEnabled())
      return;

  MiGenServerCommunicator serverCommunicator = MiGenContext.getServerCommunicator();
  User newUser = createOnlineUser(serverCommunicator);
  while (newUser == null && allUsers.isEmpty()) {
      newUser = createOnlineUser(serverCommunicator);
  }
  if (newUser != null && !allUsers.contains(newUser)) {
      allUsers.add(newUser);
      userSet = null; // force re-computation
  }
  if (homepageFrame != null) {
      homepageFrame.updateUserLoggedInMessage();
      homepageFrame.updateSavedModelList();
  } else if (setupFrame != null) {
      setupFrame.updateUserLoggedInMessage();
  }
    }
    
    public static void removeAllUsers() {
  allUsers.clear();
    }

    /**
     * Attempts to get the appropriate UserSet from the server if enabled.
     * 
     * If the communicator is not enabled, this method returns null.
     * 
     * Otherwise, it gets all the UserSets and iterates through them looking for
     * one that consists of just the specified user. If found, this is returned.
     * If not found, null is returned.
     * 
     * @param serverCommunicator
     * @param user
     * @return
     */
    // Deprecated since only checks first user in a set
    // and supplanted by the more general following version that accepts a list of users
    @Deprecated
    public static UserSet getUserSet(MiGenServerCommunicator serverCommunicator, User user) {
  if (!isServerCommunicatorEnabled(serverCommunicator))
      return null;
  
  List<UserSet> userSets = serverCommunicator.getUserSetList();
  for (UserSet userSet : userSets) {
      if (userSet.size() == 1 && userSet.getUser(0).equals(user))
    return userSet;
  }
  return null;
    }
    
    public static UserSet getUserSet(MiGenServerCommunicator serverCommunicator, List<User> users) {
  if (!isServerCommunicatorEnabled(serverCommunicator))
      return null;
  
  int userCount = users.size();
  List<UserSet> userSets = serverCommunicator.getUserSetList();
  for (UserSet userSet : userSets) {
      if (userSet.size() == userCount) {
    List<User> usersFromServer = userSet.getUsers();
    boolean mismatch = false;
    for (User user : usersFromServer) {
        if (!users.contains(user)) {
      mismatch = true;
      break;
        }
    }
    if (!mismatch) {
        return userSet;
    }
      }
  }  
  return null;
    }

    /**
     * Creates a UserSet instance and posts it on the server (if applicable).
     * 
     * If the communicator is disabled, this method simply creates a UserSet
     * consisting solely of the given User instance and returns. Otherwise, it
     * attempts to post this to the server.
     * 
     * @param serverCommunicator
     * @param user
     * @return
     */
    @Deprecated
    // Deprecated since it uses the single user rather than a list
    public static UserSet createUserSet(MiGenServerCommunicator serverCommunicator, User user) {
  UserSet userSet = new UserSet(allUsers);
  if (!isServerCommunicatorEnabled(serverCommunicator))
      return userSet;
  
  serverCommunicator.addUserSet(userSet);
  return userSet;
    }
    
    /**
     * Creates a UserSet instance and posts it on the server (if applicable).
     * 
     * If the communicator is disabled, this method simply creates a UserSet
     * consisting of all of the given User instances and returns. Otherwise, it
     * attempts to post this to the server.
     * 
     * @param serverCommunicator
     * @param users
     * @return
     */
    public static UserSet createUserSet(MiGenServerCommunicator serverCommunicator, List<User> users) {
  UserSet userSet = new UserSet(users);
  if (isServerCommunicatorEnabled(serverCommunicator))
      serverCommunicator.addUserSet(userSet);    
      
  return userSet;
    }

    // FIXME: @Hack(who = "MM", why = "AmeryHillJune09", issues = 0)
    private static void sendStartKeys() {
  // start external programs by simulating key presses
  // TODO: use config to define these
  String[] onStartKeys = { "VK_CONTROL", "VK_SHIFT", "VK_F9" }; // Key
  RobotUtilities.sendKeysCombo(onStartKeys);
    }

    public static void setJavaAWTToolkitDesktopProperty(String key, Object value) {
  // a hack to work around the fact that
  // java.awt.Toolkit.setDesktopProperty is protected
  // based on http://www.jroller.com/tackline/entry/xp_pl_f_on_linux
  java.awt.Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit();
  java.lang.reflect.Method setter;
  try {
      setter = java.awt.Toolkit.class.getDeclaredMethod("setDesktopProperty", String.class, Object.class);
      setter.setAccessible(true); // Say please.
      setter.invoke(toolkit, key, value);
  } catch (Exception e) {
      e.printStackTrace();
  }
    }

    private static void launchMainExpresserInterface(UserSet student) {
  printTime("Before launchInterface");
  String studentName = userSet.getNamesAsString();
  LoggerConfigurator.setName(studentName);
  LoggerConfigurator.configureMainLogger(studentName);
  modelCopyTabbedPane = new MultiUniverseTabbedPanel();
  mainExpresserFrame = new ObjectCanvasFrame<IntegerValue>(modelCopyTabbedPane, studentName);
  
  prepareMainExpresserInterface(mainExpresserFrame);
  final String modelFileName = MiGenConfiguration.getInitialModelFileName();
  if (modelFileName != null && modelFileName.length() != 0) {
      Runnable loadInitialModel = new Runnable() {
    public void run() {
        ExpresserModelPanel selectedModelPanel = modelCopyTabbedPane.getSelectedModelPanel();
        ObjectSetCanvas canvas = selectedModelPanel.getCanvas();
        canvas.loadXMLDocument(new File(modelFileName));
    }};
      SwingUtilities.invokeLater(loadInitialModel);
  }
  printTime("Before createKaleidoscopeCommonFormatLogger");
  modelCopyTabbedPane.createKaleidoscopeCommonFormatLogger();
  printTime("After createKaleidoscopeCommonFormatLogger");
  /* ************************************* */  
    }

    private static void prepareMainExpresserInterface(final ObjectCanvasFrame<IntegerValue> frame) {
  frame.setVisible(true);

  if (MiGenConfiguration.isRunWozServer()) {
      frame.setTitlePostfix("-help");
  }
  frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
    closeExpresserInterface();
      }});
    }

    public static MultiUniverseTabbedPanel getModelCopyTabbedPanel() {
  return modelCopyTabbedPane;
    }

    public static BlockShapeCanvasPanel getSelectedMasterPanel() {
  return getSelectedPanel();
    }

    public static BlockShapeCanvasPanel getSelectedPanel() {
  if (modelCopyTabbedPane == null) {
      // probably not fully initialised yet or not in eXpresser
      return null;
  }
  ExpresserModelPanel selectedModelPanel = modelCopyTabbedPane.getSelectedModelPanel();
  if (selectedModelPanel instanceof MasterSlaveUniverseMicroworldPanel) {
      MasterSlaveUniverseMicroworldPanel masterSlaveUniverseMicroworldPanel = (MasterSlaveUniverseMicroworldPanel) selectedModelPanel;
      return masterSlaveUniverseMicroworldPanel.getMasterPanel();
  } else {
      return null;
  }
    }

    public static void setCurrentModelDirty() {
  if (modelCopyTabbedPane == null) {
      return;
  }
  ExpresserModel model = modelCopyTabbedPane.getModelAt(modelCopyTabbedPane.getSelectedIndex());
  if (model != null) {
      model.setDirtyModel(true);
  }
    }

    public static void autoSaveCurrentModel() {
  if (modelCopyTabbedPane == null) {
      return;
  }
  ExpresserModel model = modelCopyTabbedPane.getModelAt(modelCopyTabbedPane.getSelectedIndex());
  if (model != null) {
      model.setAutoSaveModel(true);
  }
    }

    public static void setCurrentPanelDirty() {
  if (modelCopyTabbedPane == null) {
      return;
  }
  ExpresserModel model = modelCopyTabbedPane.getModelAt(modelCopyTabbedPane.getSelectedIndex());
  if (model != null) {
      model.setDirtyPanel(true);
  }
    }

    public static ExpresserModel getModelOfSelectedTab() {
  if (modelCopyTabbedPane == null) {
      return null;
  }
  return modelCopyTabbedPane.getModelAt(modelCopyTabbedPane.getSelectedIndex());
    }

    public static ObjectCanvasFrame<IntegerValue> getFrame() {
  return mainExpresserFrame;
    }

    // Why is this necessary? - SG - Dec 2010
    // KK: A little experimenting and it seems that if the caller instead called validate() on
    // the appropriate Swing component then this would not have been necessary.
    // This is non-issue in the web version so will not fix this
    public static void repaint() {
  if (!repaintPending && mainExpresserFrame != null) {
      repaintPending = true;
      EventQueue.invokeLater(repaintRunnable);
  }
    }

    public static void add(Component component) {
  // used to give drag feedback
  Container contentPane = mainExpresserFrame.getContentPane();
  // we want this to be invisible to the layout manager
  // since it is used only for drag feedback
  // and the side effects on the layout manager
  // caused Issue 615
  LayoutManager layout = contentPane.getLayout();
  contentPane.setLayout(null);
  contentPane.add(component);
  contentPane.setComponentZOrder(component, 0);
  contentPane.setLayout(layout);
    }

    public static void remove(Component component) {
  Container contentPane = mainExpresserFrame.getContentPane();
  contentPane.remove(component);
    }

    public static Container getContentPane() {
  if (mainExpresserFrame == null) {
      return null;
  } else {
      return mainExpresserFrame.getContentPane();
  }
    }

    public static boolean isRemovalFinal(Container container) {
  return !rearrangingPanels && container != getContentPane();
    }

    public static boolean isRearrangingPanels() {
  return rearrangingPanels;
    }

    public static void setRearrangingPanels(boolean rearrangingPanels) {
  ExpresserLauncher.rearrangingPanels = rearrangingPanels;
    }

    public static UserSet getUserSet() {
  return getUserSet(true);
    }

    public static UserSet getUserSet(boolean okToCreate) {
  if (userSet == null && okToCreate) {
      initialiseUserSet(null);
  }
  return userSet;
    }

    /**
     * 
     * All exit paths should call this method instead of System.exit() to 
     * ensure that everything is in order before closing the application. 
     * 
     * @param exitStatus the exit status to be returned to the operating system.
     */
    public static void shutdown(ExitStatus exitStatus) {
  System.exit(exitStatus.toInt());
    }
    
    public static void closeExpresserInterface() {
  System.out.print("eXpresser activity closing...");
  MiGenSession.closeCurrentSession();
  if (mainExpresserFrame != null) {
      mainExpresserFrame.setVisible(false); // show that eXpresser it is closed 
      // save the current activity document
      ActivityDocument activityDocument = mainExpresserFrame.getActivityDocument();
      if (activityDocument != null && MiGenContext.isServerCommunicatorEnabled()) {
    MiGenServerCommunicator serverCommunicator = MiGenContext.getServerCommunicator();
    activityDocument.saveToServer(serverCommunicator, ActivityDocument.ACTIVITY_DOCUMENT_SAVED_BECAUSE_SHUTDOWN, null);
      }
  }  
  if (wizardOfOzFeedbackServer != null)
      wizardOfOzFeedbackServer.shutdown();

  if (modelCopyTabbedPane != null) {
      modelCopyTabbedPane.saveKaleidoscopeCommonFormatLog();
  }
  // when this is called from shutdown should the following be called depending upon the ExitStatus?
  if (homepageFrame != null) {
      homepageFrame.setVisible(true);
      homepageFrame.updateSavedModelList();
  }
  waitWhileRequestQueueIsEmptied();
  System.out.println("*** eXpresser activity closed ***");
    }

    private static void waitWhileRequestQueueIsEmptied() {
  JFrame waitFrame = new JFrame("Please wait...");
  JTextField waitText = new JTextField("Please wait while eXpresser shuts down...");
  waitText.setFont(new Font(Font.SERIF, Font.PLAIN, 16));
  waitText.setForeground(Color.BLACK);
  waitText.setEditable(false);
  waitFrame.add(waitText);
  waitFrame.pack();
  mainExpresserFrame = null;
  waitFrame.setLocationRelativeTo(null);
  System.out.println("Waiting for the request queue to empty...");
  while (!isQueueEmpty()) {
      waitFrame.setVisible(true);
      waitFrame.repaint();
      try {
    Thread.sleep(1000);
    System.out.println("Still waiting...");
      } catch (InterruptedException e) {
    System.out.println("Waked up but still waiting...");
      }
  }  
  System.out.println("Request queue empty.");
  waitFrame.setVisible(false);
    }
    
    private static boolean isQueueEmpty() {
  if (!MiGenContext.isServerCommunicatorEnabled())
      return true;
  
  return MiGenContext.getServerCommunicator().isQueueEmpty();
    }
    
    public static String getUserNames() {
  return getUserNames(", ");
    }
    
    public static String getUserNames(String separator) {
  UserSet currentUserSet = new UserSet(allUsers);
  return currentUserSet.getNamesAsString(separator);
    }

    public static boolean isSavedActivityDocumentLoadPending() {
        return savedActivityDocumentLoadPending;
    }

    public static void setUserSet(UserSet userSet) {
        ExpresserLauncher.userSet = userSet;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.