summaryrefslogtreecommitdiffstats
path: root/logo/src/xlogo/storage/global/GlobalConfig.java
diff options
context:
space:
mode:
authorMarko Živković <[email protected]>2014-12-16 02:05:55 +0000
committerMarko Živković <[email protected]>2014-12-16 02:05:55 +0000
commit57d6b0c6b96097afa06a38cc2456997ad9b60187 (patch)
treebfe3a958145cdaba3fe3114f8d167aa72c2ca1a4 /logo/src/xlogo/storage/global/GlobalConfig.java
parentb12c21a1f4c88c70faa678f1b53d05383009f937 (diff)
- USB Stick Recognition, automatically propose workspace
- New Default Workspace in user home directory - Automatically select last active user now works - Several bug fixes and minor changes git-svn-id: https://svn.code.sf.net/p/xlogo4schools/svn/trunk@11 3b0d7934-f7ef-4143-9606-b51f2e2281fd
Diffstat (limited to 'logo/src/xlogo/storage/global/GlobalConfig.java')
-rw-r--r--logo/src/xlogo/storage/global/GlobalConfig.java658
1 files changed, 456 insertions, 202 deletions
diff --git a/logo/src/xlogo/storage/global/GlobalConfig.java b/logo/src/xlogo/storage/global/GlobalConfig.java
index 6cd9124..5c0a959 100644
--- a/logo/src/xlogo/storage/global/GlobalConfig.java
+++ b/logo/src/xlogo/storage/global/GlobalConfig.java
@@ -1,27 +1,22 @@
-/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+/*
+ * XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Loic Le Coq
* Copyright (C) 2013 Marko Zivkovic
- *
* Contact Information: marko88zivkovic at gmail dot com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version. This program 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 General
- * Public License for more details. You should have received a copy of the
- * GNU General Public License along with this program; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program 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 General
+ * Public License for more details. You should have received a copy of the
+ * GNU General Public License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
- *
- *
* This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
- * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * during his Bachelor thesis at the computer science department of ETH Zurich,
* in the year 2013 and/or during future work.
- *
- * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * It is a reengineered version of XLogo written by Loic Le Coq, published
* under the GPL License at http://xlogo.tuxfamily.org/
- *
* Contents of this file were entirely written by Marko Zivkovic
*/
@@ -38,13 +33,24 @@ import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.TreeMap;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import net.samuelcampos.usbdrivedectector.USBDeviceDetectorManager;
+import net.samuelcampos.usbdrivedectector.USBStorageDevice;
+import net.samuelcampos.usbdrivedectector.events.IUSBDriveListener;
+import net.samuelcampos.usbdrivedectector.events.USBStorageEvent;
+import xlogo.AppSettings;
import xlogo.Logo;
import xlogo.messages.MessageKeys;
import xlogo.messages.async.dialog.DialogMessenger;
import xlogo.storage.StorableObject;
import xlogo.storage.WSManager;
+import xlogo.storage.user.UserConfig;
import xlogo.storage.workspace.WorkspaceConfig;
/**
@@ -52,91 +58,137 @@ import xlogo.storage.workspace.WorkspaceConfig;
* @author Marko Zivkovic
*/
public class GlobalConfig extends StorableObject implements Serializable {
-
- private static final long serialVersionUID = 2787615728665011813L;
- public static final String LOGO_FILE_EXTENSION = ".lgo";
- public static boolean DEBUG = true; // TODO set false
+ private static final long serialVersionUID = 2787615728665011813L;
+ private static Logger logger = LogManager.getLogger(GlobalConfig.class.getSimpleName());
+ public static final String LOGO_FILE_EXTENSION = ".lgo";
+ public static boolean DEBUG = true; // TODO set false
+
/**
* Creates the global config at default location, together with a virtual workspace
*/
- protected GlobalConfig()
- {
- try
- {
+ protected GlobalConfig() {
+ try {
setLocation(getDefaultLocation());
}
- catch (IllegalArgumentException ignore) { } // This is thrown if name illegal, but it is legal
+ catch (IllegalArgumentException ignore) {} // This is thrown if name illegal, but it is legal
workspaces = new TreeMap<String, String>();
workspaces.put(WorkspaceConfig.VIRTUAL_WORKSPACE, "");
+ workspaces.put(WorkspaceConfig.USER_DEFAULT_WORKSPACE, WorkspaceConfig.getDefaultWorkspaceDirectory().getAbsolutePath());
}
/**
* If GlobalConfig exists on the file system in default location, it is loaded, otherwise it will be created there.
* @return
*/
- public static GlobalConfig create()
- {
+ public static GlobalConfig create() {
File gcf = getFile(getDefaultLocation(), GlobalConfig.class);
GlobalConfig globalConfig = null;
-
- try
- {
- if (gcf.exists())
+ if (gcf.exists()) {
+ logger.trace("Try to read GlobalConfig from " + gcf.getAbsolutePath());
+ try {
globalConfig = (GlobalConfig) loadObject(gcf);
- else
- {
+ }
+ catch (Exception e) {
+ logger.error("GlobalConfig was corrupted.");
+ DialogMessenger.getInstance().dispatchError(
+ "Error while loading configuration files",
+ "Could not read GlobalConfig file " + e.toString()
+ + "\n Instead creating a new one.\nYou might need to import you workspaces manually.");
+ gcf.delete();
+ globalConfig = null;
+ }
+ }
+
+ if (globalConfig == null) {
+ try {
+ logger.info(gcf.getAbsolutePath() + " not found. Creating new.");
globalConfig = new GlobalConfig();
globalConfig.store();
}
- }catch(Exception e)
- {
- // Best effort : We will try to operate the program without storing anything on disk
- globalConfig = getNewVirtualInstance();
- DialogMessenger.getInstance().dispatchError("Error while setting up XLogo4Schools", "Could not create or open GlobalConfig file at default location: " + e.toString());
+ catch (Exception e) {
+ // Best effort : We will try to operate the program without storing anything on disk
+ logger.error("Cannot store global config at " + gcf.getAbsolutePath() + ". Running in virtual mode.");
+ globalConfig = getNewVirtualInstance();
+ DialogMessenger.getInstance().dispatchError("Error while setting up XLogo4Schools",
+ "Could not create or open GlobalConfig file at default location: " + e.toString());
+ }
}
- globalConfig.enterLastUsedWorkspace();// This is used to have a workspace ready at the beginning, without any user interaction.
+ globalConfig.init();
return globalConfig;
}
- public static GlobalConfig getNewVirtualInstance()
- {
+ protected void init(){
+ logger.trace("Initialize");
+ initUSBWorkspaces();
+ cleanUpWorkspaces();
+ enterInitialWorkspace();
+ }
+
+ private void cleanUpWorkspaces() {
+ logger.trace("Cleaning up workspaces.");
+ Map<String, String> existingWorkspaces = new TreeMap<String, String>();
+ Map<String, String> lostWorkspaces = new TreeMap<String, String>();
+ for (Entry<String, String> e : workspaces.entrySet()) {
+ File file = new File(e.getValue());
+ if (file.exists() || WorkspaceConfig.isSpecialWorkspace(e.getKey(), e.getValue())) {
+ logger.trace("\tConfirmed existence: " + e.getKey() + " at " + e.getValue());
+ existingWorkspaces.put(e.getKey(), e.getValue());
+ }
+ else {
+ logger.trace("\tLost workspace: " + e.getKey() + " at " + e.getValue());
+ if (e.getKey().equals(lastUsedWorkspace)){
+ lastUsedWorkspace = null;
+ currentWorkspace = null;
+ }
+ lostWorkspaces.put(e.getKey(), e.getValue());
+ }
+ }
+
+ if(!existingWorkspaces.containsKey(WorkspaceConfig.USER_DEFAULT_WORKSPACE)){
+ // This might be the case if the GlobalConfig version stored on the disk comes from a version
+ // that did not contain a default workspace
+ existingWorkspaces.put(WorkspaceConfig.USER_DEFAULT_WORKSPACE, WorkspaceConfig.getDefaultWorkspaceLocation().getAbsolutePath());
+ }
+
+ if (lostWorkspaces.size() > 0) {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Some workspaces could not be found:\n"); // TODO translate
+ for (Entry<String, String> e : lostWorkspaces.entrySet()) {
+ msg.append("\t").append(e.getKey()).append(" at ").append(e.getValue()).append("\n");
+ }
+ DialogMessenger.getInstance().dispatchMessage(msg.toString());
+ }
+ workspaces = existingWorkspaces;
+ }
+
+ public static GlobalConfig getNewVirtualInstance() {
GlobalConfig gc = new GlobalConfig();
gc.makeVirtual();
return gc;
}
- /**
- * @return File from system property "user.home"
- */
- public static File getDefaultLocation()
- {
- return new File(System.getProperty("user.home"));
- }
-
- /*
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Physical Workspaces (stored on file system)
- */
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- public void createWorkspace(File dir, String workspaceName) throws IOException
- {
+ public void createWorkspace(File dir, String workspaceName) throws IOException {
+ logger.trace("Creating workspace '" + workspaceName + "' at " + dir.getAbsolutePath());
if (WorkspaceConfig.createNewWorkspace(dir, workspaceName) != null)
addWorkspace(workspaceName, dir.toString());
}
- public void importWorkspace(File workspaceDir, String wsName)
- {
- if(!WSManager.isWorkspaceDirectory(workspaceDir))
- {
- DialogMessenger.getInstance().dispatchError(
- Logo.messages.getString(MessageKeys.WS_ERROR_TITLE),
+ public void importWorkspace(File workspaceDir, String workspaceName) {
+ logger.trace("Importing workspace '" + workspaceName + "' from " + workspaceDir.getAbsolutePath());
+ if (!WSManager.isWorkspaceDirectory(workspaceDir)) {
+ DialogMessenger.getInstance().dispatchError(Logo.messages.getString(MessageKeys.WS_ERROR_TITLE),
workspaceDir + " " + Logo.messages.getString(MessageKeys.WS_NOT_A_WORKSPACE_DIRECTORY));
return;
}
- addWorkspace(wsName, workspaceDir.getParent());
+ addWorkspace(workspaceName, workspaceDir.getParent());
}
/**
@@ -145,93 +197,181 @@ public class GlobalConfig extends StorableObject implements Serializable {
* @return the specified workspace or null if it does not exist.
* @throws IOException
*/
- private WorkspaceConfig retrieveWorkspace(String workspaceName) throws IOException
- {
- if(!existsWorkspace(workspaceName))
- {
- System.out.print("Attempting to load an inexistent workspace.");
+ private WorkspaceConfig retrieveWorkspace(String workspaceName) throws IOException {
+ WorkspaceConfig wsc = getLoadedWorkspace(workspaceName);
+ if (wsc != null) {
+ logger.trace("Retrieving cached workspace: " + workspaceName);
+ return wsc;
+ }
+
+ if (!existsWorkspace(workspaceName)) {
+ logger.warn("Attempting to load an inexistent workspace: " + workspaceName);
return null;
}
- File dir = getWorkspaceLocation(workspaceName);
- WorkspaceConfig wc = WorkspaceConfig.loadWorkspace(dir, workspaceName);
- if (wc == null)
- {
+ File location = getWorkspaceLocation(workspaceName);
+
+ if (WorkspaceConfig.isDefaultWorkspace(workspaceName, location)) {
+ logger.trace("Retrieving Default workspace from: " + location.getAbsolutePath());
+ wsc = getDefaultWorkspace();
+ }
+ else if (isUSBDrive(workspaceName)) {
+ logger.trace("Retrieving USB workspace: " + workspaceName);
+ wsc = initUSBDrive(workspaceName);
+ }
+ else {
+ logger.trace("Retrieving workspace: " + workspaceName + " from " + location.getAbsolutePath());
+ wsc = WorkspaceConfig.loadWorkspace(location, workspaceName);
+ }
+
+ if (wsc == null) {
WSManager.getInstance().deleteWorkspace(workspaceName, false);
}
- return wc;
+ cacheWorkspace(workspaceName, wsc);
+
+ return wsc;
+ }
+
+ private WorkspaceConfig getDefaultWorkspace() throws IOException{
+ File wsDir = WorkspaceConfig.getDefaultWorkspaceDirectory();
+ File wsFile = getFile(wsDir, WorkspaceConfig.class);
+ File wsLocation = WorkspaceConfig.getDefaultWorkspaceLocation();
+ WorkspaceConfig wsc = null;
+ if (wsFile.exists()) {
+ wsc = WorkspaceConfig.loadWorkspace(wsLocation, WorkspaceConfig.USER_DEFAULT_WORKSPACE);
+ } else {
+ wsc = WorkspaceConfig.createNewWorkspace(wsLocation, WorkspaceConfig.USER_DEFAULT_WORKSPACE);
+ wsc.setAllowUserCreation(true);
+ wsc.createUser(UserConfig.DEFAULT_USER);
+ }
+ return wsc;
}
- /*
- * Logical Workspaces (name and location stored in Map)
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Workspace Cache
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * Workspace Objects that have already been created or loaded from disk.
*/
+ private transient Map<String, WorkspaceConfig> cachedWorkspaces;
+
+ private WorkspaceConfig getLoadedWorkspace(String workspaceName) {
+ if (cachedWorkspaces == null) {
+ cachedWorkspaces = new TreeMap<String, WorkspaceConfig>();
+ }
+ return cachedWorkspaces.get(workspaceName);
+ }
+
+ private void cacheWorkspace(String workspaceName, WorkspaceConfig wsc) {
+ cachedWorkspaces.put(workspaceName, wsc);
+ }
- private TreeMap<String,String> workspaces;
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Workspaces
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * Logical Workspaces (name and location stored in Map)
+ */
+ private Map<String, String> workspaces;
/**
* @param workspaceName
* @param location where the workspace is located: location/workspaceName/
*/
- public void addWorkspace(String workspaceName, String location)
- {
+ public void addWorkspace(String workspaceName, String location) {
+ logger.trace("Adding workspace: '" + workspaceName + "' at " + location);
workspaces.put(workspaceName, location);
makeDirty();
notifyWorkspaceListChanged();
+ setLastUsedWorkspace(workspaceName);
+ enterInitialWorkspace();
}
- public void removeWorkspace(String workspaceName)
- {
+ public void removeWorkspace(String workspaceName) {
+ logger.trace("Removing workspace: " + workspaceName);
workspaces.remove(workspaceName);
+ cachedWorkspaces.remove(workspaceName);
makeDirty();
notifyWorkspaceListChanged();
+ if(lastUsedWorkspace.equals(workspaceName)){
+ lastUsedWorkspace = null;
+ currentWorkspace = null;
+ enterInitialWorkspace();
+ }
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Workspace File Utility
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * @return File from system property "user.home"
+ */
+ public static File getDefaultLocation() {
+ return new File(System.getProperty("user.home"));
}
/**
* @param wsName
- * @return the location of the workspace in the file system, or null if the workspace does not exist
+ * @return the parent directory of the workspace directory, or null if the workspace does not exist
*/
- public File getWorkspaceLocation(String wsName)
- {
+ public File getWorkspaceLocation(String wsName) {
String location = workspaces.get(wsName);
- if(location == null)
+ if (location == null)
return null;
return new File(location);
}
- public File getWorkspaceDirectory(String wsName)
- {
+ /**
+ * @param wsName
+ * @return The workspace Directory that contains a physical representation of {@link WorkspaceConfig}
+ */
+ public File getWorkspaceDirectory(String wsName) {
File wsLocation = getWorkspaceLocation(wsName);
- if(wsLocation == null)
+ if (wsLocation == null)
return null;
return new File(wsLocation.toString() + File.separator + wsName);
}
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Workspaces
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @return the names of all existing workspaces
*/
- public String[] getAllWorkspaces()
- {
+ public String[] getAllWorkspaces() {
return (String[]) workspaces.keySet().toArray(new String[workspaces.size()]);
}
-
+
/**
* A workspace exists logically, if its location is known by the GlobalConfig.
* @param workspace
* @return
*/
- public boolean existsWorkspace(String workspace)
- {
- return getWorkspaceLocation(workspace) != null;
+ public boolean existsWorkspace(String workspace) {
+ return workspaces.get(workspace) != null;
}
- /*
+
+ public String getFirstUSBWorkspace() {
+ for (String ws : workspaces.keySet()) {
+ if (isUSBDrive(ws)) { return ws; }
+ }
+ return null;
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Last used workspace
- */
- private String lastUsedWorkspace;
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- public String getLastUsedWorkspace()
- {
+ private String lastUsedWorkspace;
+
+ public String getLastUsedWorkspace() {
return lastUsedWorkspace;
}
@@ -239,46 +379,63 @@ public class GlobalConfig extends StorableObject implements Serializable {
* Succeeds if the workspace exists
* @param workspace
*/
- private void setLastUsedWorkspace(String workspace)
- {
- if(existsWorkspace(workspace))
- {
- lastUsedWorkspace = new String(workspace);
+ private void setLastUsedWorkspace(String workspace) {
+ if (existsWorkspace(workspace)) {
+ lastUsedWorkspace = workspace;
makeDirty();
}
}
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Current Workspace
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ private transient WorkspaceConfig currentWorkspace;
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Entering and Leaving Workspaces
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ public WorkspaceConfig getCurrentWorkspace() {
+ return currentWorkspace;
+ }
+
/**
* This is used to have a workspace ready at the beginning, without any user interaction.
* <p>
- * Enters the workspace that was used the last time XLogo4Schools was run on this computer.
- * If no regular workspace is available, a purely logical "virtual workspace" is entered instead.
+ * Tries to enter workspaces with the following priority.
+ * 1. Last used workspace (if any)
+ * 2. Default workspace, if there is no last used workspace
+ * 3. Virtual Workspace, if entering or creating the default workspace failed for some reason.
*/
- private void enterLastUsedWorkspace()
- {
- String last = getLastUsedWorkspace();
+ private void enterInitialWorkspace() {
+ logger.trace("Entering initial workspace.");
+
+ String initialWs = getFirstUSBWorkspace();
+
+ if (initialWs == null) {
+ initialWs = getLastUsedWorkspace();
+ }
- if(last == null || !existsWorkspace(last))
- last = WorkspaceConfig.VIRTUAL_WORKSPACE; // this exists, see constructor
+ if (initialWs == null) {
+ initialWs = WorkspaceConfig.USER_DEFAULT_WORKSPACE;
+ }
+
+ if (initialWs == null) {
+ initialWs = WorkspaceConfig.VIRTUAL_WORKSPACE; // this exists, see constructor
+ }
try {
- enterWorkspace(last);
- } catch (IOException e1) {
- try { enterWorkspace(WorkspaceConfig.VIRTUAL_WORKSPACE); } catch (IOException e2) { }
+ enterWorkspace(initialWs);
+ }
+ catch (IOException e1) {
+ try {
+ enterWorkspace(WorkspaceConfig.VIRTUAL_WORKSPACE);
+ }
+ catch (IOException e2) {}
DialogMessenger.getInstance().dispatchError("Workspace Error", "Cannot enter workspace: " + e1.toString());
}
}
-
- /*
- * Current Workspace
- */
-
- private transient WorkspaceConfig currentWorkspace;
-
- public WorkspaceConfig getCurrentWorkspace()
- {
- return currentWorkspace;
- }
/**
* Load the workspace
@@ -286,10 +443,9 @@ public class GlobalConfig extends StorableObject implements Serializable {
* @param workspaceName - the workspace to load and enter
* @throws IOException - if the workspace could not be loaded
*/
- public void enterWorkspace(String workspaceName) throws IOException
- {
- if(currentWorkspace != null)
- {
+ public void enterWorkspace(String workspaceName) throws IOException {
+ logger.trace("Entering workspace: " + workspaceName);
+ if (currentWorkspace != null) {
leaveWorkspace();
}
currentWorkspace = retrieveWorkspace(workspaceName);
@@ -299,35 +455,130 @@ public class GlobalConfig extends StorableObject implements Serializable {
setLastUsedWorkspace(workspaceName);
notifyWorkspacEntered();
+
+ currentWorkspace.enterInitialUserSpace();
+
+ AppSettings.getInstance().setLanguage(currentWorkspace.getLanguage());
}
/**
+ * Afterwards, currentWorkspace is null
* @throws IOException If workspace could not be saved.
*/
- void leaveWorkspace() throws IOException
- {
- if(currentWorkspace == null)
+ public void leaveWorkspace() throws IOException {
+ if (currentWorkspace == null)
throw new IllegalStateException("Attempt to leave workspace without being in one.");
+ logger.trace("Leaving workspace: " + currentWorkspace.getWorkspaceName());
- if(currentWorkspace.getActiveUser() != null)
- {
+ if (currentWorkspace.getActiveUser() != null) {
currentWorkspace.leaveUserSpace();
}
- if(currentWorkspace.isDirty())
+ if (currentWorkspace.isDirty())
currentWorkspace.store();
currentWorkspace = null;
}
-
- /*
- * Password protection
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * USB Detection & Handling
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ private transient USBDeviceDetectorManager driveDetector;
+
+ /**
+ * Detect External Drives
*/
+ protected void initUSBWorkspaces() {
+ driveDetector = new USBDeviceDetectorManager(800);
+
+ for (USBStorageDevice rmDevice : driveDetector.getRemovableDevices()) {
+ if (rmDevice.canRead() && rmDevice.canWrite()) {
+ addUSBDrive(rmDevice);
+ }
+ }
+
+ driveDetector.addDriveListener(new IUSBDriveListener(){
+
+ @Override
+ public void usbDriveEvent(USBStorageEvent event) {
+ USBStorageDevice rmDevice = event.getStorageDevice();
+ switch (event.getEventType()) {
+ case CONNECTED:
+ addUSBDrive(rmDevice);
+ break;
+ case REMOVED:
+ removeUSBDrive(rmDevice);
+ break;
+ }
+ }
+ });
+ }
+
+ protected void addUSBDrive(USBStorageDevice rmDevice) {
+ if (getWorkspaceDirectory(rmDevice.getSystemDisplayName()) == null) {
+ logger.trace("USB Drive attached: " + rmDevice);
+ String deviceName = rmDevice.getSystemDisplayName();
+ File location = rmDevice.getRootDirectory();
+ addWorkspace(deviceName, location.getAbsolutePath());
+ }
+ }
+
+ protected void removeUSBDrive(USBStorageDevice rmDevice) {
+ logger.trace("USB Drive removed: " + rmDevice);
+ String deviceName = rmDevice.getSystemDisplayName();
+ removeWorkspace(deviceName);
+ }
+
+ protected WorkspaceConfig initUSBDrive(String deviceName) throws IOException {
+ logger.trace("Initializing USB Drive: " + deviceName);
+ File usbRoot = null;
+ for (USBStorageDevice device : driveDetector.getRemovableDevices()) {
+ if (deviceName.equals(device.getSystemDisplayName())) {
+ usbRoot = device.getRootDirectory();
+ break;
+ }
+ }
+ if (usbRoot == null) { return null; }
+
+ File wsDir = WorkspaceConfig.getDirectory(usbRoot, WorkspaceConfig.USB_DEFAULT_WORKSPACE);
+ File wsConfigFile = WorkspaceConfig.getFile(wsDir, WorkspaceConfig.class);
+
+ WorkspaceConfig wsc = null;
+ if (wsConfigFile.exists()) {
+ logger.trace("Loading USB workspace from " + wsDir.getAbsolutePath());
+ wsc = WorkspaceConfig.loadWorkspace(usbRoot, WorkspaceConfig.USB_DEFAULT_WORKSPACE);
+ for (String user : wsc.getUserList()) {
+ logger.trace("\t Having user " + user);
+ }
+ }
+ else {
+ logger.trace("Creating new temporary USB workspace at " + usbRoot);
+ wsc = WorkspaceConfig.createDeferredWorkspace(usbRoot, WorkspaceConfig.USB_DEFAULT_WORKSPACE);
+ wsc.setAllowUserCreation(true);
+ }
+ return wsc;
+ }
+
+ /* *
+ * Workspace Types
+ * */
+
+ public boolean isUSBDrive(String workspaceName) {
+ for (USBStorageDevice device : driveDetector.getRemovableDevices()) {
+ if (workspaceName.equals(device.getSystemDisplayName())) { return true; }
+ }
+ return false;
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Password protection
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* if null, no password is requested
*/
- private byte[] masterPassword = null;
+ private byte[] masterPassword = null;
/**
* Need old password to authenticate
@@ -335,28 +586,25 @@ public class GlobalConfig extends StorableObject implements Serializable {
* @param newPw
* @return success
*/
- public boolean setNewPassword(String oldPw, String newPw)
- {
- if(masterPassword == null || authenticate(oldPw))
- {
+ public boolean setNewPassword(String oldPw, String newPw) {
+ if (masterPassword == null || authenticate(oldPw)) {
if (newPw == null)
masterPassword = null;
else
masterPassword = hash(newPw);
makeDirty();
return true;
- }else
- {
+ }
+ else {
return false;
}
}
- public boolean isPasswordRequired()
- {
+ public boolean isPasswordRequired() {
return masterPassword != null;
}
- public boolean authenticate(String password){
+ public boolean authenticate(String password) {
if (masterPassword == null)
return true;
String entered = null;
@@ -373,69 +621,79 @@ public class GlobalConfig extends StorableObject implements Serializable {
* @param text
* @return hashed bytes
*/
- private byte[] hash(String text)
- {
+ private byte[] hash(String text) {
if (text == null)
return null;
byte[] bytesOfMessage;
try {
bytesOfMessage = text.getBytes("UTF-8");
- } catch (UnsupportedEncodingException e1) {
+ }
+ catch (UnsupportedEncodingException e1) {
bytesOfMessage = text.getBytes(); // this should not happen anyway
}
-
+
try {
MessageDigest md = MessageDigest.getInstance("MD5");
return md.digest(bytesOfMessage);
- } catch (NoSuchAlgorithmException e) {
+ }
+ catch (NoSuchAlgorithmException e) {
return bytesOfMessage; // this should not happen anyway
}
}
- /*
- * PATH
- */
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Path variable
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
- * This Stack contains all startup files
+ * Path to the current directory for the Logo environment
*/
- private ArrayList<String> path = new ArrayList<String>();
+ private ArrayList<String> path = new ArrayList<String>();
public ArrayList<String> getPath() {
return path;
}
-
-
+
public void setPath(ArrayList<String> path) {
this.path = path;
makeDirty();
}
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Application Meta Data
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * This is not really used. Artifact from the past.
+ * @return
+ */
public static String getVersion() {
return "XLogo4Schools 0.0.1";
}
-
- /**
+
+ /* *
* Note : should be equal as in {@link Lanceur}
*/
//private static String PROPERTIES_PREFIX = "ch.ethz.abz.xlogo4schools";
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * JRE Memory allocation parameters
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
/**
* Note : should be equal as in {@link Lanceur}
*/
- private static int DEFAULT_MEMORY_ALLOC = 128;
+ private static int DEFAULT_MEMORY_ALLOC = 128;
- private static int maximumMemory;
+ private static int maximumMemory;
/**
* The Maximum amount of memory that this application is allowed to consume by the JVM
* @return
*/
- public static int getMaximumMemory()
- {
- if (maximumMemory < 64)
- {
+ public static int getMaximumMemory() {
+ if (maximumMemory < 64) {
// This doesn't work as expected :-(
//Preferences prefs = Preferences.systemRoot().node(PROPERTIES_PREFIX);
//maximumMemory = prefs.getInt("appMemory", DEFAULT_MEMORY_ALLOC);
@@ -444,51 +702,51 @@ public class GlobalConfig extends StorableObject implements Serializable {
return maximumMemory;
}
- private transient int maxMemoryAtNextStart = getMaximumMemory();
-
- public static final Font[] fonts = GraphicsEnvironment
- .getLocalGraphicsEnvironment().getAllFonts();// Toolkit.getDefaultToolkit().getFontList();
-
+ private transient int maxMemoryAtNextStart = getMaximumMemory();
+
/**
* @return The amount of memory in MB that Lanceur will cause JVM to allocate to XLogo4Schools the next time this application is started.
*/
- public int getMaxMemoryAtNextStart()
- {
+ public int getMaxMemoryAtNextStart() {
if (maxMemoryAtNextStart < 64)
maxMemoryAtNextStart = getMaximumMemory();
return maxMemoryAtNextStart;
}
+
/**
* @see #getMaxMemoryAtNextStart()
* cannot set this below 64MB
* @param maxMemory
*/
- public void setMaxMemoryAtNextStart(int maxMemory)
- {
+ public void setMaxMemoryAtNextStart(int maxMemory) {
if (maxMemory < 64)
return;
// This doesn't work as well :-(
//Preferences prefs = Preferences.systemRoot().node(PROPERTIES_PREFIX);
//prefs.putInt("appMemory", maxMemory);
}
-
- static public int police_id(Font font) {
- for (int i = 0; i < fonts.length; i++) {
- if (fonts[i].getFontName().equals(font.getFontName()))
- return i;
- }
- return 0;
- }
/**
* The amount of memory that the memory checker allows the application to consume.
* It's 0.9*{@link #getMaximumMemory()}} in bytes.
*/
- public static long getMemoryThreshold()
- {
+ public static long getMemoryThreshold() {
return (long) (0.9 * ((long) GlobalConfig.getMaximumMemory() * 1024L * 1024L));
}
-
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Fonts
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ public static final Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getAllFonts(); // Toolkit.getDefaultToolkit().getFontList();
+ static public int getFontId(Font font) {
+ for (int i = 0; i < fonts.length; i++) {
+ if (fonts[i].getFontName().equals(font.getFontName()))
+ return i;
+ }
+ return 0;
+ }
/* * * * * * *
* Event Handling
@@ -496,50 +754,46 @@ public class GlobalConfig extends StorableObject implements Serializable {
// workspace list change
- private transient ArrayList<ActionListener> workspaceListChangeListeners;
+ private transient ArrayList<ActionListener> workspaceListChangeListeners;
- public void addWorkspaceListChangeListener(ActionListener listener)
- {
+ public void addWorkspaceListChangeListener(ActionListener listener) {
if (workspaceListChangeListeners == null)
workspaceListChangeListeners = new ArrayList<ActionListener>();
workspaceListChangeListeners.add(listener);
}
- public void removeWorkspaceListChangeListener(ActionListener listener)
- {
+ public void removeWorkspaceListChangeListener(ActionListener listener) {
workspaceListChangeListeners.remove(listener);
}
- private void notifyWorkspaceListChanged()
- {
+ private void notifyWorkspaceListChanged() {
+ if (workspaceListChangeListeners == null)
+ workspaceListChangeListeners = new ArrayList<ActionListener>();
ActionEvent event = new ActionEvent(this, 0, "workspaceListChanged");
for (ActionListener listener : workspaceListChangeListeners)
listener.actionPerformed(event);
}
-
+
// enter workspace event
- private transient ArrayList<ActionListener> enterWorkspaceListeners;
+ private transient ArrayList<ActionListener> enterWorkspaceListeners;
- public void addEnterWorkspaceListener(ActionListener listener)
- {
+ public void addEnterWorkspaceListener(ActionListener listener) {
if (enterWorkspaceListeners == null)
enterWorkspaceListeners = new ArrayList<ActionListener>();
enterWorkspaceListeners.add(listener);
}
- public void removeEnterWorkspaceListener(ActionListener listener)
- {
+ public void removeEnterWorkspaceListener(ActionListener listener) {
enterWorkspaceListeners.remove(listener);
}
- private void notifyWorkspacEntered()
- {
+ private void notifyWorkspacEntered() {
if (enterWorkspaceListeners == null)
return;
ActionEvent event = new ActionEvent(this, 0, "workspaceEntered");
for (ActionListener listener : enterWorkspaceListeners)
listener.actionPerformed(event);
}
-
+
}