blob: 3718dcca6d12ebbdcba93d7c87531f8cabc89c15 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed 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 com.motorola.studio.android.remote.ui.wireless;
import java.util.Collection;
import java.util.LinkedHashSet;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.sequoyah.device.framework.factory.InstanceRegistry;
import org.eclipse.sequoyah.device.framework.model.AbstractMobileInstance;
import org.eclipse.sequoyah.device.framework.ui.DeviceUIResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import com.motorola.studio.android.adt.ISerialNumbered;
import com.motorola.studio.android.devices.DevicesManager;
import com.motorola.studio.android.remote.RemoteDeviceConstants;
import com.motorola.studio.android.remote.RemoteDevicePlugin;
import com.motorola.studio.android.remote.RemoteDeviceUtils;
import com.motorola.studio.android.remote.i18n.RemoteDeviceNLS;
import com.motorola.studio.android.remote.instance.RemoteDeviceInstance;
/**
* Composite containing the Android Wireless Remote Device properties for edition.
*/
public class WirelessPropertiesComposite extends Composite
{
/**
* Empty String
*/
private static final String EMPTY_STRING = "";
/**
* Default invalid integer
*/
private static final int DEFAULT_INVALID_INTEGER = -1;
private String name;
private final String host;
private int port;
private int timeout;
// DEVICE - if it already exist
ISerialNumbered device;
private IProgressMonitor monitor;
private final Collection<WirelessPropertiesChangedListener> listeners =
new LinkedHashSet<WirelessPropertiesChangedListener>();
// Error messages
private static final String NAME_ERR_MESSAGE =
RemoteDeviceNLS.ERR_WirelessDeviceWizardPage_Name;
private static final String HOST_ERR_MESSAGE = RemoteDeviceNLS.ERR_RemoteDeviceWizardPage_IP;
private static final String PORT_ERR_MESSAGE = RemoteDeviceNLS.ERR_RemoteDeviceWizardPage_Port;
private static final String TIMEOUT_ERR_MESSAGE =
RemoteDeviceNLS.ERR_RemoteDeviceWizardPage_Timeout;
private final Text nameText;
private final Text portText;
private final Text timeoutText;
/*
* Listener used for handle Timeout text change.
*/
private final class TimeoutModifyListener implements ModifyListener
{
public void modifyText(ModifyEvent e)
{
String timeoutStr = timeoutText.getText();
try
{
timeout = Integer.parseInt(timeoutStr);
}
catch (NumberFormatException e1)
{
timeout = DEFAULT_INVALID_INTEGER;
}
finally
{
notifyListeners();
}
}
}
/*
* Listener used for handle Port text change.
*/
private final class PortModifyListener implements ModifyListener
{
public void modifyText(ModifyEvent e)
{
String portStr = portText.getText();
try
{
port = Integer.parseInt(portStr);
// manage the case where the entered IP/Port matches of the an existing device
manageSameIPAndPortOfRemoteDevice();
}
catch (NumberFormatException e1)
{
port = DEFAULT_INVALID_INTEGER;
}
finally
{
notifyListeners();
}
}
}
/*
* Listener used for handle Name text change.
*/
private final class NameModifyListener implements ModifyListener
{
public void modifyText(ModifyEvent e)
{
name = nameText.getText();
notifyListeners();
}
}
/**
* Listener that must be implemented by others who want to monitor changes
* in this composite
*/
public interface WirelessPropertiesChangedListener
{
public void propertiesChanged();
}
/**
* Constructor
*
* @param parent the parent composite
*/
public WirelessPropertiesComposite(Composite parent, String host, ISerialNumbered device)
{
this(parent, host, EMPTY_STRING, EMPTY_STRING, device);
}
/**
* Create contents of the composite
*
* @param parent the parent composite
* @param initialHost initial value for host
* @param initialPort initial value for port number
* @param initialTiomeout initial value for timeout
*/
public WirelessPropertiesComposite(Composite parent, String initialHost, String initialPort,
String initialTimeout, ISerialNumbered device)
{
super(parent, SWT.NONE);
this.name = device.getDeviceName() + RemoteDeviceConstants.DEFAULT_WIRELESS_SUFIX;
this.host = initialHost;
this.port = RemoteDeviceConstants.DEFAULT_PORT;
this.timeout = RemoteDeviceConstants.DEFAULT_TIMEOUT;
// Set Help
PlatformUI.getWorkbench().getHelpSystem()
.setHelp(parent, RemoteDeviceConstants.WIRELESS_HELP_ID);
setLayout(new GridLayout(2, false));
// add device name
Label nameLabel = new Label(this, SWT.NONE);
nameLabel.setText(RemoteDeviceNLS.UI_Name);
nameLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, false));
// add device text
nameText = new Text(this, SWT.BORDER);
nameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
nameText.addModifyListener(new NameModifyListener());
nameText.setText(name);
// add IP name
Label hostLabel = new Label(this, SWT.NONE);
hostLabel.setText(RemoteDeviceNLS.UI_Host);
hostLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, false));
// add IP text
Text hostText = new Text(this, SWT.BORDER);
hostText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
hostText.setEnabled(false);
hostText.setText(host);
// add port name
Label portLabel = new Label(this, SWT.NONE);
portLabel.setText(RemoteDeviceNLS.UI_Port);
portLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, false));
// add port text
portText = new Text(this, SWT.BORDER);
portText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
portText.setText(String.valueOf(port));
portText.addModifyListener(new PortModifyListener());
portText.setText(String.valueOf(port));
// add timeout label
Label timeoutLabel = new Label(this, SWT.NONE);
timeoutLabel.setText(RemoteDeviceNLS.UI_Timeout);
timeoutLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, false));
// add timeout text
timeoutText = new Text(this, SWT.BORDER);
timeoutText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
timeoutText.addModifyListener(new TimeoutModifyListener());
timeoutText.setText((!initialTimeout.equals(EMPTY_STRING)) ? initialTimeout : String
.valueOf(RemoteDeviceConstants.DEFAULT_TIMEOUT));
// manage the case where the entered IP/Port matches of the an existing device
manageSameIPAndPortOfRemoteDevice();
}
/**
* Add a listener which will be notified when there is a change in the composite
*
* @param wirelessDeviceWizardPage a listener which will be notified when there is a change in the composite
*/
public void addPropertyChangeListener(WirelessPropertiesChangedListener listener)
{
synchronized (listeners)
{
listeners.add(listener);
}
}
/**
* Remove a listener from the list
*
* @param wirelessDeviceWizardPage the listener to be removed
*/
public void removePropertyChangeListener(WirelessPropertiesChangedListener listener)
{
synchronized (listeners)
{
listeners.remove(listener);
}
}
/**
* Get the configured host
*
* @return the configured host
*/
public String getHost()
{
return host;
}
/**
* Get the configured timeout
*
* @return the configured timeout
*/
public int getTimeout()
{
return timeout;
}
/**
* Get the configured port number
*
* @return the configured port number
*/
public int getPort()
{
return port;
}
/**
* Get the status associated with the current state.
*
* @return The {@link IStatus}.
*/
public IStatus getStatus()
{
IStatus status =
new Status(IStatus.OK, RemoteDevicePlugin.PLUGIN_ID,
RemoteDeviceNLS.UI_WirelessInformationPage_Description);
String errorMessage = null;
boolean isValidationOK = true;
if ((name == null) || name.equals(""))
{
errorMessage = NAME_ERR_MESSAGE;
status = new Status(IStatus.ERROR, RemoteDevicePlugin.PLUGIN_ID, errorMessage);
isValidationOK = false;
}
if (isValidationOK && (port < 0))
{
errorMessage = PORT_ERR_MESSAGE;
status = new Status(IStatus.ERROR, RemoteDevicePlugin.PLUGIN_ID, errorMessage);
isValidationOK = false;
}
if ((isValidationOK && (port < RemoteDeviceConstants.MINIMUM_PORT_NUMBER))
|| (port > RemoteDeviceConstants.MAXIMUM_PORT_NUMBER))
{
errorMessage =
NLS.bind(
RemoteDeviceNLS.WirelessPropertiesComposite_MsgPortNumberEqualOrHigherThan,
RemoteDeviceConstants.MINIMUM_PORT_NUMBER,
RemoteDeviceConstants.MAXIMUM_PORT_NUMBER);
status = new Status(IStatus.ERROR, RemoteDevicePlugin.PLUGIN_ID, errorMessage);
isValidationOK = false;
}
if (isValidationOK && (timeout < 0))
{
errorMessage = TIMEOUT_ERR_MESSAGE;
status = new Status(IStatus.ERROR, RemoteDevicePlugin.PLUGIN_ID, errorMessage);
isValidationOK = false;
}
if (isValidationOK && (host != null))
{
if (host.equals(EMPTY_STRING))
{
errorMessage = HOST_ERR_MESSAGE;
status = new Status(IStatus.ERROR, RemoteDevicePlugin.PLUGIN_ID, errorMessage);
isValidationOK = false;
}
}
if (isValidationOK)
{
// check if host:port already exist
Collection<ISerialNumbered> existentRemoteDeviceInstances =
DevicesManager.getInstance().getInstancesByType(RemoteDeviceInstance.class);
for (ISerialNumbered device : existentRemoteDeviceInstances)
{
if (RemoteDeviceUtils.hasSameHostAndPort(device, host, port))
{
if ((this.device == null)
|| ((this.device != null) && (!this.device.getDeviceName().equals(
device.getDeviceName()))))
{
errorMessage =
NLS.bind(
RemoteDeviceNLS.ERR_RemoteDeviceWizardPage_WirelessDuplicated,
device.getDeviceName());
status =
new Status(IStatus.WARNING, RemoteDevicePlugin.PLUGIN_ID,
errorMessage);
isValidationOK = false;
break;
}
}
}
}
if (isValidationOK && (name != null))
{
// this verification is only applied if the IP/Port does not coincide with another application
if (getRemoteDeviceWithSameIPAndPort() == null)
{
InstanceRegistry registry = InstanceRegistry.getInstance();
if (!name.equals(EMPTY_STRING))
{ //$NON-NLS-1$
if (!(registry.getInstancesByName(name).size() == 0))
{
errorMessage =
DeviceUIResources.SEQUOYAH_Emulator_Wizard_Project_Description_Duplicated_Error;
status =
new Status(IStatus.ERROR, RemoteDevicePlugin.PLUGIN_ID,
errorMessage);
isValidationOK = false;
}
else if (!AbstractMobileInstance.validName(name))
{
errorMessage = DeviceUIResources.SEQUOYAH_Instance_Name_Invalid_Error;
status =
new Status(IStatus.ERROR, RemoteDevicePlugin.PLUGIN_ID,
errorMessage);
isValidationOK = false;
}
}
}
}
return status;
}
/*
* Notify change listeners that there was a change in the values
*/
private void notifyListeners()
{
synchronized (listeners)
{
for (WirelessPropertiesChangedListener listener : listeners)
{
listener.propertiesChanged();
}
}
}
/*
* Manage the case in which was inputed the same IP and port of
* an existing remote device.
*/
private void manageSameIPAndPortOfRemoteDevice()
{
ISerialNumbered matchedDevice = getRemoteDeviceWithSameIPAndPort();
// if there is a device which matches the IP/Port of this wizard, set its Name and disable the field
if (matchedDevice != null)
{
nameText.setText(matchedDevice.getDeviceName());
nameText.setEnabled(false);
}
// since there is no device, enable the name field
else
{
nameText.setEnabled(true);
}
}
/*
* Returns a device which matches the IP/Port of this wizard,
* in cas there is any.
*
* @return get the {@link ISerialNumbered} device which matches
* the IP/Port of this wizard.
*/
private ISerialNumbered getRemoteDeviceWithSameIPAndPort()
{
ISerialNumbered matchedDevice = null;
Collection<ISerialNumbered> existentRemoteDeviceInstances =
DevicesManager.getInstance().getInstancesByType(RemoteDeviceInstance.class);
for (ISerialNumbered device : existentRemoteDeviceInstances)
{
if (RemoteDeviceUtils.hasSameHostAndPort(device, host, port))
{
if ((this.device == null)
|| ((this.device != null) && (!this.device.getDeviceName().equals(
device.getDeviceName()))))
{
matchedDevice = device;
break;
}
}
}
return matchedDevice;
}
/**
* Get the {@link IProgressMonitor}
*
* @return Return the monitor
*/
public IProgressMonitor getProgressMonitor()
{
return monitor;
}
/**
* @param monitor the monitor to set
*/
public void setProgressMonitor(IProgressMonitor monitor)
{
this.monitor = monitor;
}
/**
* Get the device name.
*
* @return Device name
*/
public String getDeviceName()
{
return this.name;
}
}