You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2020/05/04 09:18:09 UTC
[cayenne] branch master updated: CAY-2656 Modeler: option to
download required jars directly from maven central
This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
The following commit(s) were added to refs/heads/master by this push:
new bf31182 CAY-2656 Modeler: option to download required jars directly from maven central
new 325ecff Merge pull request #420 from stariy95/4.2-FEATURE-modeler-classpath-download-from-central
bf31182 is described below
commit bf311828c0e67aeae92822665abd503e4c8446aa
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Thu Apr 30 14:06:26 2020 +0300
CAY-2656 Modeler: option to download required jars directly from maven central
---
.../modeler/dialog/pref/ClasspathPreferences.java | 113 ++++++++--------
.../dialog/pref/ClasspathPreferencesView.java | 7 +
.../modeler/dialog/pref/MavenDependencyDialog.java | 148 +++++++++++++++++++++
.../dialog/pref/MavenDependencyDialogView.java | 101 ++++++++++++++
4 files changed, 310 insertions(+), 59 deletions(-)
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/ClasspathPreferences.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/ClasspathPreferences.java
index e3cf205..052cdf1 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/ClasspathPreferences.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/ClasspathPreferences.java
@@ -43,12 +43,13 @@ public class ClasspathPreferences extends CayenneController {
private static final Logger logger = LoggerFactory.getLogger(ClasspathPreferences.class);
- protected ClasspathPreferencesView view;
- protected List<String> classPathEntries;
- protected ClasspathTableModel tableModel;
- protected CayennePreferenceEditor editor;
- protected List<String> classPathKeys;
- private Preferences preferences;
+ private final ClasspathPreferencesView view;
+ private final List<String> classPathEntries;
+ private final List<String> classPathKeys;
+ private final ClasspathTableModel tableModel;
+ private final CayennePreferenceEditor editor;
+ private final Preferences preferences;
+
private int counter;
public ClasspathPreferences(PreferenceDialog parentController) {
@@ -56,29 +57,24 @@ public class ClasspathPreferences extends CayenneController {
this.view = new ClasspathPreferencesView();
+ PreferenceEditor editor = parentController.getEditor();
+ this.editor = editor instanceof CayennePreferenceEditor
+ ? (CayennePreferenceEditor) editor
+ : null;
+
// this prefs node is shared with other dialog panels... be aware of
// that when accessing the keys
this.preferences = getApplication().getPreferencesNode(this.getClass(), "");
- PreferenceEditor editor = parentController.getEditor();
- if (editor instanceof CayennePreferenceEditor) {
- this.editor = (CayennePreferenceEditor) editor;
- }
-
- List<String> classPathEntries = new ArrayList<String>();
- List<String> classPathKeys = new ArrayList<String>();
-
- this.counter = loadPreferences(classPathEntries, classPathKeys);
-
- this.classPathEntries = classPathEntries;
- this.classPathKeys = classPathKeys;
-
- this.tableModel = new ClasspathTableModel();
+ this.classPathEntries = new ArrayList<>();
+ this.classPathKeys = new ArrayList<>();
+ this.counter = loadPreferences();
+ this.tableModel = new ClasspathTableModel(classPathEntries);
initBindings();
}
- private int loadPreferences(List<String> classPathEntries, List<String> classPathKeys) {
+ private synchronized int loadPreferences() {
String[] cpKeys;
try {
@@ -89,13 +85,12 @@ public class ClasspathPreferences extends CayenneController {
}
int max = 0;
-
for (String cpKey : cpKeys) {
-
- int c;
-
try {
- c = Integer.parseInt(cpKey);
+ int c = Integer.parseInt(cpKey);
+ if (c > max) {
+ max = c;
+ }
} catch (NumberFormatException e) {
// we are sharing the 'preferences' node with other dialogs, and
// this is a rather poor way of telling our preference keys from
@@ -106,10 +101,6 @@ public class ClasspathPreferences extends CayenneController {
continue;
}
- if (c > max) {
- max = c;
- }
-
String tempValue = preferences.get(cpKey, "");
if (!"".equals(tempValue)) {
classPathEntries.add(tempValue);
@@ -127,8 +118,9 @@ public class ClasspathPreferences extends CayenneController {
protected void initBindings() {
view.getTable().setModel(tableModel);
view.getAddDirButton().addActionListener(e -> addClassDirectoryAction());
- view.getRemoveEntryButton().addActionListener(e -> removeEntryAction());
view.getAddJarButton().addActionListener(e -> addJarOrZipAction());
+ view.getAddMvnButton().addActionListener(e -> addMvnDependencyAction());
+ view.getRemoveEntryButton().addActionListener(e -> removeEntryAction());
}
protected void addJarOrZipAction() {
@@ -139,13 +131,18 @@ public class ClasspathPreferences extends CayenneController {
chooseClassEntry(null, "Select Java Class Directory.", JFileChooser.DIRECTORIES_ONLY);
}
- protected void removeEntryAction() {
+ protected void addMvnDependencyAction() {
+ MavenDependencyDialog dialog = new MavenDependencyDialog(this);
+ dialog.getView().setVisible(true);
+ }
+
+ protected synchronized void removeEntryAction() {
int selected = view.getTable().getSelectedRow();
if (selected < 0) {
return;
}
- addRemovedPreferences(classPathKeys.get(selected));
+ updatePreferences(classPathKeys.get(selected), "");
classPathEntries.remove(selected);
classPathKeys.remove(selected);
@@ -157,13 +154,10 @@ public class ClasspathPreferences extends CayenneController {
chooser.setFileSelectionMode(selectionMode);
chooser.setDialogType(JFileChooser.OPEN_DIALOG);
chooser.setAcceptAllFileFilterUsed(true);
-
getLastDirectory().updateChooser(chooser);
-
if (filter != null) {
chooser.addChoosableFileFilter(filter);
}
-
chooser.setDialogTitle(title);
File selected = null;
@@ -172,25 +166,29 @@ public class ClasspathPreferences extends CayenneController {
selected = chooser.getSelectedFile();
}
- if (selected != null) {
- if (!classPathEntries.contains(selected.getAbsolutePath())) {
- // store last dir in preferences
- getLastDirectory().updateFromChooser(chooser);
+ // store last dir in preferences
+ getLastDirectory().updateFromChooser(chooser);
+ // add to classpath list
+ addClasspathEntry(selected);
+ }
- int len = classPathEntries.size();
- int key = ++counter;
+ public synchronized void addClasspathEntry(File selected) {
+ if (selected == null || classPathEntries.contains(selected.getAbsolutePath())) {
+ return;
+ }
- String value = selected.getAbsolutePath();
- addChangedPreferences(Integer.toString(key), value);
- classPathEntries.add(value);
- classPathKeys.add(Integer.toString(key));
+ int len = classPathEntries.size();
+ int key = ++counter;
- tableModel.fireTableRowsInserted(len, len);
- }
- }
+ String value = selected.getAbsolutePath();
+ updatePreferences(Integer.toString(key), value);
+ classPathEntries.add(value);
+ classPathKeys.add(Integer.toString(key));
+
+ tableModel.fireTableRowsInserted(len, len);
}
- public void addChangedPreferences(String key, String value) {
+ public void updatePreferences(String key, String value) {
Map<String, String> map = editor.getChangedPreferences().get(preferences);
if (map == null) {
map = new HashMap<>();
@@ -199,16 +197,13 @@ public class ClasspathPreferences extends CayenneController {
editor.getChangedPreferences().put(preferences, map);
}
- public void addRemovedPreferences(String key) {
- Map<String, String> map = editor.getRemovedPreferences().get(preferences);
- if (map == null) {
- map = new HashMap<>();
- }
- map.put(key, "");
- editor.getRemovedPreferences().put(preferences, map);
- }
+ static class ClasspathTableModel extends AbstractTableModel {
- class ClasspathTableModel extends AbstractTableModel {
+ private final List<String> classPathEntries;
+
+ ClasspathTableModel(List<String> classPathEntries) {
+ this.classPathEntries = classPathEntries;
+ }
public int getColumnCount() {
return 1;
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/ClasspathPreferencesView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/ClasspathPreferencesView.java
index 292d362..6b0574c 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/ClasspathPreferencesView.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/ClasspathPreferencesView.java
@@ -37,6 +37,7 @@ public class ClasspathPreferencesView extends JPanel {
protected JButton addJarButton;
protected JButton addDirButton;
+ protected JButton addMvnButton;
protected JButton removeEntryButton;
protected JTable table;
@@ -45,6 +46,7 @@ public class ClasspathPreferencesView extends JPanel {
// create widgets
addJarButton = new JButton("Add Jar/Zip");
addDirButton = new JButton("Add Class Folder");
+ addMvnButton = new JButton("Get From Maven Central");
removeEntryButton = new JButton("Remove");
table = new CayenneTable();
@@ -59,6 +61,7 @@ public class ClasspathPreferencesView extends JPanel {
builder.append(addJarButton);
builder.append(addDirButton);
+ builder.append(addMvnButton);
builder.append(removeEntryButton);
setLayout(new BorderLayout());
@@ -76,6 +79,10 @@ public class ClasspathPreferencesView extends JPanel {
return addJarButton;
}
+ public JButton getAddMvnButton() {
+ return addMvnButton;
+ }
+
public JButton getRemoveEntryButton() {
return removeEntryButton;
}
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/MavenDependencyDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/MavenDependencyDialog.java
new file mode 100644
index 0000000..7c95097
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/MavenDependencyDialog.java
@@ -0,0 +1,148 @@
+package org.apache.cayenne.modeler.dialog.pref;
+
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.Window;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.Objects;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.util.CayenneController;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MavenDependencyDialog extends CayenneController {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MavenDependencyDialog.class);
+ private static final int DEFAULT_BUFFER_SIZE = 8192;
+
+ private final ClasspathPreferences preferencesController;
+ private final MavenDependencyDialogView view;
+
+ private volatile boolean closing;
+
+ public MavenDependencyDialog(ClasspathPreferences preferencesController) {
+ this.preferencesController = preferencesController;
+ Window parentView = preferencesController.getView() instanceof Window
+ ? (Window) preferencesController.getView()
+ : SwingUtilities.getWindowAncestor(preferencesController.getView());
+ if(parentView instanceof Dialog) {
+ view = new MavenDependencyDialogView((Dialog) parentView);
+ } else {
+ view = new MavenDependencyDialogView((Frame) parentView);
+ }
+ initBindings();
+ }
+
+ private void initBindings() {
+ view.getDownloadButton().addActionListener(e -> loadArtifact());
+ view.getCancelButton().addActionListener(e -> close());
+ }
+
+ private void loadArtifact() {
+ // url template: https://repo1.maven.org/maven2/org/apache/cayenne/cayenne-server/4.2.M1/cayenne-server-4.2.M1.jar
+ String groupPath = view.getGroupId().getText().replace('.', '/').trim();
+ String artifactIdText = view.getArtifactId().getText().trim();
+ String versionText = view.getVersion().getText().trim();
+
+ if("".equals(groupPath)) {
+ JOptionPane.showMessageDialog(view, "Empty group Id", "Warning", JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+
+ if("".equals(artifactIdText)) {
+ JOptionPane.showMessageDialog(view, "Empty artifact Id", "Warning", JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+
+ if("".equals(versionText)) {
+ JOptionPane.showMessageDialog(view, "Empty version", "Warning", JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+
+ String urlText = "https://repo1.maven.org/maven2/" + groupPath + "/"
+ + artifactIdText + "/" + versionText + "/"
+ + artifactIdText + "-" + versionText + ".jar";
+
+ Application.getInstance().getFrameController().updateStatus("Loading " + urlText);
+
+ String localPath = System.getProperty( "user.home" ) + "/.cayenne/modeler/"
+ + groupPath + "/" + artifactIdText + "-" + versionText + ".jar";
+ File targetFile = new File(localPath);
+
+ view.getDownloadButton().setEnabled(false);
+ new Thread(() -> download(urlText, targetFile)).start();
+ }
+
+ private void close() {
+ this.closing = true;
+ view.close();
+ }
+
+ public void download(String srcUrl, File dstFile) {
+ if(!dstFile.getParentFile().exists()
+ && !dstFile.getParentFile().mkdirs()) {
+ finalizeDownload(dstFile, "Unable to create file " + dstFile, false, false);
+ return;
+ }
+
+ try {
+ BufferedInputStream is = new BufferedInputStream(new URL(srcUrl).openStream());
+ OutputStream os = new FileOutputStream(dstFile);
+ transferTo(is, os);
+ } catch (FileNotFoundException fnf) {
+ finalizeDownload(dstFile, "Url not found: " + srcUrl, false, false);
+ return;
+ } catch (Exception e) {
+ LOGGER.warn("Failed to download Maven dependency " + srcUrl, e);
+ finalizeDownload(dstFile, "Unable to download file " + dstFile, false, true);
+ return;
+ }
+ finalizeDownload(dstFile, "Succesfully downloaded", true, true);
+ }
+
+ private void finalizeDownload(File dstFile, String status, boolean success, boolean shouldClose) {
+ SwingUtilities.invokeLater(() -> {
+ if(success) {
+ preferencesController.addClasspathEntry(dstFile);
+ } else {
+ JOptionPane.showMessageDialog(view, status, "Error", JOptionPane.ERROR_MESSAGE);
+ }
+
+ view.getDownloadButton().setEnabled(true);
+ Application.getInstance().getFrameController().updateStatus(status);
+
+ if(shouldClose) {
+ close();
+ }
+ });
+ }
+
+ private void transferTo(InputStream in, OutputStream out) throws IOException {
+ Objects.requireNonNull(in);
+ Objects.requireNonNull(out);
+ byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+ int read;
+ while ((read = in.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) {
+ out.write(buffer, 0, read);
+ if(closing) {
+ break;
+ }
+ }
+ }
+
+ @Override
+ public Component getView() {
+ return view;
+ }
+}
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/MavenDependencyDialogView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/MavenDependencyDialogView.java
new file mode 100644
index 0000000..8ecc370
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/MavenDependencyDialogView.java
@@ -0,0 +1,101 @@
+package org.apache.cayenne.modeler.dialog.pref;
+
+import java.awt.BorderLayout;
+import java.awt.Dialog;
+import java.awt.Frame;
+
+import javax.swing.JButton;
+import javax.swing.JTextField;
+
+import com.jgoodies.forms.builder.PanelBuilder;
+import com.jgoodies.forms.layout.CellConstraints;
+import com.jgoodies.forms.layout.FormLayout;
+import org.apache.cayenne.modeler.util.CayenneDialog;
+import org.apache.cayenne.modeler.util.ModelerUtil;
+import org.apache.cayenne.modeler.util.PanelFactory;
+
+public class MavenDependencyDialogView extends CayenneDialog {
+
+ private JButton downloadButton;
+ private JButton cancelButton;
+ private JTextField groupId;
+ private JTextField artifactId;
+ private JTextField version;
+
+ public MavenDependencyDialogView(Dialog parentDialog) {
+ super(parentDialog, "Download artifact", true);
+ this.initView();
+ this.pack();
+ ModelerUtil.centerWindow(parentDialog, this);
+ }
+
+ public MavenDependencyDialogView(Frame parentFrame) {
+ super(parentFrame, "Download artifact", true);
+ this.initView();
+ this.pack();
+ ModelerUtil.centerWindow(parentFrame, this);
+ }
+
+ private void initView() {
+ getContentPane().setLayout(new BorderLayout());
+
+ {
+ groupId = new JTextField(25);
+ artifactId = new JTextField(25);
+ version = new JTextField(25);
+
+ CellConstraints cc = new CellConstraints();
+ PanelBuilder builder = new PanelBuilder(
+ new FormLayout(
+ "right:max(50dlu;pref), 3dlu, fill:min(100dlu;pref)",
+ "p, 3dlu, p, 3dlu, p, 3dlu"
+ ));
+ builder.setDefaultDialogBorder();
+
+ builder.addLabel("group id:", cc.xy(1, 1));
+ builder.add(groupId, cc.xy(3, 1));
+
+ builder.addLabel("artifact id:", cc.xy(1, 3));
+ builder.add(artifactId, cc.xy(3, 3));
+
+ builder.addLabel("version:", cc.xy(1, 5));
+ builder.add(version, cc.xy(3, 5));
+
+ getContentPane().add(builder.getPanel(), BorderLayout.NORTH);
+ }
+
+ {
+ downloadButton = new JButton("Download");
+ cancelButton = new JButton("Cancel");
+ getRootPane().setDefaultButton(downloadButton);
+
+ JButton[] buttons = {cancelButton, downloadButton};
+ getContentPane().add(PanelFactory.createButtonPanel(buttons), BorderLayout.SOUTH);
+ }
+ }
+
+ public void close() {
+ setVisible(false);
+ dispose();
+ }
+
+ public JButton getCancelButton() {
+ return cancelButton;
+ }
+
+ public JButton getDownloadButton() {
+ return downloadButton;
+ }
+
+ public JTextField getArtifactId() {
+ return artifactId;
+ }
+
+ public JTextField getGroupId() {
+ return groupId;
+ }
+
+ public JTextField getVersion() {
+ return version;
+ }
+}
\ No newline at end of file