upload manager work

This commit is contained in:
Branislav Stojkovic
2016-10-30 12:26:45 +01:00
parent 1849eec874
commit 98087d8889
12 changed files with 244 additions and 53 deletions
@@ -97,11 +97,13 @@ public interface IServiceAPI {
* @param page * @param page
* @param itemsPerPage * @param itemsPerPage
* @param sort * @param sort
* @param username
* @return string with error message if the error occurred or a list of {@link ProjectEntity} * @return string with error message if the error occurred or a list of {@link ProjectEntity}
* objects. * objects.
*/ */
Object search(@ParamName("criteria") String criteria, @ParamName("category") String category, Object search(@ParamName("criteria") String criteria, @ParamName("category") String category,
@ParamName("page") Integer page, @ParamName("itemsPerPage") Integer itemsPerPage, @ParamName("sort") String sort); @ParamName("page") Integer page, @ParamName("itemsPerPage") Integer itemsPerPage, @ParamName("sort") String sort,
@ParamName("username") String username);
/** /**
* Uploads a project using token to authenticate. When projectI is specified, it updates the * Uploads a project using token to authenticate. When projectI is specified, it updates the
@@ -128,7 +130,7 @@ public interface IServiceAPI {
@ParamName("projectId") Integer projectId); @ParamName("projectId") Integer projectId);
/** /**
*Deletes an existing project. The project must belong to the user * Deletes an existing project. The project must belong to the user
* *
* @param username * @param username
* @param token * @param token
@@ -134,8 +134,8 @@ public class CloudPresenter {
return categories; return categories;
} }
public void uploadProject(String projectName, String category, String description, String keywords, String diylcVersion, public void uploadProject(String projectName, String category, String description, String keywords,
File thumbnail, File project) throws IOException, CloudException { String diylcVersion, File thumbnail, File project) throws IOException, CloudException {
String username = ConfigurationManager.getInstance().readString(USERNAME_KEY, null); String username = ConfigurationManager.getInstance().readString(USERNAME_KEY, null);
String token = ConfigurationManager.getInstance().readString(TOKEN_KEY, null); String token = ConfigurationManager.getInstance().readString(TOKEN_KEY, null);
@@ -234,37 +234,54 @@ public class CloudPresenter {
throws CloudException { throws CloudException {
LOG.info(String.format("search(%1$s,%2$s,%3$s,%4$d,%5$d)", criteria, category, sortOrder, pageNumber, itemsPerPage)); LOG.info(String.format("search(%1$s,%2$s,%3$s,%4$d,%5$d)", criteria, category, sortOrder, pageNumber, itemsPerPage));
try { try {
Object res = getService().search(criteria, category, pageNumber, itemsPerPage, sortOrder); Object res = getService().search(criteria, category, pageNumber, itemsPerPage, sortOrder, null);
// Thread.sleep(2000); return processResults(res);
if (res == null) } catch (CloudException ce) {
throw new CloudException("Failed to retreive search results."); throw ce;
if (res instanceof String)
throw new CloudException(res.toString());
if (res instanceof List<?>) {
@SuppressWarnings("unchecked")
List<ProjectEntity> projects = (List<ProjectEntity>) res;
LOG.info("Received " + projects.size() + " results. Downloading thumbnails...");
// Download thumbnails and replace urls with local paths to speed up loading in the main
// thread
for (int i = 0; i < projects.size(); i++) {
String url = projects.get(i).getThumbnailUrl();
URL website = new URL(url);
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
File temp = File.createTempFile("thumbnail", ".png");
FileOutputStream fos = new FileOutputStream(temp);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
projects.get(i).setThumbnailUrl(temp.getAbsolutePath());
fos.close();
}
LOG.info("Finished downloading thumbnails.");
return projects;
}
throw new CloudException("Unexpected server response received for search results: " + res.getClass().getName());
} catch (Exception e) { } catch (Exception e) {
throw new CloudException(e); throw new CloudException(e);
} }
} }
public List<ProjectEntity> fetchUserUploads() throws CloudException {
UserEntity user = getUserDetails();
try {
Object res = getService().search("", "", 1, Integer.MAX_VALUE, getSortings()[0], user.getUsername());
return processResults(res);
} catch (CloudException ce) {
throw ce;
} catch (Exception e) {
throw new CloudException(e);
}
}
private List<ProjectEntity> processResults(Object res) throws CloudException, IOException {
if (res == null)
throw new CloudException("Failed to retreive search results.");
if (res instanceof String)
throw new CloudException(res.toString());
if (res instanceof List<?>) {
@SuppressWarnings("unchecked")
List<ProjectEntity> projects = (List<ProjectEntity>) res;
LOG.info("Received " + projects.size() + " results. Downloading thumbnails...");
// Download thumbnails and replace urls with local paths to speed up loading in the main
// thread
for (int i = 0; i < projects.size(); i++) {
String url = projects.get(i).getThumbnailUrl();
URL website = new URL(url);
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
File temp = File.createTempFile("thumbnail", ".png");
FileOutputStream fos = new FileOutputStream(temp);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
projects.get(i).setThumbnailUrl(temp.getAbsolutePath());
fos.close();
}
LOG.info("Finished downloading thumbnails.");
return projects;
}
throw new CloudException("Unexpected server response received for search results: " + res.getClass().getName());
}
public String[] getSortings() throws CloudException { public String[] getSortings() throws CloudException {
try { try {
return getService().getSortings().toArray(new String[0]); return getService().getSortings().toArray(new String[0]);
@@ -17,7 +17,12 @@ public class PagingProvider {
private List<ProjectEntity> currentResults; private List<ProjectEntity> currentResults;
public PagingProvider(CloudPresenter cloudPresenter) { public PagingProvider(CloudPresenter cloudPresenter) {
this(cloudPresenter, 10);
}
public PagingProvider(CloudPresenter cloudPresenter, int itemsPerPage) {
this.cloudPresenter = cloudPresenter; this.cloudPresenter = cloudPresenter;
this.itemsPerPage = itemsPerPage;
} }
public List<ProjectEntity> startSession(String searchFor, String category, String sort) throws CloudException { public List<ProjectEntity> startSession(String searchFor, String category, String sort) throws CloudException {
@@ -32,10 +32,10 @@ public enum IconLoader {
"briefcase_into.png"), RotateCW("rotate_cw.png"), RotateCCW("rotate_ccw.png"), ElementInto("element_into.png"), Arrow( "briefcase_into.png"), RotateCW("rotate_cw.png"), RotateCCW("rotate_ccw.png"), ElementInto("element_into.png"), Arrow(
"arrow.png"), Cloud("cloud.png"), CloudUp("cloud_up.png"), CloudGear("cloud_gear.png"), IdCardEdit( "arrow.png"), Cloud("cloud.png"), CloudUp("cloud_up.png"), CloudGear("cloud_gear.png"), IdCardEdit(
"id_card_edit.png"), KeyEdit("key_edit.png"), Find("find.png"), Dashboard("dashboard.png"), DataFind( "id_card_edit.png"), KeyEdit("key_edit.png"), Find("find.png"), Dashboard("dashboard.png"), DataFind(
"data_find.png"), CloudDownload("cloud-download.png"), NavLeftBlue("nav_left_blue.png"), NavRightBlue( "data_find.png"), CloudDownload("cloud_download.png"), CloudUpload("cloud_upload.png"), NavLeftBlue(
"nav_right_blue.png"), MissingImage("missing_image.png"), CloudBg("cloud_bg.png"), CloudBig("cloud_big.png"), CloudWait( "nav_left_blue.png"), NavRightBlue("nav_right_blue.png"), MissingImage("missing_image.png"), CloudBg(
"cloud_wait.png"), Spinning("spinning.gif"), Megaphone("megaphone.png"), Download("download.png"), Eye("eye.png"), Messages( "cloud_bg.png"), CloudBig("cloud_big.png"), CloudWait("cloud_wait.png"), Spinning("spinning.gif"), Megaphone(
"messages.png"); "megaphone.png"), Download("download.png"), Eye("eye.png"), Messages("messages.png");
protected String name; protected String name;

Before

Width:  |  Height:  |  Size: 717 B

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

@@ -0,0 +1,29 @@
package org.diylc.swing;
import javax.swing.JFrame;
import org.diylc.common.ITask;
/**
* Interface for secondary windows that support basic functionalities.
*
* @author Branislav Stojkovic
*/
public interface ISimpleView {
/**
* Runs a task in background while showing busy cursor and a glass pane.
*
* @param task
*/
<T extends Object> void executeBackgroundTask(ITask<T> task);
void showMessage(String message, String title, int messageType);
int showConfirmDialog(String message, String title, int optionType, int messageType);
/**
* @return {@link JFrame} that can be used to reference secondary dialogs and frames
*/
JFrame getOwnerFrame();
}
@@ -26,9 +26,9 @@ import org.diylc.swing.plugins.cloud.view.LoginDialog;
import org.diylc.swing.plugins.cloud.view.UploadDialog; import org.diylc.swing.plugins.cloud.view.UploadDialog;
import org.diylc.swing.plugins.cloud.view.UserEditDialog; import org.diylc.swing.plugins.cloud.view.UserEditDialog;
import org.diylc.swing.plugins.cloud.view.browser.CloudBrowserFrame; import org.diylc.swing.plugins.cloud.view.browser.CloudBrowserFrame;
import org.diylc.swing.plugins.cloud.view.browser.UploadManagerFrame;
import org.diylc.swing.plugins.file.FileFilterEnum; import org.diylc.swing.plugins.file.FileFilterEnum;
import org.diylc.swingframework.ButtonDialog; import org.diylc.swingframework.ButtonDialog;
import org.diylc.swingframework.ProgressDialog;
public class CloudPlugIn implements IPlugIn, CloudListener { public class CloudPlugIn implements IPlugIn, CloudListener {
@@ -118,6 +118,10 @@ public class CloudPlugIn implements IPlugIn, CloudListener {
return cloudBrowser; return cloudBrowser;
} }
public UploadManagerFrame createUploadManagerFrame() {
return new UploadManagerFrame(swingUI, plugInPort, cloudPresenter);
}
public LibraryAction getLibraryAction() { public LibraryAction getLibraryAction() {
if (libraryAction == null) { if (libraryAction == null) {
libraryAction = new LibraryAction(); libraryAction = new LibraryAction();
@@ -455,15 +459,14 @@ public class CloudPlugIn implements IPlugIn, CloudListener {
public ManageProjectsAction() { public ManageProjectsAction() {
super(); super();
putValue(AbstractAction.NAME, "Manage My Projects"); putValue(AbstractAction.NAME, "Manage My Uploads");
putValue(AbstractAction.SMALL_ICON, IconLoader.CloudGear.getIcon()); putValue(AbstractAction.SMALL_ICON, IconLoader.CloudGear.getIcon());
} }
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
ProgressDialog dialog = UploadManagerFrame frame = createUploadManagerFrame();
DialogFactory.getInstance().createProgressDialog("Test", new String[] {}, "Some text", false); frame.setVisible(true);
dialog.setVisible(true);
} }
} }
@@ -23,7 +23,7 @@ import org.diylc.core.IView;
import org.diylc.plugins.cloud.model.CommentEntity; import org.diylc.plugins.cloud.model.CommentEntity;
import org.diylc.plugins.cloud.model.ProjectEntity; import org.diylc.plugins.cloud.model.ProjectEntity;
import org.diylc.plugins.cloud.presenter.CloudPresenter; import org.diylc.plugins.cloud.presenter.CloudPresenter;
import org.diylc.swing.plugins.cloud.view.browser.CloudBrowserFrame; import org.diylc.swing.ISimpleView;
public class CommentDialog extends JDialog { public class CommentDialog extends JDialog {
@@ -44,19 +44,18 @@ public class CommentDialog extends JDialog {
private int lastPosition = 0; private int lastPosition = 0;
private CloudBrowserFrame owner; private ISimpleView owner;
public CommentDialog(CloudBrowserFrame owner, ProjectEntity project, List<CommentEntity> comments, public CommentDialog(ISimpleView cloudUI, ProjectEntity project, List<CommentEntity> comments,
CloudPresenter presenter) { CloudPresenter presenter) {
super(owner, "Comments on " + project.getName()); super(cloudUI.getOwnerFrame(), "Comments on " + project.getName());
this.owner = owner;
this.project = project; this.project = project;
this.comments = comments; this.comments = comments;
this.presenter = presenter; this.presenter = presenter;
setMinimumSize(new Dimension(400, 600)); setMinimumSize(new Dimension(400, 600));
setContentPane(getMainPanel()); setContentPane(getMainPanel());
pack(); pack();
setLocationRelativeTo(owner); setLocationRelativeTo(cloudUI.getOwnerFrame());
setModal(true); setModal(true);
if (!presenter.isLoggedIn()) { if (!presenter.isLoggedIn()) {
getReplyArea().setEnabled(false); getReplyArea().setEnabled(false);
@@ -28,10 +28,13 @@ import org.diylc.images.IconLoader;
import org.diylc.plugins.cloud.model.ProjectEntity; import org.diylc.plugins.cloud.model.ProjectEntity;
import org.diylc.plugins.cloud.presenter.CloudPresenter; import org.diylc.plugins.cloud.presenter.CloudPresenter;
import org.diylc.plugins.cloud.presenter.PagingProvider; import org.diylc.plugins.cloud.presenter.PagingProvider;
import org.diylc.swing.ISimpleView;
import org.diylc.swing.ISwingUI; import org.diylc.swing.ISwingUI;
import org.diylc.utils.Pair; import org.diylc.utils.Pair;
public class CloudBrowserFrame extends JFrame { public class CloudBrowserFrame extends JFrame implements ISimpleView {
private static final String TITLE = "Search The Cloud";
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -52,7 +55,7 @@ public class CloudBrowserFrame extends JFrame {
private ISwingUI swingUI; private ISwingUI swingUI;
public CloudBrowserFrame(ISwingUI swingUI, IPlugInPort plugInPort, CloudPresenter cloudPresenter) { public CloudBrowserFrame(ISwingUI swingUI, IPlugInPort plugInPort, CloudPresenter cloudPresenter) {
super("Search The Cloud"); super(TITLE);
this.swingUI = swingUI; this.swingUI = swingUI;
this.setIconImage(IconLoader.Cloud.getImage()); this.setIconImage(IconLoader.Cloud.getImage());
this.setPreferredSize(new Dimension(700, 640)); this.setPreferredSize(new Dimension(700, 640));
@@ -201,6 +204,7 @@ public class CloudBrowserFrame extends JFrame {
}); });
} }
@Override
public <T extends Object> void executeBackgroundTask(final ITask<T> task) { public <T extends Object> void executeBackgroundTask(final ITask<T> task) {
getGlassPane().setVisible(true); getGlassPane().setVisible(true);
SwingWorker<T, Void> worker = new SwingWorker<T, Void>() { SwingWorker<T, Void> worker = new SwingWorker<T, Void>() {
@@ -228,11 +232,18 @@ public class CloudBrowserFrame extends JFrame {
worker.execute(); worker.execute();
} }
@Override
public void showMessage(String message, String title, int messageType) { public void showMessage(String message, String title, int messageType) {
JOptionPane.showMessageDialog(this, message, title, messageType); JOptionPane.showMessageDialog(this, message, title, messageType);
} }
@Override
public int showConfirmDialog(String message, String title, int optionType, int messageType) { public int showConfirmDialog(String message, String title, int optionType, int messageType) {
return JOptionPane.showConfirmDialog(this, message, title, optionType, messageType); return JOptionPane.showConfirmDialog(this, message, title, optionType, messageType);
} }
@Override
public JFrame getOwnerFrame() {
return this;
}
} }
@@ -44,6 +44,7 @@ import org.diylc.plugins.cloud.model.CommentEntity;
import org.diylc.plugins.cloud.model.ProjectEntity; import org.diylc.plugins.cloud.model.ProjectEntity;
import org.diylc.plugins.cloud.presenter.CloudPresenter; import org.diylc.plugins.cloud.presenter.CloudPresenter;
import org.diylc.plugins.cloud.presenter.PagingProvider; import org.diylc.plugins.cloud.presenter.PagingProvider;
import org.diylc.swing.ISimpleView;
import org.diylc.swing.ISwingUI; import org.diylc.swing.ISwingUI;
import org.diylc.swing.gui.DialogFactory; import org.diylc.swing.gui.DialogFactory;
import org.diylc.swing.plugins.cloud.view.CommentDialog; import org.diylc.swing.plugins.cloud.view.CommentDialog;
@@ -65,7 +66,7 @@ public class ResultsScrollPanel extends JScrollPane {
private JLabel topLabel; private JLabel topLabel;
private ISwingUI mainUI; private ISwingUI mainUI;
private CloudBrowserFrame cloudUI; private ISimpleView cloudUI;
private IPlugInPort plugInPort; private IPlugInPort plugInPort;
@@ -80,7 +81,7 @@ public class ResultsScrollPanel extends JScrollPane {
private Icon spinnerIcon = IconLoader.Spinning.getIcon(); private Icon spinnerIcon = IconLoader.Spinning.getIcon();
public ResultsScrollPanel(ISwingUI mainUI, CloudBrowserFrame cloudUI, IPlugInPort plugInPort, public ResultsScrollPanel(ISwingUI mainUI, ISimpleView cloudUI, IPlugInPort plugInPort,
PagingProvider provider, CloudPresenter cloudPresenter) { PagingProvider provider, CloudPresenter cloudPresenter) {
super(); super();
this.mainUI = mainUI; this.mainUI = mainUI;
@@ -157,7 +158,7 @@ public class ResultsScrollPanel extends JScrollPane {
getViewport().setViewPosition(old); getViewport().setViewPosition(old);
} }
}); });
if (provider.hasMoreData()) { if (provider != null && provider.hasMoreData()) {
getLoadMoreLabel().setText("Querying the cloud for more results..."); getLoadMoreLabel().setText("Querying the cloud for more results...");
getLoadMoreLabel().setIcon(spinnerIcon); getLoadMoreLabel().setIcon(spinnerIcon);
} else { } else {
@@ -387,7 +388,7 @@ public class ResultsScrollPanel extends JScrollPane {
@Override @Override
public void paint(Graphics g) { public void paint(Graphics g) {
super.paint(g); super.paint(g);
if (armed && provider.hasMoreData()) { if (armed && provider != null && provider.hasMoreData()) {
// disarm immediately so we don't trigger successive requests to the provider // disarm immediately so we don't trigger successive requests to the provider
armed = false; armed = false;
SwingWorker<List<ProjectEntity>, Void> worker = new SwingWorker<List<ProjectEntity>, Void>() { SwingWorker<List<ProjectEntity>, Void> worker = new SwingWorker<List<ProjectEntity>, Void>() {
@@ -0,0 +1,124 @@
package org.diylc.swing.plugins.cloud.view.browser;
import java.awt.Dimension;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import org.apache.log4j.Logger;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ITask;
import org.diylc.core.IView;
import org.diylc.images.IconLoader;
import org.diylc.plugins.cloud.model.ProjectEntity;
import org.diylc.plugins.cloud.presenter.CloudPresenter;
import org.diylc.swing.ISimpleView;
import org.diylc.swing.ISwingUI;
public class UploadManagerFrame extends JFrame implements ISimpleView {
private static final String TITLE = "Manage My Uploads";
private static final long serialVersionUID = 1L;
private static final Logger LOG = Logger.getLogger(UploadManagerFrame.class);
private ResultsScrollPanel resultsScrollPane;
private IPlugInPort plugInPort;
private CloudPresenter cloudPresenter;
private ISwingUI swingUI;
public UploadManagerFrame(ISwingUI swingUI, IPlugInPort plugInPort, CloudPresenter cloudPresenter) {
super(TITLE);
this.swingUI = swingUI;
this.setIconImage(IconLoader.CloudGear.getImage());
this.setPreferredSize(new Dimension(700, 640));
this.plugInPort = plugInPort;
this.cloudPresenter = cloudPresenter;
setContentPane(getResultsScrollPane());
this.pack();
this.setLocationRelativeTo(swingUI.getOwnerFrame());
this.setGlassPane(SimpleCloudGlassPane.GLASS_PANE);
search();
}
private ResultsScrollPanel getResultsScrollPane() {
if (resultsScrollPane == null) {
resultsScrollPane = new ResultsScrollPanel(swingUI, this, plugInPort, null, cloudPresenter);
}
return resultsScrollPane;
}
private void search() {
getResultsScrollPane().clearPrevious();
executeBackgroundTask(new ITask<List<ProjectEntity>>() {
@Override
public List<ProjectEntity> doInBackground() throws Exception {
return cloudPresenter.fetchUserUploads();
}
@Override
public void failed(Exception e) {
showMessage("Search failed! Detailed message is in the logs. Please report to the author.", "Search Failed",
IView.ERROR_MESSAGE);
}
@Override
public void complete(List<ProjectEntity> result) {
setTitle(TITLE + " - " + result.size() + " Uploads Found");
getResultsScrollPane().startSearch(result);
}
});
}
@Override
public <T extends Object> void executeBackgroundTask(final ITask<T> task) {
getGlassPane().setVisible(true);
SwingWorker<T, Void> worker = new SwingWorker<T, Void>() {
@Override
protected T doInBackground() throws Exception {
return task.doInBackground();
}
@Override
protected void done() {
getGlassPane().setVisible(false);
try {
T result = get();
task.complete(result);
} catch (ExecutionException e) {
LOG.error("Background task execution failed", e);
task.failed(e);
} catch (InterruptedException e) {
LOG.error("Background task execution interrupted", e);
task.failed(e);
}
}
};
worker.execute();
}
@Override
public void showMessage(String message, String title, int messageType) {
JOptionPane.showMessageDialog(this, message, title, messageType);
}
@Override
public int showConfirmDialog(String message, String title, int optionType, int messageType) {
return JOptionPane.showConfirmDialog(this, message, title, optionType, messageType);
}
@Override
public JFrame getOwnerFrame() {
return this;
}
}