| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.hdt.ui.wizards; |
| |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.SortedMap; |
| import java.util.TreeMap; |
| import java.util.Map.Entry; |
| |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hdt.core.cluster.ConfProp; |
| import org.apache.hdt.core.cluster.HadoopCluster; |
| import org.apache.hdt.core.cluster.ServerRegistry; |
| import org.eclipse.jface.dialogs.IMessageProvider; |
| import org.eclipse.jface.wizard.WizardPage; |
| 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.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.graphics.Image; |
| 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.Display; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Group; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.TabFolder; |
| import org.eclipse.swt.widgets.TabItem; |
| import org.eclipse.swt.widgets.Text; |
| |
| /** |
| * Wizard for editing the settings of a Hadoop location |
| * |
| * The wizard contains 3 tabs: General, Tunneling and Advanced. It edits |
| * parameters of the location member which either a new location or a copy of |
| * an existing registered location. |
| */ |
| |
| public class HadoopLocationWizard extends WizardPage { |
| |
| Image circle; |
| |
| /** |
| * The location effectively edited by the wizard. This location is a copy |
| * or a new one. |
| */ |
| private HadoopCluster location; |
| |
| /** |
| * The original location being edited by the wizard (null if we create a |
| * new instance). |
| */ |
| private HadoopCluster original; |
| |
| /** |
| * New Hadoop location wizard |
| */ |
| public HadoopLocationWizard() { |
| super("Hadoop Server", "New Hadoop Location", null); |
| |
| this.original = null; |
| this.location = new HadoopCluster(); |
| this.location.setLocationName(""); |
| } |
| |
| /** |
| * Constructor to edit the parameters of an existing Hadoop server |
| * |
| * @param server |
| */ |
| public HadoopLocationWizard(HadoopCluster server) { |
| super("Create a new Hadoop location", "Edit Hadoop Location", null); |
| |
| this.original = server; |
| this.location = new HadoopCluster(server); |
| } |
| |
| /** |
| * Performs any actions appropriate in response to the user having pressed |
| * the Finish button, or refuse if finishing now is not permitted. |
| * |
| * @return the created or updated Hadoop location |
| */ |
| |
| public HadoopCluster performFinish() { |
| try { |
| if (this.original == null) { |
| // New location |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| ServerRegistry.getInstance().addServer( |
| HadoopLocationWizard.this.location); |
| } |
| }); |
| return this.location; |
| |
| } else { |
| // Update location |
| final String originalName = this.original.getLocationName(); |
| this.original.load(this.location); |
| |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| ServerRegistry.getInstance().updateServer(originalName, |
| HadoopLocationWizard.this.location); |
| } |
| }); |
| return this.original; |
| |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| setMessage("Invalid server location values", IMessageProvider.ERROR); |
| return null; |
| } |
| } |
| |
| /** |
| * Validates the current Hadoop location settings (look for Hadoop |
| * installation directory). |
| * |
| */ |
| private void testLocation() { |
| setMessage("Not implemented yet", IMessageProvider.WARNING); |
| } |
| |
| /** |
| * Location is not complete (and finish button not available) until a host |
| * name is specified. |
| * |
| * @inheritDoc |
| */ |
| @Override |
| public boolean isPageComplete() { |
| |
| { |
| String locName = location.getConfProp(ConfProp.PI_LOCATION_NAME); |
| if ((locName == null) || (locName.length() == 0) |
| || locName.contains("/")) { |
| |
| setMessage("Bad location name: " |
| + "the location name should not contain " |
| + "any character prohibited in a file name.", WARNING); |
| |
| return false; |
| } |
| } |
| |
| { |
| String master = location.getConfProp(ConfProp.PI_JOB_TRACKER_HOST); |
| if ((master == null) || (master.length() == 0)) { |
| |
| setMessage("Bad master host name: " |
| + "the master host name refers to the machine " |
| + "that runs the Job tracker.", WARNING); |
| |
| return false; |
| } |
| } |
| |
| { |
| String jobTracker = location.getConfProp(ConfProp.JOB_TRACKER_URI); |
| String[] strs = jobTracker.split(":"); |
| boolean ok = (strs.length == 2); |
| if (ok) { |
| try { |
| int port = Integer.parseInt(strs[1]); |
| ok = (port >= 0) && (port < 65536); |
| } catch (NumberFormatException nfe) { |
| ok = false; |
| } |
| } |
| if (!ok) { |
| setMessage("The job tracker information (" |
| + ConfProp.JOB_TRACKER_URI.name + ") is invalid. " |
| + "This usually looks like \"host:port\"", WARNING); |
| return false; |
| } |
| } |
| |
| { |
| String fsDefaultURI = location.getConfProp(ConfProp.FS_DEFAULT_URI); |
| try { |
| URI uri = new URI(fsDefaultURI); |
| } catch (URISyntaxException e) { |
| |
| setMessage("The default file system URI is invalid. " |
| + "This usually looks like \"hdfs://host:port/\" " |
| + "or \"file:///dir/\"", WARNING); |
| } |
| } |
| |
| setMessage("Define the location of a Hadoop infrastructure " |
| + "for running MapReduce applications."); |
| return true; |
| } |
| |
| /** |
| * Create the wizard |
| */ |
| /* @inheritDoc */ |
| public void createControl(Composite parent) { |
| setTitle("Define Hadoop location"); |
| setDescription("Define the location of a Hadoop infrastructure " |
| + "for running MapReduce applications."); |
| |
| Composite panel = new Composite(parent, SWT.FILL); |
| GridLayout glayout = new GridLayout(2, false); |
| panel.setLayout(glayout); |
| |
| TabMediator mediator = new TabMediator(panel); |
| { |
| GridData gdata = new GridData(GridData.FILL_BOTH); |
| gdata.horizontalSpan = 2; |
| mediator.folder.setLayoutData(gdata); |
| } |
| this.setControl(panel /* mediator.folder */); |
| { |
| final Button btn = new Button(panel, SWT.NONE); |
| btn.setText("&Load from file"); |
| btn.setEnabled(false); |
| btn.setToolTipText("Not yet implemented"); |
| btn.addListener(SWT.Selection, new Listener() { |
| public void handleEvent(Event e) { |
| // TODO |
| } |
| }); |
| } |
| { |
| final Button validate = new Button(panel, SWT.NONE); |
| validate.setText("&Validate location"); |
| validate.setEnabled(false); |
| validate.setToolTipText("Not yet implemented"); |
| validate.addListener(SWT.Selection, new Listener() { |
| public void handleEvent(Event e) { |
| testLocation(); |
| } |
| }); |
| } |
| } |
| |
| private interface TabListener { |
| void notifyChange(ConfProp prop, String propValue); |
| } |
| |
| /* |
| * Mediator pattern to keep tabs synchronized with each other and with the |
| * location state. |
| */ |
| |
| private class TabMediator { |
| TabFolder folder; |
| |
| private Set<TabListener> tabs = new HashSet<TabListener>(); |
| |
| TabMediator(Composite parent) { |
| folder = new TabFolder(parent, SWT.NONE); |
| tabs.add(new TabMain(this)); |
| tabs.add(new TabAdvanced(this)); |
| } |
| |
| /** |
| * Access to current configuration settings |
| * |
| * @param propName the property name |
| * @return the current property value |
| */ |
| String get(String propName) { |
| return location.getConfProp(propName); |
| } |
| |
| String get(ConfProp prop) { |
| return location.getConfProp(prop); |
| } |
| |
| /** |
| * Implements change notifications from any tab: update the location |
| * state and other tabs |
| * |
| * @param source origin of the notification (one of the tree tabs) |
| * @param propName modified property |
| * @param propValue new value |
| */ |
| void notifyChange(TabListener source, final ConfProp prop, |
| final String propValue) { |
| // Ignore notification when no change |
| String oldValue = location.getConfProp(prop); |
| if ((oldValue != null) && oldValue.equals(propValue)) |
| return; |
| |
| location.setConfProp(prop, propValue); |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| getContainer().updateButtons(); |
| } |
| }); |
| |
| this.fireChange(source, prop, propValue); |
| |
| /* |
| * Now we deal with dependencies between settings |
| */ |
| final String jobTrackerHost = |
| location.getConfProp(ConfProp.PI_JOB_TRACKER_HOST); |
| final String jobTrackerPort = |
| location.getConfProp(ConfProp.PI_JOB_TRACKER_PORT); |
| final String nameNodeHost = |
| location.getConfProp(ConfProp.PI_NAME_NODE_HOST); |
| final String nameNodePort = |
| location.getConfProp(ConfProp.PI_NAME_NODE_PORT); |
| final boolean colocate = |
| location.getConfProp(ConfProp.PI_COLOCATE_MASTERS) |
| .equalsIgnoreCase("yes"); |
| final String jobTrackerURI = |
| location.getConfProp(ConfProp.JOB_TRACKER_URI); |
| final String fsDefaultURI = |
| location.getConfProp(ConfProp.FS_DEFAULT_URI); |
| final String socksServerURI = |
| location.getConfProp(ConfProp.SOCKS_SERVER); |
| final boolean socksProxyEnable = |
| location.getConfProp(ConfProp.PI_SOCKS_PROXY_ENABLE) |
| .equalsIgnoreCase("yes"); |
| final String socksProxyHost = |
| location.getConfProp(ConfProp.PI_SOCKS_PROXY_HOST); |
| final String socksProxyPort = |
| location.getConfProp(ConfProp.PI_SOCKS_PROXY_PORT); |
| |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| switch (prop) { |
| case PI_JOB_TRACKER_HOST: { |
| if (colocate) |
| notifyChange(null, ConfProp.PI_NAME_NODE_HOST, |
| jobTrackerHost); |
| String newJobTrackerURI = |
| String.format("%s:%s", jobTrackerHost, jobTrackerPort); |
| notifyChange(null, ConfProp.JOB_TRACKER_URI, newJobTrackerURI); |
| break; |
| } |
| case PI_JOB_TRACKER_PORT: { |
| String newJobTrackerURI = |
| String.format("%s:%s", jobTrackerHost, jobTrackerPort); |
| notifyChange(null, ConfProp.JOB_TRACKER_URI, newJobTrackerURI); |
| break; |
| } |
| case PI_NAME_NODE_HOST: { |
| String newHDFSURI = |
| String.format("hdfs://%s:%s/", nameNodeHost, nameNodePort); |
| notifyChange(null, ConfProp.FS_DEFAULT_URI, newHDFSURI); |
| |
| // Break colocation if someone force the DFS Master |
| if (!colocate && !nameNodeHost.equals(jobTrackerHost)) |
| notifyChange(null, ConfProp.PI_COLOCATE_MASTERS, "no"); |
| break; |
| } |
| case PI_NAME_NODE_PORT: { |
| String newHDFSURI = |
| String.format("hdfs://%s:%s/", nameNodeHost, nameNodePort); |
| notifyChange(null, ConfProp.FS_DEFAULT_URI, newHDFSURI); |
| break; |
| } |
| case PI_SOCKS_PROXY_HOST: { |
| String newSocksProxyURI = |
| String.format("%s:%s", socksProxyHost, socksProxyPort); |
| notifyChange(null, ConfProp.SOCKS_SERVER, newSocksProxyURI); |
| break; |
| } |
| case PI_SOCKS_PROXY_PORT: { |
| String newSocksProxyURI = |
| String.format("%s:%s", socksProxyHost, socksProxyPort); |
| notifyChange(null, ConfProp.SOCKS_SERVER, newSocksProxyURI); |
| break; |
| } |
| case JOB_TRACKER_URI: { |
| String[] strs = jobTrackerURI.split(":", 2); |
| String host = strs[0]; |
| String port = (strs.length == 2) ? strs[1] : ""; |
| notifyChange(null, ConfProp.PI_JOB_TRACKER_HOST, host); |
| notifyChange(null, ConfProp.PI_JOB_TRACKER_PORT, port); |
| break; |
| } |
| case FS_DEFAULT_URI: { |
| try { |
| URI uri = new URI(fsDefaultURI); |
| if (uri.getScheme().equals("hdfs")) { |
| String host = uri.getHost(); |
| String port = Integer.toString(uri.getPort()); |
| notifyChange(null, ConfProp.PI_NAME_NODE_HOST, host); |
| notifyChange(null, ConfProp.PI_NAME_NODE_PORT, port); |
| } |
| } catch (URISyntaxException use) { |
| // Ignore the update! |
| } |
| break; |
| } |
| case SOCKS_SERVER: { |
| String[] strs = socksServerURI.split(":", 2); |
| String host = strs[0]; |
| String port = (strs.length == 2) ? strs[1] : ""; |
| notifyChange(null, ConfProp.PI_SOCKS_PROXY_HOST, host); |
| notifyChange(null, ConfProp.PI_SOCKS_PROXY_PORT, port); |
| break; |
| } |
| case PI_COLOCATE_MASTERS: { |
| if (colocate) |
| notifyChange(null, ConfProp.PI_NAME_NODE_HOST, |
| jobTrackerHost); |
| break; |
| } |
| case PI_SOCKS_PROXY_ENABLE: { |
| if (socksProxyEnable) { |
| notifyChange(null, ConfProp.SOCKET_FACTORY_DEFAULT, |
| "org.apache.hadoop.net.SocksSocketFactory"); |
| } else { |
| notifyChange(null, ConfProp.SOCKET_FACTORY_DEFAULT, |
| "org.apache.hadoop.net.StandardSocketFactory"); |
| } |
| break; |
| } |
| } |
| } |
| }); |
| |
| } |
| |
| /** |
| * Change notifications on properties (by name). A property might not be |
| * reflected as a ConfProp enum. If it is, the notification is forwarded |
| * to the ConfProp notifyChange method. If not, it is processed here. |
| * |
| * @param source |
| * @param propName |
| * @param propValue |
| */ |
| void notifyChange(TabListener source, String propName, String propValue) { |
| |
| ConfProp prop = ConfProp.getByName(propName); |
| if (prop != null) |
| notifyChange(source, prop, propValue); |
| |
| location.setConfProp(propName, propValue); |
| } |
| |
| /** |
| * Broadcast a property change to all registered tabs. If a tab is |
| * identified as the source of the change, this tab will not be notified. |
| * |
| * @param source TODO |
| * @param prop |
| * @param value |
| */ |
| private void fireChange(TabListener source, ConfProp prop, String value) { |
| for (TabListener tab : tabs) { |
| if (tab != source) |
| tab.notifyChange(prop, value); |
| } |
| } |
| |
| } |
| |
| /** |
| * Create a SWT Text component for the given {@link ConfProp} text |
| * configuration property. |
| * |
| * @param listener |
| * @param parent |
| * @param prop |
| * @return |
| */ |
| private Text createConfText(ModifyListener listener, Composite parent, |
| ConfProp prop) { |
| |
| Text text = new Text(parent, SWT.SINGLE | SWT.BORDER); |
| GridData data = new GridData(GridData.FILL_HORIZONTAL); |
| text.setLayoutData(data); |
| text.setData("hProp", prop); |
| text.setText(location.getConfProp(prop)); |
| text.addModifyListener(listener); |
| |
| return text; |
| } |
| |
| /** |
| * Create a SWT Checked Button component for the given {@link ConfProp} |
| * boolean configuration property. |
| * |
| * @param listener |
| * @param parent |
| * @param prop |
| * @return |
| */ |
| private Button createConfCheckButton(SelectionListener listener, |
| Composite parent, ConfProp prop, String text) { |
| |
| Button button = new Button(parent, SWT.CHECK); |
| button.setText(text); |
| button.setData("hProp", prop); |
| button.setSelection(location.getConfProp(prop).equalsIgnoreCase("yes")); |
| button.addSelectionListener(listener); |
| |
| return button; |
| } |
| |
| /** |
| * Create editor entry for the given configuration property. The editor is |
| * a couple (Label, Text). |
| * |
| * @param listener the listener to trigger on property change |
| * @param parent the SWT parent container |
| * @param prop the property to create an editor for |
| * @param labelText a label (null will defaults to the property name) |
| * |
| * @return a SWT Text field |
| */ |
| private Text createConfLabelText(ModifyListener listener, |
| Composite parent, ConfProp prop, String labelText) { |
| |
| Label label = new Label(parent, SWT.NONE); |
| if (labelText == null) |
| labelText = prop.name; |
| label.setText(labelText); |
| |
| return createConfText(listener, parent, prop); |
| } |
| |
| /** |
| * Create an editor entry for the given configuration name |
| * |
| * @param listener the listener to trigger on property change |
| * @param parent the SWT parent container |
| * @param propName the name of the property to create an editor for |
| * @param labelText a label (null will defaults to the property name) |
| * |
| * @return a SWT Text field |
| */ |
| private Text createConfNameEditor(ModifyListener listener, |
| Composite parent, String propName, String labelText) { |
| |
| { |
| ConfProp prop = ConfProp.getByName(propName); |
| if (prop != null) |
| return createConfLabelText(listener, parent, prop, labelText); |
| } |
| |
| Label label = new Label(parent, SWT.NONE); |
| if (labelText == null) |
| labelText = propName; |
| label.setText(labelText); |
| |
| Text text = new Text(parent, SWT.SINGLE | SWT.BORDER); |
| GridData data = new GridData(GridData.FILL_HORIZONTAL); |
| text.setLayoutData(data); |
| text.setData("hPropName", propName); |
| text.setText(location.getConfProp(propName)); |
| text.addModifyListener(listener); |
| |
| return text; |
| } |
| |
| /** |
| * Main parameters of the Hadoop location: |
| * <li> host and port of the Map/Reduce master (Job tracker) |
| * <li> host and port of the DFS master (Name node) |
| * <li> SOCKS proxy |
| */ |
| private class TabMain implements TabListener, ModifyListener, |
| SelectionListener { |
| |
| TabMediator mediator; |
| |
| Text locationName; |
| |
| Text textJTHost; |
| |
| Text textNNHost; |
| |
| Button colocateMasters; |
| |
| Text textJTPort; |
| |
| Text textNNPort; |
| |
| Text userName; |
| |
| Button useSocksProxy; |
| |
| Text socksProxyHost; |
| |
| Text socksProxyPort; |
| |
| TabMain(TabMediator mediator) { |
| this.mediator = mediator; |
| TabItem tab = new TabItem(mediator.folder, SWT.NONE); |
| tab.setText("General"); |
| tab.setToolTipText("General location parameters"); |
| tab.setImage(circle); |
| tab.setControl(createControl(mediator.folder)); |
| } |
| |
| private Control createControl(Composite parent) { |
| |
| Composite panel = new Composite(parent, SWT.FILL); |
| panel.setLayout(new GridLayout(2, false)); |
| |
| GridData data; |
| |
| /* |
| * Location name |
| */ |
| { |
| Composite subpanel = new Composite(panel, SWT.FILL); |
| subpanel.setLayout(new GridLayout(2, false)); |
| data = new GridData(); |
| data.horizontalSpan = 2; |
| data.horizontalAlignment = SWT.FILL; |
| subpanel.setLayoutData(data); |
| |
| locationName = |
| createConfLabelText(this, subpanel, ConfProp.PI_LOCATION_NAME, |
| "&Location name:"); |
| } |
| |
| /* |
| * Map/Reduce group |
| */ |
| { |
| Group groupMR = new Group(panel, SWT.SHADOW_NONE); |
| groupMR.setText("Map/Reduce Master"); |
| groupMR.setToolTipText("Address of the Map/Reduce master node " |
| + "(the Job Tracker)."); |
| GridLayout layout = new GridLayout(2, false); |
| groupMR.setLayout(layout); |
| data = new GridData(); |
| data.verticalAlignment = SWT.FILL; |
| data.horizontalAlignment = SWT.CENTER; |
| data.widthHint = 250; |
| groupMR.setLayoutData(data); |
| |
| // Job Tracker host |
| Label label = new Label(groupMR, SWT.NONE); |
| label.setText("Host:"); |
| data = |
| new GridData(GridData.BEGINNING, GridData.CENTER, false, true); |
| label.setLayoutData(data); |
| |
| textJTHost = |
| createConfText(this, groupMR, ConfProp.PI_JOB_TRACKER_HOST); |
| data = new GridData(GridData.FILL, GridData.CENTER, true, true); |
| textJTHost.setLayoutData(data); |
| |
| // Job Tracker port |
| label = new Label(groupMR, SWT.NONE); |
| label.setText("Port:"); |
| data = |
| new GridData(GridData.BEGINNING, GridData.CENTER, false, true); |
| label.setLayoutData(data); |
| |
| textJTPort = |
| createConfText(this, groupMR, ConfProp.PI_JOB_TRACKER_PORT); |
| data = new GridData(GridData.FILL, GridData.CENTER, true, true); |
| textJTPort.setLayoutData(data); |
| } |
| |
| /* |
| * DFS group |
| */ |
| { |
| Group groupDFS = new Group(panel, SWT.SHADOW_NONE); |
| groupDFS.setText("DFS Master"); |
| groupDFS.setToolTipText("Address of the Distributed FileSystem " |
| + "master node (the Name Node)."); |
| GridLayout layout = new GridLayout(2, false); |
| groupDFS.setLayout(layout); |
| data = new GridData(); |
| data.horizontalAlignment = SWT.CENTER; |
| data.widthHint = 250; |
| groupDFS.setLayoutData(data); |
| |
| colocateMasters = |
| createConfCheckButton(this, groupDFS, |
| ConfProp.PI_COLOCATE_MASTERS, "Use M/R Master host"); |
| data = new GridData(); |
| data.horizontalSpan = 2; |
| colocateMasters.setLayoutData(data); |
| |
| // Job Tracker host |
| Label label = new Label(groupDFS, SWT.NONE); |
| data = new GridData(); |
| label.setText("Host:"); |
| label.setLayoutData(data); |
| |
| textNNHost = |
| createConfText(this, groupDFS, ConfProp.PI_NAME_NODE_HOST); |
| |
| // Job Tracker port |
| label = new Label(groupDFS, SWT.NONE); |
| data = new GridData(); |
| label.setText("Port:"); |
| label.setLayoutData(data); |
| |
| textNNPort = |
| createConfText(this, groupDFS, ConfProp.PI_NAME_NODE_PORT); |
| } |
| |
| { |
| Composite subpanel = new Composite(panel, SWT.FILL); |
| subpanel.setLayout(new GridLayout(2, false)); |
| data = new GridData(); |
| data.horizontalSpan = 2; |
| data.horizontalAlignment = SWT.FILL; |
| subpanel.setLayoutData(data); |
| |
| userName = |
| createConfLabelText(this, subpanel, ConfProp.PI_USER_NAME, |
| "&User name:"); |
| } |
| |
| // SOCKS proxy group |
| { |
| Group groupSOCKS = new Group(panel, SWT.SHADOW_NONE); |
| groupSOCKS.setText("SOCKS proxy"); |
| groupSOCKS.setToolTipText("Address of the SOCKS proxy to use " |
| + "to connect to the infrastructure."); |
| GridLayout layout = new GridLayout(2, false); |
| groupSOCKS.setLayout(layout); |
| data = new GridData(); |
| data.horizontalAlignment = SWT.CENTER; |
| data.horizontalSpan = 2; |
| data.widthHint = 250; |
| groupSOCKS.setLayoutData(data); |
| |
| useSocksProxy = |
| createConfCheckButton(this, groupSOCKS, |
| ConfProp.PI_SOCKS_PROXY_ENABLE, "Enable SOCKS proxy"); |
| data = new GridData(); |
| data.horizontalSpan = 2; |
| useSocksProxy.setLayoutData(data); |
| |
| // SOCKS proxy host |
| Label label = new Label(groupSOCKS, SWT.NONE); |
| data = new GridData(); |
| label.setText("Host:"); |
| label.setLayoutData(data); |
| |
| socksProxyHost = |
| createConfText(this, groupSOCKS, ConfProp.PI_SOCKS_PROXY_HOST); |
| |
| // SOCKS proxy port |
| label = new Label(groupSOCKS, SWT.NONE); |
| data = new GridData(); |
| label.setText("Port:"); |
| label.setLayoutData(data); |
| |
| socksProxyPort = |
| createConfText(this, groupSOCKS, ConfProp.PI_SOCKS_PROXY_PORT); |
| } |
| |
| // Update the state of all widgets according to the current values! |
| reloadConfProp(ConfProp.PI_COLOCATE_MASTERS); |
| reloadConfProp(ConfProp.PI_SOCKS_PROXY_ENABLE); |
| reloadConfProp(ConfProp.PI_JOB_TRACKER_HOST); |
| |
| return panel; |
| } |
| |
| /** |
| * Reload the given configuration property value |
| * |
| * @param prop |
| */ |
| private void reloadConfProp(ConfProp prop) { |
| this.notifyChange(prop, location.getConfProp(prop)); |
| } |
| |
| public void notifyChange(ConfProp prop, String propValue) { |
| switch (prop) { |
| case PI_JOB_TRACKER_HOST: { |
| textJTHost.setText(propValue); |
| break; |
| } |
| case PI_JOB_TRACKER_PORT: { |
| textJTPort.setText(propValue); |
| break; |
| } |
| case PI_LOCATION_NAME: { |
| locationName.setText(propValue); |
| break; |
| } |
| case PI_USER_NAME: { |
| userName.setText(propValue); |
| break; |
| } |
| case PI_COLOCATE_MASTERS: { |
| if (colocateMasters != null) { |
| boolean colocate = propValue.equalsIgnoreCase("yes"); |
| colocateMasters.setSelection(colocate); |
| if (textNNHost != null) { |
| textNNHost.setEnabled(!colocate); |
| } |
| } |
| break; |
| } |
| case PI_NAME_NODE_HOST: { |
| textNNHost.setText(propValue); |
| break; |
| } |
| case PI_NAME_NODE_PORT: { |
| textNNPort.setText(propValue); |
| break; |
| } |
| case PI_SOCKS_PROXY_ENABLE: { |
| if (useSocksProxy != null) { |
| boolean useProxy = propValue.equalsIgnoreCase("yes"); |
| useSocksProxy.setSelection(useProxy); |
| if (socksProxyHost != null) |
| socksProxyHost.setEnabled(useProxy); |
| if (socksProxyPort != null) |
| socksProxyPort.setEnabled(useProxy); |
| } |
| break; |
| } |
| case PI_SOCKS_PROXY_HOST: { |
| socksProxyHost.setText(propValue); |
| break; |
| } |
| case PI_SOCKS_PROXY_PORT: { |
| socksProxyPort.setText(propValue); |
| break; |
| } |
| } |
| } |
| |
| /* @inheritDoc */ |
| public void modifyText(ModifyEvent e) { |
| final Text text = (Text) e.widget; |
| final ConfProp prop = (ConfProp) text.getData("hProp"); |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| mediator.notifyChange(TabMain.this, prop, text.getText()); |
| } |
| }); |
| } |
| |
| /* @inheritDoc */ |
| public void widgetDefaultSelected(SelectionEvent e) { |
| this.widgetSelected(e); |
| } |
| |
| /* @inheritDoc */ |
| public void widgetSelected(SelectionEvent e) { |
| final Button button = (Button) e.widget; |
| final ConfProp prop = (ConfProp) button.getData("hProp"); |
| |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| // We want to receive the update also! |
| mediator.notifyChange(null, prop, button.getSelection() ? "yes" |
| : "no"); |
| } |
| }); |
| } |
| |
| } |
| |
| private class TabAdvanced implements TabListener, ModifyListener { |
| TabMediator mediator; |
| |
| private Composite panel; |
| |
| private Map<String, Text> textMap = new TreeMap<String, Text>(); |
| |
| TabAdvanced(TabMediator mediator) { |
| this.mediator = mediator; |
| TabItem tab = new TabItem(mediator.folder, SWT.NONE); |
| tab.setText("Advanced parameters"); |
| tab.setToolTipText("Access to advanced Hadoop parameters"); |
| tab.setImage(circle); |
| tab.setControl(createControl(mediator.folder)); |
| |
| } |
| |
| private Control createControl(Composite parent) { |
| ScrolledComposite sc = |
| new ScrolledComposite(parent, SWT.BORDER | SWT.H_SCROLL |
| | SWT.V_SCROLL); |
| |
| panel = new Composite(sc, SWT.NONE); |
| sc.setContent(panel); |
| |
| sc.setExpandHorizontal(true); |
| sc.setExpandVertical(true); |
| |
| sc.setMinSize(640, 480); |
| |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| layout.makeColumnsEqualWidth = false; |
| panel.setLayout(layout); |
| panel.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, |
| true, 1, 1)); |
| |
| // Sort by property name |
| Configuration config = location.getConfiguration(); |
| SortedMap<String, String> map = new TreeMap<String, String>(); |
| Iterator<Entry<String, String>> it = config.iterator(); |
| while (it.hasNext()) { |
| Entry<String, String> entry = it.next(); |
| map.put(entry.getKey(), entry.getValue()); |
| } |
| |
| for (Entry<String, String> entry : map.entrySet()) { |
| Text text = createConfNameEditor(this, panel, entry.getKey(), null); |
| textMap.put(entry.getKey(), text); |
| } |
| |
| sc.setMinSize(panel.computeSize(SWT.DEFAULT, SWT.DEFAULT)); |
| |
| return sc; |
| } |
| |
| public void notifyChange(ConfProp prop, final String propValue) { |
| Text text = textMap.get(prop.name); |
| text.setText(propValue); |
| } |
| |
| public void modifyText(ModifyEvent e) { |
| final Text text = (Text) e.widget; |
| Object hProp = text.getData("hProp"); |
| final ConfProp prop = (hProp != null) ? (ConfProp) hProp : null; |
| Object hPropName = text.getData("hPropName"); |
| final String propName = |
| (hPropName != null) ? (String) hPropName : null; |
| |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| if (prop != null) |
| mediator.notifyChange(TabAdvanced.this, prop, text.getText()); |
| else |
| mediator |
| .notifyChange(TabAdvanced.this, propName, text.getText()); |
| } |
| }); |
| } |
| } |
| |
| } |