From c0003a559a36dfca1bdc4add0034e67bd22824ed Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 21 Jun 2018 15:41:44 +0200 Subject: [client] Sanitize class/var names, split up control package All configurators have moved from *.control to *.configurator *.control should be used for simple controls that feel like they're really just one thing. The configurators are more like a group of controls. --- .../src/main/java/org/openslx/dozmod/Config.java | 6 +- .../src/main/java/org/openslx/dozmod/gui/Gui.java | 4 +- .../java/org/openslx/dozmod/gui/MainWindow.java | 8 +- .../openslx/dozmod/gui/activity/DownloadPanel.java | 4 +- .../openslx/dozmod/gui/activity/UpdatePanel.java | 6 +- .../gui/changemonitor/DialogChangeMonitor.java | 4 +- .../LecturePermissionManagerWrapper.java | 10 +- .../configurator/ImagePermissionConfigurator.java | 201 +++++++++ .../gui/configurator/LdapFilterConfigurator.java | 221 ++++++++++ .../LecturePermissionConfigurator.java | 236 +++++++++++ .../gui/configurator/NetrulesConfigurator.java | 450 +++++++++++++++++++++ .../gui/configurator/NetshareConfigurator.java | 372 +++++++++++++++++ .../gui/configurator/RunscriptConfigurator.java | 266 ++++++++++++ .../gui/control/ImageCustomPermissionManager.java | 201 --------- .../dozmod/gui/control/LdapFilterConfigurator.java | 219 ---------- .../control/LectureCustomPermissionManager.java | 236 ----------- .../dozmod/gui/control/NetrulesConfigurator.java | 449 -------------------- .../dozmod/gui/control/NetshareConfigurator.java | 374 ----------------- .../openslx/dozmod/gui/control/PersonLabel.java | 4 +- .../dozmod/gui/control/RunscriptConfigurator.java | 263 ------------ .../openslx/dozmod/gui/window/BwIDMLinkWindow.java | 131 ------ .../openslx/dozmod/gui/window/BwIdmLinkWindow.java | 131 ++++++ .../dozmod/gui/window/CheckUpdateWindow.java | 6 +- .../dozmod/gui/window/ImageDetailsWindow.java | 4 +- .../dozmod/gui/window/LecturePermissionWindow.java | 110 ----- .../org/openslx/dozmod/gui/window/LoginWindow.java | 10 +- .../dozmod/gui/window/VirtualizerNoticeWindow.java | 6 +- .../window/layout/ImagePermissionWindowLayout.java | 6 +- .../window/layout/LectureDetailsWindowLayout.java | 12 +- .../window/layout/LectureNetrulesWindowLayout.java | 2 +- .../layout/LecturePermissionWindowLayout.java | 89 ---- .../layout/ImageCustomPermissionPageLayout.java | 6 +- .../layout/LectureCustomPermissionPageLayout.java | 6 +- .../openslx/dozmod/util/DesktopEnvironment.java | 121 ++++++ .../java/org/openslx/dozmod/util/OSHelper.java | 13 - .../java/org/openslx/dozmod/util/OpenLinks.java | 121 ------ .../java/org/openslx/dozmod/util/OsHelper.java | 13 + 37 files changed, 2063 insertions(+), 2258 deletions(-) create mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/ImagePermissionConfigurator.java create mode 100755 dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LdapFilterConfigurator.java create mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LecturePermissionConfigurator.java create mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetrulesConfigurator.java create mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetshareConfigurator.java create mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/RunscriptConfigurator.java delete mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/ImageCustomPermissionManager.java delete mode 100755 dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LdapFilterConfigurator.java delete mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LectureCustomPermissionManager.java delete mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetrulesConfigurator.java delete mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetshareConfigurator.java delete mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/RunscriptConfigurator.java delete mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/BwIDMLinkWindow.java create mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/BwIdmLinkWindow.java delete mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LecturePermissionWindow.java delete mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LecturePermissionWindowLayout.java create mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/util/DesktopEnvironment.java delete mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/util/OSHelper.java delete mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/util/OpenLinks.java create mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/util/OsHelper.java (limited to 'dozentenmodul/src/main/java') diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/Config.java b/dozentenmodul/src/main/java/org/openslx/dozmod/Config.java index efa59fe2..b1e771b4 100755 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/Config.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/Config.java @@ -11,7 +11,7 @@ import java.util.Properties; import org.apache.log4j.Logger; import org.openslx.dozmod.gui.window.DisclaimerWindow; import org.openslx.dozmod.gui.window.PrivacyNoticeWindow; -import org.openslx.dozmod.util.OSHelper; +import org.openslx.dozmod.util.OsHelper; import org.openslx.util.QuickTimer; import org.openslx.util.QuickTimer.Task; import org.openslx.util.Util; @@ -71,7 +71,7 @@ public class Config { // Determine OS String osName = System.getProperty("os.name").toLowerCase(); LOGGER.info("Machine's OS: " + osName); - if (OSHelper.isWindows()) { + if (OsHelper.isWindows()) { // Windows machine. Use the environment variable 'APPDATA' which // should point to a path similar to: // C:\Users\\AppData\Roaming @@ -83,7 +83,7 @@ public class Config { LOGGER.warn("APPDATA is empty."); configPath = System.getProperty("user.home") + "\\AppData\\Roaming"; } - } else if (OSHelper.isLinux()) { + } else if (OsHelper.isLinux()) { configPath = System.getProperty("user.home") + "/.config"; } if (configPath == null || configPath.isEmpty()) { diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java index bf6cf060..6d17022d 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java @@ -32,7 +32,7 @@ import javax.swing.text.html.HTMLDocument; import org.apache.log4j.Logger; import org.openslx.dozmod.Config; import org.openslx.dozmod.gui.helper.MessageType; -import org.openslx.dozmod.util.OpenLinks; +import org.openslx.dozmod.util.DesktopEnvironment; import org.openslx.util.QuickTimer; import org.openslx.util.ResourceLoader; @@ -336,7 +336,7 @@ public class Gui { public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { try { - OpenLinks.openWebpageUri(e.getURL().toURI()); + DesktopEnvironment.openWebpageUri(e.getURL().toURI()); } catch (URISyntaxException ex) { LOGGER.error("Couldn't parse hyperlink", ex); } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java index ca188fc7..051def34 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java @@ -65,8 +65,8 @@ import org.openslx.dozmod.thrift.Session; import org.openslx.dozmod.thrift.ThriftActions; import org.openslx.dozmod.util.ClientVersion; import org.openslx.dozmod.util.FormatHelper; -import org.openslx.dozmod.util.OpenLinks; -import org.openslx.dozmod.util.OpenLinks.Link; +import org.openslx.dozmod.util.DesktopEnvironment; +import org.openslx.dozmod.util.DesktopEnvironment.Link; import org.openslx.thrifthelper.ThriftManager; import org.openslx.util.QuickTimer; import org.openslx.util.QuickTimer.Task; @@ -477,7 +477,7 @@ public abstract class MainWindow { logDirItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - OpenLinks.openLocal(new File(Config.getPath())); + DesktopEnvironment.openLocal(new File(Config.getPath())); } }); logoutItem.addActionListener(new ActionListener() { @@ -520,7 +520,7 @@ public abstract class MainWindow { wikiItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - OpenLinks.openWebpage(Link.FAQ); + DesktopEnvironment.openWebpage(Link.FAQ); } }); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/DownloadPanel.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/DownloadPanel.java index cfa64221..adf1554d 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/DownloadPanel.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/DownloadPanel.java @@ -10,7 +10,7 @@ import org.openslx.dozmod.filetransfer.DownloadTask; import org.openslx.dozmod.filetransfer.TransferEvent; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.helper.MessageType; -import org.openslx.dozmod.util.OpenLinks; +import org.openslx.dozmod.util.DesktopEnvironment; @SuppressWarnings("serial") public class DownloadPanel extends TransferPanel implements ActionListener { @@ -44,7 +44,7 @@ public class DownloadPanel extends TransferPanel implements ActionListener { download.removeListener(panel); close(); } else if (e.getSource() == btnOpenFolder) { - OpenLinks.openLocal(download.getFile().getAbsoluteFile().getParentFile()); + DesktopEnvironment.openLocal(download.getFile().getAbsoluteFile().getParentFile()); } } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UpdatePanel.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UpdatePanel.java index 3e6ca7ff..46290a83 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UpdatePanel.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UpdatePanel.java @@ -12,8 +12,8 @@ import javax.swing.SwingUtilities; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.control.QLabel; import org.openslx.dozmod.gui.window.CheckUpdateWindow; -import org.openslx.dozmod.util.OpenLinks; -import org.openslx.dozmod.util.OpenLinks.Link; +import org.openslx.dozmod.util.DesktopEnvironment; +import org.openslx.dozmod.util.DesktopEnvironment.Link; public class UpdatePanel extends ActivityPanel implements ActionListener { @@ -61,7 +61,7 @@ public class UpdatePanel extends ActivityPanel implements ActionListener { @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == btnLink) { - OpenLinks.openWebpage(Link.DOZMOD); + DesktopEnvironment.openWebpage(Link.DOZMOD); close(); } if (e.getSource() == btnClose) { diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/changemonitor/DialogChangeMonitor.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/changemonitor/DialogChangeMonitor.java index a1d01eaf..7b2c879c 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/changemonitor/DialogChangeMonitor.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/changemonitor/DialogChangeMonitor.java @@ -16,9 +16,9 @@ import javax.swing.tree.TreePath; import org.apache.log4j.Logger; import org.jdatepicker.JDatePicker; import org.openslx.bwlp.thrift.iface.LecturePermissions; +import org.openslx.dozmod.gui.configurator.LecturePermissionConfigurator; import org.openslx.dozmod.gui.control.ComboBox; import org.openslx.dozmod.gui.control.JCheckBoxTree; -import org.openslx.dozmod.gui.control.LectureCustomPermissionManager; import org.openslx.util.Util; public class DialogChangeMonitor { @@ -82,7 +82,7 @@ public class DialogChangeMonitor { return add(new TimeSpinnerWrapper(this, spinner)); } - public AbstractControlWrapper> add(LectureCustomPermissionManager manager) { + public AbstractControlWrapper> add(LecturePermissionConfigurator manager) { return add(new LecturePermissionManagerWrapper(this, manager)); } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/changemonitor/LecturePermissionManagerWrapper.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/changemonitor/LecturePermissionManagerWrapper.java index a1f066a0..5f68c4f2 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/changemonitor/LecturePermissionManagerWrapper.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/changemonitor/LecturePermissionManagerWrapper.java @@ -4,9 +4,9 @@ import java.util.Comparator; import java.util.Map; import org.openslx.bwlp.thrift.iface.LecturePermissions; -import org.openslx.dozmod.gui.control.LectureCustomPermissionManager; -import org.openslx.dozmod.gui.control.LectureCustomPermissionManager.UserChangeEvent; -import org.openslx.dozmod.gui.control.LectureCustomPermissionManager.UserChangeEventListener; +import org.openslx.dozmod.gui.configurator.LecturePermissionConfigurator; +import org.openslx.dozmod.gui.configurator.LecturePermissionConfigurator.UserChangeEvent; +import org.openslx.dozmod.gui.configurator.LecturePermissionConfigurator.UserChangeEventListener; import org.openslx.dozmod.util.MapHelper; class LecturePermissionManagerWrapper extends AbstractControlWrapper> { @@ -20,9 +20,9 @@ class LecturePermissionManagerWrapper extends AbstractControlWrapper permissionList = new ArrayList(); + private Map newPermissionMap; + + private ImagePermissions defaultPermissions; + + private static final Logger LOGGER = Logger.getLogger(ImagePermissionConfigurator.class); + + public ImagePermissionConfigurator() { + super(); + me = this; + GridManager grid = new GridManager(this, 1); + + permissionTable = new ImagePermissionTable(); + + // Panel for the add- and remove buttons + JPanel userButtonPane = new JPanel(); + userButtonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + userButtonPane.setLayout(new BoxLayout(userButtonPane, BoxLayout.LINE_AXIS)); + + btnAddUser = new JButton("Benutzer hinzufügen"); + userButtonPane.add(btnAddUser); + btnRemoveUser = new JButton("Benutzer entfernen"); + userButtonPane.add(btnRemoveUser); + userButtonPane.add(Box.createGlue()); + + // Put everything into the grid + QScrollPane jsp = new QScrollPane(permissionTable); + jsp.setBackground(UIManager.getColor("Table.background")); + grid.add(jsp).fill(true, true).expand(true, true); + grid.nextRow(); + grid.add(userButtonPane).fill(true, false).expand(true, false); + grid.nextRow(); + grid.finish(false); + + // add user button listener + btnAddUser.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + UserListWindow.open(SwingUtilities.getWindowAncestor(me), new UserAddedCallback() { + @Override + public void userAdded(final UserInfo newUser, UserListWindow window) { + // check if we have this user already + for (UserImagePermissions current : permissionList) { + if (current.userId.equals(newUser.userId)) { + LOGGER.debug("User already present in the list, skipping!"); + return; + } + } + // add it to the list with default permissions + permissionList.add(new UserImagePermissions(newUser.userId, new ImagePermissions( + defaultPermissions))); + permissionTable.setData(permissionList, false); + } + }, "Hinzufügen", ownerId); + } + }); + + // delete user button listener + btnRemoveUser.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + final UserImagePermissions selected = permissionTable.getSelectedItem(); + if (selected != null && !permissionList.remove(selected)) { + LOGGER.debug("Could not remove: " + selected); + } + permissionTable.setData(permissionList, false); + } + }); + + // keyboard shortcut + permissionTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put( + KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete"); + permissionTable.getActionMap().put("delete", new AbstractAction() { + @Override + public void actionPerformed(ActionEvent ae) { + btnRemoveUser.doClick(); + } + }); + } + + /** + * Initialize the PermissionManager. Note that the given permissionMap and + * defaultPermissions reference + * will get changed when the user interacts with the controls. + * + * @param permissionMap the old permission, to initialize the table with, + * null creates empty table. + * @param defaultPermissions the permissions for a newly added user + * @param ownerId The user to exclude from the add user list. Can be null. + */ + public void initPanel(Map permissionMap, + final ImagePermissions defaultPermissions, String ownerId) { + this.ownerId = ownerId; + this.newPermissionMap = permissionMap == null ? new HashMap() + : permissionMap; + this.defaultPermissions = defaultPermissions; + + permissionList.clear(); + for (Entry e : newPermissionMap.entrySet()) { + permissionList.add(new UserImagePermissions(e.getKey(), e.getValue())); + } + // lexicographic sort on the last names + Collections.sort(permissionList, new Comparator() { + @Override + public int compare(UserImagePermissions o1, UserImagePermissions o2) { + UserInfo u1 = UserCache.find(o1.userId); + UserInfo u2 = UserCache.find(o2.userId); + if (u1 != null && u2 != null) + return FormatHelper.userName(u1).compareTo(FormatHelper.userName(u2)); + else + return 0; + } + }); + permissionTable.setData(permissionList, false); + } + + /** + * Get map with the permissions set in the table of the manager. + * + * @return Map with new custom permissions, null if something went wrong + */ + public Map updatePermissionReferences() { + if (permissionList == null) + return null; + + newPermissionMap.clear(); + + // put permissions of the list into the map + for (UserImagePermissions perm : permissionList) { + newPermissionMap.put(perm.userId, perm.permissions); + } + return newPermissionMap; + } + + /** + * Update the used default permissions of the manager. + * + * @param link + * @param download + * @param edit + * @param admin + */ + public void updateDefaultPermissions(boolean link, boolean download, boolean edit, boolean admin) { + this.defaultPermissions.link = link; + this.defaultPermissions.download = download; + this.defaultPermissions.edit = edit; + this.defaultPermissions.admin = admin; + } + +} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LdapFilterConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LdapFilterConfigurator.java new file mode 100755 index 00000000..3727b50e --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LdapFilterConfigurator.java @@ -0,0 +1,221 @@ +package org.openslx.dozmod.gui.configurator; + +import java.awt.GridBagConstraints; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.event.ChangeListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; + +import org.apache.log4j.Logger; +import org.openslx.bwlp.thrift.iface.LdapFilter; +import org.openslx.dozmod.gui.Gui; +import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; +import org.openslx.dozmod.gui.control.QLabel; +import org.openslx.dozmod.gui.control.WordWrapLabel; +import org.openslx.dozmod.gui.control.table.LectureLdapFilterTable; +import org.openslx.dozmod.gui.control.table.QScrollPane; +import org.openslx.dozmod.gui.helper.GridManager; +import org.openslx.dozmod.gui.helper.MessageType; + +/** + * Widget for network share configuration of lectures + */ +public class LdapFilterConfigurator extends LdapFilterConfiguratorLayout { + + private static final long serialVersionUID = -3336605759245603655L; + private final static Logger LOGGER = Logger.getLogger(LdapFilterConfigurator.class); + private List filterList = null; + + public LdapFilterConfigurator() { + + super(); + + tblFilters.getModel().addTableModelListener(new TableModelListener() { + @Override + public void tableChanged(TableModelEvent e) { + fireChangeEvent(); + } + }); + + tblFilters.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + LdapFilter item = tblFilters.getSelectedItem(); + if (item == null) { + clearInputFields(); + return; + } + // share from the list is selected: fill bottom form and change "Add" to "Apply" + btnDel.setEnabled(true); + txtAttribute.setText(item.attribute); + txtValue.setText(item.value); + btnAdd.setText("Ändern"); + } + }); + + btnAdd.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // check if we are editing an existing share entry or + // creating a new one, check for input either way + LdapFilter input = new LdapFilter(); + + input.attribute = txtAttribute.getText(); + if (input.attribute == null || input.attribute.isEmpty()) { + Gui.showMessageBox("Kein Attribut angegeben", MessageType.ERROR, null, null); + return; + } + input.value = txtValue.getText(); + if (input.value == null) { + input.value = ""; + } + + // either we delete the existing share from the data or we are + // creating a new one, either way add it to the list and update + // the table, if its not present already + if (filterList.contains(input)) { + Gui.showMessageBox("Eintrag bereits vorhanden", MessageType.ERROR, null, null); + return; + } + // now decide whether to create a new entry or update existing one + LdapFilter oldEntry = tblFilters.getSelectedItem(); + if (oldEntry != null) { + // editing existing one, delete it from the internal data + filterList.remove(oldEntry); + } + filterList.add(input); + tblFilters.setData(filterList, false); + clearInputFields(); + } + }); + + btnDel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // try to delete the selected share + LdapFilter selection = tblFilters.getSelectedItem(); + if (selection == null) { + return; + } + try { + if (!filterList.remove(selection)) { + // false if it was not found + LOGGER.error("Could not remove non-existent filter '" + selection.toString() + + "' from the table data: " + filterList.toString()); + return; + } + // refresh table data + tblFilters.setData(filterList, false); + } catch (Exception ex) { + LOGGER.debug("Failed to remove " + selection.toString() + " from the table data.", ex); + return; + } + } + }); + btnDel.setEnabled(false); + } + + private void clearInputFields() { + btnDel.setEnabled(false); + txtAttribute.setText(null); + txtValue.setText(null); + btnAdd.setText("Hinzufügen"); + } + + public List getState() { + return filterList; + } + + public boolean setState(List data) { + if (data == null) + return false; + if (filterList == null) { + filterList = new ArrayList<>(); + } + filterList = data; + tblFilters.setData(filterList, false); + return true; + } + + protected List listenerList = new ArrayList<>(); + + public void addLdapFilterListTableContentConfigurationChangeEventListener(ChangeListener listener) { + listenerList.add(listener); + } + + public void removeNetshareConfigurationChangeEventListener(ChangeListener listener) { + listenerList.remove(listener); + } + + void fireChangeEvent() { + for (ChangeListener listener : new ArrayList<>(listenerList)) { + listener.stateChanged(null); + } + } + + public void addToChangeMonitor(DialogChangeMonitor changeMonitor) { + changeMonitor.add(tblFilters); + } + +} + +/** + * Internal layout class for this widget + */ +class LdapFilterConfiguratorLayout extends JPanel { + + private static final long serialVersionUID = 6479838641542743622L; + + private final static String HELPTEXT = "Geben Sie hier LDAP Filter ein, die die Sichtbarkeit" + + " der Veranstaltung abhängig vom angemeldeten Benutzer einschränken. Eine Veranstaltung" + + " ist sichtbar, sobald einer der angegebenen Filter zutrifft. Zusätzliche Raumbeschränkungen" + + " greifen weiterhin."; + + protected final LectureLdapFilterTable tblFilters = new LectureLdapFilterTable(); + protected final JTextField txtAttribute, txtValue; + protected final JButton btnAdd, btnDel; + + public LdapFilterConfiguratorLayout() { + GridManager grid = new GridManager(this, 1, true, new Insets(3, 3, 3, 3)); + // top info panel + grid.add(new WordWrapLabel(HELPTEXT)).fill(true, false).expand(true, false); + grid.nextRow(); + // middle filter list + grid.add(new QScrollPane(tblFilters)).fill(true, true).expand(true, true); + grid.nextRow(); + + btnDel = new JButton("Entfernen"); + grid.add(btnDel).anchor(GridBagConstraints.EAST); + grid.nextRow(); + + JPanel pnlNewShare = new JPanel(); + GridManager gridNewFilter = new GridManager(pnlNewShare, 2, true); + pnlNewShare.setBorder(BorderFactory.createTitledBorder("Filter definieren")); + gridNewFilter.add(new QLabel("Attribut")); + txtAttribute = new JTextField(); + gridNewFilter.add(txtAttribute).fill(true, false).expand(true, false); + gridNewFilter.nextRow(); + gridNewFilter.add(new QLabel("Wert")); + txtValue = new JTextField(); + gridNewFilter.add(txtValue).fill(true, false).expand(true, false); + gridNewFilter.nextRow(); + btnAdd = new JButton("Hinzufügen"); + gridNewFilter.add(btnAdd, 2).anchor(GridBagConstraints.EAST); + gridNewFilter.nextRow(); + gridNewFilter.finish(false); + grid.add(pnlNewShare).fill(true, false).expand(true, false); + grid.nextRow(); + grid.finish(false); + } +} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LecturePermissionConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LecturePermissionConfigurator.java new file mode 100644 index 00000000..b99df3f2 --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LecturePermissionConfigurator.java @@ -0,0 +1,236 @@ +package org.openslx.dozmod.gui.configurator; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.EventListener; +import java.util.EventObject; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.event.EventListenerList; + +import org.apache.log4j.Logger; +import org.openslx.bwlp.thrift.iface.LecturePermissions; +import org.openslx.bwlp.thrift.iface.UserInfo; +import org.openslx.dozmod.gui.control.table.LecturePermissionTable; +import org.openslx.dozmod.gui.control.table.LecturePermissionTable.UserLecturePermissions; +import org.openslx.dozmod.gui.control.table.QScrollPane; +import org.openslx.dozmod.gui.helper.GridManager; +import org.openslx.dozmod.gui.window.UserListWindow; +import org.openslx.dozmod.gui.window.UserListWindow.UserAddedCallback; + +/** + * Panel including LecturePermissionTable and add/remove buttons for setting + * customLecturePermissions. + */ +/** + * @author joe + * + */ +@SuppressWarnings("serial") +public class LecturePermissionConfigurator extends JPanel { + + /** + * Self reference + */ + private LecturePermissionConfigurator me; + + protected LecturePermissionTable permissionTable; + + protected JButton btnAddUser; + protected JButton btnRemoveUser; + + private final ArrayList permissionList = new ArrayList(); + + private LecturePermissions defaultPermissions; + + private String ownerId = null; + + private static final Logger LOGGER = Logger.getLogger(LecturePermissionConfigurator.class); + + public LecturePermissionConfigurator() { + super(); + me = this; + + GridManager grid = new GridManager(this, 1); + + permissionTable = new LecturePermissionTable(); + + // Panel for the add- and remove buttons + JPanel userButtonPane = new JPanel(); + userButtonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + userButtonPane.setLayout(new BoxLayout(userButtonPane, BoxLayout.LINE_AXIS)); + + btnAddUser = new JButton("Benutzer hinzufügen"); + userButtonPane.add(btnAddUser); + btnRemoveUser = new JButton("Benutzer entfernen"); + userButtonPane.add(btnRemoveUser); + userButtonPane.add(Box.createGlue()); + + // Put everything into the grid + QScrollPane jsp = new QScrollPane(permissionTable); + jsp.setBackground(UIManager.getColor("Table.background")); + grid.add(jsp).fill(true, true).expand(true, true); + grid.nextRow(); + grid.add(userButtonPane).fill(true, false).expand(true, false); + grid.nextRow(); + grid.finish(false); + + // add user button listener + btnAddUser.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + UserListWindow.open(SwingUtilities.getWindowAncestor(me), new UserAddedCallback() { + @Override + public void userAdded(final UserInfo newUser, UserListWindow window) { + // check if we have this user already + for (UserLecturePermissions current : permissionList) { + if (current.userId.equals(newUser.userId)) { + LOGGER.debug("User already present in the list, skipping!"); + return; + } + } + // add it to the list with default permissions + permissionList.add(new UserLecturePermissions(newUser.userId, new LecturePermissions( + defaultPermissions))); + permissionTable.setData(permissionList, false); + fireUserChangeEvent(); + } + }, "Hinzufügen", ownerId); + } + }); + + // delete user button listener + btnRemoveUser.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + final UserLecturePermissions selected = permissionTable.getSelectedItem(); + if (selected != null && !permissionList.remove(selected)) { + LOGGER.debug("Could not remove: " + selected); + } + permissionTable.setData(permissionList, false); + fireUserChangeEvent(); + } + }); + + // keyboard shortcut + permissionTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put( + KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete"); + permissionTable.getActionMap().put("delete", new AbstractAction() { + @Override + public void actionPerformed(ActionEvent ae) { + btnRemoveUser.doClick(); + } + }); + permissionTable.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + // TODO: This is stupid; permissionTable should fire an event + // if one of the check boxes changes. + fireUserChangeEvent(); + } + }); + } + + /** + * Initialise the PermissionManager + * + * @param permissionMap the old permission, to initialise the table with, + * null creates empty table. + * @param defaultPermissions the permissions for a newly added user + * @param ownerId The user to exclude in the list do add user. May be null. + */ + public void initPanel(Map permissionMap, + final LecturePermissions defaultPermissions, String ownerId) { + this.ownerId = ownerId; + this.defaultPermissions = defaultPermissions; + permissionList.clear(); + if (permissionMap != null) { + for (Entry e : permissionMap.entrySet()) { + permissionList.add(new UserLecturePermissions(e.getKey(), e.getValue())); + } + } + permissionTable.setData(permissionList, false); + } + + /** + * Get map with the permissions set in the table of the manager. + * + * @return Map with new custom permissions, null if something went wrong + */ + public Map getPermissions() { + Map newPermissionMap = new HashMap<>(permissionList.size()); + // put permissions of the list into the map + for (UserLecturePermissions perm : permissionList) { + newPermissionMap.put(perm.userId, perm.permissions); + } + return newPermissionMap; + } + + /** + * Update the default permissions used by the manager. + * + * @param admin + * @param edit + */ + public void updateDefaultPermissions(boolean admin, boolean edit) { + defaultPermissions.admin = admin; + defaultPermissions.edit = edit; + } + + + /** + * Custom event mechanism to detect changes to the user list + * (Mostly needed for the reactToChange() stuff in LectureDetailsWindow) + */ + protected EventListenerList listenerList = new EventListenerList(); + + /** + * Shared instance, since there is no data attached (yet) + */ + private static final UserChangeEvent CHANGE_EVENT = new UserChangeEvent(); + + public static class UserChangeEvent extends EventObject { + + public UserChangeEvent() { + super(new Object()); + } + } + + public interface UserChangeEventListener extends EventListener { + public void stateChanged(UserChangeEvent event); + } + + public void addUserChangeEventListener(UserChangeEventListener listener) { + listenerList.add(UserChangeEventListener.class, listener); + } + + public void removeUserChangeEventListener(UserChangeEventListener listener) { + listenerList.remove(UserChangeEventListener.class, listener); + } + + void fireUserChangeEvent() { + Object[] listeners = listenerList.getListenerList(); + for (int i = 0; i < listeners.length; i++) { + if (listeners[i] == UserChangeEventListener.class) { + ((UserChangeEventListener) listeners[i + 1]) + .stateChanged(CHANGE_EVENT); + } + } + } +} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetrulesConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetrulesConfigurator.java new file mode 100644 index 00000000..cb80fc3e --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetrulesConfigurator.java @@ -0,0 +1,450 @@ +package org.openslx.dozmod.gui.configurator; + +import java.awt.Color; +import java.awt.Insets; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.EventListener; +import java.util.EventObject; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextPane; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.event.EventListenerList; +import javax.swing.text.BadLocationException; +import javax.swing.text.DefaultStyledDocument; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; + +import org.apache.log4j.Logger; +import org.openslx.bwlp.thrift.iface.NetDirection; +import org.openslx.bwlp.thrift.iface.NetRule; +import org.openslx.dozmod.gui.Gui; +import org.openslx.dozmod.gui.control.WordWrapLabel; +import org.openslx.dozmod.gui.helper.GridManager; +import org.openslx.dozmod.gui.helper.MessageType; +import org.openslx.dozmod.gui.helper.TextChangeListener; +import org.openslx.util.Util; + +/** + * Widget for netrules configuration of lectures + */ +public class NetrulesConfigurator extends NetrulesConfiguratorLayout { + + private static final long serialVersionUID = -3497629601818983994L; + private final static Logger LOGGER = Logger + .getLogger(NetrulesConfigurator.class); + + private String originalRawRuleText = null; + /** + * Character defining how the rules are parsed, e.g. for whitespace \\s + * Example: "8.8.8.8 80 in" would be split in -hostname "8.8.8.8" -port "80" + * -direction "in" + */ + private static final String FIELD_DELIMITER = "\\s+"; + + private static final Color FOREGROUND_TEXT_COLOR; + + static { + Color fgOrigColor = UIManager.getDefaults().getColor("ColorChooser.foreground"); + if (fgOrigColor == null) { + // use black as fallback + fgOrigColor = Color.BLACK; + } + FOREGROUND_TEXT_COLOR = fgOrigColor; + } + + public NetrulesConfigurator() { + super(); + + final TextChangeListener docListener = new TextChangeListener() { + @Override + public void changed() { + fireNetrulesConfigurationChangeEvent(new NetrulesConfigurationChangeEvent(NetrulesConfigurator.this)); + } + }; + final SimpleAttributeSet as = new SimpleAttributeSet(); + StyleConstants.setForeground(as, FOREGROUND_TEXT_COLOR); + tpNetworkRules.getDocument().addDocumentListener(docListener); + tpNetworkRules.addKeyListener(new KeyAdapter() { + @Override + public void keyTyped(KeyEvent e) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + int pos = tpNetworkRules.getCaretPosition(); + if (pos < 0) { + return; + } + // Odd: On windows, getText() returns the text with CRLF line breaks, + // regardless of what you put into the text box. + // The offsets passed to setCharAttrs() below and the caret position + // you get from getCaretPosition() however have to adhere to the + // text version with just LF, exactly how we created the document. + String text = tpNetworkRules.getText().replace("\r", ""); + if (pos >= text.length()) { + return; + } + int start = text.lastIndexOf('\n', pos == 0 ? 0 : pos - 1); + int end = text.indexOf('\n', pos); + if (start == -1) { + start = 0; + } + if (end == -1) { + end = text.length() - 1; + } + if (end <= start) { + return; + } + tpNetworkRules.getStyledDocument().setCharacterAttributes(start, end - start, as, true); + } + }); + } + }); + } + + public boolean hasChanged() { + return !originalRawRuleText.equalsIgnoreCase(tpNetworkRules.getText()); + } + + /** + * Gets the state of the widget as a list of netrules. Internally it first + * transforms the input text in a list of netrules. + * + * @return the list of rules as parsed by parseNetRules() + */ + public List getState(boolean silent) { + // cleanup the TextPane for network rules if needed + return parseNetRules(silent); + } + + /** + * Sets the state of this widget to the given list of netrules. This will + * internally transform the list to its string representation + * + * @param netrules + * as a list of NetRule to set the state to + */ + public void setState(final List netrules) { + // setText() blanks the text area if null is given, so no null checks + originalRawRuleText = decodeNetRulesToText(netrules); + this.tpNetworkRules.setText(originalRawRuleText); + } + + /** + * "Decodes" the given list of NetRule to a single String. This should be + * used to set the text in the TextPane for the network rules + * + * @param netRulesList + * list of NetRule to decode + * @return String representation of the list of rules + */ + public static String decodeNetRulesToText(final List netRulesList) { + if (netRulesList == null || netRulesList.isEmpty()) + return ""; + + String decodedRules = ""; + Iterator it = netRulesList.iterator(); + while (it.hasNext()) { + String currentLine = ""; + NetRule currentRule = it.next(); + // simple test for validity (since this comes from the server it + // should be correct anyways) + if (currentRule.host.isEmpty() || currentRule.port > 65535) { + LOGGER.error("Invalid rule! Ignoring: " + currentRule.host + + ":" + currentRule.port); + continue; + } + currentLine += currentRule.host + " \t "; + currentLine += currentRule.port + " \t "; + currentLine += currentRule.direction.name(); + decodedRules += currentLine + + (it.hasNext() ? "\n" : ""); + } + return decodedRules; + } + + /** + * Parses the given rawNetRules String to a list of NetRule + * + * @param rawNetRules + * the raw text to be parsed + * @return list of netrules if successful. If any errors occured while + * parsing, null is returned. + */ + public List parseNetRules(boolean silent) { + String rawNetRules = tpNetworkRules.getText().trim(); + List rulesList = new ArrayList(); + if (rawNetRules.isEmpty()) { + return rulesList; + } + + // split it line by line + boolean invalid = false; // True if the rules are invalid and null should be returned + DefaultStyledDocument newdoc = null; + if (!silent) { + newdoc = new DefaultStyledDocument(); // Used to build new document with colors + } + StringBuilder errors = new StringBuilder(); // Error messages to show (if not silent) + int lineNo = 0; // Show line numbers in error messages + Set warnedHosts = new HashSet<>(); // Ask only once about each unknown host + for (String ruleLine : rawNetRules.split("[\r\n]+")) { + if (silent && invalid) + return null; + Color lineColor = null; + LOGGER.debug("Parsing rule: " + ruleLine); + // split the fields and check if we have 3 as expected. + String[] fields = ruleLine.trim().split(FIELD_DELIMITER); + if (fields.length != 3) { + lineNo += addLine(newdoc, ruleLine, Color.RED, true); + // log numbers for fields independently... + LOGGER.debug("Invalid number of fields! Expected 3, got: " + fields.length); + if (fields.length > 3) { + errors.append("Zeile " + lineNo + ": Zu viele Felder.\n"); + } else { + errors.append("Zeile " + lineNo + ": Zu wenig Felder.\n"); + } + invalid = true; + continue; + } + // Have 3 fields, pretty up + String ruleDirection = fields[2].toUpperCase(); + ruleLine = fields[0] + " \t " + fields[1] + " \t " + ruleDirection; + + // start to check fields one by one from the last to the first .... + // check net direction: accept either 'in' or 'out' (case + // insensitive) + // TODO support combined 'in/out' rules + if (!ruleDirection.equals("IN") && !ruleDirection.equals("OUT")) { + lineNo += addLine(newdoc, ruleLine, Color.RED, true); + LOGGER.debug("Invalid net direction! Expected 'in' or out'. Got: " + ruleDirection); + errors.append("Zeile " + lineNo + ": Ungültige Richtung. Bitte nutzen Sie 'IN' bzw. 'OUT'.\n"); + invalid = true; + continue; + } + // check port: accept if >= 0 and <= 65535 + int port = Util.parseInt(fields[1], -1); + + // port = 0 means match only host (all protocols and ports) + if (port < 0 || port > 65535) { + lineNo += addLine(newdoc, ruleLine, Color.RED, true); + LOGGER.debug("Invalid port! Got: " + port); + errors.append("Zeile " + lineNo + ": Ungültiger Port. Gültiger Bereich ist 0-65535.\n"); + invalid = true; + continue; + } + // check hostname: bit more to do here + // for IPs and/or resolvable hostnames we make use of java.net's + // InetAddress.getByName() method which checks the validity of + // an IP-Address represented by a string or if the given hostname + // is resolvable. If any of these happen, we have a valid hostname. + // Non-resolvable hostnames are handled differently, see after the + // try/catch-block + InetAddress ruleHost = null; + try { + // TODO: Find a way to reliably set a timeout (external DNS library?) + // Otherwise just remove this check + ruleHost = InetAddress.getByName(fields[0]); + } catch (UnknownHostException e) { + // might be good to see this exception in the log file + // LOGGER.debug("Invalid hostname (java.net): ", e); + } + if (ruleHost == null) { + // either invalid IP-Address or an invalid resolvable hostname + // however it might also be a non-resolvable hostname that would + // be valid in the actual pool-rooms, so lets check its syntax + // according to: http://tools.ietf.org/html/rfc1034#section-3.1 + LOGGER.debug("Invalid host/IP! Got: " + fields[0]); + String checkRes = checkHostnameSimple(fields[0]); + if (checkRes == null) { + if (!silent + && !warnedHosts.contains(fields[0]) + && !Gui.showMessageBox("Konnte '" + fields[0] + + "' nicht auflösen. Wollen Sie diesen Hostnamen trotzdem verwenden?", + MessageType.WARNING_RETRY, null, null)) { + invalid = true; + } + warnedHosts.add(fields[0]); + lineColor = Color.ORANGE; + } else { + lineNo += addLine(newdoc, ruleLine, Color.RED, true); + errors.append("Zeile " + lineNo + ": " + checkRes + "\n"); + invalid = true; + continue; + } + } + // Made it to here - line is valid + lineNo += addLine(newdoc, ruleLine, lineColor, false); + rulesList.add(new NetRule(NetDirection.valueOf(ruleDirection), fields[0], port)); + } + if (!silent && errors.length() != 0) { + Gui.showMessageBox("Fehler beim Auswerten der angegebenen Netzwerkregeln.\n\n" + errors.toString() + + "\nBitte geben Sie die Regeln zeilenweise im Format\n" + + " \n" + + "an.", + MessageType.ERROR, null, null); + } + if (newdoc != null) { + tpNetworkRules.setDocument(newdoc); + } + if (invalid) { + return null; + } + // Success + return rulesList; + } + + private int addLine(DefaultStyledDocument doc, String line, Color color, boolean bold) { + if (doc == null) + return 0; + if (color == null) { + color = FOREGROUND_TEXT_COLOR; + } + SimpleAttributeSet attrs = new SimpleAttributeSet(); + StyleConstants.setForeground(attrs, color); + StyleConstants.setBold(attrs, bold); + try { + doc.insertString(doc.getLength(), line + "\n", attrs); + } catch (BadLocationException e) { + LOGGER.warn("Cannot append to new textbox document", e); + } + return 1; + } + + /** + * Very simple hostname check for the given String. This will only check for + * some requirements of valid hostnames as stated in + * http://tools.ietf.org/html/rfc1034#section-3.1 To recap: max length of + * the whole hostname must be < 254 ASCII characters, all domain labels + * (between two dots) must be between 1 and 63 chars long and domain labels + * can only contain digits, letters and hyphen. (Note: we also accept + * forward slash to accept subnets!) + * + * @param hostname the hostname to check for syntactical validity + * @return null if valid, error string otherwise + */ + private String checkHostnameSimple(final String hostname) { + if (hostname.length() > 254) { + return "Hostname ist zu lang."; + } + // split by '.' to get domain levels + boolean allNumeric = true; + String[] domainLabels = hostname.split("\\."); + for (String domainLabel : domainLabels) { + if (domainLabel.length() > 63) { + // fail since domain level should be max 63 chars + return "Domain-Ebene '" + domainLabel + "' länger als 63 Zeichen."; + } + if (Util.parseInt(domainLabel, -1) == -1) { + allNumeric = false; + } + // checking for valid chars is pointless with punycode + } + if (allNumeric && domainLabels.length != 4) { + return "Unvollständige IP-Adresse."; + } + return null; + } + + /** + * Custom event mechanism to detect changes to the netrules list (Mostly + * needed for the reactToChange() stuff in LectureDetailsWindow) + */ + protected EventListenerList listenerList = new EventListenerList(); + + public class NetrulesConfigurationChangeEvent extends EventObject { + + private static final long serialVersionUID = -8779550754760035845L; + + public NetrulesConfigurationChangeEvent(Object source) { + super(source); + } + } + + public interface NetrulesConfigurationChangeEventListener extends + EventListener { + public void stateChanged(NetrulesConfigurationChangeEvent event); + } + + public void addNetrulesConfigurationChangeEventListener( + NetrulesConfigurationChangeEventListener listener) { + listenerList.add(NetrulesConfigurationChangeEventListener.class, + listener); + } + + public void removeNetrulesConfigurationChangeEventListener( + NetrulesConfigurationChangeEventListener listener) { + listenerList.remove(NetrulesConfigurationChangeEventListener.class, + listener); + } + + void fireNetrulesConfigurationChangeEvent( + NetrulesConfigurationChangeEvent evt) { + Object[] listeners = listenerList.getListenerList(); + for (int i = 0; i < listeners.length; i++) { + if (listeners[i] == NetrulesConfigurationChangeEventListener.class) { + ((NetrulesConfigurationChangeEventListener) listeners[i + 1]) + .stateChanged(evt); + } + } + } +} + +/** + * Internal layout class for this widget + */ +class NetrulesConfiguratorLayout extends JPanel { + + private static final long serialVersionUID = 5266120380443817325L; + private final static String txtNetworkOptionsTitle = "Netzwerk Einstellungen"; + private final static String txtNetworkOptionsDesc = "Wenn Sie den Internetzugriff deaktiviert haben," + + " können Sie hier Ausnahmen definieren (Whitelist)." + + " Bitte definieren Sie Ihre Regeln im Format\n .\n" + + "Sie können Port 0 angeben, was sämtlichen TCP und UDP Ports eines Hosts entspricht.\n\n" + + "Wenn Sie Internetzugriff aktivieren, hat diese Liste den gegenteiligen Effekt"; + private final static String txtNetworkRulesTitle = "Netzwerkregeln"; + + private final JPanel pnlNetworkOptions; + protected final JTextPane tpNetworkRules; + + public NetrulesConfiguratorLayout() { + + GridManager grid = new GridManager(this, 1, true, + new Insets(5, 5, 5, 5)); + + // middle panel for network rules + pnlNetworkOptions = new JPanel(); + GridManager gridNetworkOptions = new GridManager(pnlNetworkOptions, 1, + true, new Insets(2, 2, 2, 2)); + pnlNetworkOptions.setBorder(BorderFactory + .createTitledBorder(txtNetworkOptionsTitle)); + tpNetworkRules = new JTextPane(); + + JScrollPane scpNetworkRules = new JScrollPane(tpNetworkRules, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + pnlNetworkOptions.setBorder(BorderFactory + .createTitledBorder(txtNetworkRulesTitle)); + gridNetworkOptions + .add(new WordWrapLabel(txtNetworkOptionsDesc)) + .fill(true, false).expand(true, false); + gridNetworkOptions.nextRow(); + gridNetworkOptions.add(scpNetworkRules).fill(true, true) + .expand(true, true); + gridNetworkOptions.finish(false); + + // build the final grid + grid.add(pnlNetworkOptions).fill(true, true).expand(true, true); + grid.finish(false); + } +} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetshareConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetshareConfigurator.java new file mode 100644 index 00000000..6141992c --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetshareConfigurator.java @@ -0,0 +1,372 @@ +package org.openslx.dozmod.gui.configurator; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.TableModelListener; + +import org.apache.log4j.Logger; +import org.openslx.bwlp.thrift.iface.NetShare; +import org.openslx.bwlp.thrift.iface.NetShareAuth; +import org.openslx.dozmod.gui.Gui; +import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; +import org.openslx.dozmod.gui.control.ComboBox; +import org.openslx.dozmod.gui.control.QLabel; +import org.openslx.dozmod.gui.control.ComboBox.ComboBoxRenderer; +import org.openslx.dozmod.gui.control.table.NetshareTable; +import org.openslx.dozmod.gui.control.table.QScrollPane; +import org.openslx.dozmod.gui.helper.GridManager; +import org.openslx.dozmod.gui.helper.MessageType; +import org.openslx.dozmod.util.FormatHelper; + +/** + * Widget for network share configuration of lectures + */ +public class NetshareConfigurator extends NetshareConfiguratorLayout { + + private static final long serialVersionUID = -3336605759245603655L; + private final static Logger LOGGER = Logger.getLogger(NetshareConfigurator.class); + private List shareList = null; + + // mount points / win drive letters - ideally, we would check whether the image is linux or windows based + // and either show a drive selection list like this one, or a textfield for a user-defined mount point... + private Character[] mountPoints = { 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', + 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; + + public NetshareConfigurator() { + super(); + tblNetshare.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + NetShare item = tblNetshare.getSelectedItem(); + // ugly block-wise sets, but only one test needed compared to + // doing lots of item != null ? ... : ... + if (item == null) { + clearInputFields(); + return; + } + // share from the list is selected: fill bottom form and change "Add" to "Apply" + btnDel.setEnabled(true); + tfSharePath.setText(item.path); + tfShareName.setText(item.displayname); + tfUsername.setText(item.username); + tfPassword.setText(item.password); + cboNetshareAuth.setSelectedItem(item.auth); + cboNetshareMountPoint.setSelectedItem(Character.valueOf(item.mountpoint.charAt(0))); + btnAdd.setText("Ändern"); + } + }); + + cboNetshareMountPoint.setModel(new DefaultComboBoxModel(mountPoints)); + cboNetshareMountPoint.setSelectedItem(null); + + // combobox for share authentication types + cboNetshareAuth.setModel(new DefaultComboBoxModel(NetShareAuth.values())); + cboNetshareAuth.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + NetShareAuth selectedAuth = cboNetshareAuth.getItemAt(cboNetshareAuth.getSelectedIndex()); + if (selectedAuth == null) + return; + boolean activate = selectedAuth == NetShareAuth.OTHER_USER; + // username field is needed to either special or guest user + tfUsername.setEnabled(activate); + lblUsername.setEnabled(activate); + tfPassword.setEnabled(activate); + lblPassword.setEnabled(activate); + chkShowPass.setEnabled(activate); + } + }); + cboNetshareAuth.setSelectedItem(null); + + btnAdd.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // check if we are editing an existing share entry or + // creating a new one, check for input either way + NetShare input = new NetShare(); + + input.path = tfSharePath.getText(); + if (input.path == null || input.path.isEmpty()) { + lblError.setText("Kein Pfad angegeben!"); + return; + } + String inputShareName = tfShareName.getText(); + if (inputShareName.isEmpty()) { + lblError.setText("Kein Anzeigename angegeben!"); + return; + } + input.displayname = inputShareName; + + NetShareAuth inputNetShareAuth = cboNetshareAuth + .getItemAt(cboNetshareAuth.getSelectedIndex()); + if (inputNetShareAuth == null) { + lblError.setText("Kein Authentifizierungstyp angegeben!"); + return; + } + input.auth = inputNetShareAuth; + switch (inputNetShareAuth) { + case LOGIN_USER: + // this uses the bwLehrpool client's logged in user + // we don't need to have anything + break; + case OTHER_USER: + // save given username/password + input.username = tfUsername.getText(); + input.password = new String(tfPassword.getPassword()); + if (input.username.isEmpty()) { + lblError.setText("Kein Nutzername angegeben!"); + return; + } + break; + default: + input = null; + break; + } + if (input == null) { + lblError.setText("Fehlerhafte Eingabe"); + LOGGER.debug("Bad input, aborting."); + return; + } + // now check for optional mount path + Character inputMountPoint = cboNetshareMountPoint + .getItemAt(cboNetshareMountPoint.getSelectedIndex()); + if (inputMountPoint == null) { + lblError.setText("Kein Ziel angegeben!"); + return; + } + input.mountpoint = inputMountPoint.toString(); + // now decide whether to create a new entry or update existing one + NetShare oldEntry = tblNetshare.getSelectedItem(); + if (oldEntry != null) { + // editing existing one, delete it from the internal data + if (!shareList.remove(oldEntry)) { + lblError.setText("Änderung fehlgeschlagen!"); + LOGGER.debug("Failed to remove selected share for replacement: " + oldEntry); + return; + } + tblNetshare.setData(shareList, false); + } + // either we delete the existing share from the data or we are + // creating a new one, either way add it to the list and update + // the table, if its not present already + if (shareList.contains(input)) { + lblError.setText("Existiert bereits!"); + LOGGER.error("Network share already in the list, aborting."); + return; + } + // if a password is set, warn the user about its unsafe storage + // which we might want to implement one day... + if (input.password != null && !input.password.isEmpty()) { + if (!Gui.showMessageBox( + "Das eingebene Passwort wird im Klartext gespeichert " + + "und ist in der VM für jeden Nutzer sichtbar.\n" + + "Verwenden Sie auf keinen Fall sicherheitskritische Passwörter!" + + "\n\nMöchten Sie diesen Netzlaufwerk trotzdem hinzufügen?", + MessageType.QUESTION_YESNO, LOGGER, null)) { + return; + } + } + lblError.setText(null); + shareList.add(input); + tblNetshare.setData(shareList, false); + clearInputFields(); + } + }); + + btnDel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // try to delete the selected share + NetShare selection = tblNetshare.getSelectedItem(); + if (selection == null) { + return; + } + try { + if (!shareList.remove(selection)) { + // false if it was not found + LOGGER.error("Could not remove non-existant network share '" + selection.toString() + + "' from the table data: " + shareList.toString()); + return; + } + // refresh table data + tblNetshare.getModel().setData(shareList); + } catch (Exception ex) { + LOGGER.debug("Failed to remove " + selection.toString() + " from the table data.", ex); + return; + } + } + }); + + chkShowPass.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() != ItemEvent.SELECTED) { + tfPassword.setEchoChar('*'); + } else { + tfPassword.setEchoChar((char) 0); + } + } + }); + chkShowPass.setEnabled(false); + tfUsername.setEnabled(false); + lblUsername.setEnabled(false); + tfPassword.setEnabled(false); + lblPassword.setEnabled(false); + } + + private void clearInputFields() { + btnDel.setEnabled(false); + tfSharePath.setText(null); + tfShareName.setText(null); + tfUsername.setText(null); + tfPassword.setText(null); + cboNetshareAuth.setSelectedItem(null); + cboNetshareMountPoint.setSelectedItem(null); + btnAdd.setText("Hinzufügen"); + } + public List getState() { + return shareList; + } + + public boolean setState(List data) { + if (data == null) + return false; + if (shareList == null) { + shareList = new ArrayList<>(); + } + shareList = data; + tblNetshare.setData(shareList, false); + return true; + } + + public void addTableModelListener(TableModelListener listener) { + tblNetshare.getModel().addTableModelListener(listener); + } + + public void addToChangeMonitor(DialogChangeMonitor changeMonitor) { + changeMonitor.add(tblNetshare); + } +} + +/** + * Internal layout class for this widget + */ +class NetshareConfiguratorLayout extends JPanel { + + private static final long serialVersionUID = 6479525981542743622L; + + private final static String txtNetshareDesc = "Hier können Sie Netzlaufwerke angeben," + + " die automatisch beim Start der Veranstaltung eingebunden werden sollen." + + " Der Platzhalter %loginuser% wird im Pfad durch den Loginnamen des Nutzers ersetzt."; + + protected final QLabel lblShareAuth, lblSharePath, lblShareName, lblMountPoint, lblUsername, lblPassword, + lblError; + protected final NetshareTable tblNetshare = new NetshareTable(); + protected final JTextField tfSharePath, tfShareName, tfUsername; + protected final JPasswordField tfPassword; + protected final JButton btnAdd, btnDel; + protected final JCheckBox chkShowPass; + protected final ComboBox cboNetshareAuth = new ComboBox<>(new ComboBoxRenderer() { + @Override + public String renderItem(NetShareAuth item) { + if (item == null) + return null; + return FormatHelper.netShareAuthName(item); + } + }); + protected final ComboBox cboNetshareMountPoint = new ComboBox<>(new ComboBoxRenderer() { + @Override + public String renderItem(Character letter) { + if (letter == null) + return null; + return letter.toString() + ":"; + } + }); + + public NetshareConfiguratorLayout() { + GridManager grid = new GridManager(this, 5, true, new Insets(3, 3, 3, 3)); + // top info panel + grid.add(new JLabel(txtNetshareDesc), 5).fill(true, false).expand(true, false); + grid.nextRow(); + // middle netshare list + grid.add(new QScrollPane(tblNetshare), 5).fill(true, true).expand(true, true); + grid.nextRow(); + + JPanel pnlNewShare = new JPanel(); + GridManager gridNewShare = new GridManager(pnlNewShare, 6, true); + pnlNewShare.setBorder(BorderFactory.createTitledBorder("Details")); + lblSharePath = new QLabel("Pfad"); + gridNewShare.add(lblSharePath); + tfSharePath = new JTextField(); + gridNewShare.add(tfSharePath, 5).fill(true, false).expand(true, false); + gridNewShare.nextRow(); + // bottom form to add a new share + lblShareName = new QLabel("Anzeigename"); + lblMountPoint = new QLabel("Ziel"); + tfShareName = new JTextField(); + // extra panel for fancy layout purposes... + JPanel pnlShareName = new JPanel(); + pnlShareName.setLayout(new BoxLayout(pnlShareName, BoxLayout.LINE_AXIS)); + pnlShareName.add(lblShareName); + pnlShareName.add(tfShareName); + pnlShareName.add(lblMountPoint); + pnlShareName.add(cboNetshareMountPoint); + gridNewShare.add(lblShareName); + gridNewShare.add(pnlShareName, 5).fill(true, false).expand(true, false); + gridNewShare.nextRow(); + lblShareAuth = new QLabel("Authentifizierung"); + gridNewShare.add(lblShareAuth); + gridNewShare.add(cboNetshareAuth, 5).fill(true, false).expand(true, false); + gridNewShare.nextRow(); + lblUsername = new QLabel("Username"); + gridNewShare.add(lblUsername); + tfUsername = new JTextField(20); + gridNewShare.add(tfUsername, 2).fill(true, false).expand(true, false); + lblPassword = new QLabel("Passwort"); + gridNewShare.add(lblPassword); + tfPassword = new JPasswordField(20); + gridNewShare.add(tfPassword, 2).fill(true, false).expand(true, false); + gridNewShare.nextRow(); + chkShowPass = new JCheckBox("Passwort anzeigen"); + JPanel pnlShowPass = new JPanel(); + pnlShowPass.setLayout(new BoxLayout(pnlShowPass, BoxLayout.LINE_AXIS)); + pnlShowPass.add(Box.createGlue()); + pnlShowPass.add(chkShowPass, BorderLayout.LINE_END); + gridNewShare.add(pnlShowPass, 6).fill(true, false).expand(true, false); + gridNewShare.nextRow(); + grid.add(pnlNewShare, 5).fill(true, false).expand(true, false); + grid.nextRow(); + // bottom panel for right-aligned button... + JPanel pnlButtonAdd = new JPanel(); + pnlButtonAdd.setLayout(new BoxLayout(pnlButtonAdd, BoxLayout.LINE_AXIS)); + btnAdd = new JButton("Hinzufügen"); + btnDel = new JButton("Entfernen"); + lblError = new QLabel(""); + lblError.setForeground(Color.RED); + pnlButtonAdd.add(lblError); + pnlButtonAdd.add(Box.createGlue()); + pnlButtonAdd.add(btnAdd, BorderLayout.LINE_END); + pnlButtonAdd.add(btnDel, BorderLayout.LINE_END); + grid.add(pnlButtonAdd, 5).fill(true, false).expand(true, false); + grid.finish(false); + } +} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/RunscriptConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/RunscriptConfigurator.java new file mode 100644 index 00000000..52a686bb --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/RunscriptConfigurator.java @@ -0,0 +1,266 @@ +package org.openslx.dozmod.gui.configurator; + +import java.awt.Color; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.EventListener; +import java.util.EventObject; + +import javax.swing.Box; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.event.EventListenerList; + +import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; +import org.openslx.dozmod.gui.configurator.RunscriptConfigurator.RunscriptType; +import org.openslx.dozmod.gui.control.ComboBox; +import org.openslx.dozmod.gui.control.QLabel; +import org.openslx.dozmod.gui.control.WordWrapLabel; +import org.openslx.dozmod.gui.control.ComboBox.ComboBoxRenderer; +import org.openslx.dozmod.gui.helper.GridManager; +import org.openslx.dozmod.gui.helper.TextChangeListener; + +/** + * Widget for advanced configuration options for lectures. This handles + * following options - Network rules - Runscript - USB + */ +public class RunscriptConfigurator extends RunscriptConfiguratorLayout { + + private static final long serialVersionUID = -3497629601818983994L; + + public static enum RunscriptType { + SHELL("Shellskript", "sh"), BATCH("Windows-Batch", "bat"); + + private final String displayName; + private final String extension; + + private RunscriptType(String name, String extension) { + this.displayName = name; + this.extension = extension; + } + + @Override + public String toString() { + return extension + " (" + displayName + ")"; + } + } + + public RunscriptConfigurator() { + super(); + + final TextChangeListener docListener = new TextChangeListener() { + @Override + public void changed() { + fireRunscriptConfigurationChangeEvent(new RunscriptConfigurationChangeEvent( + new Object())); + } + }; + taRunScript.getDocument().addDocumentListener(docListener); + cboRunscriptType.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + fireRunscriptConfigurationChangeEvent(new RunscriptConfigurationChangeEvent( + new Object())); + } + }); + cboRunscriptType.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + fireRunscriptConfigurationChangeEvent(new RunscriptConfigurationChangeEvent( + new Object())); + } + }); + } + + private void setError(final String msg) { + lblError.setText(msg); + } + /** + * Gets the runscript as String. The chosen interpreter will get encoded as + * the first line of the script. + * + * @return runscript as String. If no text was entered, returns a empty + * string. + */ + public String getState() { + setError(""); // fill remove any prior errors, we'll reset them if needed + // handle user input, this is tricky since + // * either an item has been selected -> editorContent will be of our enum type + // * user typed its own interpreter into the box -> editorContent will be a castable String + String extension = null; + Object cboContent = cboRunscriptType.getEditor().getItem(); + if (cboContent instanceof RunscriptType) { + extension = ((RunscriptType) cboContent).extension; + } else if (cboContent instanceof String) { + extension = (String) cboContent; + } + String taInputText = taRunScript.getText(); + if (taInputText.isEmpty()) + return ""; + if (extension == null || extension.isEmpty()) { + // this should never happen, so return null to report this invalid state + setError("Fehlende Dateinamenerweiterung!"); + return null; + } + setError(""); + return "ext=" + extension + "\n" + taInputText; + } + + /** + * Sets the state of this widget to the given AdvancedConfiguration. Basicly + * this sets the content of the text areas to the corresponding network + * rules/runscript as given by the AdvancedConfiguration object + * + * @param config + * AdvancedConfiguration to set the state to + */ + public void setState(final String config) { + if (config == null || config.isEmpty()) { + cboRunscriptType.setSelectedItem(null); + taRunScript.setText(""); + return; + } + String extensionHeader = null; + try { + BufferedReader reader = new BufferedReader(new StringReader(config)); + extensionHeader = reader.readLine(); + reader.close(); + } catch (IOException e) { + // swallow ... + } + if (extensionHeader != null) { + // we should have following format: ext= + // e.g. ext=sh + extensionHeader = extensionHeader.replace("ext=", ""); + for (RunscriptType type : RunscriptType.values()) { + if (type.extension.equals(extensionHeader)) { + cboRunscriptType.setSelectedItem(type); + // mark that we found it by nulling the shebang... + extensionHeader = null; + continue; + } + } + if (extensionHeader != null) { + // user specific shebang, so just write the text to the cbo + cboRunscriptType.getEditor().setItem(extensionHeader); + } + } + // finished with the interpreter, remove that line from the given config + // before setting that text + taRunScript.setText(config.replaceFirst("^ext=.*\n", "")); + } + + /** + * Custom event mechanism to detect changes to the user list (Mostly needed + * for the reactToChange() stuff in LectureDetailsWindow) + */ + protected EventListenerList listenerList = new EventListenerList(); + + public class RunscriptConfigurationChangeEvent extends EventObject { + + private static final long serialVersionUID = -8779550754760035845L; + + public RunscriptConfigurationChangeEvent(Object source) { + super(source); + } + } + + public interface RunscriptConfigurationChangeEventListener extends + EventListener { + public void stateChanged(RunscriptConfigurationChangeEvent event); + } + + public void addRunscriptConfigurationChangeEventListener( + RunscriptConfigurationChangeEventListener listener) { + listenerList.add(RunscriptConfigurationChangeEventListener.class, + listener); + } + + public void removeRunscriptConfigurationChangeEventListener( + RunscriptConfigurationChangeEventListener listener) { + listenerList.remove(RunscriptConfigurationChangeEventListener.class, + listener); + } + + void fireRunscriptConfigurationChangeEvent( + RunscriptConfigurationChangeEvent evt) { + Object[] listeners = listenerList.getListenerList(); + for (int i = 0; i < listeners.length; i++) { + if (listeners[i] == RunscriptConfigurationChangeEventListener.class) { + ((RunscriptConfigurationChangeEventListener) listeners[i + 1]) + .stateChanged(evt); + } + } + } + + public void addToChangeMonitor(DialogChangeMonitor changeMonitor) { + changeMonitor.add(taRunScript); + changeMonitor.addEditableCombo(cboRunscriptType, null); + } + +} + +/** + * Internal layout class for the advanced configurator (to keep it clean even + * for widgets) + */ +class RunscriptConfiguratorLayout extends JPanel { + + private static final long serialVersionUID = 648729071828404053L; + + private final static String txtRunScriptDesc = "Ein hier eingetragenes Skript wird nach dem Start dieser VM automatisch ausgeführt."; + protected final QLabel lblError; + protected final JTextArea taRunScript; + protected final ComboBox cboRunscriptType; + + public RunscriptConfiguratorLayout() { + + GridManager grid = new GridManager(this, 2, true, new Insets(5, 5, 5, 5)); + taRunScript = new JTextArea("", 5, 20); + JScrollPane scpRunScript = new JScrollPane(taRunScript, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + taRunScript.setLineWrap(true); + taRunScript.setWrapStyleWord(true); + grid.add(new WordWrapLabel(txtRunScriptDesc, false, true), 2) + .fill(true, false).expand(true, false); + grid.nextRow(); + cboRunscriptType = new ComboBox( + new ComboBoxRenderer() { + @Override + public String renderItem(RunscriptType item) { + if (item == null) + return null; + return item.toString(); + } + }); + cboRunscriptType.setModel(new DefaultComboBoxModel( + RunscriptType.values())); + ; + cboRunscriptType.setEditable(true); + grid.add(new QLabel("Dateinamenserweiterung: ")).fill(false, false) + .expand(false, false); + grid.add(cboRunscriptType).fill(true, false) + .expand(true, false); + grid.nextRow(); + grid.add(scpRunScript, 2).fill(true, true).expand(true, true); + grid.nextRow(); + lblError = new QLabel(""); + lblError.setForeground(Color.RED); + JPanel pnlError = new JPanel(); + pnlError.add(Box.createGlue()); + pnlError.add(lblError); + pnlError.add(Box.createGlue()); + grid.add(pnlError, 2).fill(true, false).expand(true, false); + grid.finish(false); + + } +} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/ImageCustomPermissionManager.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/ImageCustomPermissionManager.java deleted file mode 100644 index 8dadbd71..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/ImageCustomPermissionManager.java +++ /dev/null @@ -1,201 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import javax.swing.AbstractAction; -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JPanel; -import javax.swing.KeyStroke; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; - -import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.ImagePermissions; -import org.openslx.bwlp.thrift.iface.UserInfo; -import org.openslx.dozmod.gui.control.table.ImagePermissionTable; -import org.openslx.dozmod.gui.control.table.QScrollPane; -import org.openslx.dozmod.gui.control.table.ImagePermissionTable.UserImagePermissions; -import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.gui.window.UserListWindow; -import org.openslx.dozmod.gui.window.UserListWindow.UserAddedCallback; -import org.openslx.dozmod.thrift.cache.UserCache; -import org.openslx.dozmod.util.FormatHelper; - -/** - * Panel including ImagePermissionTable and add/remove buttons for setting - * customImagePermissions. - */ -@SuppressWarnings("serial") -public class ImageCustomPermissionManager extends JPanel { - - protected ImagePermissionTable permissionTable; - - protected JButton btnAddUser; - protected JButton btnRemoveUser; - - private ImageCustomPermissionManager me; - - private String ownerId; - - private ArrayList permissionList = new ArrayList(); - private Map newPermissionMap; - - private ImagePermissions defaultPermissions; - - private static final Logger LOGGER = Logger.getLogger(ImageCustomPermissionManager.class); - - public ImageCustomPermissionManager() { - super(); - me = this; - GridManager grid = new GridManager(this, 1); - - permissionTable = new ImagePermissionTable(); - - // Panel for the add- and remove buttons - JPanel userButtonPane = new JPanel(); - userButtonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - userButtonPane.setLayout(new BoxLayout(userButtonPane, BoxLayout.LINE_AXIS)); - - btnAddUser = new JButton("Benutzer hinzufügen"); - userButtonPane.add(btnAddUser); - btnRemoveUser = new JButton("Benutzer entfernen"); - userButtonPane.add(btnRemoveUser); - userButtonPane.add(Box.createGlue()); - - // Put everything into the grid - QScrollPane jsp = new QScrollPane(permissionTable); - jsp.setBackground(UIManager.getColor("Table.background")); - grid.add(jsp).fill(true, true).expand(true, true); - grid.nextRow(); - grid.add(userButtonPane).fill(true, false).expand(true, false); - grid.nextRow(); - grid.finish(false); - - // add user button listener - btnAddUser.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - UserListWindow.open(SwingUtilities.getWindowAncestor(me), new UserAddedCallback() { - @Override - public void userAdded(final UserInfo newUser, UserListWindow window) { - // check if we have this user already - for (UserImagePermissions current : permissionList) { - if (current.userId.equals(newUser.userId)) { - LOGGER.debug("User already present in the list, skipping!"); - return; - } - } - // add it to the list with default permissions - permissionList.add(new UserImagePermissions(newUser.userId, new ImagePermissions( - defaultPermissions))); - permissionTable.setData(permissionList, false); - } - }, "Hinzufügen", ownerId); - } - }); - - // delete user button listener - btnRemoveUser.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - final UserImagePermissions selected = permissionTable.getSelectedItem(); - if (selected != null && !permissionList.remove(selected)) { - LOGGER.debug("Could not remove: " + selected); - } - permissionTable.setData(permissionList, false); - } - }); - - // keyboard shortcut - permissionTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put( - KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete"); - permissionTable.getActionMap().put("delete", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ae) { - btnRemoveUser.doClick(); - } - }); - } - - /** - * Initialize the PermissionManager. Note that the given permissionMap and - * defaultPermissions reference - * will get changed when the user interacts with the controls. - * - * @param permissionMap the old permission, to initialize the table with, - * null creates empty table. - * @param defaultPermissions the permissions for a newly added user - * @param ownerId The user to exclude from the add user list. Can be null. - */ - public void initPanel(Map permissionMap, - final ImagePermissions defaultPermissions, String ownerId) { - this.ownerId = ownerId; - this.newPermissionMap = permissionMap == null ? new HashMap() - : permissionMap; - this.defaultPermissions = defaultPermissions; - - permissionList.clear(); - for (Entry e : newPermissionMap.entrySet()) { - permissionList.add(new UserImagePermissions(e.getKey(), e.getValue())); - } - // lexicographic sort on the last names - Collections.sort(permissionList, new Comparator() { - @Override - public int compare(UserImagePermissions o1, UserImagePermissions o2) { - UserInfo u1 = UserCache.find(o1.userId); - UserInfo u2 = UserCache.find(o2.userId); - if (u1 != null && u2 != null) - return FormatHelper.userName(u1).compareTo(FormatHelper.userName(u2)); - else - return 0; - } - }); - permissionTable.setData(permissionList, false); - } - - /** - * Get map with the permissions set in the table of the manager. - * - * @return Map with new custom permissions, null if something went wrong - */ - public Map updatePermissionReferences() { - if (permissionList == null) - return null; - - newPermissionMap.clear(); - - // put permissions of the list into the map - for (UserImagePermissions perm : permissionList) { - newPermissionMap.put(perm.userId, perm.permissions); - } - return newPermissionMap; - } - - /** - * Update the used default permissions of the manager. - * - * @param link - * @param download - * @param edit - * @param admin - */ - public void updateDefaultPermissions(boolean link, boolean download, boolean edit, boolean admin) { - this.defaultPermissions.link = link; - this.defaultPermissions.download = download; - this.defaultPermissions.edit = edit; - this.defaultPermissions.admin = admin; - } - -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LdapFilterConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LdapFilterConfigurator.java deleted file mode 100755 index b4e5a4a8..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LdapFilterConfigurator.java +++ /dev/null @@ -1,219 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.GridBagConstraints; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.ArrayList; -import java.util.List; - -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JPanel; -import javax.swing.JTextField; -import javax.swing.event.ChangeListener; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; - -import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.LdapFilter; -import org.openslx.dozmod.gui.Gui; -import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; -import org.openslx.dozmod.gui.control.table.LectureLdapFilterTable; -import org.openslx.dozmod.gui.control.table.QScrollPane; -import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.gui.helper.MessageType; - -/** - * Widget for network share configuration of lectures - */ -public class LdapFilterConfigurator extends LdapFilterConfiguratorLayout { - - private static final long serialVersionUID = -3336605759245603655L; - private final static Logger LOGGER = Logger.getLogger(LdapFilterConfigurator.class); - private List filterList = null; - - public LdapFilterConfigurator() { - - super(); - - tblFilters.getModel().addTableModelListener(new TableModelListener() { - @Override - public void tableChanged(TableModelEvent e) { - fireChangeEvent(); - } - }); - - tblFilters.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - LdapFilter item = tblFilters.getSelectedItem(); - if (item == null) { - clearInputFields(); - return; - } - // share from the list is selected: fill bottom form and change "Add" to "Apply" - btnDel.setEnabled(true); - txtAttribute.setText(item.attribute); - txtValue.setText(item.value); - btnAdd.setText("Ändern"); - } - }); - - btnAdd.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // check if we are editing an existing share entry or - // creating a new one, check for input either way - LdapFilter input = new LdapFilter(); - - input.attribute = txtAttribute.getText(); - if (input.attribute == null || input.attribute.isEmpty()) { - Gui.showMessageBox("Kein Attribut angegeben", MessageType.ERROR, null, null); - return; - } - input.value = txtValue.getText(); - if (input.value == null) { - input.value = ""; - } - - // either we delete the existing share from the data or we are - // creating a new one, either way add it to the list and update - // the table, if its not present already - if (filterList.contains(input)) { - Gui.showMessageBox("Eintrag bereits vorhanden", MessageType.ERROR, null, null); - return; - } - // now decide whether to create a new entry or update existing one - LdapFilter oldEntry = tblFilters.getSelectedItem(); - if (oldEntry != null) { - // editing existing one, delete it from the internal data - filterList.remove(oldEntry); - } - filterList.add(input); - tblFilters.setData(filterList, false); - clearInputFields(); - } - }); - - btnDel.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // try to delete the selected share - LdapFilter selection = tblFilters.getSelectedItem(); - if (selection == null) { - return; - } - try { - if (!filterList.remove(selection)) { - // false if it was not found - LOGGER.error("Could not remove non-existent filter '" + selection.toString() - + "' from the table data: " + filterList.toString()); - return; - } - // refresh table data - tblFilters.setData(filterList, false); - } catch (Exception ex) { - LOGGER.debug("Failed to remove " + selection.toString() + " from the table data.", ex); - return; - } - } - }); - btnDel.setEnabled(false); - } - - private void clearInputFields() { - btnDel.setEnabled(false); - txtAttribute.setText(null); - txtValue.setText(null); - btnAdd.setText("Hinzufügen"); - } - - public List getState() { - return filterList; - } - - public boolean setState(List data) { - if (data == null) - return false; - if (filterList == null) { - filterList = new ArrayList<>(); - } - filterList = data; - tblFilters.setData(filterList, false); - return true; - } - - protected List listenerList = new ArrayList<>(); - - public void addLdapFilterListTableContentConfigurationChangeEventListener(ChangeListener listener) { - listenerList.add(listener); - } - - public void removeNetshareConfigurationChangeEventListener(ChangeListener listener) { - listenerList.remove(listener); - } - - void fireChangeEvent() { - for (ChangeListener listener : new ArrayList<>(listenerList)) { - listener.stateChanged(null); - } - } - - public void addToChangeMonitor(DialogChangeMonitor changeMonitor) { - changeMonitor.add(tblFilters); - } - -} - -/** - * Internal layout class for this widget - */ -class LdapFilterConfiguratorLayout extends JPanel { - - private static final long serialVersionUID = 6479838641542743622L; - - private final static String HELPTEXT = "Geben Sie hier LDAP Filter ein, die die Sichtbarkeit" - + " der Veranstaltung abhängig vom angemeldeten Benutzer einschränken. Eine Veranstaltung" - + " ist sichtbar, sobald einer der angegebenen Filter zutrifft. Zusätzliche Raumbeschränkungen" - + " greifen weiterhin."; - - protected final LectureLdapFilterTable tblFilters = new LectureLdapFilterTable(); - protected final JTextField txtAttribute, txtValue; - protected final JButton btnAdd, btnDel; - - public LdapFilterConfiguratorLayout() { - GridManager grid = new GridManager(this, 1, true, new Insets(3, 3, 3, 3)); - // top info panel - grid.add(new WordWrapLabel(HELPTEXT)).fill(true, false).expand(true, false); - grid.nextRow(); - // middle filter list - grid.add(new QScrollPane(tblFilters)).fill(true, true).expand(true, true); - grid.nextRow(); - - btnDel = new JButton("Entfernen"); - grid.add(btnDel).anchor(GridBagConstraints.EAST); - grid.nextRow(); - - JPanel pnlNewShare = new JPanel(); - GridManager gridNewFilter = new GridManager(pnlNewShare, 2, true); - pnlNewShare.setBorder(BorderFactory.createTitledBorder("Filter definieren")); - gridNewFilter.add(new QLabel("Attribut")); - txtAttribute = new JTextField(); - gridNewFilter.add(txtAttribute).fill(true, false).expand(true, false); - gridNewFilter.nextRow(); - gridNewFilter.add(new QLabel("Wert")); - txtValue = new JTextField(); - gridNewFilter.add(txtValue).fill(true, false).expand(true, false); - gridNewFilter.nextRow(); - btnAdd = new JButton("Hinzufügen"); - gridNewFilter.add(btnAdd, 2).anchor(GridBagConstraints.EAST); - gridNewFilter.nextRow(); - gridNewFilter.finish(false); - grid.add(pnlNewShare).fill(true, false).expand(true, false); - grid.nextRow(); - grid.finish(false); - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LectureCustomPermissionManager.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LectureCustomPermissionManager.java deleted file mode 100644 index b853f7e2..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LectureCustomPermissionManager.java +++ /dev/null @@ -1,236 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.EventListener; -import java.util.EventObject; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import javax.swing.AbstractAction; -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JPanel; -import javax.swing.KeyStroke; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.event.EventListenerList; - -import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.LecturePermissions; -import org.openslx.bwlp.thrift.iface.UserInfo; -import org.openslx.dozmod.gui.control.table.LecturePermissionTable; -import org.openslx.dozmod.gui.control.table.LecturePermissionTable.UserLecturePermissions; -import org.openslx.dozmod.gui.control.table.QScrollPane; -import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.gui.window.UserListWindow; -import org.openslx.dozmod.gui.window.UserListWindow.UserAddedCallback; - -/** - * Panel including LecturePermissionTable and add/remove buttons for setting - * customLecturePermissions. - */ -/** - * @author joe - * - */ -@SuppressWarnings("serial") -public class LectureCustomPermissionManager extends JPanel { - - /** - * Self reference - */ - private LectureCustomPermissionManager me; - - protected LecturePermissionTable permissionTable; - - protected JButton btnAddUser; - protected JButton btnRemoveUser; - - private final ArrayList permissionList = new ArrayList(); - - private LecturePermissions defaultPermissions; - - private String ownerId = null; - - private static final Logger LOGGER = Logger.getLogger(LectureCustomPermissionManager.class); - - public LectureCustomPermissionManager() { - super(); - me = this; - - GridManager grid = new GridManager(this, 1); - - permissionTable = new LecturePermissionTable(); - - // Panel for the add- and remove buttons - JPanel userButtonPane = new JPanel(); - userButtonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - userButtonPane.setLayout(new BoxLayout(userButtonPane, BoxLayout.LINE_AXIS)); - - btnAddUser = new JButton("Benutzer hinzufügen"); - userButtonPane.add(btnAddUser); - btnRemoveUser = new JButton("Benutzer entfernen"); - userButtonPane.add(btnRemoveUser); - userButtonPane.add(Box.createGlue()); - - // Put everything into the grid - QScrollPane jsp = new QScrollPane(permissionTable); - jsp.setBackground(UIManager.getColor("Table.background")); - grid.add(jsp).fill(true, true).expand(true, true); - grid.nextRow(); - grid.add(userButtonPane).fill(true, false).expand(true, false); - grid.nextRow(); - grid.finish(false); - - // add user button listener - btnAddUser.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - UserListWindow.open(SwingUtilities.getWindowAncestor(me), new UserAddedCallback() { - @Override - public void userAdded(final UserInfo newUser, UserListWindow window) { - // check if we have this user already - for (UserLecturePermissions current : permissionList) { - if (current.userId.equals(newUser.userId)) { - LOGGER.debug("User already present in the list, skipping!"); - return; - } - } - // add it to the list with default permissions - permissionList.add(new UserLecturePermissions(newUser.userId, new LecturePermissions( - defaultPermissions))); - permissionTable.setData(permissionList, false); - fireUserChangeEvent(); - } - }, "Hinzufügen", ownerId); - } - }); - - // delete user button listener - btnRemoveUser.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - final UserLecturePermissions selected = permissionTable.getSelectedItem(); - if (selected != null && !permissionList.remove(selected)) { - LOGGER.debug("Could not remove: " + selected); - } - permissionTable.setData(permissionList, false); - fireUserChangeEvent(); - } - }); - - // keyboard shortcut - permissionTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put( - KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete"); - permissionTable.getActionMap().put("delete", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ae) { - btnRemoveUser.doClick(); - } - }); - permissionTable.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - // TODO: This is stupid; permissionTable should fire an event - // if one of the check boxes changes. - fireUserChangeEvent(); - } - }); - } - - /** - * Initialise the PermissionManager - * - * @param permissionMap the old permission, to initialise the table with, - * null creates empty table. - * @param defaultPermissions the permissions for a newly added user - * @param ownerId The user to exclude in the list do add user. May be null. - */ - public void initPanel(Map permissionMap, - final LecturePermissions defaultPermissions, String ownerId) { - this.ownerId = ownerId; - this.defaultPermissions = defaultPermissions; - permissionList.clear(); - if (permissionMap != null) { - for (Entry e : permissionMap.entrySet()) { - permissionList.add(new UserLecturePermissions(e.getKey(), e.getValue())); - } - } - permissionTable.setData(permissionList, false); - } - - /** - * Get map with the permissions set in the table of the manager. - * - * @return Map with new custom permissions, null if something went wrong - */ - public Map getPermissions() { - Map newPermissionMap = new HashMap<>(permissionList.size()); - // put permissions of the list into the map - for (UserLecturePermissions perm : permissionList) { - newPermissionMap.put(perm.userId, perm.permissions); - } - return newPermissionMap; - } - - /** - * Update the default permissions used by the manager. - * - * @param admin - * @param edit - */ - public void updateDefaultPermissions(boolean admin, boolean edit) { - defaultPermissions.admin = admin; - defaultPermissions.edit = edit; - } - - - /** - * Custom event mechanism to detect changes to the user list - * (Mostly needed for the reactToChange() stuff in LectureDetailsWindow) - */ - protected EventListenerList listenerList = new EventListenerList(); - - /** - * Shared instance, since there is no data attached (yet) - */ - private static final UserChangeEvent CHANGE_EVENT = new UserChangeEvent(); - - public static class UserChangeEvent extends EventObject { - - public UserChangeEvent() { - super(new Object()); - } - } - - public interface UserChangeEventListener extends EventListener { - public void stateChanged(UserChangeEvent event); - } - - public void addUserChangeEventListener(UserChangeEventListener listener) { - listenerList.add(UserChangeEventListener.class, listener); - } - - public void removeUserChangeEventListener(UserChangeEventListener listener) { - listenerList.remove(UserChangeEventListener.class, listener); - } - - void fireUserChangeEvent() { - Object[] listeners = listenerList.getListenerList(); - for (int i = 0; i < listeners.length; i++) { - if (listeners[i] == UserChangeEventListener.class) { - ((UserChangeEventListener) listeners[i + 1]) - .stateChanged(CHANGE_EVENT); - } - } - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetrulesConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetrulesConfigurator.java deleted file mode 100644 index 036f3726..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetrulesConfigurator.java +++ /dev/null @@ -1,449 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.Color; -import java.awt.Insets; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.EventListener; -import java.util.EventObject; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.swing.BorderFactory; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextPane; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.event.EventListenerList; -import javax.swing.text.BadLocationException; -import javax.swing.text.DefaultStyledDocument; -import javax.swing.text.SimpleAttributeSet; -import javax.swing.text.StyleConstants; - -import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.NetDirection; -import org.openslx.bwlp.thrift.iface.NetRule; -import org.openslx.dozmod.gui.Gui; -import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.gui.helper.MessageType; -import org.openslx.dozmod.gui.helper.TextChangeListener; -import org.openslx.util.Util; - -/** - * Widget for netrules configuration of lectures - */ -public class NetrulesConfigurator extends NetrulesConfiguratorLayout { - - private static final long serialVersionUID = -3497629601818983994L; - private final static Logger LOGGER = Logger - .getLogger(NetrulesConfigurator.class); - - private String originalRawRuleText = null; - /** - * Character defining how the rules are parsed, e.g. for whitespace \\s - * Example: "8.8.8.8 80 in" would be split in -hostname "8.8.8.8" -port "80" - * -direction "in" - */ - private static final String FIELD_DELIMITER = "\\s+"; - - private static final Color FOREGROUND_TEXT_COLOR; - - static { - Color fgOrigColor = UIManager.getDefaults().getColor("ColorChooser.foreground"); - if (fgOrigColor == null) { - // use black as fallback - fgOrigColor = Color.BLACK; - } - FOREGROUND_TEXT_COLOR = fgOrigColor; - } - - public NetrulesConfigurator() { - super(); - - final TextChangeListener docListener = new TextChangeListener() { - @Override - public void changed() { - fireNetrulesConfigurationChangeEvent(new NetrulesConfigurationChangeEvent(NetrulesConfigurator.this)); - } - }; - final SimpleAttributeSet as = new SimpleAttributeSet(); - StyleConstants.setForeground(as, FOREGROUND_TEXT_COLOR); - tpNetworkRules.getDocument().addDocumentListener(docListener); - tpNetworkRules.addKeyListener(new KeyAdapter() { - @Override - public void keyTyped(KeyEvent e) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - int pos = tpNetworkRules.getCaretPosition(); - if (pos < 0) { - return; - } - // Odd: On windows, getText() returns the text with CRLF line breaks, - // regardless of what you put into the text box. - // The offsets passed to setCharAttrs() below and the caret position - // you get from getCaretPosition() however have to adhere to the - // text version with just LF, exactly how we created the document. - String text = tpNetworkRules.getText().replace("\r", ""); - if (pos >= text.length()) { - return; - } - int start = text.lastIndexOf('\n', pos == 0 ? 0 : pos - 1); - int end = text.indexOf('\n', pos); - if (start == -1) { - start = 0; - } - if (end == -1) { - end = text.length() - 1; - } - if (end <= start) { - return; - } - tpNetworkRules.getStyledDocument().setCharacterAttributes(start, end - start, as, true); - } - }); - } - }); - } - - public boolean hasChanged() { - return !originalRawRuleText.equalsIgnoreCase(tpNetworkRules.getText()); - } - - /** - * Gets the state of the widget as a list of netrules. Internally it first - * transforms the input text in a list of netrules. - * - * @return the list of rules as parsed by parseNetRules() - */ - public List getState(boolean silent) { - // cleanup the TextPane for network rules if needed - return parseNetRules(silent); - } - - /** - * Sets the state of this widget to the given list of netrules. This will - * internally transform the list to its string representation - * - * @param netrules - * as a list of NetRule to set the state to - */ - public void setState(final List netrules) { - // setText() blanks the text area if null is given, so no null checks - originalRawRuleText = decodeNetRulesToText(netrules); - this.tpNetworkRules.setText(originalRawRuleText); - } - - /** - * "Decodes" the given list of NetRule to a single String. This should be - * used to set the text in the TextPane for the network rules - * - * @param netRulesList - * list of NetRule to decode - * @return String representation of the list of rules - */ - public static String decodeNetRulesToText(final List netRulesList) { - if (netRulesList == null || netRulesList.isEmpty()) - return ""; - - String decodedRules = ""; - Iterator it = netRulesList.iterator(); - while (it.hasNext()) { - String currentLine = ""; - NetRule currentRule = it.next(); - // simple test for validity (since this comes from the server it - // should be correct anyways) - if (currentRule.host.isEmpty() || currentRule.port > 65535) { - LOGGER.error("Invalid rule! Ignoring: " + currentRule.host - + ":" + currentRule.port); - continue; - } - currentLine += currentRule.host + " \t "; - currentLine += currentRule.port + " \t "; - currentLine += currentRule.direction.name(); - decodedRules += currentLine - + (it.hasNext() ? "\n" : ""); - } - return decodedRules; - } - - /** - * Parses the given rawNetRules String to a list of NetRule - * - * @param rawNetRules - * the raw text to be parsed - * @return list of netrules if successful. If any errors occured while - * parsing, null is returned. - */ - public List parseNetRules(boolean silent) { - String rawNetRules = tpNetworkRules.getText().trim(); - List rulesList = new ArrayList(); - if (rawNetRules.isEmpty()) { - return rulesList; - } - - // split it line by line - boolean invalid = false; // True if the rules are invalid and null should be returned - DefaultStyledDocument newdoc = null; - if (!silent) { - newdoc = new DefaultStyledDocument(); // Used to build new document with colors - } - StringBuilder errors = new StringBuilder(); // Error messages to show (if not silent) - int lineNo = 0; // Show line numbers in error messages - Set warnedHosts = new HashSet<>(); // Ask only once about each unknown host - for (String ruleLine : rawNetRules.split("[\r\n]+")) { - if (silent && invalid) - return null; - Color lineColor = null; - LOGGER.debug("Parsing rule: " + ruleLine); - // split the fields and check if we have 3 as expected. - String[] fields = ruleLine.trim().split(FIELD_DELIMITER); - if (fields.length != 3) { - lineNo += addLine(newdoc, ruleLine, Color.RED, true); - // log numbers for fields independently... - LOGGER.debug("Invalid number of fields! Expected 3, got: " + fields.length); - if (fields.length > 3) { - errors.append("Zeile " + lineNo + ": Zu viele Felder.\n"); - } else { - errors.append("Zeile " + lineNo + ": Zu wenig Felder.\n"); - } - invalid = true; - continue; - } - // Have 3 fields, pretty up - String ruleDirection = fields[2].toUpperCase(); - ruleLine = fields[0] + " \t " + fields[1] + " \t " + ruleDirection; - - // start to check fields one by one from the last to the first .... - // check net direction: accept either 'in' or 'out' (case - // insensitive) - // TODO support combined 'in/out' rules - if (!ruleDirection.equals("IN") && !ruleDirection.equals("OUT")) { - lineNo += addLine(newdoc, ruleLine, Color.RED, true); - LOGGER.debug("Invalid net direction! Expected 'in' or out'. Got: " + ruleDirection); - errors.append("Zeile " + lineNo + ": Ungültige Richtung. Bitte nutzen Sie 'IN' bzw. 'OUT'.\n"); - invalid = true; - continue; - } - // check port: accept if >= 0 and <= 65535 - int port = Util.parseInt(fields[1], -1); - - // port = 0 means match only host (all protocols and ports) - if (port < 0 || port > 65535) { - lineNo += addLine(newdoc, ruleLine, Color.RED, true); - LOGGER.debug("Invalid port! Got: " + port); - errors.append("Zeile " + lineNo + ": Ungültiger Port. Gültiger Bereich ist 0-65535.\n"); - invalid = true; - continue; - } - // check hostname: bit more to do here - // for IPs and/or resolvable hostnames we make use of java.net's - // InetAddress.getByName() method which checks the validity of - // an IP-Address represented by a string or if the given hostname - // is resolvable. If any of these happen, we have a valid hostname. - // Non-resolvable hostnames are handled differently, see after the - // try/catch-block - InetAddress ruleHost = null; - try { - // TODO: Find a way to reliably set a timeout (external DNS library?) - // Otherwise just remove this check - ruleHost = InetAddress.getByName(fields[0]); - } catch (UnknownHostException e) { - // might be good to see this exception in the log file - // LOGGER.debug("Invalid hostname (java.net): ", e); - } - if (ruleHost == null) { - // either invalid IP-Address or an invalid resolvable hostname - // however it might also be a non-resolvable hostname that would - // be valid in the actual pool-rooms, so lets check its syntax - // according to: http://tools.ietf.org/html/rfc1034#section-3.1 - LOGGER.debug("Invalid host/IP! Got: " + fields[0]); - String checkRes = checkHostnameSimple(fields[0]); - if (checkRes == null) { - if (!silent - && !warnedHosts.contains(fields[0]) - && !Gui.showMessageBox("Konnte '" + fields[0] - + "' nicht auflösen. Wollen Sie diesen Hostnamen trotzdem verwenden?", - MessageType.WARNING_RETRY, null, null)) { - invalid = true; - } - warnedHosts.add(fields[0]); - lineColor = Color.ORANGE; - } else { - lineNo += addLine(newdoc, ruleLine, Color.RED, true); - errors.append("Zeile " + lineNo + ": " + checkRes + "\n"); - invalid = true; - continue; - } - } - // Made it to here - line is valid - lineNo += addLine(newdoc, ruleLine, lineColor, false); - rulesList.add(new NetRule(NetDirection.valueOf(ruleDirection), fields[0], port)); - } - if (!silent && errors.length() != 0) { - Gui.showMessageBox("Fehler beim Auswerten der angegebenen Netzwerkregeln.\n\n" + errors.toString() - + "\nBitte geben Sie die Regeln zeilenweise im Format\n" - + " \n" - + "an.", - MessageType.ERROR, null, null); - } - if (newdoc != null) { - tpNetworkRules.setDocument(newdoc); - } - if (invalid) { - return null; - } - // Success - return rulesList; - } - - private int addLine(DefaultStyledDocument doc, String line, Color color, boolean bold) { - if (doc == null) - return 0; - if (color == null) { - color = FOREGROUND_TEXT_COLOR; - } - SimpleAttributeSet attrs = new SimpleAttributeSet(); - StyleConstants.setForeground(attrs, color); - StyleConstants.setBold(attrs, bold); - try { - doc.insertString(doc.getLength(), line + "\n", attrs); - } catch (BadLocationException e) { - LOGGER.warn("Cannot append to new textbox document", e); - } - return 1; - } - - /** - * Very simple hostname check for the given String. This will only check for - * some requirements of valid hostnames as stated in - * http://tools.ietf.org/html/rfc1034#section-3.1 To recap: max length of - * the whole hostname must be < 254 ASCII characters, all domain labels - * (between two dots) must be between 1 and 63 chars long and domain labels - * can only contain digits, letters and hyphen. (Note: we also accept - * forward slash to accept subnets!) - * - * @param hostname the hostname to check for syntactical validity - * @return null if valid, error string otherwise - */ - private String checkHostnameSimple(final String hostname) { - if (hostname.length() > 254) { - return "Hostname ist zu lang."; - } - // split by '.' to get domain levels - boolean allNumeric = true; - String[] domainLabels = hostname.split("\\."); - for (String domainLabel : domainLabels) { - if (domainLabel.length() > 63) { - // fail since domain level should be max 63 chars - return "Domain-Ebene '" + domainLabel + "' länger als 63 Zeichen."; - } - if (Util.parseInt(domainLabel, -1) == -1) { - allNumeric = false; - } - // checking for valid chars is pointless with punycode - } - if (allNumeric && domainLabels.length != 4) { - return "Unvollständige IP-Adresse."; - } - return null; - } - - /** - * Custom event mechanism to detect changes to the netrules list (Mostly - * needed for the reactToChange() stuff in LectureDetailsWindow) - */ - protected EventListenerList listenerList = new EventListenerList(); - - public class NetrulesConfigurationChangeEvent extends EventObject { - - private static final long serialVersionUID = -8779550754760035845L; - - public NetrulesConfigurationChangeEvent(Object source) { - super(source); - } - } - - public interface NetrulesConfigurationChangeEventListener extends - EventListener { - public void stateChanged(NetrulesConfigurationChangeEvent event); - } - - public void addNetrulesConfigurationChangeEventListener( - NetrulesConfigurationChangeEventListener listener) { - listenerList.add(NetrulesConfigurationChangeEventListener.class, - listener); - } - - public void removeNetrulesConfigurationChangeEventListener( - NetrulesConfigurationChangeEventListener listener) { - listenerList.remove(NetrulesConfigurationChangeEventListener.class, - listener); - } - - void fireNetrulesConfigurationChangeEvent( - NetrulesConfigurationChangeEvent evt) { - Object[] listeners = listenerList.getListenerList(); - for (int i = 0; i < listeners.length; i++) { - if (listeners[i] == NetrulesConfigurationChangeEventListener.class) { - ((NetrulesConfigurationChangeEventListener) listeners[i + 1]) - .stateChanged(evt); - } - } - } -} - -/** - * Internal layout class for this widget - */ -class NetrulesConfiguratorLayout extends JPanel { - - private static final long serialVersionUID = 5266120380443817325L; - private final static String txtNetworkOptionsTitle = "Netzwerk Einstellungen"; - private final static String txtNetworkOptionsDesc = "Wenn Sie den Internetzugriff deaktiviert haben," - + " können Sie hier Ausnahmen definieren (Whitelist)." - + " Bitte definieren Sie Ihre Regeln im Format\n .\n" - + "Sie können Port 0 angeben, was sämtlichen TCP und UDP Ports eines Hosts entspricht.\n\n" - + "Wenn Sie Internetzugriff aktivieren, hat diese Liste den gegenteiligen Effekt"; - private final static String txtNetworkRulesTitle = "Netzwerkregeln"; - - private final JPanel pnlNetworkOptions; - protected final JTextPane tpNetworkRules; - - public NetrulesConfiguratorLayout() { - - GridManager grid = new GridManager(this, 1, true, - new Insets(5, 5, 5, 5)); - - // middle panel for network rules - pnlNetworkOptions = new JPanel(); - GridManager gridNetworkOptions = new GridManager(pnlNetworkOptions, 1, - true, new Insets(2, 2, 2, 2)); - pnlNetworkOptions.setBorder(BorderFactory - .createTitledBorder(txtNetworkOptionsTitle)); - tpNetworkRules = new JTextPane(); - - JScrollPane scpNetworkRules = new JScrollPane(tpNetworkRules, - JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, - JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - pnlNetworkOptions.setBorder(BorderFactory - .createTitledBorder(txtNetworkRulesTitle)); - gridNetworkOptions - .add(new WordWrapLabel(txtNetworkOptionsDesc)) - .fill(true, false).expand(true, false); - gridNetworkOptions.nextRow(); - gridNetworkOptions.add(scpNetworkRules).fill(true, true) - .expand(true, true); - gridNetworkOptions.finish(false); - - // build the final grid - grid.add(pnlNetworkOptions).fill(true, true).expand(true, true); - grid.finish(false); - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetshareConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetshareConfigurator.java deleted file mode 100644 index d80ba8b3..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetshareConfigurator.java +++ /dev/null @@ -1,374 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.util.ArrayList; -import java.util.EventListener; -import java.util.EventObject; -import java.util.List; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JTextField; -import javax.swing.event.EventListenerList; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; - -import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.NetShare; -import org.openslx.bwlp.thrift.iface.NetShareAuth; -import org.openslx.dozmod.gui.Gui; -import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; -import org.openslx.dozmod.gui.control.ComboBox.ComboBoxRenderer; -import org.openslx.dozmod.gui.control.table.NetshareTable; -import org.openslx.dozmod.gui.control.table.QScrollPane; -import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.gui.helper.MessageType; -import org.openslx.dozmod.util.FormatHelper; - -/** - * Widget for network share configuration of lectures - */ -public class NetshareConfigurator extends NetshareConfiguratorLayout { - - private static final long serialVersionUID = -3336605759245603655L; - private final static Logger LOGGER = Logger.getLogger(NetshareConfigurator.class); - private List tblNetshareData = null; - - // mount points / win drive letters - ideally, we would check whether the image is linux or windows based - // and either show a drive selection list like this one, or a textfield for a user-defined mount point... - private Character[] mountPoints = { 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', - 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; - - public NetshareConfigurator() { - super(); - tblNetshare.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - NetShare item = tblNetshare.getSelectedItem(); - // ugly block-wise sets, but only one test needed compared to - // doing lots of item != null ? ... : ... - if (item == null) { - clearInputFields(); - return; - } - // share from the list is selected: fill bottom form and change "Add" to "Apply" - btnDel.setEnabled(true); - tfSharePath.setText(item.path); - tfShareName.setText(item.displayname); - tfUsername.setText(item.username); - tfPassword.setText(item.password); - cboNetshareAuth.setSelectedItem(item.auth); - cboNetshareMountPoint.setSelectedItem(Character.valueOf(item.mountpoint.charAt(0))); - btnAdd.setText("Ändern"); - } - }); - - cboNetshareMountPoint.setModel(new DefaultComboBoxModel(mountPoints)); - cboNetshareMountPoint.setSelectedItem(null); - - // combobox for share authentication types - cboNetshareAuth.setModel(new DefaultComboBoxModel(NetShareAuth.values())); - cboNetshareAuth.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - NetShareAuth selectedAuth = cboNetshareAuth.getItemAt(cboNetshareAuth.getSelectedIndex()); - if (selectedAuth == null) - return; - boolean activate = selectedAuth == NetShareAuth.OTHER_USER; - // username field is needed to either special or guest user - tfUsername.setEnabled(activate); - lblUsername.setEnabled(activate); - tfPassword.setEnabled(activate); - lblPassword.setEnabled(activate); - chkShowPass.setEnabled(activate); - } - }); - cboNetshareAuth.setSelectedItem(null); - - btnAdd.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // check if we are editing an existing share entry or - // creating a new one, check for input either way - NetShare input = new NetShare(); - - input.path = tfSharePath.getText(); - if (input.path == null || input.path.isEmpty()) { - lblError.setText("Kein Pfad angegeben!"); - return; - } - String inputShareName = tfShareName.getText(); - if (inputShareName.isEmpty()) { - lblError.setText("Kein Anzeigename angegeben!"); - return; - } - input.displayname = inputShareName; - - NetShareAuth inputNetShareAuth = cboNetshareAuth - .getItemAt(cboNetshareAuth.getSelectedIndex()); - if (inputNetShareAuth == null) { - lblError.setText("Kein Authentifizierungstyp angegeben!"); - return; - } - input.auth = inputNetShareAuth; - switch (inputNetShareAuth) { - case LOGIN_USER: - // this uses the bwLehrpool client's logged in user - // we don't need to have anything - break; - case OTHER_USER: - // save given username/password - input.username = tfUsername.getText(); - input.password = new String(tfPassword.getPassword()); - if (input.username.isEmpty()) { - lblError.setText("Kein Nutzername angegeben!"); - return; - } - break; - default: - input = null; - break; - } - if (input == null) { - lblError.setText("Fehlerhafte Eingabe"); - LOGGER.debug("Bad input, aborting."); - return; - } - // now check for optional mount path - Character inputMountPoint = cboNetshareMountPoint - .getItemAt(cboNetshareMountPoint.getSelectedIndex()); - if (inputMountPoint == null) { - lblError.setText("Kein Ziel angegeben!"); - return; - } - input.mountpoint = inputMountPoint.toString(); - // now decide whether to create a new entry or update existing one - NetShare oldEntry = tblNetshare.getSelectedItem(); - if (oldEntry != null) { - // editing existing one, delete it from the internal data - if (!tblNetshareData.remove(oldEntry)) { - lblError.setText("Änderung fehlgeschlagen!"); - LOGGER.debug("Failed to remove selected share for replacement: " + oldEntry); - return; - } - tblNetshare.setData(tblNetshareData, false); - } - // either we delete the existing share from the data or we are - // creating a new one, either way add it to the list and update - // the table, if its not present already - if (tblNetshareData.contains(input)) { - lblError.setText("Existiert bereits!"); - LOGGER.error("Network share already in the list, aborting."); - return; - } - // if a password is set, warn the user about its unsafe storage - // which we might want to implement one day... - if (input.password != null && !input.password.isEmpty()) { - if (!Gui.showMessageBox( - "Das eingebene Passwort wird im Klartext gespeichert " - + "und ist in der VM für jeden Nutzer sichtbar.\n" - + "Verwenden Sie auf keinen Fall sicherheitskritische Passwörter!" - + "\n\nMöchten Sie diesen Netzlaufwerk trotzdem hinzufügen?", - MessageType.QUESTION_YESNO, LOGGER, null)) { - return; - } - } - lblError.setText(null); - tblNetshareData.add(input); - tblNetshare.setData(tblNetshareData, false); - clearInputFields(); - } - }); - - btnDel.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // try to delete the selected share - NetShare selection = tblNetshare.getSelectedItem(); - if (selection == null) { - return; - } - try { - if (!tblNetshareData.remove(selection)) { - // false if it was not found - LOGGER.error("Could not remove non-existant network share '" + selection.toString() - + "' from the table data: " + tblNetshareData.toString()); - return; - } - // refresh table data - tblNetshare.getModel().setData(tblNetshareData); - } catch (Exception ex) { - LOGGER.debug("Failed to remove " + selection.toString() + " from the table data.", ex); - return; - } - } - }); - - chkShowPass.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() != ItemEvent.SELECTED) { - tfPassword.setEchoChar('*'); - } else { - tfPassword.setEchoChar((char) 0); - } - } - }); - chkShowPass.setEnabled(false); - tfUsername.setEnabled(false); - lblUsername.setEnabled(false); - tfPassword.setEnabled(false); - lblPassword.setEnabled(false); - } - - private void clearInputFields() { - btnDel.setEnabled(false); - tfSharePath.setText(null); - tfShareName.setText(null); - tfUsername.setText(null); - tfPassword.setText(null); - cboNetshareAuth.setSelectedItem(null); - cboNetshareMountPoint.setSelectedItem(null); - btnAdd.setText("Hinzufügen"); - } - public List getState() { - return tblNetshareData; - } - - public boolean setState(List data) { - if (data == null) - return false; - if (tblNetshareData == null) { - tblNetshareData = new ArrayList<>(); - } - tblNetshareData = data; - tblNetshare.setData(tblNetshareData, false); - return true; - } - - public void addTableModelListener(TableModelListener listener) { - tblNetshare.getModel().addTableModelListener(listener); - } - - public void addToChangeMonitor(DialogChangeMonitor changeMonitor) { - changeMonitor.add(tblNetshare); - } -} - -/** - * Internal layout class for this widget - */ -class NetshareConfiguratorLayout extends JPanel { - - private static final long serialVersionUID = 6479525981542743622L; - - private final static String txtNetshareDesc = "Hier können Sie Netzlaufwerke angeben," - + " die automatisch beim Start der Veranstaltung eingebunden werden sollen." - + " Der Platzhalter %loginuser% wird im Pfad durch den Loginnamen des Nutzers ersetzt."; - - protected final QLabel lblShareAuth, lblSharePath, lblShareName, lblMountPoint, lblUsername, lblPassword, - lblError; - protected final NetshareTable tblNetshare = new NetshareTable(); - protected final JTextField tfSharePath, tfShareName, tfUsername; - protected final JPasswordField tfPassword; - protected final JButton btnAdd, btnDel; - protected final JCheckBox chkShowPass; - protected final ComboBox cboNetshareAuth = new ComboBox<>(new ComboBoxRenderer() { - @Override - public String renderItem(NetShareAuth item) { - if (item == null) - return null; - return FormatHelper.netShareAuthName(item); - } - }); - protected final ComboBox cboNetshareMountPoint = new ComboBox<>(new ComboBoxRenderer() { - @Override - public String renderItem(Character letter) { - if (letter == null) - return null; - return letter.toString() + ":"; - } - }); - - public NetshareConfiguratorLayout() { - GridManager grid = new GridManager(this, 5, true, new Insets(3, 3, 3, 3)); - // top info panel - grid.add(new JLabel(txtNetshareDesc), 5).fill(true, false).expand(true, false); - grid.nextRow(); - // middle netshare list - grid.add(new QScrollPane(tblNetshare), 5).fill(true, true).expand(true, true); - grid.nextRow(); - - JPanel pnlNewShare = new JPanel(); - GridManager gridNewShare = new GridManager(pnlNewShare, 6, true); - pnlNewShare.setBorder(BorderFactory.createTitledBorder("Details")); - lblSharePath = new QLabel("Pfad"); - gridNewShare.add(lblSharePath); - tfSharePath = new JTextField(); - gridNewShare.add(tfSharePath, 5).fill(true, false).expand(true, false); - gridNewShare.nextRow(); - // bottom form to add a new share - lblShareName = new QLabel("Anzeigename"); - lblMountPoint = new QLabel("Ziel"); - tfShareName = new JTextField(); - // extra panel for fancy layout purposes... - JPanel pnlShareName = new JPanel(); - pnlShareName.setLayout(new BoxLayout(pnlShareName, BoxLayout.LINE_AXIS)); - pnlShareName.add(lblShareName); - pnlShareName.add(tfShareName); - pnlShareName.add(lblMountPoint); - pnlShareName.add(cboNetshareMountPoint); - gridNewShare.add(lblShareName); - gridNewShare.add(pnlShareName, 5).fill(true, false).expand(true, false); - gridNewShare.nextRow(); - lblShareAuth = new QLabel("Authentifizierung"); - gridNewShare.add(lblShareAuth); - gridNewShare.add(cboNetshareAuth, 5).fill(true, false).expand(true, false); - gridNewShare.nextRow(); - lblUsername = new QLabel("Username"); - gridNewShare.add(lblUsername); - tfUsername = new JTextField(20); - gridNewShare.add(tfUsername, 2).fill(true, false).expand(true, false); - lblPassword = new QLabel("Passwort"); - gridNewShare.add(lblPassword); - tfPassword = new JPasswordField(20); - gridNewShare.add(tfPassword, 2).fill(true, false).expand(true, false); - gridNewShare.nextRow(); - chkShowPass = new JCheckBox("Passwort anzeigen"); - JPanel pnlShowPass = new JPanel(); - pnlShowPass.setLayout(new BoxLayout(pnlShowPass, BoxLayout.LINE_AXIS)); - pnlShowPass.add(Box.createGlue()); - pnlShowPass.add(chkShowPass, BorderLayout.LINE_END); - gridNewShare.add(pnlShowPass, 6).fill(true, false).expand(true, false); - gridNewShare.nextRow(); - grid.add(pnlNewShare, 5).fill(true, false).expand(true, false); - grid.nextRow(); - // bottom panel for right-aligned button... - JPanel pnlButtonAdd = new JPanel(); - pnlButtonAdd.setLayout(new BoxLayout(pnlButtonAdd, BoxLayout.LINE_AXIS)); - btnAdd = new JButton("Hinzufügen"); - btnDel = new JButton("Entfernen"); - lblError = new QLabel(""); - lblError.setForeground(Color.RED); - pnlButtonAdd.add(lblError); - pnlButtonAdd.add(Box.createGlue()); - pnlButtonAdd.add(btnAdd, BorderLayout.LINE_END); - pnlButtonAdd.add(btnDel, BorderLayout.LINE_END); - grid.add(pnlButtonAdd, 5).fill(true, false).expand(true, false); - grid.finish(false); - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/PersonLabel.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/PersonLabel.java index a0071824..7c53bf96 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/PersonLabel.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/PersonLabel.java @@ -11,7 +11,7 @@ import javax.swing.UIManager; import org.openslx.bwlp.thrift.iface.UserInfo; import org.openslx.dozmod.gui.helper.ColorUtil; import org.openslx.dozmod.util.FormatHelper; -import org.openslx.dozmod.util.OpenLinks; +import org.openslx.dozmod.util.DesktopEnvironment; /** * A label for displaying a {@link UserInfo} object. Supports a callback event @@ -91,7 +91,7 @@ public class PersonLabel extends QLabel { public void clicked(UserInfo user) { if (user == null || user.eMail == null) return; - OpenLinks.sendMail(user.eMail, null); + DesktopEnvironment.sendMail(user.eMail, null); } }; diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/RunscriptConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/RunscriptConfigurator.java deleted file mode 100644 index 3378294c..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/RunscriptConfigurator.java +++ /dev/null @@ -1,263 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.Color; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; -import java.util.EventListener; -import java.util.EventObject; - -import javax.swing.Box; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.event.EventListenerList; - -import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; -import org.openslx.dozmod.gui.control.ComboBox.ComboBoxRenderer; -import org.openslx.dozmod.gui.control.RunscriptConfigurator.RunscriptType; -import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.gui.helper.TextChangeListener; - -/** - * Widget for advanced configuration options for lectures. This handles - * following options - Network rules - Runscript - USB - */ -public class RunscriptConfigurator extends RunscriptConfiguratorLayout { - - private static final long serialVersionUID = -3497629601818983994L; - - public static enum RunscriptType { - SHELL("Shellskript", "sh"), BATCH("Windows-Batch", "bat"); - - private final String displayName; - private final String extension; - - private RunscriptType(String name, String extension) { - this.displayName = name; - this.extension = extension; - } - - @Override - public String toString() { - return extension + " (" + displayName + ")"; - } - } - - public RunscriptConfigurator() { - super(); - - final TextChangeListener docListener = new TextChangeListener() { - @Override - public void changed() { - fireRunscriptConfigurationChangeEvent(new RunscriptConfigurationChangeEvent( - new Object())); - } - }; - taRunScript.getDocument().addDocumentListener(docListener); - cboRunscriptType.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - fireRunscriptConfigurationChangeEvent(new RunscriptConfigurationChangeEvent( - new Object())); - } - }); - cboRunscriptType.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() { - @Override - public void keyReleased(KeyEvent e) { - fireRunscriptConfigurationChangeEvent(new RunscriptConfigurationChangeEvent( - new Object())); - } - }); - } - - private void setError(final String msg) { - lblError.setText(msg); - } - /** - * Gets the runscript as String. The chosen interpreter will get encoded as - * the first line of the script. - * - * @return runscript as String. If no text was entered, returns a empty - * string. - */ - public String getState() { - setError(""); // fill remove any prior errors, we'll reset them if needed - // handle user input, this is tricky since - // * either an item has been selected -> editorContent will be of our enum type - // * user typed its own interpreter into the box -> editorContent will be a castable String - String extension = null; - Object cboContent = cboRunscriptType.getEditor().getItem(); - if (cboContent instanceof RunscriptType) { - extension = ((RunscriptType) cboContent).extension; - } else if (cboContent instanceof String) { - extension = (String) cboContent; - } - String taInputText = taRunScript.getText(); - if (taInputText.isEmpty()) - return ""; - if (extension == null || extension.isEmpty()) { - // this should never happen, so return null to report this invalid state - setError("Fehlende Dateinamenerweiterung!"); - return null; - } - setError(""); - return "ext=" + extension + "\n" + taInputText; - } - - /** - * Sets the state of this widget to the given AdvancedConfiguration. Basicly - * this sets the content of the text areas to the corresponding network - * rules/runscript as given by the AdvancedConfiguration object - * - * @param config - * AdvancedConfiguration to set the state to - */ - public void setState(final String config) { - if (config == null || config.isEmpty()) { - cboRunscriptType.setSelectedItem(null); - taRunScript.setText(""); - return; - } - String extensionHeader = null; - try { - BufferedReader reader = new BufferedReader(new StringReader(config)); - extensionHeader = reader.readLine(); - reader.close(); - } catch (IOException e) { - // swallow ... - } - if (extensionHeader != null) { - // we should have following format: ext= - // e.g. ext=sh - extensionHeader = extensionHeader.replace("ext=", ""); - for (RunscriptType type : RunscriptType.values()) { - if (type.extension.equals(extensionHeader)) { - cboRunscriptType.setSelectedItem(type); - // mark that we found it by nulling the shebang... - extensionHeader = null; - continue; - } - } - if (extensionHeader != null) { - // user specific shebang, so just write the text to the cbo - cboRunscriptType.getEditor().setItem(extensionHeader); - } - } - // finished with the interpreter, remove that line from the given config - // before setting that text - taRunScript.setText(config.replaceFirst("^ext=.*\n", "")); - } - - /** - * Custom event mechanism to detect changes to the user list (Mostly needed - * for the reactToChange() stuff in LectureDetailsWindow) - */ - protected EventListenerList listenerList = new EventListenerList(); - - public class RunscriptConfigurationChangeEvent extends EventObject { - - private static final long serialVersionUID = -8779550754760035845L; - - public RunscriptConfigurationChangeEvent(Object source) { - super(source); - } - } - - public interface RunscriptConfigurationChangeEventListener extends - EventListener { - public void stateChanged(RunscriptConfigurationChangeEvent event); - } - - public void addRunscriptConfigurationChangeEventListener( - RunscriptConfigurationChangeEventListener listener) { - listenerList.add(RunscriptConfigurationChangeEventListener.class, - listener); - } - - public void removeRunscriptConfigurationChangeEventListener( - RunscriptConfigurationChangeEventListener listener) { - listenerList.remove(RunscriptConfigurationChangeEventListener.class, - listener); - } - - void fireRunscriptConfigurationChangeEvent( - RunscriptConfigurationChangeEvent evt) { - Object[] listeners = listenerList.getListenerList(); - for (int i = 0; i < listeners.length; i++) { - if (listeners[i] == RunscriptConfigurationChangeEventListener.class) { - ((RunscriptConfigurationChangeEventListener) listeners[i + 1]) - .stateChanged(evt); - } - } - } - - public void addToChangeMonitor(DialogChangeMonitor changeMonitor) { - changeMonitor.add(taRunScript); - changeMonitor.addEditableCombo(cboRunscriptType, null); - } - -} - -/** - * Internal layout class for the advanced configurator (to keep it clean even - * for widgets) - */ -class RunscriptConfiguratorLayout extends JPanel { - - private static final long serialVersionUID = 648729071828404053L; - - private final static String txtRunScriptDesc = "Ein hier eingetragenes Skript wird nach dem Start dieser VM automatisch ausgeführt."; - protected final QLabel lblError; - protected final JTextArea taRunScript; - protected final ComboBox cboRunscriptType; - - public RunscriptConfiguratorLayout() { - - GridManager grid = new GridManager(this, 2, true, new Insets(5, 5, 5, 5)); - taRunScript = new JTextArea("", 5, 20); - JScrollPane scpRunScript = new JScrollPane(taRunScript, - JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, - JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - taRunScript.setLineWrap(true); - taRunScript.setWrapStyleWord(true); - grid.add(new WordWrapLabel(txtRunScriptDesc, false, true), 2) - .fill(true, false).expand(true, false); - grid.nextRow(); - cboRunscriptType = new ComboBox( - new ComboBoxRenderer() { - @Override - public String renderItem(RunscriptType item) { - if (item == null) - return null; - return item.toString(); - } - }); - cboRunscriptType.setModel(new DefaultComboBoxModel( - RunscriptType.values())); - ; - cboRunscriptType.setEditable(true); - grid.add(new QLabel("Dateinamenserweiterung: ")).fill(false, false) - .expand(false, false); - grid.add(cboRunscriptType).fill(true, false) - .expand(true, false); - grid.nextRow(); - grid.add(scpRunScript, 2).fill(true, true).expand(true, true); - grid.nextRow(); - lblError = new QLabel(""); - lblError.setForeground(Color.RED); - JPanel pnlError = new JPanel(); - pnlError.add(Box.createGlue()); - pnlError.add(lblError); - pnlError.add(Box.createGlue()); - grid.add(pnlError, 2).fill(true, false).expand(true, false); - grid.finish(false); - - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/BwIDMLinkWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/BwIDMLinkWindow.java deleted file mode 100644 index 951b9f0c..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/BwIDMLinkWindow.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.openslx.dozmod.gui.window; - -import java.awt.Frame; -import java.awt.GridBagConstraints; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.net.URISyntaxException; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextArea; - -import org.apache.log4j.Logger; -import org.openslx.dozmod.authentication.ShibbolethEcp; -import org.openslx.dozmod.gui.Gui; -import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.gui.helper.UiFeedback; -import org.openslx.dozmod.util.OpenLinks; - -/** - * Class for showing window with button to open registration page in browser. - */ -@SuppressWarnings("serial") -public class BwIDMLinkWindow extends JDialog implements UiFeedback { - private static final String title = "Registrierung erforderlich"; - private static final String infoText = "" - + "Sie sind nicht bei bwLehrpool registriert. " - + "Bitte rufen Sie die angegebene Seite auf um sich zu registrieren und versuchen Sie es erneut." - + ""; - - protected JButton btnLink; - protected JButton OkButton; - - private static final Logger LOGGER = Logger.getLogger(BwIDMLinkWindow.class); - - /** - * Don't use this, use static function open instead! - */ - public BwIDMLinkWindow(Frame modalParent) { - super(modalParent, title, modalParent != null ? ModalityType.APPLICATION_MODAL - : ModalityType.MODELESS); - - final BwIDMLinkWindow me = this; - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - - // panel for the border. - JPanel contentPanel = new JPanel(); - contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(contentPanel); - GridManager grid = new GridManager(contentPanel, 1); - - // infotext - JLabel infoLabel = new JLabel(infoText); - infoLabel.setBorder(BorderFactory.createTitledBorder("Hinweis")); - grid.add(infoLabel).fill(true, true).expand(true, true).anchor(GridBagConstraints.CENTER); - grid.nextRow(); - - // button for opening the link - btnLink = new JButton("Seite im Browser öffnen"); - btnLink.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - try { - OpenLinks.openWebpageUri(ShibbolethEcp.getRegistrationUrl().toURI()); - } catch (URISyntaxException e1) { - LOGGER.error("Could not convert from url to uri: ", e1); - } - } - }); - - grid.add(btnLink).anchor(GridBagConstraints.CENTER).fill(false, false).expand(false, false); - grid.nextRow(); - - // text area for copying the link if needed. - JTextArea linkText = new JTextArea(ShibbolethEcp.getRegistrationUrl().toString()); - linkText.setEditable(false); - linkText.setMaximumSize(linkText.getPreferredSize()); - linkText.setMinimumSize(linkText.getPreferredSize()); - grid.add(linkText).anchor(GridBagConstraints.CENTER).fill(false, false).expand(false, false); - grid.nextRow(); - - // Ok button on the bottom - JPanel bottomPane = new JPanel(); - bottomPane.setLayout(new BoxLayout(bottomPane, BoxLayout.LINE_AXIS)); - bottomPane.add(Box.createHorizontalGlue()); - - // close/ok button - OkButton = new JButton("Schließen"); - OkButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - me.dispose(); - } - }); - bottomPane.add(OkButton); - - grid.add(bottomPane).fill(true, false).expand(true, false); - grid.nextRow(); - grid.finish(false); - - // Scale window with font - setMinimumSize(Gui.getScaledDimension(500, 200)); - setPreferredSize(getMinimumSize()); - setLocationRelativeTo(modalParent); - } - - /** - * Open a new window for showing the registration page in browser. - * - * @param modalParent the parent of the window. - */ - public static void open(Frame modalParent) { - new BwIDMLinkWindow(modalParent).setVisible(true); - } - - @Override - public boolean wantConfirmQuit() { - return false; - } - - @Override - public void escapePressed() { - dispose(); - } -} \ No newline at end of file diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/BwIdmLinkWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/BwIdmLinkWindow.java new file mode 100644 index 00000000..f97f0330 --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/BwIdmLinkWindow.java @@ -0,0 +1,131 @@ +package org.openslx.dozmod.gui.window; + +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.net.URISyntaxException; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextArea; + +import org.apache.log4j.Logger; +import org.openslx.dozmod.authentication.ShibbolethEcp; +import org.openslx.dozmod.gui.Gui; +import org.openslx.dozmod.gui.helper.GridManager; +import org.openslx.dozmod.gui.helper.UiFeedback; +import org.openslx.dozmod.util.DesktopEnvironment; + +/** + * Class for showing window with button to open registration page in browser. + */ +@SuppressWarnings("serial") +public class BwIdmLinkWindow extends JDialog implements UiFeedback { + private static final String title = "Registrierung erforderlich"; + private static final String infoText = "" + + "Sie sind nicht bei bwLehrpool registriert. " + + "Bitte rufen Sie die angegebene Seite auf um sich zu registrieren und versuchen Sie es erneut." + + ""; + + protected JButton btnLink; + protected JButton OkButton; + + private static final Logger LOGGER = Logger.getLogger(BwIdmLinkWindow.class); + + /** + * Don't use this, use static function open instead! + */ + public BwIdmLinkWindow(Frame modalParent) { + super(modalParent, title, modalParent != null ? ModalityType.APPLICATION_MODAL + : ModalityType.MODELESS); + + final BwIdmLinkWindow me = this; + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + // panel for the border. + JPanel contentPanel = new JPanel(); + contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + add(contentPanel); + GridManager grid = new GridManager(contentPanel, 1); + + // infotext + JLabel infoLabel = new JLabel(infoText); + infoLabel.setBorder(BorderFactory.createTitledBorder("Hinweis")); + grid.add(infoLabel).fill(true, true).expand(true, true).anchor(GridBagConstraints.CENTER); + grid.nextRow(); + + // button for opening the link + btnLink = new JButton("Seite im Browser öffnen"); + btnLink.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + DesktopEnvironment.openWebpageUri(ShibbolethEcp.getRegistrationUrl().toURI()); + } catch (URISyntaxException e1) { + LOGGER.error("Could not convert from url to uri: ", e1); + } + } + }); + + grid.add(btnLink).anchor(GridBagConstraints.CENTER).fill(false, false).expand(false, false); + grid.nextRow(); + + // text area for copying the link if needed. + JTextArea linkText = new JTextArea(ShibbolethEcp.getRegistrationUrl().toString()); + linkText.setEditable(false); + linkText.setMaximumSize(linkText.getPreferredSize()); + linkText.setMinimumSize(linkText.getPreferredSize()); + grid.add(linkText).anchor(GridBagConstraints.CENTER).fill(false, false).expand(false, false); + grid.nextRow(); + + // Ok button on the bottom + JPanel bottomPane = new JPanel(); + bottomPane.setLayout(new BoxLayout(bottomPane, BoxLayout.LINE_AXIS)); + bottomPane.add(Box.createHorizontalGlue()); + + // close/ok button + OkButton = new JButton("Schließen"); + OkButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + me.dispose(); + } + }); + bottomPane.add(OkButton); + + grid.add(bottomPane).fill(true, false).expand(true, false); + grid.nextRow(); + grid.finish(false); + + // Scale window with font + setMinimumSize(Gui.getScaledDimension(500, 200)); + setPreferredSize(getMinimumSize()); + setLocationRelativeTo(modalParent); + } + + /** + * Open a new window for showing the registration page in browser. + * + * @param modalParent the parent of the window. + */ + public static void open(Frame modalParent) { + new BwIdmLinkWindow(modalParent).setVisible(true); + } + + @Override + public boolean wantConfirmQuit() { + return false; + } + + @Override + public void escapePressed() { + dispose(); + } +} \ No newline at end of file diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/CheckUpdateWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/CheckUpdateWindow.java index 0a0f5883..b3c8ae05 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/CheckUpdateWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/CheckUpdateWindow.java @@ -9,8 +9,8 @@ import org.openslx.dozmod.gui.helper.UiFeedback; import org.openslx.dozmod.gui.window.layout.CheckUpdateWindowLayout; import org.openslx.dozmod.util.ClientVersion; import org.openslx.dozmod.util.FormatHelper; -import org.openslx.dozmod.util.OpenLinks; -import org.openslx.dozmod.util.OpenLinks.Link; +import org.openslx.dozmod.util.DesktopEnvironment; +import org.openslx.dozmod.util.DesktopEnvironment.Link; @SuppressWarnings("serial") public class CheckUpdateWindow extends CheckUpdateWindowLayout implements UiFeedback, ActionListener { @@ -35,7 +35,7 @@ public class CheckUpdateWindow extends CheckUpdateWindowLayout implements UiFeed @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == btnLink) { - OpenLinks.openWebpage(Link.DOZMOD); + DesktopEnvironment.openWebpage(Link.DOZMOD); } if (e.getSource() == btnClose) { dispose(); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java index d198e897..15964e65 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java @@ -62,7 +62,7 @@ import org.openslx.dozmod.thrift.cache.MetaDataCache; import org.openslx.dozmod.thrift.cache.UserCache; import org.openslx.dozmod.util.FormatHelper; import org.openslx.dozmod.util.MapHelper; -import org.openslx.dozmod.util.OpenLinks; +import org.openslx.dozmod.util.DesktopEnvironment; import org.openslx.sat.thrift.version.Feature; import org.openslx.thrifthelper.TConst; import org.openslx.thrifthelper.ThriftManager; @@ -524,7 +524,7 @@ public class ImageDetailsWindow extends ImageDetailsWindowLayout implements UiFe "Upload der VM auf den Masterserver fehlgeschlagen." + " Prüfen Sie, ob Sie bei der Registrierung dem landesweiten VM-Austausch zugestimmt haben.\n" + " Sie können dies hier überprüfen:\n" - + OpenLinks.Link.REGISTER_BWIDM.uri.toString() + "\n\n"); + + DesktopEnvironment.Link.REGISTER_BWIDM.uri.toString() + "\n\n"); return; } Gui.asyncExec(new Runnable() { diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LecturePermissionWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LecturePermissionWindow.java deleted file mode 100644 index 332835f9..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LecturePermissionWindow.java +++ /dev/null @@ -1,110 +0,0 @@ -package org.openslx.dozmod.gui.window; - -import java.awt.Window; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Map; - -import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.LecturePermissions; -import org.openslx.dozmod.gui.helper.UiFeedback; -import org.openslx.dozmod.gui.window.layout.LecturePermissionWindowLayout; - -/** - * Window for modifying the custom permissions of an lecture. - */ -@SuppressWarnings("serial") -public class LecturePermissionWindow extends LecturePermissionWindowLayout implements UiFeedback { - - private static final Logger LOGGER = Logger.getLogger(LecturePermissionWindow.class); - - private boolean okUsed = false; - - /** - * Don't use this constructor, use static function - * LectureCustomPermissionWindow.open instead. - */ - protected LecturePermissionWindow(final Window modalParent, - final Map permissionMap, final LecturePermissions defaultPermissions, - String ownerId) { - super(modalParent); - - /** - * initialise the lecturePermissionManager - */ - ctlPermissionManager.initPanel(permissionMap, defaultPermissions, ownerId); - - chkCustomPermAdmin.setSelected(defaultPermissions.admin); - chkCustomPermEdit.setSelected(defaultPermissions.edit); - - ActionListener updateDefaultPermissionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - ctlPermissionManager.updateDefaultPermissions(chkCustomPermAdmin.isSelected(), - chkCustomPermEdit.isSelected()); - } - }; - - chkCustomPermAdmin.addActionListener(updateDefaultPermissionListener); - chkCustomPermEdit.addActionListener(updateDefaultPermissionListener); - - /** - * ActionListeners for the buttons. - */ - btnOk.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - okUsed = true; - dispose(); - } - }); - btnClose.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - dispose(); - } - }); - } - - /** - * Set a created ImageCustomPermissionWindow visible and return resulting - * permissions - * - * @return PermissionDefaultToCustomLink with default- and customPermissions - * when using OK button, null otherwise - */ - private void run() { - setVisible(true); - if (okUsed) - ctlPermissionManager.getPermissions(); - } - - /** - * Create new LecturePermissionWindow dialog - * - * @param modalParent parentwindow of the popup window - * @param permissionMap the permissions of the lecture - * @param defaultPermissions default permissions of the lecture - * @param ownerId Id not to be shown in the list to add new users. Can be - * null. - * @return PermissionDefaultToCustomLink with new permissions of null, if - * abort button has been used - */ - - public static void open(Window modalParent, Map permissionMap, - LecturePermissions defaultPermissions, String ownerId) { - new LecturePermissionWindow(modalParent, permissionMap, defaultPermissions, ownerId).run(); - - } - - @Override - public boolean wantConfirmQuit() { - // TODO only return true if user added something new in the list - return false; - } - - @Override - public void escapePressed() { - dispose(); - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java index 07b36328..87524764 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java @@ -42,8 +42,8 @@ import org.openslx.dozmod.thrift.Session; import org.openslx.dozmod.thrift.ThriftActions; import org.openslx.dozmod.thrift.ThriftError; import org.openslx.dozmod.thrift.cache.OrganizationCache; -import org.openslx.dozmod.util.OpenLinks; -import org.openslx.dozmod.util.OpenLinks.Link; +import org.openslx.dozmod.util.DesktopEnvironment; +import org.openslx.dozmod.util.DesktopEnvironment.Link; import org.openslx.util.QuickTimer; import org.openslx.util.QuickTimer.Task; @@ -169,7 +169,7 @@ public class LoginWindow extends LoginWindowLayout { btnOpenRegistration.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - OpenLinks.openWebpage(Link.REGISTER_BWIDM); + DesktopEnvironment.openWebpage(Link.REGISTER_BWIDM); } }); @@ -193,7 +193,7 @@ public class LoginWindow extends LoginWindowLayout { btnLogDir.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - OpenLinks.openLocal(new File(Config.getPath())); + DesktopEnvironment.openLocal(new File(Config.getPath())); } }); @@ -359,7 +359,7 @@ public class LoginWindow extends LoginWindowLayout { break; case UNREGISTERED_ERROR: LOGGER.error("User not registered!"); - BwIDMLinkWindow.open((JFrame) SwingUtilities.getWindowAncestor(me)); + BwIdmLinkWindow.open((JFrame) SwingUtilities.getWindowAncestor(me)); break; case INVALID_URL_ERROR: Gui.showMessageBox(me, "ECP Authenticator says: Invalid URL.", MessageType.ERROR, LOGGER, diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/VirtualizerNoticeWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/VirtualizerNoticeWindow.java index 9f7258b0..8da88314 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/VirtualizerNoticeWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/VirtualizerNoticeWindow.java @@ -12,8 +12,8 @@ import org.apache.log4j.Logger; import org.openslx.dozmod.Config; import org.openslx.dozmod.gui.helper.UiFeedback; import org.openslx.dozmod.gui.window.layout.VirtualizerNoticeWindowLayout; -import org.openslx.dozmod.util.OpenLinks; -import org.openslx.dozmod.util.OpenLinks.Link; +import org.openslx.dozmod.util.DesktopEnvironment; +import org.openslx.dozmod.util.DesktopEnvironment.Link; @SuppressWarnings("serial") public class VirtualizerNoticeWindow extends VirtualizerNoticeWindowLayout implements UiFeedback { @@ -45,7 +45,7 @@ public class VirtualizerNoticeWindow extends VirtualizerNoticeWindowLayout imple btnDownload.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - OpenLinks.openWebpage(Link.VMWARE); + DesktopEnvironment.openWebpage(Link.VMWARE); } }); } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImagePermissionWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImagePermissionWindowLayout.java index 231dc4f7..6b9ea566 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImagePermissionWindowLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImagePermissionWindowLayout.java @@ -13,7 +13,7 @@ import javax.swing.JPanel; import org.apache.log4j.Logger; import org.openslx.dozmod.gui.Gui; -import org.openslx.dozmod.gui.control.ImageCustomPermissionManager; +import org.openslx.dozmod.gui.configurator.ImagePermissionConfigurator; import org.openslx.dozmod.gui.helper.GridManager; /** @@ -32,7 +32,7 @@ public class ImagePermissionWindowLayout extends JDialog { protected final JButton btnOk; protected final JButton btnClose; - protected final ImageCustomPermissionManager imagePermissionManager; + protected final ImagePermissionConfigurator imagePermissionManager; private static String title = "Berechtigungen"; private static String infoTextDefPerms = "" @@ -48,7 +48,7 @@ public class ImagePermissionWindowLayout extends JDialog { contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); add(contentPanel); - imagePermissionManager = new ImageCustomPermissionManager(); + imagePermissionManager = new ImagePermissionConfigurator(); // Panel for the buttons at the bottom JPanel buttonPane = new JPanel(); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureDetailsWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureDetailsWindowLayout.java index f0e03375..1508d95e 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureDetailsWindowLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureDetailsWindowLayout.java @@ -28,16 +28,16 @@ import javax.swing.text.DateFormatter; import org.jdatepicker.JDatePicker; import org.openslx.bwlp.thrift.iface.ImageVersionDetails; import org.openslx.dozmod.gui.Gui; +import org.openslx.dozmod.gui.configurator.LdapFilterConfigurator; +import org.openslx.dozmod.gui.configurator.LecturePermissionConfigurator; +import org.openslx.dozmod.gui.configurator.NetshareConfigurator; +import org.openslx.dozmod.gui.configurator.RunscriptConfigurator; import org.openslx.dozmod.gui.control.ComboBox; import org.openslx.dozmod.gui.control.ComboBox.ComboBoxRenderer; -import org.openslx.dozmod.gui.control.LdapFilterConfigurator; -import org.openslx.dozmod.gui.control.LectureCustomPermissionManager; import org.openslx.dozmod.gui.control.LocationSelector; -import org.openslx.dozmod.gui.control.NetshareConfigurator; import org.openslx.dozmod.gui.control.PersonLabel; import org.openslx.dozmod.gui.control.QDatePickerImpl; import org.openslx.dozmod.gui.control.QLabel; -import org.openslx.dozmod.gui.control.RunscriptConfigurator; import org.openslx.dozmod.gui.control.WordWrapLabel; import org.openslx.dozmod.gui.helper.GridManager; import org.openslx.dozmod.thrift.Session; @@ -88,7 +88,7 @@ public abstract class LectureDetailsWindowLayout extends JDialog { protected final JSpinner spnEndTime; protected JTabbedPane pnlTabs; - protected final LectureCustomPermissionManager ctlPermissionManager; + protected final LecturePermissionConfigurator ctlPermissionManager; protected final LocationSelector ctlLocationSelector; protected final RunscriptConfigurator ctlRunscriptConfigurator; protected final NetshareConfigurator ctlNetshareConfigurator; @@ -330,7 +330,7 @@ public abstract class LectureDetailsWindowLayout extends JDialog { * Tab "Permissions" * ********************************************************************************/ - ctlPermissionManager = new LectureCustomPermissionManager(); + ctlPermissionManager = new LecturePermissionConfigurator(); pnlTabPermissions = new JPanel(); GridManager grdPermissions = new GridManager(pnlTabPermissions, 1, false); JPanel defaultPermissionPane = new JPanel(); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureNetrulesWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureNetrulesWindowLayout.java index ce4067ce..d6f13d8f 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureNetrulesWindowLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureNetrulesWindowLayout.java @@ -17,7 +17,7 @@ import javax.swing.event.ChangeListener; import org.openslx.bwlp.thrift.iface.NetRule; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.changemonitor.ListEditorWindow; -import org.openslx.dozmod.gui.control.NetrulesConfigurator; +import org.openslx.dozmod.gui.configurator.NetrulesConfigurator; public abstract class LectureNetrulesWindowLayout extends JDialog implements ListEditorWindow { diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LecturePermissionWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LecturePermissionWindowLayout.java deleted file mode 100644 index 1408242d..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LecturePermissionWindowLayout.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.openslx.dozmod.gui.window.layout; - -import java.awt.Window; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JDialog; -import javax.swing.JPanel; - -import org.apache.log4j.Logger; -import org.openslx.dozmod.gui.Gui; -import org.openslx.dozmod.gui.control.LectureCustomPermissionManager; -import org.openslx.dozmod.gui.helper.GridManager; - -/** - * Layout for the LectureCustomPermissionWindow - */ -@SuppressWarnings("serial") -public class LecturePermissionWindowLayout extends JDialog { - - private static final Logger LOGGER = Logger.getLogger(LecturePermissionWindowLayout.class); - - /** - * Buttons - */ - protected final JButton btnOk; - protected final JButton btnClose; - protected final JCheckBox chkCustomPermAdmin; - protected final JCheckBox chkCustomPermEdit; - - /** - * The lecturePermissionManager to use. - */ - protected final LectureCustomPermissionManager ctlPermissionManager; - - /** - * The title of the window. - */ - private static String title = "Benutzerdefinierte Berechtigungen"; - - protected LecturePermissionWindowLayout(Window modalParent) { - super(modalParent, title, modalParent != null ? ModalityType.APPLICATION_MODAL - : ModalityType.MODELESS); - - // Panel to add everything into, needed for the border. - JPanel contentPanel = new JPanel(); - contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(contentPanel); - - GridManager grid = new GridManager(contentPanel, 1); - - // create the lecturePermissionManager and add it to the pane. - ctlPermissionManager = new LectureCustomPermissionManager(); - - // Panel with the default permissions - JPanel defaultPermissionPane = new JPanel(); - defaultPermissionPane.setBorder(BorderFactory.createTitledBorder("Andere Nutzer")); - chkCustomPermEdit = new JCheckBox("Bearbeiten"); - chkCustomPermAdmin = new JCheckBox("Admin"); - defaultPermissionPane.add(chkCustomPermEdit); - defaultPermissionPane.add(chkCustomPermAdmin); - - // Panel for the buttons at the bottom - JPanel buttonPane = new JPanel(); - buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS)); - buttonPane.add(Box.createGlue()); - btnClose = new JButton("Abbrechen"); - buttonPane.add(btnClose); - btnOk = new JButton("Übernehmen"); - buttonPane.add(btnOk); - - // Put everything into the grid - grid.add(ctlPermissionManager).fill(true, true).expand(true, true); - grid.nextRow(); - grid.add(defaultPermissionPane).fill(true, false).expand(true, false); - grid.nextRow(); - grid.add(buttonPane).fill(true, false).expand(false, false); - grid.nextRow(); - grid.finish(false); - - contentPanel.setPreferredSize(Gui.getScaledDimension(480, 350)); - - pack(); - setLocationRelativeTo(modalParent); - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageCustomPermissionPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageCustomPermissionPageLayout.java index 1d209775..e833090b 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageCustomPermissionPageLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageCustomPermissionPageLayout.java @@ -8,7 +8,7 @@ import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; -import org.openslx.dozmod.gui.control.ImageCustomPermissionManager; +import org.openslx.dozmod.gui.configurator.ImagePermissionConfigurator; import org.openslx.dozmod.gui.helper.GridManager; import org.openslx.dozmod.gui.wizard.Wizard; import org.openslx.dozmod.gui.wizard.WizardPage; @@ -16,7 +16,7 @@ import org.openslx.dozmod.gui.wizard.WizardPage; @SuppressWarnings("serial") public class ImageCustomPermissionPageLayout extends WizardPage { - protected ImageCustomPermissionManager imageCustomPermissionManager; + protected ImagePermissionConfigurator imageCustomPermissionManager; // permissions checks protected final JCheckBox chkPermissionRead; @@ -35,7 +35,7 @@ public class ImageCustomPermissionPageLayout extends WizardPage { GridManager grid = new GridManager(this, 1, false); // custom permissions - imageCustomPermissionManager = new ImageCustomPermissionManager(); + imageCustomPermissionManager = new ImagePermissionConfigurator(); grid.add(imageCustomPermissionManager).fill(true, true).expand(true, true); grid.nextRow(); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureCustomPermissionPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureCustomPermissionPageLayout.java index 849f4a6a..64afc4df 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureCustomPermissionPageLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureCustomPermissionPageLayout.java @@ -8,7 +8,7 @@ import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; -import org.openslx.dozmod.gui.control.LectureCustomPermissionManager; +import org.openslx.dozmod.gui.configurator.LecturePermissionConfigurator; import org.openslx.dozmod.gui.helper.GridManager; import org.openslx.dozmod.gui.wizard.Wizard; import org.openslx.dozmod.gui.wizard.WizardPage; @@ -16,7 +16,7 @@ import org.openslx.dozmod.gui.wizard.WizardPage; @SuppressWarnings("serial") public abstract class LectureCustomPermissionPageLayout extends WizardPage { - protected LectureCustomPermissionManager lectureCustomPermissionManager; + protected LecturePermissionConfigurator lectureCustomPermissionManager; // permissions checks protected final JCheckBox chkPermissionEdit; @@ -30,7 +30,7 @@ public abstract class LectureCustomPermissionPageLayout extends WizardPage { setDescription("Legen Sie hier die gewünschten Berechtigungen fest."); GridManager grid = new GridManager(this, 1, false); - lectureCustomPermissionManager = new LectureCustomPermissionManager(); + lectureCustomPermissionManager = new LecturePermissionConfigurator(); grid.add(lectureCustomPermissionManager).fill(true, true).expand(true, true); grid.nextRow(); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/util/DesktopEnvironment.java b/dozentenmodul/src/main/java/org/openslx/dozmod/util/DesktopEnvironment.java new file mode 100644 index 00000000..44925b4a --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/util/DesktopEnvironment.java @@ -0,0 +1,121 @@ +package org.openslx.dozmod.util; + +import java.awt.Desktop; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URLEncoder; + +import org.apache.log4j.Logger; + +public class DesktopEnvironment { + + /** + * Logger instance for this class + */ + private final static Logger LOGGER = Logger.getLogger(DesktopEnvironment.class); + + private static final Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null; + + public static enum Link { + FAQ("https://www.bwlehrpool.de/"), + VMWARE("https://my.vmware.com/web/vmware/free#desktop_end_user_computing/vmware_workstation_player/12_0"), + //INTRO("http://www.hs-offenburg.de/fileadmin/Einrichtungen/hrz/Projekte/bwLehrpool/3_bwLehrpool_-_Image_einbinden_und_starten.pdf"), + DOZMOD("https://bwlp-masterserver.ruf.uni-freiburg.de/dozmod/"), + REGISTER_BWIDM("https://bwlp-masterserver.ruf.uni-freiburg.de/webif/"); + + public final URI uri; + + private Link(String uri) { + this.uri = URI.create(uri); + } + } + + /** + * Open the URI corresponding to the given enum constant in the user's + * default web browser. + * + * @param location web site to open, passed as a member from the + * {@link Link} enum. + * @return success on true + */ + public static boolean openWebpage(Link location) { + return openWebpageUri(location.uri); + } + + public static boolean openWebpageUri(URI uri) { + if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) { + try { + desktop.browse(uri); + return true; + } catch (Exception e) { + LOGGER.error("Got exception in openWebpage: ", e); + } + } + return fallbackExec(uri.toString()); + } + + public static boolean openLocal(File path) { + try { + desktop.open(path); + return true; + } catch (Exception e) { + LOGGER.error("Got exception in openLocal: ", e); + } + return fallbackExec(path.getAbsolutePath()); + } + + /** + * Send an email to the given email address, with an optional subject. This + * will open the user's default mail application. + * + * @param address receiver's address + * @param subject default subject to use, null for no subject + * @return false on not-success + */ + public static boolean sendMail(String address, String subject) { + URI mailToUri = null; + try { + if (subject != null) { + mailToUri = new URI("mailto:" + address + "?subject=" + URLEncoder.encode(subject, "UTF-8")); + } else { + mailToUri = new URI("mailto:" + address); + } + if (desktop != null && desktop.isSupported(Desktop.Action.MAIL)) { + desktop.mail(mailToUri); + return true; + } + } catch (Exception e) { + LOGGER.error("Got exception in sendMail: ", e); + } + return mailToUri != null && fallbackExec(mailToUri.toString()); + } + + /** + * Opens the given link using the system's preferred application. This makes + * use of OSHelper to create a OS-dependent command to execute. + * + * @param link to open + * @return true if the external command executed successfully, false + * otherwise. + */ + public static boolean fallbackExec(String link) { + String[] execCommand; + if (OsHelper.isLinux()) { + execCommand = new String[] { "xdg-open", link }; + } else if (OsHelper.isWindows()) { + execCommand = new String[] { "cmd.exe", "/c", "start", link }; + } else { + LOGGER.error("Could not set command for unknown operating system: " + OsHelper.osName); + return false; + } + int exitCode = -1; + try { + exitCode = Runtime.getRuntime().exec(execCommand).waitFor(); + } catch (InterruptedException | IOException e) { + LOGGER.debug("Failed to execute: " + execCommand + "\nTrace: ", e); + return false; + } + return exitCode == 0; + } +} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/util/OSHelper.java b/dozentenmodul/src/main/java/org/openslx/dozmod/util/OSHelper.java deleted file mode 100644 index a3860dfa..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/util/OSHelper.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.openslx.dozmod.util; - -public final class OSHelper { - - public final static String osName = System.getProperty("os.name").toLowerCase(); - - public final static boolean isWindows() { - return osName.contains("windows"); - } - public final static boolean isLinux() { - return osName.contains("linux"); - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/util/OpenLinks.java b/dozentenmodul/src/main/java/org/openslx/dozmod/util/OpenLinks.java deleted file mode 100644 index dc34922b..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/util/OpenLinks.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.openslx.dozmod.util; - -import java.awt.Desktop; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URLEncoder; - -import org.apache.log4j.Logger; - -public class OpenLinks { - - /** - * Logger instance for this class - */ - private final static Logger LOGGER = Logger.getLogger(OpenLinks.class); - - private static final Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null; - - public static enum Link { - FAQ("https://www.bwlehrpool.de/"), - VMWARE("https://my.vmware.com/web/vmware/free#desktop_end_user_computing/vmware_workstation_player/12_0"), - //INTRO("http://www.hs-offenburg.de/fileadmin/Einrichtungen/hrz/Projekte/bwLehrpool/3_bwLehrpool_-_Image_einbinden_und_starten.pdf"), - DOZMOD("https://bwlp-masterserver.ruf.uni-freiburg.de/dozmod/"), - REGISTER_BWIDM("https://bwlp-masterserver.ruf.uni-freiburg.de/webif/"); - - public final URI uri; - - private Link(String uri) { - this.uri = URI.create(uri); - } - } - - /** - * Open the URI corresponding to the given enum constant in the user's - * default web browser. - * - * @param location web site to open, passed as a member from the - * {@link Link} enum. - * @return success on true - */ - public static boolean openWebpage(Link location) { - return openWebpageUri(location.uri); - } - - public static boolean openWebpageUri(URI uri) { - if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) { - try { - desktop.browse(uri); - return true; - } catch (Exception e) { - LOGGER.error("Got exception in openWebpage: ", e); - } - } - return fallbackExec(uri.toString()); - } - - public static boolean openLocal(File path) { - try { - desktop.open(path); - return true; - } catch (Exception e) { - LOGGER.error("Got exception in openLocal: ", e); - } - return fallbackExec(path.getAbsolutePath()); - } - - /** - * Send an email to the given email address, with an optional subject. This - * will open the user's default mail application. - * - * @param address receiver's address - * @param subject default subject to use, null for no subject - * @return false on not-success - */ - public static boolean sendMail(String address, String subject) { - URI mailToUri = null; - try { - if (subject != null) { - mailToUri = new URI("mailto:" + address + "?subject=" + URLEncoder.encode(subject, "UTF-8")); - } else { - mailToUri = new URI("mailto:" + address); - } - if (desktop != null && desktop.isSupported(Desktop.Action.MAIL)) { - desktop.mail(mailToUri); - return true; - } - } catch (Exception e) { - LOGGER.error("Got exception in sendMail: ", e); - } - return mailToUri != null && fallbackExec(mailToUri.toString()); - } - - /** - * Opens the given link using the system's preferred application. This makes - * use of OSHelper to create a OS-dependent command to execute. - * - * @param link to open - * @return true if the external command executed successfully, false - * otherwise. - */ - public static boolean fallbackExec(String link) { - String[] execCommand; - if (OSHelper.isLinux()) { - execCommand = new String[] { "xdg-open", link }; - } else if (OSHelper.isWindows()) { - execCommand = new String[] { "cmd.exe", "/c", "start", link }; - } else { - LOGGER.error("Could not set command for unknown operating system: " + OSHelper.osName); - return false; - } - int exitCode = -1; - try { - exitCode = Runtime.getRuntime().exec(execCommand).waitFor(); - } catch (InterruptedException | IOException e) { - LOGGER.debug("Failed to execute: " + execCommand + "\nTrace: ", e); - return false; - } - return exitCode == 0; - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/util/OsHelper.java b/dozentenmodul/src/main/java/org/openslx/dozmod/util/OsHelper.java new file mode 100644 index 00000000..e844d0c6 --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/util/OsHelper.java @@ -0,0 +1,13 @@ +package org.openslx.dozmod.util; + +public final class OsHelper { + + public final static String osName = System.getProperty("os.name").toLowerCase(); + + public final static boolean isWindows() { + return osName.contains("windows"); + } + public final static boolean isLinux() { + return osName.contains("linux"); + } +} -- cgit v1.2.3-55-g7522