/******************************************************************************* | |
* Copyright (c) 2020 RBEI and others. | |
* | |
* This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v. 2.0 | |
* which accompanies this distribution, and is available at | |
* https://www.eclipse.org/legal/epl-2.0/ | |
* | |
* SPDX-License-Identifier: EPL-2.0 | |
* | |
* Contributors: | |
* Adhith Gopal - Initial contribution and API | |
* Pavithra Krishna Reddy | |
* Santhosh Gokhale D | |
*******************************************************************************/ | |
package org.eclipse.blockchain.server.ui.wizard.fragment; | |
import java.io.BufferedReader; | |
import java.io.File; | |
import java.io.FileReader; | |
import java.io.IOException; | |
import java.util.HashMap; | |
import java.util.Map; | |
import org.eclipse.blockchain.core.BlockchainCore; | |
import org.eclipse.blockchain.core.CoreCommandExecutor; | |
import org.eclipse.swt.SWT; | |
import org.eclipse.swt.custom.ScrolledComposite; | |
import org.eclipse.swt.events.ModifyEvent; | |
import org.eclipse.swt.events.ModifyListener; | |
import org.eclipse.swt.events.SelectionAdapter; | |
import org.eclipse.swt.events.SelectionEvent; | |
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.DirectoryDialog; | |
import org.eclipse.swt.widgets.Display; | |
import org.eclipse.swt.widgets.FileDialog; | |
import org.eclipse.swt.widgets.Group; | |
import org.eclipse.swt.widgets.Label; | |
import org.eclipse.swt.widgets.Text; | |
import org.eclipse.wst.server.ui.wizard.IWizardHandle; | |
/** | |
* This is just a proto-type class and not constructed fully. | |
*/ | |
public class GethWizardComposite extends Composite { | |
private IWizardHandle wizard = null; | |
private Text dataDirText; | |
private Text initFileText; | |
private final String userDir = System.getProperty("user.dir"); | |
private String networkId = ""; | |
private Label networkIdLabel; | |
private final Map<String, String> gethOptions = new HashMap<>(); | |
private String dataDirectory = ""; | |
private String genesisFile = ""; | |
/** | |
* @return - | |
*/ | |
protected String getDataDirectory() { | |
return this.dataDirectory; | |
} | |
/** | |
* @return - | |
*/ | |
protected String getGenesisFile() { | |
return this.genesisFile; | |
} | |
/** | |
* @return - | |
*/ | |
protected Map<String, String> getGethOptions() { | |
return this.gethOptions; | |
} | |
/** | |
* | |
*/ | |
GethWizardComposite(final Composite parent, final IWizardHandle wizard) { | |
super(parent, SWT.NONE); | |
this.wizard = wizard; | |
this.wizard.setTitle("Geth Server"); | |
this.wizard | |
.setDescription("This is used to start a geth server instance"); | |
populateGethOptions(); | |
createDialogArea(); | |
} | |
private void createDialogArea() { | |
GridLayout layout = new GridLayout(); | |
setLayout(layout); | |
setLayoutData(new GridData(GridData.FILL_BOTH)); | |
Composite containerComp = new Composite(this, SWT.None); | |
containerComp.setLayout(new GridLayout(3, false)); | |
containerComp | |
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | |
createContent(containerComp); | |
} | |
private void createContent(final Composite containerComp) { | |
// First Layer | |
Label dataDirLabel = new Label(containerComp, SWT.None); | |
dataDirLabel.setText("Data Directory"); | |
dataDirLabel | |
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); | |
this.dataDirText = new Text(containerComp, SWT.BORDER); | |
this.dataDirText | |
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); | |
this.dataDirText.setText(""); | |
this.dataDirText.setToolTipText(this.dataDirText.getText()); | |
this.dataDirText.addModifyListener(new ModifyListener() { | |
@Override | |
public void modifyText(final ModifyEvent e) { | |
GethWizardComposite.this.dataDirectory = GethWizardComposite.this.dataDirText | |
.getText(); | |
GethWizardComposite.this.wizard.update(); | |
} | |
}); | |
Button dataDirBrowse = new Button(containerComp, SWT.PUSH); | |
dataDirBrowse | |
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); | |
dataDirBrowse.setText("Browse"); | |
dataDirBrowse.addSelectionListener(new SelectionAdapter() { | |
/** | |
* {@inheritDoc} | |
*/ | |
@Override | |
public void widgetSelected(final SelectionEvent e) { | |
getAndSetSelectedDirectoryNode(containerComp, | |
GethWizardComposite.this.dataDirText); | |
GethWizardComposite.this.dataDirectory = GethWizardComposite.this.dataDirText | |
.getText(); | |
GethWizardComposite.this.wizard.update(); | |
} | |
}); | |
// Second Layer | |
Label initFileLabel = new Label(containerComp, SWT.None); | |
initFileLabel.setText("Init File"); | |
initFileLabel | |
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); | |
this.initFileText = new Text(containerComp, SWT.BORDER); | |
this.initFileText | |
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); | |
this.initFileText.setText(""); | |
this.initFileText.setToolTipText("Under development!!!"); | |
this.initFileText.setEnabled(false); | |
Button initFileBrowse = new Button(containerComp, SWT.PUSH); | |
initFileBrowse | |
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); | |
initFileBrowse.setText("Browse"); | |
initFileBrowse.addSelectionListener(new SelectionAdapter() { | |
/** | |
* {@inheritDoc} | |
*/ | |
@Override | |
public void widgetSelected(final SelectionEvent e) { | |
getandSetSelectedGenesisFile(containerComp, | |
GethWizardComposite.this.initFileText); | |
} | |
}); | |
// Scrolled Composite - contains network values | |
ScrolledComposite networkComposite = new ScrolledComposite( | |
containerComp, SWT.V_SCROLL | SWT.BORDER); | |
networkComposite.setLayout(new GridLayout(1, false)); | |
networkComposite.setLayoutData( | |
new GridData(SWT.FILL, SWT.FILL, false, false, 3, 0)); | |
Composite networkChild = createdScrolledContent(networkComposite); | |
networkComposite.setContent(networkChild); | |
networkComposite.setMinSize( | |
networkComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); | |
networkComposite.setExpandHorizontal(true); | |
networkComposite.setExpandVertical(true); | |
networkComposite.layout(); | |
} | |
private Composite createdScrolledContent( | |
final ScrolledComposite scrolledComposite) { | |
/** | |
* This contains the geth arguments which should be made configurable, | |
* as of now its static but networkId will be read from the genesis file | |
*/ | |
Composite childComp = new Composite(scrolledComposite, SWT.None); | |
childComp.setLayout(new GridLayout(1, false)); | |
childComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | |
Group networkGroup = new Group(childComp, SWT.BORDER); | |
networkGroup.setLayout(new GridLayout(1, false)); | |
networkGroup | |
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | |
networkGroup.setText("Network"); | |
this.networkIdLabel = new Label(networkGroup, SWT.None | SWT.READ_ONLY); | |
this.networkIdLabel.setText("Network ID : " + (this.networkId.isEmpty() | |
? CoreCommandExecutor.getInstance().getDefaultNetworkIdForGeth() | |
: this.networkId)); | |
Group rpcGroup = new Group(childComp, SWT.BORDER); | |
rpcGroup.setLayout(new GridLayout(1, false)); | |
rpcGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | |
rpcGroup.setText("RPC"); | |
for (Map.Entry<String, String> entry : this.gethOptions.entrySet()) { | |
Label lab = new Label(rpcGroup, SWT.None); | |
String val = entry.getValue(); | |
lab.setText(entry.getKey() + (val.isEmpty() ? "" : " : " + val)); | |
} | |
return childComp; | |
} | |
private void getandSetSelectedGenesisFile(final Composite parent, | |
final Text textWidget) { | |
FileDialog dataDir = new FileDialog(parent.getShell()); | |
dataDir.setFilterPath(this.userDir); | |
String selectedDir = dataDir.open(); | |
if (selectedDir != null) { | |
textWidget.setText(selectedDir); | |
try (BufferedReader br = new BufferedReader( | |
new FileReader(new File(selectedDir)))) { | |
String contents = ""; | |
while ((contents = br.readLine()) != null) { | |
if (contents.contains("chainId")) { | |
this.networkId = contents | |
.substring(contents.indexOf(':') + 1) | |
.replace(",", "").trim(); | |
this.networkIdLabel | |
.setText("Network ID : " + this.networkId); | |
this.networkIdLabel.getParent().layout(); | |
} | |
} | |
} catch (IOException e) { | |
BlockchainCore.getInstance().logException( | |
"org.eclipse.blockchain.server.ui", e.getMessage(), e); | |
} | |
} | |
} | |
/** | |
* @return - true if wizard is complete with out any errors, false otherwise | |
*/ | |
public boolean isWizardComplete() { | |
boolean dataDirectoryPresent = false; | |
// The validation should be done here | |
if ((this.dataDirectory != null) && !this.dataDirectory.equals("")) { | |
File folder = new File(this.dataDirectory); | |
if (folder.exists()) { | |
dataDirectoryPresent = true; | |
} else { | |
this.wizard.setDescription("Data directory path is not valid"); | |
} | |
} | |
return dataDirectoryPresent; | |
} | |
private void getAndSetSelectedDirectoryNode(final Composite parent, | |
final Text textWidget) { | |
DirectoryDialog dirDialog = new DirectoryDialog(parent.getShell()); | |
dirDialog.setFilterPath(this.userDir); | |
String selectedDir = dirDialog.open(); | |
if (selectedDir != null) { | |
textWidget.setText(selectedDir); | |
} | |
} | |
private void populateGethOptions() { | |
this.gethOptions.put("rpc", ""); | |
this.gethOptions.put("rpccorsdomain", "*"); | |
this.gethOptions.put("rpcapi", "db,eth,net,web3,personal"); | |
this.gethOptions.put("gcmode", "archive"); | |
} | |
/** | |
* | |
*/ | |
protected void prePerformFinish() { | |
this.dataDirectory = getTextValue(this.dataDirText); | |
this.genesisFile = getTextValue(this.initFileText); | |
} | |
private String getTextValue(final Text inputText) { | |
StringBuffer textValueBuffer = new StringBuffer(); | |
Display.getDefault().syncExec(() -> { | |
textValueBuffer.append(inputText.getText()); | |
}); | |
return textValueBuffer.toString(); | |
} | |
} |