summaryrefslogtreecommitdiffstats
path: root/logo/src/xlogo/storage/workspace
diff options
context:
space:
mode:
authorMarko Živković <[email protected]>2014-06-11 10:10:33 +0000
committerMarko Živković <[email protected]>2014-06-11 10:10:33 +0000
commit1107aa0763e3d7554408c401d2a1dbed11a94c51 (patch)
tree7074264bc7b63f2ee5ee14a39458380fcce1904b /logo/src/xlogo/storage/workspace
Add initial directories and files
git-svn-id: https://svn.code.sf.net/p/xlogo4schools/svn/trunk@1 3b0d7934-f7ef-4143-9606-b51f2e2281fd
Diffstat (limited to 'logo/src/xlogo/storage/workspace')
-rw-r--r--logo/src/xlogo/storage/workspace/ContestConfig.java59
-rw-r--r--logo/src/xlogo/storage/workspace/Language.java111
-rw-r--r--logo/src/xlogo/storage/workspace/NumberOfBackups.java57
-rw-r--r--logo/src/xlogo/storage/workspace/SyntaxHighlightConfig.java151
-rw-r--r--logo/src/xlogo/storage/workspace/WorkspaceConfig.java688
5 files changed, 1066 insertions, 0 deletions
diff --git a/logo/src/xlogo/storage/workspace/ContestConfig.java b/logo/src/xlogo/storage/workspace/ContestConfig.java
new file mode 100644
index 0000000..197e4d5
--- /dev/null
+++ b/logo/src/xlogo/storage/workspace/ContestConfig.java
@@ -0,0 +1,59 @@
+/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c 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,
+ * 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,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.workspace;
+
+import java.io.Serializable;
+
+public class ContestConfig implements Serializable {
+
+ private static final long serialVersionUID = 3323633026648762889L;
+
+ private int nOfContestFiles = 6;
+ private int nOfContestBonusFiles = 2;
+
+ public int getNOfContestFiles()
+ {
+ return nOfContestFiles;
+ }
+
+ public void setNOfContestFiles(int nOfContestFiles)
+ {
+ this.nOfContestFiles = nOfContestFiles;
+ }
+
+ public int getNOfContestBonusFiles()
+ {
+ return nOfContestBonusFiles;
+ }
+
+ public void setNOfContestBonusFiles(int nOfContestBonusFiles)
+ {
+ this.nOfContestBonusFiles = nOfContestBonusFiles;
+ }
+
+}
diff --git a/logo/src/xlogo/storage/workspace/Language.java b/logo/src/xlogo/storage/workspace/Language.java
new file mode 100644
index 0000000..f19b3ac
--- /dev/null
+++ b/logo/src/xlogo/storage/workspace/Language.java
@@ -0,0 +1,111 @@
+/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c 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,
+ * 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,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.workspace;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+public enum Language {
+ LANGUAGE_FRENCH(0, "French", "fr", "FR"),
+ LANGUAGE_ENGLISH(1, "English", "en", "US"),
+ LANGUAGE_ARABIC(2, "Arabic", "ar", "MA"),
+ LANGUAGE_SPANISH(3, "Spanish", "es", "ES"),
+ LANGUAGE_PORTUGAL(4, "Portuguese", "pt", "BR"),
+ LANGUAGE_ESPERANTO(5, "Esperanto", "eo", "EO"),
+ LANGUAGE_GERMAN(6, "German", "de", "DE"),
+ LANGUAGE_GALICIAN(7, "Galician", "gl", "ES"),
+ LANGUAGE_ASTURIAN(8, "Asturian", "al", "ES"),
+ LANGUAGE_GREEK(9, "Greek", "el", "GR"),
+ LANGUAGE_ITALIAN(10, "Italian", "it", "IT"),
+ LANGUAGE_CATALAN(11, "Catalan", "ca", "ES"),
+ LANGUAGE_HUNGARIAN(12, "Hungarian", "hu", "HU"),
+ LANGUAGE_ENGLISH_GERMAN(13, "ABZ German/English", "en", "DE");
+
+ private int value;
+ private String englishName;
+ private String languageCode;
+ private String countryCode;
+
+ private static Map<Integer, Language> valueToLanguage;
+
+ private Language(int value, String englishName, String languageCode, String countryCode) {
+ this.value = value;
+ this.englishName = englishName;
+ this.languageCode = languageCode;
+ this.countryCode = countryCode;
+ }
+
+ public static Language getLanguage(int i)
+ {
+ if (valueToLanguage == null)
+ initMapping();
+ return valueToLanguage.get(i);
+ }
+
+ public static void initMapping()
+ {
+ valueToLanguage = new HashMap<Integer, Language>();
+ for (Language lang : values()) {
+ valueToLanguage.put(lang.value, lang);
+ }
+ }
+
+ public int getValue()
+ {
+ return value;
+ }
+
+ public String getEnglishName()
+ {
+ return englishName;
+ }
+
+ /**
+ * return English name
+ */
+ @Override
+ public String toString() {
+ return getEnglishName();
+ }
+
+ public Locale getLocale()
+ {
+ return new Locale(languageCode, countryCode);
+ }
+
+ public String getLanguageCode()
+ {
+ return languageCode;
+ }
+
+ public String getCountryCode()
+ {
+ return countryCode;
+ }
+}
diff --git a/logo/src/xlogo/storage/workspace/NumberOfBackups.java b/logo/src/xlogo/storage/workspace/NumberOfBackups.java
new file mode 100644
index 0000000..1c8d4b2
--- /dev/null
+++ b/logo/src/xlogo/storage/workspace/NumberOfBackups.java
@@ -0,0 +1,57 @@
+/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c 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,
+ * 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,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.workspace;
+
+public enum NumberOfBackups {
+ NO_BACKUPS(0),
+ ONE(1),
+ THREE(3),
+ TEN(10),
+ FIFTY(50),
+ INFINITE(-1);
+
+ private int number;
+
+ private NumberOfBackups(int number) {
+ this.number = number;
+ }
+
+ public int getNumber()
+ {
+ return number;
+ }
+
+ public String toString()
+ {
+ if (number == -1)
+ {
+ return "infinite";
+ }
+ return Integer.toString(number);
+ }
+}
diff --git a/logo/src/xlogo/storage/workspace/SyntaxHighlightConfig.java b/logo/src/xlogo/storage/workspace/SyntaxHighlightConfig.java
new file mode 100644
index 0000000..ac89e64
--- /dev/null
+++ b/logo/src/xlogo/storage/workspace/SyntaxHighlightConfig.java
@@ -0,0 +1,151 @@
+/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c 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,
+ * 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,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.workspace;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.io.Serializable;
+
+public class SyntaxHighlightConfig implements Serializable{
+
+ private static final long serialVersionUID = 7137977560063481685L;
+
+ /**
+ * syntax Highlighting: Color for primitives
+ */
+ private int primitiveColor=new Color(0,128,0).getRGB();
+ /**
+ * syntax Highlighting: Style for primitives
+ */
+ private int primitiveStyle=Font.PLAIN;
+ /**
+ * syntax Highlighting: Color for operands: numbers....
+ */
+ private int operatorColor=Color.BLUE.getRGB();
+ /**
+ * syntax Highlighting: Style for operands
+ */
+ private int operatorStyle=Font.PLAIN;
+ /**
+ * syntax Highlighting: Color for comments
+ */
+ private int commentColor=Color.GRAY.getRGB();
+ /**
+ * syntax Highlighting: Style for comments
+ */
+ private int commentStyle=Font.PLAIN;
+ /**
+ * syntax Highlighting: Color for parenthesis
+ */
+ private int braceColor=Color.RED.getRGB();
+ /**
+ * syntax Highlighting: Style for parenthesis
+ */
+ private int braceStyle=Font.BOLD;
+ /**
+ * boolean that indicates if syntax Highlighting is enabled
+ */
+ private boolean colorEnabled=true;
+
+ public SyntaxHighlightConfig() {
+
+ }
+
+ public int getPrimitiveColor() {
+ return primitiveColor;
+ }
+
+ public void setPrimitiveColor(int primitiveColor) {
+ this.primitiveColor = primitiveColor;
+ }
+
+ public int getPrimitiveStyle() {
+ return primitiveStyle;
+ }
+
+ public void setPrimitiveStyle(int primitiveStyle) {
+ this.primitiveStyle = primitiveStyle;
+ }
+
+ public int getOperatorColor() {
+ return operatorColor;
+ }
+
+ public void setOperatorColor(int operatorColor) {
+ this.operatorColor = operatorColor;
+ }
+
+ public int getOperatorStyle() {
+ return operatorStyle;
+ }
+
+ public void setOperatorStyle(int operatorStyle) {
+ this.operatorStyle = operatorStyle;
+ }
+
+ public int getCommentColor() {
+ return commentColor;
+ }
+
+ public void setCommentColor(int commentColor) {
+ this.commentColor = commentColor;
+ }
+
+ public int getCommentStyle() {
+ return commentStyle;
+ }
+
+ public void setCommentStyle(int commentStyle) {
+ this.commentStyle = commentStyle;
+ }
+
+ public int getBraceColor() {
+ return braceColor;
+ }
+
+ public void setBraceColor(int braceColor) {
+ this.braceColor = braceColor;
+ }
+
+ public int getBraceStyle() {
+ return braceStyle;
+ }
+
+ public void setBraceStyle(int braceStyle) {
+ this.braceStyle = braceStyle;
+ }
+
+ public boolean isColorEnabled() {
+ return colorEnabled;
+ }
+
+ public void setColorEnabled(boolean colorEnabled) {
+ this.colorEnabled = colorEnabled;
+ }
+
+}
diff --git a/logo/src/xlogo/storage/workspace/WorkspaceConfig.java b/logo/src/xlogo/storage/workspace/WorkspaceConfig.java
new file mode 100644
index 0000000..9a3b60a
--- /dev/null
+++ b/logo/src/xlogo/storage/workspace/WorkspaceConfig.java
@@ -0,0 +1,688 @@
+/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c 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,
+ * 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,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.workspace;
+
+import java.awt.Font;
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import xlogo.AppSettings;
+import xlogo.Logo;
+import xlogo.messages.MessageKeys;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.Storable;
+import xlogo.storage.StorableObject;
+import xlogo.storage.WSManager;
+import xlogo.storage.user.UserConfig;
+
+/**
+ * WorkspaceConfig maintains a workspace (i.e. a "class room") that consists of several projects or "Users".
+ * It defines a common language for the project (English, French, ...) and a master password for the workspace owner.
+ * The password is intended to allow certain settings only for the workspace owner. Therefore the corresponding methods will require a password.
+ * <br> A directory on the file system is an XLogo4Schools workspace, if it contains a file named "X4S_WorkspaceConfig.ser",
+ * no matter what it contains.
+ * <br> If a workspace is made virtual, it is not stored on the file system. ({@link #createVirtualWorkspace()})
+ * <p>
+ * A user belongs to the workspace, if it is contained logically in the user list.
+ * For a user to work correctly in its user space, a user directory {@code workspaceDir/username/}
+ * and the file {@code workspaceDir/username/X4S_UserConfig.ser} are required.
+ * As long as a user exists logically in the workspace, missing or corrupted files are recreated if needed.
+ * If a user is deleted, it is deleted only logically, so it can be reintegrated later again.
+ * @author Marko Zivkovic
+ */
+public class WorkspaceConfig extends StorableObject implements Serializable {
+
+ private static final long serialVersionUID = -3554871695113998509L;
+
+ /**
+ * Name of the virtual workspace
+ */
+ public static final String VIRTUAL_WORKSPACE = "Guest Workspace (no automatic save)";
+
+ protected WorkspaceConfig()
+ {
+ super();
+ userList = new ArrayList<String>();
+ language = Language.LANGUAGE_ENGLISH;
+ font = new Font("dialog",Font.PLAIN,14); // TODO on access check if it is null.
+ // TODO what if incompatible?
+ syntaxHighlightingStyles = new SyntaxHighlightConfig();
+ AppSettings.getInstance().setFont(font);
+ }
+
+ /**
+ * @return
+ * @throws IllegalStateException if this is not virtual and {@link #getLocation()} returns null
+ */
+ public String getWorkspaceName() throws IllegalStateException
+ {
+ if (isVirtual())
+ return VIRTUAL_WORKSPACE;
+
+ File wsDir = getLocation();
+ if (wsDir == null)
+ throw new IllegalStateException("Name is not available because location is null.");
+ return wsDir.getName();
+ }
+
+ /*
+ * Static constructors
+ */
+ private static WorkspaceConfig virtualWS;
+
+ /**
+ * A virtual user can enter the application in a virtual workspace without having an actual user account on the file system. Hence nothing will be stored.
+ * A regular user (not virtual) will have his own folder in a regular workspace on the file system and all his preferences and files are stored there.
+ * To create a regular workspace, use {@link #createNewWorkspace(File, String)},
+ * to load a regular workspace from the file system, user {@link #loadWorkspace(File)}}.
+ * @see #isVirtual()
+ * @return a virtual workspace
+ */
+ public static WorkspaceConfig createVirtualWorkspace()
+ {
+ if (virtualWS == null)
+ {
+ virtualWS = new WorkspaceConfig();
+ virtualWS.makeVirtual();
+ }
+ return virtualWS;
+ }
+
+ @Override
+ protected void makeVirtual()
+ {
+ super.makeVirtual();
+ userList = new ArrayList<String>();
+ userList.add(UserConfig.VIRTUAL_USER);
+ lastActiveUser = UserConfig.VIRTUAL_USER;
+ try { enterUserSpace(UserConfig.VIRTUAL_USER); } catch (IOException e) { /* Does not happen */ }
+ }
+
+ /**
+ * @param dir
+ * @param workspaceName
+ * @return
+ * @throws IOException
+ */
+ public static WorkspaceConfig createNewWorkspace(File dir, String workspaceName) throws IOException
+ {
+ if (!Storable.checkLegalName(workspaceName))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.ILLEGAL_NAME));
+ return null;
+ }
+
+ File wsd = getDirectory(dir, workspaceName);
+ boolean existed = wsd.exists();
+ if (!existed)
+ {
+ wsd.mkdirs();
+ }
+ // wsd exists and it is empty
+ WorkspaceConfig wsc = new WorkspaceConfig();
+ wsc.setLocation(wsd);
+ //if(existed && WSManager.isUserDirectory(wsd))
+ // wsc.refreshUserList();
+ wsc.store();
+ return wsc;
+ }
+
+ /**
+ * @see #loadWorkspace(File)
+ * @param dir - location of the workspace
+ * @param workspaceName
+ * @return
+ * @throws IOException
+ */
+ public static WorkspaceConfig loadWorkspace(File dir, String workspaceName) throws IOException
+ {
+ File wsc = getDirectory(dir, workspaceName);
+ return loadWorkspace(wsc);
+ }
+
+ /**
+ * @param workspaceDir
+ * @return Load an existing workspace from the file system.
+ * If workspaceDir specifies a {@link WorkspaceConfig#VIRTUAL_WORKSPACE}, the virtual workspace is returned instead.
+ * @throws IOException
+ */
+ public static WorkspaceConfig loadWorkspace(File workspaceDir) throws IOException
+ {
+ if(workspaceDir.getName().equals(WorkspaceConfig.VIRTUAL_WORKSPACE))
+ {
+ return createVirtualWorkspace();
+ }
+
+ File wsf = getFile(workspaceDir, WorkspaceConfig.class);
+
+ WorkspaceConfig wsc;
+ try {
+ wsc = (WorkspaceConfig) WorkspaceConfig.loadObject(wsf);
+ wsc.setLocation(workspaceDir);
+ return wsc;
+ } catch (ClassNotFoundException e) {
+ return null; // this won't happen
+ }
+ }
+
+ /*
+ * User list
+ */
+
+ /**
+ * @see #getUserList()
+ */
+ private ArrayList<String> userList;
+
+ /**
+ * The names of the logical users in the workspace
+ * @return
+ */
+ public String[] getUserList()
+ {
+ String[] users = new String[userList.size()];
+ return userList.toArray(users);
+ }
+
+ public File getUserDirectroy(String username)
+ {
+ if (!existsUserLogically(username) || isVirtual())
+ return null;
+
+ return getDirectory(getLocation(), username);
+ }
+
+ /**
+ * Create new user directory and UserConfig file in this workspace on the file system, and add it logically to the userList.
+ * If either existed, only the non-existing parts are created.
+ * To create a user in a virtual workspace will have no effect, but an error message is printed.
+ * <p> Has no effect if this is virtual.
+ * @param username
+ */
+ public void createUser(String username)
+ {
+ if (!Storable.checkLegalName(username))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.ILLEGAL_NAME));
+ return;
+ }
+
+ if(isVirtual())
+ {
+ DialogMessenger.getInstance().dispatchError("Workspace Error", "Attempt to create new user to virtual workspace.");
+ return;
+ }
+
+ File userDir = getDirectory(getLocation(), username);
+
+ if(!userDir.mkdirs())
+ {
+ DialogMessenger.getInstance().dispatchError("Workspace Error","Could not make required directories: " + userDir.toString());
+ return;
+ }
+
+ if (!existsUserLogically(username))
+ {
+ userList.add(username);
+ makeDirty();
+ }
+
+ // Make new user logically existent in workspace config file
+ try { store(); } catch (IOException e) {
+ DialogMessenger.getInstance().dispatchError("Workspace Error","Could not store workspace.");
+ }
+ if(!existsUserPhysically(username))
+ UserConfig.createNewUser(this, username);
+ }
+
+ /**
+ * Import a user directory from anywhere in the file system to this workspace.
+ * All files in the user directory are copied. Already existing files might get overwritten.
+ * <p> This has no effect if this is virtual.
+ * @param srcUserDir - a legal user directory anywhere on the file system
+ * @param destUsername - Existing files of targetUser are overwritten. If targetUser does not exist, it will be created first.
+ * @throws IllegalArgumentException
+ * @throws IOException
+ * @see WSManager#isUserDirectory(File)
+ */
+ public void importUser(File srcUserDir, String destUsername) throws IllegalArgumentException, IOException
+ {
+ if (isVirtual())
+ return;
+
+ if (!WSManager.isUserDirectory(srcUserDir))
+ throw new IllegalArgumentException();
+
+ createUser(destUsername);
+ File targetUserDir = getDirectory(getLocation(), destUsername);
+
+ WSManager.copyFullyRecursive(srcUserDir, targetUserDir);
+ }
+
+ /**
+ * @param userName will be removed logically only
+ */
+ public void removeUser(String userName)
+ {
+ if(existsUserLogically(userName))
+ makeDirty();
+
+ userList.remove(userName);
+ }
+
+ /**
+ * @param username - if this exists not logically in the workspace, null is returned.
+ * @return a {@link UserConfig} generated from the file system. If this is a virtual workspace, a virtual user is created instead.
+ * @throws IOException if the UserConfig could not be loaded
+ * @see UserConfig#loadUser(File, String)
+ */
+ public UserConfig loadUser(String username) throws IOException
+ {
+ if(!existsUserLogically(username))
+ {
+ DialogMessenger.getInstance().dispatchError("Workspace Error","Attempt to load inexistent user: " + username + ". Try to import this user.");
+ return null;
+ }
+
+ if(isVirtual())
+ return UserConfig.createVirtualUser();
+
+ // exists logically and is not virtual
+
+ if(!existsUserPhysically(username))
+ {
+ // but it does exist logically => it must have been corrupted externally.
+ // => restore it.
+ if(!getLocation().mkdirs())
+ {
+ DialogMessenger.getInstance().dispatchError("Workspace Error","Could not make required directories.");
+ return null;
+ }
+ // user creation requires existence of the workspace on file system
+ try { store(); } catch (IOException e) {
+ DialogMessenger.getInstance().dispatchError("Workspace Error","Could not store workspace.");
+ }
+ return UserConfig.createNewUser(this, username);
+ }
+ // exists physically
+ return UserConfig.loadUser(this, username);
+ }
+
+ /**
+ * Produces a list of user names by reading the contents of the current workspace directory.
+ * The users in this list may contain users that have been deleted logically before.
+ * @return
+ */
+ public ArrayList<String> getPhysicalUserList()
+ {
+ if(isVirtual())
+ return new ArrayList<String>();
+
+ ArrayList<String> users = new ArrayList<String>();
+
+ if (WSManager.isWorkspaceDirectory(getLocation()))
+ {
+ DialogMessenger.getInstance().dispatchError("Workspace Error", "Current workspace was probably deleted. I will recreate it.");
+ try { store(); } catch (IOException e) {
+ DialogMessenger.getInstance().dispatchError("Workspace Error", "I could not recreate the Workspace. Try to delete the Workspace and recreate it manually.");
+ return users;
+ }
+ }
+
+
+ for(File dir : WSManager.listDirectories(getLocation()))
+ {
+ if(WSManager.isUserDirectory(dir))
+ {
+ users.add(dir.getName());
+ }
+ }
+ return users;
+ }
+
+ /**
+ * A user exists logically, if its name is known by the workspace.
+ * @param userName
+ * @return
+ */
+ public boolean existsUserLogically(String username)
+ {
+ return userList.contains(username);
+ }
+
+ /**
+ * A user exists physically, if a folder with the user's name exists in this workspace and if it contains a UserConfig file.
+ * @param username
+ * @return
+ * @see WSManager#isUserDirectory(File)
+ */
+ public boolean existsUserPhysically(String username)
+ {
+ File userDir = getDirectory(getLocation(), username);
+ return WSManager.isUserDirectory(userDir);
+ }
+
+ /*
+ * last active user
+ */
+
+ private String lastActiveUser;
+
+ /**
+ * @return name of the last active user
+ */
+ public String getLastActiveUser()
+ {
+ return lastActiveUser;
+ }
+
+ /**
+ * Succeeds if the user exists
+ * @param workspace
+ */
+ public void setLastActiveUser(String username)
+ {
+ if(existsUserLogically(username) && !username.equals(lastActiveUser))
+ {
+ lastActiveUser = new String(username);
+ makeDirty();
+ }
+ }
+
+ /*
+ * active user
+ */
+
+ private transient UserConfig activeUser;
+
+ public UserConfig getActiveUser()
+ {
+ return activeUser;
+ }
+
+ /**
+ * @throws IOException If the old userConfig could not be stored.
+ */
+ public void enterUserSpace(String username) throws IOException
+ {
+ if(activeUser != null)
+ {
+ leaveUserSpace();
+ }
+
+ if (isVirtual())
+ activeUser = UserConfig.createVirtualUser();
+ else
+ activeUser = UserConfig.loadUser(this, username);
+
+ setLastActiveUser(username);
+ }
+
+ /**
+ * @throws IOException If userConfig could not be stored.
+ */
+ public void leaveUserSpace() throws IOException
+ {
+ if (activeUser.isDirty())
+ activeUser.store();
+ activeUser = null;
+ }
+
+ /*
+ * Version control
+ */
+
+ /**
+ * How many old versions of a file should be kept, in addition to the most recent one?
+ * Default is infinite.
+ */
+ private NumberOfBackups numberOfBackups = NumberOfBackups.INFINITE;
+
+ /**
+ * @see #numberOfBackups
+ */
+ public NumberOfBackups getNumberOfBackups()
+ {
+ return numberOfBackups;
+ }
+
+ /**
+ * @see #numberOfBackups
+ */
+ public void setNumberOfBackups(NumberOfBackups n)
+ {
+ numberOfBackups = n;
+ makeDirty();
+ }
+
+ /*
+ * Workspace language
+ */
+
+ /**
+ * The language to be used within this workspace
+ */
+ public Language language;
+
+ public void setLanguage(Language language)
+ {
+ this.language = language;
+ AppSettings.getInstance().setLanguage(language);
+ makeDirty();
+ }
+
+ public Language getLanguage()
+ {
+ return language;
+ }
+
+ /*
+ * Allow users (children) to create new user accounts in workspaces?
+ */
+
+ private boolean allowUserCreation = true;
+
+ public void setAllowUserCreation(boolean allowed)
+ {
+ this.allowUserCreation = allowed;
+ makeDirty();
+ }
+
+ public boolean isUserCreationAllowed()
+ {
+ return allowUserCreation && !isVirtual();
+ }
+
+ /*
+ * Contest //TODO create options in workspace settings
+ */
+
+ private ContestConfig contestConfig;
+
+ protected ContestConfig getContestSettings()
+ {
+ return contestConfig;
+ }
+
+ public int getNOfContestFiles()
+ {
+ if (contestConfig == null)
+ contestConfig = new ContestConfig();
+ return getContestSettings().getNOfContestFiles();
+ }
+
+ public void setNOfContestFiles(int nOfContestFiles)
+ {
+ getContestSettings().setNOfContestFiles(nOfContestFiles);
+ }
+
+ public int getNOfContestBonusFiles()
+ {
+ return getContestSettings().getNOfContestBonusFiles();
+ }
+
+ public void setNOfContestBonusFiles(int nOfContestBonusFiles)
+ {
+ getContestSettings().setNOfContestBonusFiles(nOfContestBonusFiles);
+ }
+
+ /*
+ * Syntax Highlighting
+ */
+ private SyntaxHighlightConfig syntaxHighlightingStyles; // TODO = new SyntaxHighlightStyles();
+
+ /**
+ * This font is the default font for all menus ... in XLogo Application
+ */
+ private Font font;// TODO =new Font("dialog",Font.PLAIN,14);
+
+ public SyntaxHighlightConfig getSyntaxHighlightStyles()
+ {
+ if (syntaxHighlightingStyles == null)
+ {
+ syntaxHighlightingStyles = new SyntaxHighlightConfig();
+ makeDirty();
+ }
+ return syntaxHighlightingStyles;
+ }
+
+ public void setSyntaxHighlightConfig(SyntaxHighlightConfig syntaxHighlightingStyles)
+ {
+ this.syntaxHighlightingStyles = syntaxHighlightingStyles;
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(syntaxHighlightingStyles);
+ }
+
+ public int getPrimitiveColor() {
+ return getSyntaxHighlightStyles().getPrimitiveColor();
+ }
+
+
+ public void setPrimitiveColor(int primitiveColor) {
+ getSyntaxHighlightStyles().setPrimitiveColor(primitiveColor);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getPrimitiveStyle() {
+ return getSyntaxHighlightStyles().getPrimitiveStyle();
+ }
+
+ public void setPrimitiveStyle(int primitiveStyle) {
+ getSyntaxHighlightStyles().setPrimitiveStyle(primitiveStyle);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getOperatorColor() {
+ return getSyntaxHighlightStyles().getOperatorColor();
+ }
+
+ public void setOperandColor(int operatorColor) {
+ getSyntaxHighlightStyles().setOperatorColor(operatorColor);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getOperatorStyle() {
+ return getSyntaxHighlightStyles().getOperatorStyle();
+ }
+
+ public void setOperandStyle(int operatorStyle) {
+ getSyntaxHighlightStyles().setOperatorStyle(operatorStyle);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getCommentColor() {
+ return getSyntaxHighlightStyles().getCommentColor();
+ }
+
+ public void setCommentColor(int commentColor) {
+ getSyntaxHighlightStyles().setCommentColor(commentColor);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getCommentStyle() {
+ return getSyntaxHighlightStyles().getCommentStyle();
+ }
+
+ public void setCommentStyle(int commentStyle) {
+ getSyntaxHighlightStyles().setCommentStyle(commentStyle);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getBraceColor() {
+ return getSyntaxHighlightStyles().getBraceColor();
+ }
+
+ public void setBraceColor(int braceColor) {
+ getSyntaxHighlightStyles().setBraceColor(braceColor);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getBraceStyle() {
+ return getSyntaxHighlightStyles().getBraceStyle();
+ }
+
+ public void setBraceStyle(int braceStyle) {
+ getSyntaxHighlightStyles().setBraceStyle(braceStyle);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public boolean isSyntaxHighlightingEnabled() {
+ return getSyntaxHighlightStyles().isColorEnabled();
+ }
+
+ public void setSyntaxHighlightingEnabled(boolean colorEnabled) {
+ getSyntaxHighlightStyles().setColorEnabled(colorEnabled);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public Font getFont() {
+ return font;
+ }
+
+ public void setFont(Font font) {
+ this.font = font;
+ makeDirty();
+ AppSettings.getInstance().setFont(font);
+ }
+
+}