blob: ac615325756e6a4be7677c0a118a657993a7d8d2 [file] [log] [blame]
/*
* Copyright (c) Robert Bosch GmbH. All rights reserved.
*/
package org.eclipse.blockchain.ui.preference;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.blockchain.core.BlockchainCore;
import org.eclipse.blockchain.core.SecoBlocksPreferenceConstants;
import org.eclipse.blockchain.ui.Activator;
import org.eclipse.blockchain.ui.util.UnzipUtility;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;
import org.osgi.service.prefs.BackingStoreException;
/**
* @author ADG5COB
*/
public class SolidityCompilerPreference extends PreferencePage implements IWorkbenchPreferencePage {
private Text solcPathText = null;
String solidityCompilerPath;
boolean added, removed;
List<String> avaiableVersions = new ArrayList<>();
List<String> selectedVersions = new ArrayList<>();
/**
* {@inheritDoc}
*/
@Override
public void init(final IWorkbench workbench) {
this.solidityCompilerPath =
Platform.getPreferencesService().getString(SecoBlocksPreferenceConstants.SECOBLOCKS_PREF_NODE,
SecoBlocksPreferenceConstants.SOLIDITY_COMPILER_PREF_KEY, "", null);
String list = Platform.getPreferencesService().getString(SecoBlocksPreferenceConstants.SECOBLOCKS_PREF_NODE,
SecoBlocksPreferenceConstants.PREF_KEY_VersionList, null, null);
if (list != null) {
for (String version : list.split(",")) {
this.avaiableVersions.add(version);
}
}
list = Platform.getPreferencesService().getString(SecoBlocksPreferenceConstants.SECOBLOCKS_PREF_NODE,
SecoBlocksPreferenceConstants.PREF_KEY_SelectedList, null, null);
if (list != null) {
for (String version : list.split(",")) {
this.selectedVersions.add(version);
}
}
}
/**
* {@inheritDoc}
*/
@Override
protected Control createContents(final Composite parent) {
Composite container = new Composite(parent, SWT.None);
container.setLayout(new GridLayout(3, false));
GridData layoutData = new GridData(SWT.FILL, SWT.FILL, false, false);
container.setLayoutData(layoutData);
Label solcLabel = new Label(container, SWT.None);
solcLabel.setLayoutData(new GridData(SWT.FILL, SWT.RIGHT, false, false));
solcLabel.setText("Solidity Compiler Path");
this.solcPathText = new Text(container, SWT.BORDER);
this.solcPathText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
this.solcPathText.setToolTipText("Please mention the filesystem path of solidity compiler to be downloaded");
this.solcPathText.setText(this.solidityCompilerPath);
Button compilerPathBrowseButton = new Button(container, SWT.PUSH);
compilerPathBrowseButton.setText("Browse");
compilerPathBrowseButton.setLayoutData(new GridData(SWT.FILL, SWT.RIGHT, false, false, 1, 1));
compilerPathBrowseButton.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(final SelectionEvent e) {
DirectoryDialog solcCompilerPathDialog = new DirectoryDialog(parent.getShell());
solcCompilerPathDialog.setFilterPath(System.getProperty("user.dir"));
String selectedDir = solcCompilerPathDialog.open();
if (selectedDir != null) {
SolidityCompilerPreference.this.solcPathText.setText(selectedDir);
SolidityCompilerPreference.this.solidityCompilerPath = selectedDir;
}
}
@Override
public void widgetDefaultSelected(final SelectionEvent e) {
// do nothing
}
});
Composite composite = new Composite(parent, SWT.NONE);
GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);
data.horizontalSpan = 2;
composite.setLayoutData(data);
GridLayout layout = new GridLayout();
layout.numColumns = 3;
layout.marginHeight = 15;
composite.setLayout(layout);
Label candidatesLbl = new Label(composite, SWT.None);
candidatesLbl.setText("Versions avaliable");
candidatesLbl.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, true));
Composite emptyContainer = new Composite(composite, SWT.None);
layout = new GridLayout(1, false);
emptyContainer.setLayout(layout);
layoutData = new GridData(SWT.CENTER, SWT.CENTER, true, true);
layout.horizontalSpacing = 20;
layout.verticalSpacing = 30;
emptyContainer.setLayoutData(layoutData);
Label selected = new Label(composite, SWT.None);
selected.setText("Versions to be downloaded");
selected.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, true));
ListViewer listViewer = new ListViewer(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
data = new GridData(GridData.FILL_BOTH);
data.heightHint = convertHeightInCharsToPixels(10);
data.widthHint = convertWidthInCharsToPixels(60);
listViewer.getList().setLayoutData(data);
listViewer.getList().setFont(parent.getFont());
listViewer.setContentProvider(new IStructuredContentProvider() {
@Override
public Object[] getElements(final Object inputElement) {
return ((ArrayList<String>) inputElement).toArray();
}
});
if (this.avaiableVersions.isEmpty()) {
this.avaiableVersions = new ArrayList<String>(Arrays.asList(SecoBlocksPreferenceConstants.versionList));
}
listViewer.setInput(this.avaiableVersions);
// Set the initial selection
listViewer.setSelection(new StructuredSelection(SecoBlocksPreferenceConstants.versionList[0]), true);
Composite buttonContainer = new Composite(composite, SWT.None);
layout = new GridLayout(1, false);
buttonContainer.setLayout(layout);
layoutData = new GridData(SWT.CENTER, SWT.CENTER, true, true);
layout.horizontalSpacing = 20;
layout.verticalSpacing = 30;
buttonContainer.setLayoutData(layoutData);
ListViewer listViewerSelected = new ListViewer(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
listViewerSelected.getList().setLayoutData(data);
listViewerSelected.getList().setFont(parent.getFont());
listViewerSelected.setContentProvider(new IStructuredContentProvider() {
@Override
public Object[] getElements(final Object inputElement) {
return ((ArrayList<String>) inputElement).toArray();
}
});
listViewerSelected.setInput(this.selectedVersions);
Button sendRightButton = new Button(buttonContainer, SWT.BOLD);
sendRightButton.setText(" > ");
sendRightButton.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(final SelectionEvent e) {
IStructuredSelection s = (IStructuredSelection) listViewer.getSelection();
String firstElement = (String) s.getFirstElement();
if (firstElement != null) {
SolidityCompilerPreference.this.avaiableVersions.remove(firstElement);
SolidityCompilerPreference.this.selectedVersions.add(firstElement);
listViewer.refresh(false);
listViewerSelected.add(firstElement);
SolidityCompilerPreference.this.added = true;
}
}
@Override
public void widgetDefaultSelected(final SelectionEvent e) {
// TODO Auto-generated method stub
}
});
Button sendLeftButton = new Button(buttonContainer, SWT.BOLD);
sendLeftButton.setText(" < ");
sendLeftButton.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(final SelectionEvent e) {
IStructuredSelection s = (IStructuredSelection) listViewerSelected.getSelection();
String firstElement = (String) s.getFirstElement();
if (firstElement != null) {
SolidityCompilerPreference.this.selectedVersions.remove(firstElement);
SolidityCompilerPreference.this.avaiableVersions.add(firstElement);
listViewerSelected.refresh(false);
listViewer.add(firstElement);
SolidityCompilerPreference.this.removed = true;
}
}
@Override
public void widgetDefaultSelected(final SelectionEvent e) {
// TODO Auto-generated method stub
}
});
return parent;
}
/**
* {@inheritDoc}
*/
@Override
public boolean performOk() {
if (this.added) {
Shell shell = PlatformUI.getWorkbench().getDisplay().getActiveShell();
if (shell == null) {
shell = new Shell(PlatformUI.getWorkbench().getDisplay());
}
MessageDialog messageBox = new MessageDialog(shell, "Download Information", null,
"The selected compiler versions will be downloaded in the specified location", MessageDialog.INFORMATION, 0,
new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL });
messageBox.setBlockOnOpen(true);
int mbr = messageBox.open();
if (mbr == IDialogConstants.CANCEL_ID) {
// cancel
}
else if (mbr == IDialogConstants.OK_ID) {
processDownload(this.selectedVersions);
}
}
this.solidityCompilerPath = getSolText();
InstanceScope.INSTANCE.getNode(SecoBlocksPreferenceConstants.SECOBLOCKS_PREF_NODE)
.put(SecoBlocksPreferenceConstants.SOLIDITY_COMPILER_PREF_KEY, this.solidityCompilerPath);
InstanceScope.INSTANCE.getNode(SecoBlocksPreferenceConstants.PREF_KEY_VersionList)
.put(SecoBlocksPreferenceConstants.PREF_KEY_VersionList, String.join(",", this.avaiableVersions));
InstanceScope.INSTANCE.getNode(SecoBlocksPreferenceConstants.PREF_KEY_SelectedList)
.put(SecoBlocksPreferenceConstants.PREF_KEY_SelectedList, String.join(",", this.selectedVersions));
try {
InstanceScope.INSTANCE.getNode(SecoBlocksPreferenceConstants.SECOBLOCKS_PREF_NODE).flush();
}
catch (BackingStoreException e) {
BlockchainCore.getInstance().logException(Activator.PLUGIN_ID, e.getMessage(), e);
}
return super.performOk();
}
private String getSolText() {
List<String> solcPathList = new ArrayList<>();
Display.getDefault().syncExec(() -> {
solcPathList.add(this.solcPathText.getText());
});
return solcPathList.get(0);
}
/**
* @param selectedVersion
* @throws IOException
*/
private void processDownload(final List<String> selectedVersion) {
if (!this.solidityCompilerPath.isEmpty()) {
Job job = new Job("Downloading Complier Packages") {
@Override
public IStatus run(final IProgressMonitor monitor) {
SubMonitor subMonitor = SubMonitor.convert(monitor);
for (String version : selectedVersion) {
String urlString =
"https://github.com/ethereum/solidity/releases/download/" + version + "/solidity-windows.zip";
version = version.replace(".", "_");
java.io.File file =
new java.io.File(SolidityCompilerPreference.this.solidityCompilerPath + File.separator + version);
file.getParentFile().setReadable(true);
file.mkdir();
file.setReadable(true);
file.getParentFile().mkdirs();
try {
URL website = new URL(urlString.trim());
String zipFile = file + File.separator + "solidity-windows.zip";
URLConnection connection = website.openConnection();
InputStream reader = website.openStream();
subMonitor.beginTask(getName(), connection.getContentLength());
byte[] buffer = new byte[102400];
int totalBytesRead = 0;
int bytesRead = 0;
try (FileOutputStream writer = new FileOutputStream(zipFile, true)) {
while ((bytesRead = reader.read(buffer)) > 0) {
writer.write(buffer, 0, bytesRead);
buffer = new byte[102400];
totalBytesRead += bytesRead;
subMonitor.newChild(1);
}
writer.close();
reader.close();
}
// unzip the file
UnzipUtility.unzip(zipFile, file.getCanonicalPath());
subMonitor.done();
}
catch (Exception e) {
return new Status(IStatus.ERROR, "download",
"The network proxy has to be checked. Please go to Window -> Preferences->General-> NetworkConnections.\\n Please set the correct proxy to download the selected complier versions");
}
}
Display.getDefault().syncExec(() -> {
MessageDialog messageBox = new MessageDialog(Display.getDefault().getActiveShell(), "Download Information",
null, "Downloaded successfully", MessageDialog.INFORMATION, 0,
new String[] { IDialogConstants.OK_LABEL });
messageBox.setBlockOnOpen(true);
messageBox.open();
});
return new Status(IStatus.OK, "download", "Successfully downloaded");
}
};
job.setRule(ResourcesPlugin.getWorkspace().getRoot());
job.setUser(true);
job.schedule();
}
}
}