/* | |
* 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(); | |
} | |
} | |
} |