diff --git a/diylc-server-api/v1/replaceProjectFiles.php b/diylc-server-api/v1/replaceProjectFiles.php
new file mode 100644
index 00000000..254b6652
--- /dev/null
+++ b/diylc-server-api/v1/replaceProjectFiles.php
@@ -0,0 +1,116 @@
+ 100000) {
+ echo "{\"string\":Thumbnail file is too big.}";
+ exit;
+}
+if ($projectFile['size'] > 10000000) {
+ echo "{\"string\":Project file is too big.}";
+ exit;
+}
+if (getimagesize($thumbnailFile['tmp_name']) == false) {
+ echo "{\"string\":Thumbnail image is not valid.}";
+ exit;
+}
+
+// Load help class
+require_once("properties.php");
+
+// Load properties
+$dbProperties = new Properties();
+$propertiesFile = fopen("db.properties", "rb");
+$dbProperties->load($propertiesFile);
+
+// Connect to the DB
+$username=$dbProperties->getProperty("user");
+$password=$dbProperties->getProperty("pass");
+$database=$dbProperties->getProperty("db");
+$mysqli = new mysqli(localhost,$username,$password,$database);
+
+// Verify that the user is logged in
+$sql = "
+SELECT user_id
+FROM diylc_user
+WHERE name = \"".addslashes($name)."\" AND token= \"".addslashes($token)."\" AND machine_id = \"".addslashes($machineId)."\"";
+
+if (!$result = $mysqli->query($sql)) {
+ echo "{\"string\":Error while looking up the user.}";
+ exit;
+}
+
+if ($row = $result->fetch_assoc()) {
+ $userId = $row["user_id"];
+
+ $sql = "
+ SELECT project_id
+ FROM diylc_project
+ WHERE project_id = \"".addslashes($projectId)."\" AND owner_user_id = \"".addslashes($userId)."\"";
+
+ if (!$result = $mysqli->query($sql)) {
+ echo "{\"string\":Error while looking up the project.}";
+ exit;
+ }
+
+ $sql= "
+ UPDATE diylc_project
+ SET diylc_version=\"".$diylcVersion."\", last_update = NOW()
+ WHERE project_id=".addslashes($projectId)." AND owner_user_id=".$userId;
+
+ if (!$result = $mysqli->query($sql) || $mysqli->affected_rows == 0) {
+ echo "{\"string\":\"Error while uploading the project into the database.".$mysqli->error."\"}";
+ exit;
+ } else {
+ // Move the uploaded files
+ if (move_uploaded_file($thumbnailFile['tmp_name'], '/home/diyfever/public_html/diylc/thumbnails/'.$projectId.".png") and
+ move_uploaded_file($projectFile['tmp_name'], '/home/diyfever/public_html/diylc/uploads/'.$projectId.".diy"))
+ echo "{\"string\":Success}";
+ else {
+ echo "{\"string\":Error processing uploaded files.}";
+ }
+ }
+} else {
+ echo "{\"string\":User is not logged in.}";
+}
+
+$mysqli->close();
+
+?>
\ No newline at end of file
diff --git a/diylc-server-api/v1/uploadProject.php b/diylc-server-api/v1/uploadProject.php
index 8752477d..2c2d7772 100644
--- a/diylc-server-api/v1/uploadProject.php
+++ b/diylc-server-api/v1/uploadProject.php
@@ -39,11 +39,11 @@ if (!$diylcVersion) {
echo "{\"string\":DIYLC version not provided.}";
exit;
}
-if (!$thumbnailFile && !projectId) {
+if (!$thumbnailFile && !$projectId) {
echo "{\"string\":Thumbnail file not uploaded.}";
exit;
}
-if (!$projectFile && !projectId) {
+if (!$projectFile && !$projectId) {
echo "{\"string\":Project file not uploaded.}";
exit;
}
@@ -55,7 +55,7 @@ if ($projectFile['size'] > 10000000) {
echo "{\"string\":Project file is too big.}";
exit;
}
-if (!projectId && getimagesize($thumbnailFile['tmp_name']) == false) {
+if (!$projectId && getimagesize($thumbnailFile['tmp_name']) == false) {
echo "{\"string\":Thumbnail image is not valid.}";
exit;
}
diff --git a/diylc/diylc-core/src/org/diylc/plugins/cloud/model/IServiceAPI.java b/diylc/diylc-core/src/org/diylc/plugins/cloud/model/IServiceAPI.java
index 7eadbb1d..c7873032 100644
--- a/diylc/diylc-core/src/org/diylc/plugins/cloud/model/IServiceAPI.java
+++ b/diylc/diylc-core/src/org/diylc/plugins/cloud/model/IServiceAPI.java
@@ -149,6 +149,23 @@ public interface IServiceAPI {
@ParamName("category") String category, @ParamName("description") String description,
@ParamName("diylcVersion") String diylcVersion, @ParamName("keywords") String keywords,
@ParamName("thumbnail") File thumbnail, @ParamName("project") File project,
+ @ParamName("projectId") Integer projectId);
+
+ /**
+ * Replaces project files using token to authenticate. The project must belong to the user.
+ *
+ * @param username
+ * @param token
+ * @param machineId
+ * @param diylcVersion
+ * @param thumbnail
+ * @param project
+ * @param projectId
+ * @return "Success" if the upload was successful or error message if it failed.
+ */
+ String replaceProjectFiles(@ParamName("username") String username, @ParamName("token") String token,
+ @ParamName("machineId") String machineId, @ParamName("diylcVersion") String diylcVersion,
+ @ParamName("thumbnail") File thumbnail, @ParamName("project") File project,
@ParamName("projectId") Integer projectId);
/**
diff --git a/diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/CloudPresenter.java b/diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/CloudPresenter.java
index 0a564461..385b292a 100644
--- a/diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/CloudPresenter.java
+++ b/diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/CloudPresenter.java
@@ -167,8 +167,12 @@ public class CloudPresenter {
if (username == null || token == null)
throw new CloudException("Login failed. Please try to login again.");
-
- LOG.info("Uploading a new project: " + projectName);
+
+ if (projectId == null)
+ LOG.info("Uploading a new project: " + projectName);
+ else
+ LOG.info("Updating project: " + projectId);
+
try {
String res =
getService().uploadProject(username, token, getMachineId(), projectName, category, description, diylcVersion,
@@ -178,6 +182,24 @@ public class CloudPresenter {
} catch (Exception e) {
throw new CloudException(e);
}
+ }
+
+ public void replaceProjectFile(String diylcVersion, File thumbnail, File project, Integer projectId) throws IOException, CloudException {
+ String username = ConfigurationManager.getInstance().readString(USERNAME_KEY, null);
+ String token = ConfigurationManager.getInstance().readString(TOKEN_KEY, null);
+
+ if (username == null || token == null)
+ throw new CloudException("Login failed. Please try to login again.");
+
+ LOG.info("Replacing project files for: " + projectId);
+ try {
+ String res =
+ getService().replaceProjectFiles(username, token, getMachineId(), diylcVersion, thumbnail, project, projectId);
+ if (!res.equals(SUCCESS))
+ throw new CloudException(res);
+ } catch (Exception e) {
+ throw new CloudException(e);
+ }
}
public void updateProjectDetails(ProjectEntity project, String diylcVersion) throws IOException, CloudException {
diff --git a/diylc/diylc-swing/.gitignore b/diylc/diylc-swing/.gitignore
index c35c3382..6a7aab75 100644
--- a/diylc/diylc-swing/.gitignore
+++ b/diylc/diylc-swing/.gitignore
@@ -5,4 +5,5 @@
/library/
/lib/diylc-core.jar
autoSave.diy
-config.xml
\ No newline at end of file
+config.xml
+/launch4j.log
diff --git a/diylc/diylc-swing/izpack.xml b/diylc/diylc-swing/izpack.xml
index 9aaacfd7..1df0aaaa 100644
--- a/diylc/diylc-swing/izpack.xml
+++ b/diylc/diylc-swing/izpack.xml
@@ -43,9 +43,6 @@
-
-
diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java
index 39e7d86d..29d89b96 100644
--- a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java
+++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java
@@ -1,215 +1,213 @@
/*
+ *
+ * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
+ *
+ * This file is part of DIYLC.
+ *
+ * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with DIYLC. If not, see
+ * .
+ *
+ */
+package org.diylc.swing.plugins.cloud.view.browser;
- DIY Layout Creator (DIYLC).
- Copyright (c) 2009-2018 held jointly by the individual authors.
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.FlowLayout;
+import java.awt.Graphics;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.net.URL;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.util.List;
- This file is part of DIYLC.
+import javax.imageio.ImageIO;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSeparator;
+import javax.swing.JTextArea;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.SwingWorker;
+import javax.swing.text.DefaultCaret;
- DIYLC is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- DIYLC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DIYLC. If not, see .
-
-*/
-package org.diylc.swing.plugins.cloud.view.browser;
-
-import java.awt.Color;
-import java.awt.Cursor;
-import java.awt.FlowLayout;
-import java.awt.Graphics;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.awt.Point;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.net.URL;
-import java.nio.channels.Channels;
-import java.nio.channels.ReadableByteChannel;
-import java.util.List;
-
-import javax.imageio.ImageIO;
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-import javax.swing.JComponent;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JSeparator;
-import javax.swing.JTextArea;
-import javax.swing.SwingConstants;
-import javax.swing.SwingUtilities;
-import javax.swing.SwingWorker;
-import javax.swing.text.DefaultCaret;
-
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.InMemoryConfigurationManager;
-import org.diylc.common.IPlugInPort;
-import org.diylc.common.ITask;
-import org.diylc.common.PropertyWrapper;
+import org.diylc.common.IPlugInPort;
+import org.diylc.common.ITask;
+import org.diylc.common.PropertyWrapper;
import org.diylc.core.IView;
import org.diylc.swing.images.IconLoader;
-import org.diylc.plugins.cloud.model.CommentEntity;
-import org.diylc.plugins.cloud.model.ProjectEntity;
-import org.diylc.plugins.cloud.presenter.CloudPresenter;
-import org.diylc.plugins.cloud.presenter.SearchSession;
-import org.diylc.presenter.Presenter;
-import org.diylc.swing.ISimpleView;
-import org.diylc.swing.ISwingUI;
-import org.diylc.swing.gui.DialogFactory;
-import org.diylc.swing.gui.DummyView;
-import org.diylc.swing.gui.components.HTMLTextArea;
-import org.diylc.swing.gui.editor.PropertyEditorDialog;
-import org.diylc.swing.plugins.cloud.view.CommentDialog;
-import org.diylc.swing.plugins.cloud.view.UploadDialog;
-import org.diylc.swing.plugins.file.FileFilterEnum;
-import org.diylc.swingframework.ButtonDialog;
-
-/**
- * Component that is capable of showing a list of {@link ProjectEntity} objects. Can work in paging
- * mode and pull one page of data at a time.
- *
- * @see {@link SearchSession}
- *
- * @author Branislav Stojkovic
- */
-public class ResultsScrollPanel extends JScrollPane {
-
- private static final long serialVersionUID = 1L;
-
- private static final Logger LOG = Logger.getLogger(ResultsScrollPanel.class);
-
- private JPanel resultsPanel;
- /**
- * This label goes at the end of the page. When it gets rendered we know that we need to request
- * another page.
- */
- private JLabel loadMoreLabel;
-
- private JLabel topLabel;
-
- private ISwingUI mainUI;
- private ISimpleView cloudUI;
-
- private IPlugInPort plugInPort;
-
- private int currentLocation;
- /**
- * This flag tells us whether the loadMoreLabel should invoke a new data pull or not.
- */
- private boolean armed;
- private SearchSession searchSession;
-
- private Icon spinnerIcon = IconLoader.Spinning.getIcon();
-
- private boolean showEditControls;
-
- public ResultsScrollPanel(ISwingUI mainUI, ISimpleView cloudUI, IPlugInPort plugInPort, SearchSession searchSession,
- boolean showEditControls) {
- super();
- this.mainUI = mainUI;
- this.cloudUI = cloudUI;
- this.plugInPort = plugInPort;
- this.searchSession = searchSession;
- this.showEditControls = showEditControls;
-
- this.getVerticalScrollBar().setUnitIncrement(16);
- this.setBorder(null);
- setViewportView(getResultsPanel());
- }
-
- public void clearPrevious() {
- currentLocation = 0;
- getResultsPanel().removeAll();
- armed = false;
- }
-
- public void startSearch(List projects) {
- GridBagConstraints gbc = new GridBagConstraints();
- gbc.anchor = GridBagConstraints.NORTHWEST;
- gbc.gridx = 0;
- gbc.gridy = 10000;
- gbc.fill = GridBagConstraints.BOTH;
- gbc.weightx = 100;
- gbc.weighty = 100;
- gbc.gridwidth = 3;
- resultsPanel.add(getLoadMoreLabel(), gbc);
-
- gbc.gridx = 3;
- gbc.gridwidth = 2;
- gbc.weightx = 0;
- gbc.insets = new Insets(0, 0, 0, 2);
- gbc.fill = GridBagConstraints.NONE;
- gbc.anchor = GridBagConstraints.LINE_END;
- resultsPanel.add(getTopLabel(), gbc);
-
- addData(projects);
- }
-
- public void showNoMatches() {
- JLabel label =
- new JLabel("No projects match the search criteria.");
- label.setHorizontalAlignment(SwingConstants.CENTER);
- GridBagConstraints gbc = new GridBagConstraints();
- gbc.insets = new Insets(2, 2, 2, 2);
- gbc.gridx = 0;
- gbc.gridy = 0;
- gbc.fill = GridBagConstraints.BOTH;
- gbc.weightx = 1;
- gbc.weighty = Integer.MAX_VALUE;
- getResultsPanel().add(label, gbc);
- getLoadMoreLabel().setText("");
- getLoadMoreLabel().setIcon(null);
- remove(getTopLabel());
- }
-
- public void addData(List projects) {
- if (projects == null || projects.isEmpty() && currentLocation == 0) {
- showNoMatches();
- } else {
- final Point old = getViewport().getViewPosition();
- LOG.info("Adding " + projects.size() + " projects to display.");
- for (ProjectEntity project : projects) {
- addProjectToDisplay(project);
- this.currentLocation++;
- }
- getResultsPanel().invalidate();
- getResultsPanel().revalidate();
-
- // Reset scrollbar position, for some reason it jumps to the last added element
- SwingUtilities.invokeLater(new Runnable() {
-
- @Override
- public void run() {
- old.translate(0, -16);
- getViewport().setViewPosition(old);
- LOG.info("Paging mechanism is armed");
- armed = true;
- }
- });
-
- if (searchSession != null && searchSession.hasMoreData()) {
- getLoadMoreLabel().setText("Querying the cloud for more results...");
- getLoadMoreLabel().setIcon(spinnerIcon);
- } else {
- getLoadMoreLabel().setText("No more results.");
- getLoadMoreLabel().setIcon(null);
- }
- }
- }
-
+import org.diylc.plugins.cloud.model.CommentEntity;
+import org.diylc.plugins.cloud.model.ProjectEntity;
+import org.diylc.plugins.cloud.presenter.CloudPresenter;
+import org.diylc.plugins.cloud.presenter.SearchSession;
+import org.diylc.presenter.Presenter;
+import org.diylc.swing.ISimpleView;
+import org.diylc.swing.ISwingUI;
+import org.diylc.swing.gui.DialogFactory;
+import org.diylc.swing.gui.DummyView;
+import org.diylc.swing.gui.components.HTMLTextArea;
+import org.diylc.swing.gui.editor.PropertyEditorDialog;
+import org.diylc.swing.plugins.cloud.view.CommentDialog;
+import org.diylc.swing.plugins.cloud.view.UploadDialog;
+import org.diylc.swing.plugins.file.FileFilterEnum;
+import org.diylc.swingframework.ButtonDialog;
+import org.diylc.utils.Pair;
+
+/**
+ * Component that is capable of showing a list of {@link ProjectEntity} objects. Can work in paging
+ * mode and pull one page of data at a time.
+ *
+ * @see {@link SearchSession}
+ *
+ * @author Branislav Stojkovic
+ */
+public class ResultsScrollPanel extends JScrollPane {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Logger LOG = Logger.getLogger(ResultsScrollPanel.class);
+
+ private JPanel resultsPanel;
+ /**
+ * This label goes at the end of the page. When it gets rendered we know that we need to request
+ * another page.
+ */
+ private JLabel loadMoreLabel;
+
+ private JLabel topLabel;
+
+ private ISwingUI mainUI;
+ private ISimpleView cloudUI;
+
+ private IPlugInPort plugInPort;
+
+ private int currentLocation;
+ /**
+ * This flag tells us whether the loadMoreLabel should invoke a new data pull or not.
+ */
+ private boolean armed;
+ private SearchSession searchSession;
+
+ private Icon spinnerIcon = IconLoader.Spinning.getIcon();
+
+ private boolean showEditControls;
+
+ public ResultsScrollPanel(ISwingUI mainUI, ISimpleView cloudUI, IPlugInPort plugInPort,
+ SearchSession searchSession, boolean showEditControls) {
+ super();
+ this.mainUI = mainUI;
+ this.cloudUI = cloudUI;
+ this.plugInPort = plugInPort;
+ this.searchSession = searchSession;
+ this.showEditControls = showEditControls;
+
+ this.getVerticalScrollBar().setUnitIncrement(16);
+ this.setBorder(null);
+ setViewportView(getResultsPanel());
+ }
+
+ public void clearPrevious() {
+ currentLocation = 0;
+ getResultsPanel().removeAll();
+ armed = false;
+ }
+
+ public void startSearch(List projects) {
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.anchor = GridBagConstraints.NORTHWEST;
+ gbc.gridx = 0;
+ gbc.gridy = 10000;
+ gbc.fill = GridBagConstraints.BOTH;
+ gbc.weightx = 100;
+ gbc.weighty = 100;
+ gbc.gridwidth = 3;
+ resultsPanel.add(getLoadMoreLabel(), gbc);
+
+ gbc.gridx = 3;
+ gbc.gridwidth = 2;
+ gbc.weightx = 0;
+ gbc.insets = new Insets(0, 0, 0, 2);
+ gbc.fill = GridBagConstraints.NONE;
+ gbc.anchor = GridBagConstraints.LINE_END;
+ resultsPanel.add(getTopLabel(), gbc);
+
+ addData(projects);
+ }
+
+ public void showNoMatches() {
+ JLabel label = new JLabel(
+ "No projects match the search criteria.");
+ label.setHorizontalAlignment(SwingConstants.CENTER);
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.insets = new Insets(2, 2, 2, 2);
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.fill = GridBagConstraints.BOTH;
+ gbc.weightx = 1;
+ gbc.weighty = Integer.MAX_VALUE;
+ getResultsPanel().add(label, gbc);
+ getLoadMoreLabel().setText("");
+ getLoadMoreLabel().setIcon(null);
+ remove(getTopLabel());
+ }
+
+ public void addData(List projects) {
+ if (projects == null || projects.isEmpty() && currentLocation == 0) {
+ showNoMatches();
+ } else {
+ final Point old = getViewport().getViewPosition();
+ LOG.info("Adding " + projects.size() + " projects to display.");
+ for (ProjectEntity project : projects) {
+ addProjectToDisplay(project);
+ this.currentLocation++;
+ }
+ getResultsPanel().invalidate();
+ getResultsPanel().revalidate();
+
+ // Reset scrollbar position, for some reason it jumps to the last added element
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+ old.translate(0, -16);
+ getViewport().setViewPosition(old);
+ LOG.info("Paging mechanism is armed");
+ armed = true;
+ }
+ });
+
+ if (searchSession != null && searchSession.hasMoreData()) {
+ getLoadMoreLabel().setText("Querying the cloud for more results...");
+ getLoadMoreLabel().setIcon(spinnerIcon);
+ } else {
+ getLoadMoreLabel().setText("No more results.");
+ getLoadMoreLabel().setIcon(null);
+ }
+ }
+ }
+
private JComponent addProjectToDisplay(final ProjectEntity project) {
final JLabel thumbnailLabel = new JLabel(loadImage(project.getThumbnailUrl()));
final JLabel nameLabel = new JLabel("" + project.getName() + "");
@@ -395,83 +393,74 @@ public class ResultsScrollPanel extends JScrollPane {
replaceButton.setFocusable(true);
replaceButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
replaceButton.setToolTipText("Replace project with a new version");
- replaceButton.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseClicked(MouseEvent e) {
- if (cloudUI.showConfirmDialog(
- "Are you sure you want to replace the project \""
- + project.getName()
- + "\" with a new file?\nThis opperation is irreversible. Once replaced, the old version of the project cannot be restored.",
- "Replace Project", IView.YES_NO_OPTION, IView.QUESTION_MESSAGE) == IView.YES_OPTION) {
- final Presenter thumbnailPresenter = new Presenter(new DummyView(), InMemoryConfigurationManager.getInstance());
- final File file =
- DialogFactory.getInstance().showOpenDialog(FileFilterEnum.DIY.getFilter(), null,
- FileFilterEnum.DIY.getExtensions()[0], null, cloudUI.getOwnerFrame());
- if (file != null) {
- LOG.info("Preparing replacement for project " + project.getName() + "(" + project.getId() + ")");
- cloudUI.executeBackgroundTask(new ITask() {
-
- @Override
- public String[] doInBackground() throws Exception {
- LOG.debug("Uploading from " + file.getAbsolutePath());
- thumbnailPresenter.loadProjectFromFile(file.getAbsolutePath());
- return CloudPresenter.Instance.getCategories();
- }
-
- @Override
- public void complete(final String[] result) {
- final UploadDialog dialog =
- DialogFactory.getInstance().createUploadDialog(cloudUI.getOwnerFrame(), thumbnailPresenter, result,
- true);
- dialog.setVisible(true);
- if (ButtonDialog.OK.equals(dialog.getSelectedButtonCaption())) {
- try {
- final File thumbnailFile = File.createTempFile("upload-thumbnail", ".png");
- if (ImageIO.write(dialog.getThumbnail(), "png", thumbnailFile)) {
- cloudUI.executeBackgroundTask(new ITask() {
-
- @Override
- public ProjectEntity doInBackground() throws Exception {
- CloudPresenter.Instance.uploadProject(dialog.getName(), dialog.getCategory(), dialog
- .getDescription(), dialog.getKeywords(), plugInPort.getCurrentVersionNumber().toString(),
- thumbnailFile, file, project.getId());
- return CloudPresenter.Instance.fetchUserUploads(project.getId()).get(0);
- }
-
- @Override
- public void failed(Exception e) {
- cloudUI.showMessage(e.getMessage(), "Upload Error", IView.ERROR_MESSAGE);
- }
-
- @Override
- public void complete(ProjectEntity result) {
- nameLabel.setText("" + project.getName() + "");
- descriptionArea.setText(result.getDescription());
- categoryLabel.setText("Category: " + result.getCategory() + "");
- updatedLabel.setText("Last updated: " + result.getUpdated() + "");
- thumbnailLabel.setIcon(new ImageIcon(dialog.getThumbnail()));
- cloudUI.showMessage("The project has been replaced successfully.", "Upload Success",
- IView.INFORMATION_MESSAGE);
- }
- });
- } else {
- cloudUI.showMessage("Could not prepare temporary files to be uploaded to the cloud.",
- "Upload Error", IView.ERROR_MESSAGE);
- }
- } catch (Exception e) {
- cloudUI.showMessage(e.getMessage(), "Upload Error", IView.ERROR_MESSAGE);
- }
- }
- }
-
- @Override
- public void failed(Exception e) {
- cloudUI.showMessage("Could not open file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE);
- }
- });
- }
- }
- }
+ replaceButton.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (cloudUI.showConfirmDialog("Are you sure you want to replace the project \""
+ + project.getName()
+ + "\" with a new file?\nThis opperation is irreversible. Once replaced, the old version of the project cannot be restored.",
+ "Replace Project", IView.YES_NO_OPTION, IView.QUESTION_MESSAGE) == IView.YES_OPTION) {
+ final Presenter thumbnailPresenter =
+ new Presenter(new DummyView(), InMemoryConfigurationManager.getInstance());
+ final File file =
+ DialogFactory.getInstance().showOpenDialog(FileFilterEnum.DIY.getFilter(), null,
+ FileFilterEnum.DIY.getExtensions()[0], null, cloudUI.getOwnerFrame());
+ if (file != null) {
+ LOG.info("Preparing replacement for project " + project.getName() + "("
+ + project.getId() + ")");
+ cloudUI.executeBackgroundTask(new ITask>() {
+
+ @Override
+ public Pair doInBackground() throws Exception {
+ LOG.debug("Uploading from " + file.getAbsolutePath());
+ thumbnailPresenter.loadProjectFromFile(file.getAbsolutePath());
+ final UploadDialog dialog = DialogFactory.getInstance().createUploadDialog(
+ cloudUI.getOwnerFrame(), thumbnailPresenter, new String[0], true);
+ final File thumbnailFile = File.createTempFile("upload-thumbnail", ".png");
+ if (ImageIO.write(dialog.getThumbnail(), "png", thumbnailFile)) {
+ CloudPresenter.Instance.replaceProjectFile(
+ plugInPort.getCurrentVersionNumber().toString(), thumbnailFile, file,
+ project.getId());
+ return new Pair(dialog.getThumbnail(),
+ CloudPresenter.Instance.fetchUserUploads(project.getId()).get(0));
+ } else {
+ cloudUI.showMessage(
+ "Could not prepare temporary files to be uploaded to the cloud.",
+ "Upload Error", IView.ERROR_MESSAGE);
+ return null;
+ }
+ }
+
+ @Override
+ public void complete(final Pair result) {
+ if (result != null) {
+ BufferedImage thumbnail = result.getFirst();
+ ProjectEntity project = result.getSecond();
+ nameLabel.setText("" + project.getName() + "");
+ descriptionArea.setText(project.getDescription());
+ categoryLabel
+ .setText("Category: " + project.getCategory() + "");
+ updatedLabel
+ .setText("Last updated: " + project.getUpdated() + "");
+ thumbnailLabel.setIcon(new ImageIcon(thumbnail));
+ cloudUI.showMessage("The project has been replaced successfully.",
+ "Upload Success", IView.INFORMATION_MESSAGE);
+ } else {
+ cloudUI.showMessage("Unexpected error occurred while replacing the project.",
+ "Upload Error", IView.ERROR_MESSAGE);
+ }
+ }
+
+ public void failed(Exception e) {
+ cloudUI.showMessage(
+ "Could not update the project. Detailed message is in the logs.", "Error",
+ ISwingUI.ERROR_MESSAGE);
+ LOG.error("Error replacing project files", e);
+ }
+ });
+ }
+ }
+ }
});
final JLabel deleteButton = new JLabel(IconLoader.CloudDelete.getIcon());
@@ -602,77 +591,78 @@ public class ResultsScrollPanel extends JScrollPane {
getResultsPanel().add(separator, gbc);
return nameLabel;
- }
-
- public JLabel getTopLabel() {
- if (topLabel == null) {
- topLabel = new JLabel("To the top");
- topLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
- topLabel.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseClicked(MouseEvent e) {
- getViewport().setViewPosition(new Point(0, 0));
- }
- });
- }
- return topLabel;
- }
-
- private JLabel getLoadMoreLabel() {
- if (loadMoreLabel == null) {
- loadMoreLabel = new JLabel("Loading more data...") {
-
- private static final long serialVersionUID = 1L;
-
- @Override
- public void paint(Graphics g) {
- super.paint(g);
- if (armed && searchSession != null && searchSession.hasMoreData()) {
- // disarm immediately so we don't trigger successive requests to the provider
- LOG.info("Paging mechanism is disarmed");
- armed = false;
- SwingWorker, Void> worker = new SwingWorker, Void>() {
-
- @Override
- protected List doInBackground() throws Exception {
- return searchSession.requestMoreData();
- }
-
- @Override
- protected void done() {
- try {
- List newResults = get();
- addData(newResults);
- } catch (Exception e) {
- cloudUI.showMessage("Search failed! Detailed message is in the logs.", "Search Failed",
- IView.ERROR_MESSAGE);
- }
- }
- };
- worker.execute();
- }
- }
- };
- loadMoreLabel.setHorizontalAlignment(SwingConstants.CENTER);
- loadMoreLabel.setFont(loadMoreLabel.getFont().deriveFont(10f));
- }
- return loadMoreLabel;
- }
-
- private JPanel getResultsPanel() {
- if (resultsPanel == null) {
- resultsPanel = new JPanel(new GridBagLayout());
- resultsPanel.setBackground(Color.white);
- }
- return resultsPanel;
- }
-
- private Icon loadImage(String imageFile) {
- try {
- BufferedImage img = ImageIO.read(new File(imageFile));
- return new ImageIcon(img);
- } catch (Exception e) {
- return IconLoader.MissingImage.getIcon();
- }
- }
-}
+ }
+
+ public JLabel getTopLabel() {
+ if (topLabel == null) {
+ topLabel = new JLabel("To the top");
+ topLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ topLabel.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ getViewport().setViewPosition(new Point(0, 0));
+ }
+ });
+ }
+ return topLabel;
+ }
+
+ private JLabel getLoadMoreLabel() {
+ if (loadMoreLabel == null) {
+ loadMoreLabel = new JLabel("Loading more data...") {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void paint(Graphics g) {
+ super.paint(g);
+ if (armed && searchSession != null && searchSession.hasMoreData()) {
+ // disarm immediately so we don't trigger successive requests to the provider
+ LOG.info("Paging mechanism is disarmed");
+ armed = false;
+ SwingWorker, Void> worker =
+ new SwingWorker, Void>() {
+
+ @Override
+ protected List doInBackground() throws Exception {
+ return searchSession.requestMoreData();
+ }
+
+ @Override
+ protected void done() {
+ try {
+ List newResults = get();
+ addData(newResults);
+ } catch (Exception e) {
+ cloudUI.showMessage("Search failed! Detailed message is in the logs.",
+ "Search Failed", IView.ERROR_MESSAGE);
+ }
+ }
+ };
+ worker.execute();
+ }
+ }
+ };
+ loadMoreLabel.setHorizontalAlignment(SwingConstants.CENTER);
+ loadMoreLabel.setFont(loadMoreLabel.getFont().deriveFont(10f));
+ }
+ return loadMoreLabel;
+ }
+
+ private JPanel getResultsPanel() {
+ if (resultsPanel == null) {
+ resultsPanel = new JPanel(new GridBagLayout());
+ resultsPanel.setBackground(Color.white);
+ }
+ return resultsPanel;
+ }
+
+ private Icon loadImage(String imageFile) {
+ try {
+ BufferedImage img = ImageIO.read(new File(imageFile));
+ return new ImageIcon(img);
+ } catch (Exception e) {
+ return IconLoader.MissingImage.getIcon();
+ }
+ }
+}