summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Bauer2015-07-24 18:34:18 +0200
committerJonathan Bauer2015-07-24 18:34:18 +0200
commit79c7f153d72ae70fcd8bf19ef20f4ea2e543657b (patch)
tree8e7b359d8acdde75657a3c70780fea4d67ccd9e3
parent[client] rework tables to jtables for ImageListWindow (diff)
parent[client] Change upload page layout a bit (diff)
downloadtutor-module-79c7f153d72ae70fcd8bf19ef20f4ea2e543657b.tar.gz
tutor-module-79c7f153d72ae70fcd8bf19ef20f4ea2e543657b.tar.xz
tutor-module-79c7f153d72ae70fcd8bf19ef20f4ea2e543657b.zip
Merge branch 'v1.1' of git.openslx.org:openslx-ng/tutor-module into v1.1
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/DownloadTask.java7
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java21
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageListWindow.java16
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java2
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/MainMenuWindow.java81
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java36
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageListWindowLayout.java18
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureListWindowLayout.java14
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/VirtualizerNoticeWindowLayout.java18
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java31
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureCreationPageLayout.java5
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/permissions/ImagePerms.java17
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java119
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java7
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java4
15 files changed, 314 insertions, 82 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/DownloadTask.java b/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/DownloadTask.java
index db75c518..d81b2445 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/DownloadTask.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/DownloadTask.java
@@ -60,7 +60,12 @@ public class DownloadTask extends TransferTask {
public FileRange get() {
handleCompletedChunk(current, buffer);
consecutiveInitFails.lazySet(0);
- current = chunks.getMissing();
+ try {
+ current = chunks.getMissing();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return null;
+ }
if (current != null) {
buffer = new byte[current.range.getLength()];
}
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 9c9ec2e7..f7fdff4c 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
@@ -15,6 +15,7 @@ import org.openslx.dozmod.gui.MainWindow;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.SwtUtil;
import org.openslx.dozmod.gui.window.layout.ImageDetailsWindowLayout;
+import org.openslx.dozmod.permissions.ImagePerms;
import org.openslx.dozmod.thrift.MetaDataCache;
import org.openslx.dozmod.thrift.Session;
import org.openslx.dozmod.thrift.UserCache;
@@ -81,8 +82,8 @@ public class ImageDetailsWindow extends ImageDetailsWindowLayout {
private void fill() {
if (isDisposed() || image == null)
return;
- lblTitle.setText(SwtUtil.replaceMnemonics(image.getImageName()));
- lblDescription.setText(SwtUtil.replaceMnemonics(image.getDescription()));
+ txtTitle.setText(SwtUtil.replaceMnemonics(image.getImageName()));
+ txtDescription.setText(SwtUtil.replaceMnemonics(image.getDescription()));
lblOwner.setUser(UserCache.find(image.getOwnerId()));
lblUpdater.setUser(UserCache.find(image.getUpdaterId()));
lblCreateTime.setText(FormatHelper.longDate(image.getCreateTime()));
@@ -96,8 +97,24 @@ public class ImageDetailsWindow extends ImageDetailsWindowLayout {
Virtualizer virt = MetaDataCache.getVirtualizerById(image.getVirtId());
if (virt != null)
lblVirtualizer.setText(virt.getVirtName());
+ String tagsString = "";
+ for (String tag : image.getTags()) {
+ tagsString = tagsString + ", " + tag;
+ }
+ txtTags.setText(tagsString);
+ btnIsTemplate.setSelection(image.isTemplate);
+ makeEditable(ImagePerms.canEdit(image));
getShell().layout(true, true);
MainWindow.centerShell(getShell());
}
+
+ // make text fields editable if allowed
+ private void makeEditable(boolean editable){
+ txtTitle.setEnabled(editable);
+ txtDescription.setEnabled(editable);
+ cboOperatingSystem.getCombo().setEnabled(editable);
+ txtTags.setEnabled(editable);
+ btnIsTemplate.setEnabled(editable);
+ }
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageListWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageListWindow.java
index bd820ff7..ec98ed6c 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageListWindow.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageListWindow.java
@@ -82,14 +82,14 @@ public class ImageListWindow extends ImageListWindowLayout {
}
});
- editButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- ImageWizard wizard = new ImageWizard(true);
- WizardDialog wd = new WizardDialog(getShell(), wizard);
- refreshList(wd.open() == Window.OK);
- }
- });
+// editButton.addSelectionListener(new SelectionAdapter() {
+// @Override
+// public void widgetSelected(SelectionEvent e) {
+// ImageWizard wizard = new ImageWizard(true);
+// WizardDialog wd = new WizardDialog(getShell(), wizard);
+// refreshList(wd.open() == Window.OK);
+// }
+// });
// return to mainMenu
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 341748f8..af794873 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
@@ -78,6 +78,8 @@ public class LoginWindow extends LoginWindowLayout {
Gui.display.asyncExec(new Runnable() {
@Override
public void run() {
+ if (isDisposed())
+ return;
populateIdpCombo(orgs);
loginButton.setEnabled(true);
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/MainMenuWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/MainMenuWindow.java
index f36b85e2..0f3914f9 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/MainMenuWindow.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/MainMenuWindow.java
@@ -1,10 +1,23 @@
package org.openslx.dozmod.gui.window;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Shell;
+import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.MainWindow;
import org.openslx.dozmod.gui.window.layout.MainMenuWindowLayout;
+import org.openslx.util.QuickTimer;
+import org.openslx.util.QuickTimer.Task;
+
+import com.google.gson.Gson;
public class MainMenuWindow extends MainMenuWindowLayout {
@@ -22,7 +35,8 @@ public class MainMenuWindow extends MainMenuWindowLayout {
lecturesButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- MainWindow.showPage(LectureListWindow.class); }
+ MainWindow.showPage(LectureListWindow.class);
+ }
});
}
@@ -31,9 +45,72 @@ public class MainMenuWindow extends MainMenuWindowLayout {
return true;
}
+ // Stuff start
+
+ private boolean once = false;
+
+ private class GMain {
+ private GResponse responseData;
+ }
+
+ private class GResponse {
+ private GResult[] results;
+ }
+
+ private class GResult {
+ private String tbUrl;
+ }
+
+ private int loadImageToControl(int start, GResult[] results, final Button control) {
+ if (start >= results.length)
+ start = results.length - 1;
+ while (start < results.length) {
+ try {
+ URL oracle = new URL(results[start].tbUrl);
+ final ImageData img = new ImageData(oracle.openStream());
+ Gui.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ control.setImage(new Image(control.getDisplay(), img));
+ control.getParent().layout(true, true);
+ }
+ });
+ break;
+ } catch (Exception e) {
+ }
+ start++;
+ }
+ return start;
+ }
+
+ // Stuff end
+
@Override
public void show() {
- // (void)
+ // All stuff is stuff
+ if (once)
+ return;
+ once = true;
+ QuickTimer.scheduleOnce(new Task() {
+ String[] terms = new String[] { "lehrpool", "dnbd3", "lehrstuhl", "dozmod", "lehrpool-suite",
+ "java", "hund", "katze", "maus" };
+
+ @Override
+ public void fire() {
+ String term = terms[(int) Math.floor(Math.random() * terms.length)] + "+"
+ + terms[(int) Math.floor(Math.random() * terms.length)];
+ try {
+ URL oracle = new URL("http://ajax.googleapis.com/ajax/services/search/images?v=1.0&rsz=8&q=" + term);
+ Reader reader = new InputStreamReader(oracle.openStream());
+ Gson gson = new Gson();
+ GMain data = gson.fromJson(reader, GMain.class);
+ int used = loadImageToControl(0, data.responseData.results, lecturesButton);
+ loadImageToControl(used + 1, data.responseData.results, vmButton);
+ } catch (IOException e) {
+ return;
+ }
+ }
+ });
}
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java
index fba210ec..3d024a54 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java
@@ -16,15 +16,16 @@ import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.dozmod.gui.control.PersonLabel;
import org.openslx.dozmod.gui.helper.SwtUtil;
public abstract class ImageDetailsWindowLayout extends Composite {
- protected final Label lblTitle;
+ protected final Text txtTitle;
- protected final Label lblDescription;
+ protected final Text txtDescription;
protected final Label lblCreateTime;
@@ -38,11 +39,17 @@ public abstract class ImageDetailsWindowLayout extends Composite {
protected final Label lblVirtualizer;
+ protected final Text txtTags;
+
+ protected final Button btnIsTemplate;
+
protected final ComboViewer cboShareMode;
+
+ protected final Button btnSaveChanges;
protected final Button btnClose;
- // TODO: IsTemplate, Permissions, ...
+ // TODO: Permissions, ...
public ImageDetailsWindowLayout(Shell parent) {
super(parent, SWT.NONE);
@@ -50,26 +57,26 @@ public abstract class ImageDetailsWindowLayout extends Composite {
this.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// Title label
- lblTitle = new Label(this, SWT.NONE);
+ txtTitle = new Text(this, SWT.NONE);
FontData[] fonts = FontDescriptor.copy(JFaceResources.getFontRegistry().getFontData(
JFaceResources.DEFAULT_FONT));
for (FontData f : fonts) {
f.setHeight(f.getHeight() * 2);
}
final Font titleFont = new Font(getDisplay(), fonts);
- lblTitle.setFont(titleFont);
+ txtTitle.setFont(titleFont);
GridData gdTitle = SwtUtil.gridData(SWT.LEFT, SWT.FILL, true, false, 2);
gdTitle.minimumWidth = 600;
gdTitle.minimumHeight = 20;
- lblTitle.setLayoutData(gdTitle);
+ txtTitle.setLayoutData(gdTitle);
// Create a horizontal separator
Label separator = new Label(this, SWT.HORIZONTAL | SWT.SEPARATOR);
separator.setLayoutData(SwtUtil.gridData(SWT.FILL, SWT.FILL, true, false, 2));
// Description
- lblDescription = new Label(this, SWT.BORDER);
- lblDescription.setLayoutData(SwtUtil.gridData(SWT.FILL, SWT.FILL, true, false, 2));
+ txtDescription = new Text(this, SWT.BORDER);
+ txtDescription.setLayoutData(SwtUtil.gridData(SWT.FILL, SWT.FILL, true, false, 2));
// Owner
new Label(this, SWT.NONE).setText("Besitzer");
@@ -102,12 +109,23 @@ public abstract class ImageDetailsWindowLayout extends Composite {
new Label(this, SWT.NONE).setText("Virtualizer");
lblVirtualizer = new Label(this, SWT.NONE);
+ // Tags
+ new Label(this, SWT.NONE).setText("Tags");
+ txtTags = new Text(this, SWT.NONE);
+
// Share mode
new Label(this, SWT.NONE).setText("Freigabemodus");
cboShareMode = new ComboViewer(this, SWT.DROP_DOWN | SWT.READ_ONLY);
+ // Is template
+ new Label(this, SWT.NONE).setText("Vorlage");
+ btnIsTemplate = new Button(this, SWT.CHECK);
+
+ btnSaveChanges = new Button(this, SWT.PUSH);
+ btnSaveChanges.setText("Änderungen speichern");
+
// Close button
- btnClose = new org.eclipse.swt.widgets.Button(this, SWT.PUSH | SWT.RIGHT | SWT.DOWN);
+ btnClose = new Button(this, SWT.PUSH | SWT.RIGHT | SWT.DOWN);
btnClose.setText("Schließen");
btnClose.setLayoutData(SwtUtil.gridData(SWT.RIGHT, SWT.BOTTOM, false, false, 2));
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageListWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageListWindowLayout.java
index 4133c835..bd8a6728 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageListWindowLayout.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageListWindowLayout.java
@@ -13,6 +13,8 @@ import javax.swing.SwingUtilities;
import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.GridData;
@@ -45,7 +47,6 @@ public abstract class ImageListWindowLayout extends CompositePage {
// buttons
protected Button newButton;
protected Button deleteButton;
- protected Button editButton;
protected Button downloadButton;
protected Button backButton;
@@ -83,8 +84,8 @@ public abstract class ImageListWindowLayout extends CompositePage {
infoTitle.setText(infoTitleString);
// set the fond
FontData fontData = infoTitle.getFont().getFontData()[0];
- Font font = new Font(Gui.display, new FontData(fontData.getName(), fontData.getHeight(), SWT.BOLD));
- infoTitle.setFont(font);
+ final Font titleFont = new Font(Gui.display, new FontData(fontData.getName(), fontData.getHeight(), SWT.BOLD));
+ infoTitle.setFont(titleFont);
// the infotext
Label infoText = new Label(infoComposite, SWT.NONE);
infoText.setText(infoTextString);
@@ -160,9 +161,6 @@ public abstract class ImageListWindowLayout extends CompositePage {
newButton = new Button(buttonComposite, SWT.PUSH);
newButton.setText(newButtonLabel);
- editButton = new Button(buttonComposite, SWT.PUSH);
- editButton.setText(editButtonLabel);
-
deleteButton = new Button(buttonComposite, SWT.PUSH);
deleteButton.setText(deleteButtonLabel);
@@ -191,6 +189,14 @@ public abstract class ImageListWindowLayout extends CompositePage {
templateInfo = createCaptionAndTextfield("Vorlage:", vmInfoGroup);
// -- end group of details --
+ // Dispose of stuff we allocated
+ this.addDisposeListener(new DisposeListener() {
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ titleFont.dispose();
+ }
+ });
+
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureListWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureListWindowLayout.java
index 6ce50dc2..ea1ecdac 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureListWindowLayout.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureListWindowLayout.java
@@ -3,6 +3,8 @@ package org.openslx.dozmod.gui.window.layout;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.GridData;
@@ -71,8 +73,8 @@ public abstract class LectureListWindowLayout extends CompositePage {
infoTitle.setText(infoTitleString);
// set the fond
FontData fontData = infoTitle.getFont().getFontData()[0];
- Font font = new Font(Gui.display, new FontData(fontData.getName(), fontData.getHeight(), SWT.BOLD));
- infoTitle.setFont(font);
+ final Font titleFont = new Font(Gui.display, new FontData(fontData.getName(), fontData.getHeight(), SWT.BOLD));
+ infoTitle.setFont(titleFont);
// the infotext
Label infoText = new Label(infoComposite, SWT.NONE);
infoText.setText(infoTextString);
@@ -152,6 +154,14 @@ public abstract class LectureListWindowLayout extends CompositePage {
endTime = createCaptionAndTextfield("Endzeit:", vmInfoGroup);
ownerInfo = createCaptionAndTextfield("Besitzer:", vmInfoGroup);
// -- end group of details --
+
+ // Dispose of stuff we allocated
+ this.addDisposeListener(new DisposeListener() {
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ titleFont.dispose();
+ }
+ });
}
public Text createCaptionAndTextfield(String captionString, Group group) {
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/VirtualizerNoticeWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/VirtualizerNoticeWindowLayout.java
index 0227d701..dab012d3 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/VirtualizerNoticeWindowLayout.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/VirtualizerNoticeWindowLayout.java
@@ -1,6 +1,8 @@
package org.openslx.dozmod.gui.window.layout;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.GridData;
@@ -32,14 +34,16 @@ public abstract class VirtualizerNoticeWindowLayout extends Composite {
// layout for this composite
this.setLayout(new GridLayout(1, false));
+ GridData gd = new GridData();
+ gd.widthHint = 500;
+ this.setLayoutData(gd);
// bold title at start.
Label titleLabel = new Label(this, SWT.NONE);
titleLabel.setText(infoTitle);
FontData fontData = titleLabel.getFont().getFontData()[0];
- Font font = new Font(Gui.display, new FontData(fontData.getName(), fontData.getHeight(), SWT.BOLD));
+ final Font font = new Font(Gui.display, new FontData(fontData.getName(), fontData.getHeight(), SWT.BOLD));
titleLabel.setFont(font);
- // TODO dispose of font?
// infotext
Label infoLabel = new Label(this, SWT.NONE | SWT.WRAP);
@@ -72,5 +76,15 @@ public abstract class VirtualizerNoticeWindowLayout extends Composite {
continueButton.setText("Weiter");
continueButton.setLayoutData(new GridData(GridData.BEGINNING, GridData.END, false, false));
+ // Dispose of stuff we allocated
+ this.addDisposeListener(new DisposeListener() {
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ font.dispose();
+ }
+ });
+
}
+
+
} \ No newline at end of file
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java
index e072b6b4..e0b074ef 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java
@@ -27,9 +27,9 @@ public abstract class ImageUploadPageLayout extends WizardPage {
* one
*/
public ImageUploadPageLayout() {
- super("Eingabe Ihrer Daten");
- setTitle("Eingabe Ihrer Daten");
- setDescription("Geben Sie bitte einen aussagekräftigen Namen für das neue Image ein.");
+ super("Neue VM anlegen");
+ setTitle("Neue VM anlegen");
+ setDescription("Wählen Sie bitte zunächst die VM auf Ihrem lokalen Speicher aus");
}
@Override
@@ -38,37 +38,34 @@ public abstract class ImageUploadPageLayout extends WizardPage {
GridLayout layout = new GridLayout();
layout.verticalSpacing = 16;
container.setLayout(layout);
- layout.numColumns = 4;
+ layout.numColumns = 3;
// -- Browse for VM --
Label imageFileCaption = new Label(container, SWT.NONE);
imageFileCaption.setText("Virtuelle Maschine");
imageFileTextField = new Text(container, SWT.BORDER | SWT.SINGLE);
imageFileTextField.setEditable(false);
- GridData gdImageFileTextField = new GridData(SWT.FILL, SWT.FILL, true, false);
- gdImageFileTextField.horizontalSpan = 2;
- imageFileTextField.setLayoutData(gdImageFileTextField);
+ imageFileTextField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
imageFileBrowseButton = new Button(container, SWT.PUSH);
- imageFileBrowseButton.setText("Browse");
+ imageFileBrowseButton.setText("&Browse");
+ // -- Name --
Label imageNameCaption = new Label(container, SWT.NONE);
imageNameCaption.setText("Name des Images");
-
imageNameTextField = new Text(container, SWT.BORDER | SWT.SINGLE);
- GridData gdImageNameTextField = new GridData(GridData.FILL_HORIZONTAL);
- gdImageNameTextField.horizontalSpan = 2;
- imageNameTextField.setLayoutData(gdImageNameTextField);
-
+ imageNameTextField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
startUploadButton = new Button(container, SWT.PUSH);
- startUploadButton.setText("Upload");
+ startUploadButton.setText("&Upload starten");
+ startUploadButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 3, 1));
blockProgressBar = new BlockProgressBar(container, null);
- GridData gdBlockProgressBar = new GridData(SWT.FILL, SWT.END, false, false, 3, 1);
- gdBlockProgressBar.heightHint = 25;
+ GridData gdBlockProgressBar = new GridData(SWT.FILL, SWT.DOWN, true, true, 2, 1);
+ gdBlockProgressBar.heightHint = 30;
blockProgressBar.setLayoutData(gdBlockProgressBar);
cancelUpload = new Button(container, SWT.PUSH);
- cancelUpload.setText("Cancel");
+ cancelUpload.setText("&Abbrechen");
+ cancelUpload.setLayoutData(new GridData(SWT.CENTER, SWT.BOTTOM, false, true));
setControl(container);
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureCreationPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureCreationPageLayout.java
index 61d26fe3..1522cd72 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureCreationPageLayout.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureCreationPageLayout.java
@@ -53,13 +53,13 @@ public abstract class LectureCreationPageLayout extends WizardPage {
Label startDateLabel = new Label(container, SWT.NONE);
startDateLabel.setText("Startdatum:");
startDateLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
- startDate = new DateTime (container, SWT.DATE);
+ startDate = new DateTime(container, SWT.DATE | SWT.DROP_DOWN);
startDate.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
Label endDateLabel = new Label(container, SWT.NONE);
endDateLabel.setText("Enddatum:");
endDateLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
- endDate = new DateTime (container, SWT.DATE);
+ endDate = new DateTime(container, SWT.DATE | SWT.DROP_DOWN);
endDate.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
// start- and end
@@ -68,6 +68,7 @@ public abstract class LectureCreationPageLayout extends WizardPage {
endTimelabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
startTime = new DateTime (container, SWT.TIME | SWT.SHORT);
+
Label endTimeLabel = new Label(container, SWT.NONE);
endTimeLabel.setText("Endzeit:");
endTimeLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/permissions/ImagePerms.java b/dozentenmodul/src/main/java/org/openslx/dozmod/permissions/ImagePerms.java
new file mode 100644
index 00000000..5b9441ed
--- /dev/null
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/permissions/ImagePerms.java
@@ -0,0 +1,17 @@
+package org.openslx.dozmod.permissions;
+
+import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
+import org.openslx.dozmod.thrift.Session;
+
+public class ImagePerms {
+
+ public static boolean canEdit(ImageDetailsRead image){
+ if(image.getOwnerId().equals(Session.getUserId()))
+ return true;
+ if(image.userPermissions !=null) {
+ return image.userPermissions.edit;
+ }
+ return image.defaultPermissions.edit;
+ }
+
+}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java
index 92c2b2d7..f2b95aaa 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java
@@ -5,7 +5,9 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -13,6 +15,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.log4j.Logger;
import org.openslx.bwlp.sat.database.mappers.DbImage;
import org.openslx.bwlp.sat.util.Configuration;
+import org.openslx.bwlp.sat.util.Constants;
import org.openslx.bwlp.sat.util.FileSystem;
import org.openslx.bwlp.sat.util.Formatter;
import org.openslx.bwlp.sat.util.Util;
@@ -27,14 +30,28 @@ import org.openslx.filetransfer.FileRange;
import org.openslx.filetransfer.WantRangeCallback;
import org.openslx.filetransfer.util.ChunkList;
import org.openslx.filetransfer.util.FileChunk;
+import org.openslx.filetransfer.util.HashChecker;
+import org.openslx.filetransfer.util.HashChecker.HashCheckCallback;
+import org.openslx.filetransfer.util.HashChecker.HashResult;
+
+public class ActiveUpload implements HashCheckCallback {
-public class ActiveUpload {
private static final Logger LOGGER = Logger.getLogger(ActiveUpload.class);
/**
+ * How many concurrent connections per upload
+ */
+ private static final int MAX_CONNECTIONS = Math.max(Constants.MAX_UPLOADS / 4, 1);
+
+ /**
+ * Self reference for inner classes.
+ */
+ private final ActiveUpload activeUpload = this;
+
+ /**
* This is an active upload, so on our end, we have a Downloader.
*/
- private Downloader download = null;
+ private List<Downloader> downloads = new ArrayList<>();
private final File destinationFile;
@@ -80,7 +97,22 @@ public class ActiveUpload {
*/
private final AtomicBoolean versionWrittenToDb = new AtomicBoolean();
- // TODO: Use HashList for verification
+ /**
+ * Whether file is (still) writable. Used for the file transfer callbacks.
+ */
+ private boolean fileWritable = true;
+
+ private static final HashChecker hashChecker;
+
+ static {
+ HashChecker hc;
+ try {
+ hc = new HashChecker("SHA1");
+ } catch (NoSuchAlgorithmException e) {
+ hc = null;
+ }
+ hashChecker = hc;
+ }
public ActiveUpload(String uploadId, UserInfo owner, ImageDetailsRead image, File destinationFile,
long fileSize, List<ByteBuffer> sha1Sums, byte[] machineDescription) throws FileNotFoundException {
@@ -122,23 +154,29 @@ public class ActiveUpload {
* @return true if the connection is accepted, false if it should be
* discarded
*/
- public synchronized boolean addConnection(Downloader connection, ThreadPoolExecutor pool) {
- if (download != null || chunks.isComplete() || state == TransferState.FINISHED
- || state == TransferState.ERROR)
+ public synchronized boolean addConnection(final Downloader connection, ThreadPoolExecutor pool) {
+ if (chunks.isComplete() || state == TransferState.FINISHED || state == TransferState.ERROR)
return false;
- download = connection;
+ synchronized (downloads) {
+ if (downloads.size() >= MAX_CONNECTIONS)
+ return false;
+ downloads.add(connection);
+ }
try {
pool.execute(new Runnable() {
@Override
public void run() {
CbHandler cbh = new CbHandler();
- if (!download.download(cbh, cbh)) {
+ if (!connection.download(cbh, cbh)) {
if (cbh.currentChunk != null) {
// If the download failed and we have a current chunk, put it back into
// the queue, so it will be handled again later...
chunks.markFailed(cbh.currentChunk);
}
- LOGGER.warn("Download of " + destinationFile.getAbsolutePath());
+ LOGGER.warn("Download of " + destinationFile.getAbsolutePath() + " failed");
+ }
+ if (chunks.isComplete()) {
+ finishUpload();
}
}
});
@@ -159,7 +197,7 @@ public class ActiveUpload {
* @param data
* @return
*/
- private boolean writeFileData(long fileOffset, int dataLength, byte[] data) {
+ private void writeFileData(long fileOffset, int dataLength, byte[] data) {
if (state != TransferState.WORKING)
throw new IllegalStateException("Cannot write to file if state != RUNNING");
synchronized (outFile) {
@@ -169,10 +207,9 @@ public class ActiveUpload {
} catch (IOException e) {
LOGGER.error("Cannot write to '" + destinationFile
+ "'. Disk full, network storage error, bad permissions, ...?", e);
- return false;
+ fileWritable = false;
}
}
- return true;
}
/**
@@ -230,8 +267,10 @@ public class ActiveUpload {
}
public synchronized void cancel() {
- if (download != null) {
- download.cancel();
+ synchronized (downloads) {
+ for (Downloader download : downloads) {
+ download.cancel();
+ }
}
if (state != TransferState.FINISHED) {
state = TransferState.ERROR;
@@ -267,31 +306,42 @@ public class ActiveUpload {
/**
* The current chunk being transfered.
*/
- public FileChunk currentChunk = null;
+ private FileChunk currentChunk = null;
+ private byte[] buffer = new byte[FileChunk.CHUNK_SIZE];
@Override
public boolean dataReceived(long fileOffset, int dataLength, byte[] data) {
- // TODO: Maybe cache in RAM and write full CHUNK_SIZE blocks at a time?
- // Would probably help with slower storage, especially if it's using
- // rotating disks and we're running multiple uploads.
- // Also we wouldn't have to re-read a block form disk for sha1 checking.
- return writeFileData(fileOffset, dataLength, data);
+ if (currentChunk == null)
+ throw new IllegalStateException("dataReceived without current chunk");
+ if (!currentChunk.range.contains(fileOffset, fileOffset + dataLength))
+ throw new IllegalStateException("dataReceived with file data out of range");
+ System.arraycopy(data, 0, buffer, (int) (fileOffset - currentChunk.range.startOffset), dataLength);
+ return fileWritable;
}
@Override
public FileRange get() {
if (currentChunk != null) {
- // TODO: A chunk was requested before, check hash and requeue if not matching
- // This needs to be async (own thread) so will be a little complicated
- // For now, we just mark it as complete
- chunks.markSuccessful(currentChunk);
- LOGGER.info("There was a previous chunk!");
+ if (currentChunk.hasSha1Sum() && hashChecker != null) {
+ try {
+ hashChecker.queue(currentChunk, buffer, activeUpload);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return null;
+ }
+ } else {
+ chunks.markSuccessful(currentChunk);
+ }
}
// Get next missing chunk
- currentChunk = chunks.getMissing();
+ try {
+ currentChunk = chunks.getMissing();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return null;
+ }
LOGGER.info("Next missing chunk: " + currentChunk);
if (currentChunk == null) {
- finishUpload();
return null; // No more chunks, returning null tells the Downloader we're done.
}
return currentChunk.range;
@@ -306,6 +356,21 @@ public class ActiveUpload {
return uploadId;
}
+ @Override
+ public void hashCheckDone(HashResult result, byte[] data, FileChunk chunk) {
+ switch (result) {
+ case FAILURE:
+ LOGGER.warn("Hash check of chunk " + chunk.toString() + " failed. Assuming valid.");
+ // Fall through
+ case VALID:
+ writeFileData(chunk.range.startOffset, chunk.range.getLength(), data);
+ chunks.markSuccessful(chunk);
+ break;
+ case INVALID:
+ chunks.markFailed(chunk);
+ }
+ }
+
// TODO: Clean up old stale uploads
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
index 0869612f..9895e655 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
@@ -72,7 +72,9 @@ public class FileServer implements IncomingEvent {
downloader.cancel();
return;
}
- upload.addConnection(downloader, transferPool);
+ if (!upload.addConnection(downloader, transferPool)) {
+ downloader.cancel();
+ }
}
/**
@@ -110,7 +112,8 @@ public class FileServer implements IncomingEvent {
String key = UUID.randomUUID().toString();
ActiveUpload upload;
try {
- upload = new ActiveUpload(key, owner, image, destinationFile, fileSize, sha1Sums, machineDescription);
+ upload = new ActiveUpload(key, owner, image, destinationFile, fileSize, sha1Sums,
+ machineDescription);
} catch (FileNotFoundException e) {
LOGGER.error("Could not open destination file for writing", e);
throw new TTransferRejectedException("Destination file not writable!");
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java
index ad5ea0e2..774d1c88 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java
@@ -12,8 +12,8 @@ public class Constants {
long maxMem = Runtime.getRuntime().maxMemory();
if (maxMem == Long.MAX_VALUE) {
// Apparently the JVM was started without a memory limit (no -Xmx cmdline),
- // so we assume a default of 256MB
- maxMem = 256l * 1024l * 1024l;
+ // so we assume a default of 512MB
+ maxMem = 512l * 1024l * 1024l;
}
maxMem /= 1024l * 1024l;
// Now maxMem is the amount of memory in MiB