diff options
| author | Jonathan Bauer | 2015-07-24 18:34:18 +0200 |
|---|---|---|
| committer | Jonathan Bauer | 2015-07-24 18:34:18 +0200 |
| commit | 79c7f153d72ae70fcd8bf19ef20f4ea2e543657b (patch) | |
| tree | 8e7b359d8acdde75657a3c70780fea4d67ccd9e3 | |
| parent | [client] rework tables to jtables for ImageListWindow (diff) | |
| parent | [client] Change upload page layout a bit (diff) | |
| download | tutor-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
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 |
