/*******************************************************************************
* Copyright (c) 2011, 2016 Eurotech and/or its affiliates
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eurotech
*******************************************************************************/
package org.eclipse.kura.web.client.network;
import org.eclipse.kura.web.client.messages.Messages;
import org.eclipse.kura.web.client.resources.Resources;
import org.eclipse.kura.web.client.util.FailureHandler;
import org.eclipse.kura.web.shared.model.GwtNetIfConfigMode;
import org.eclipse.kura.web.shared.model.GwtNetInterfaceConfig;
import org.eclipse.kura.web.shared.model.GwtSession;
import org.eclipse.kura.web.shared.model.GwtXSRFToken;
import org.eclipse.kura.web.shared.service.GwtNetworkService;
import org.eclipse.kura.web.shared.service.GwtNetworkServiceAsync;
import org.eclipse.kura.web.shared.service.GwtSecurityTokenService;
import org.eclipse.kura.web.shared.service.GwtSecurityTokenServiceAsync;
import com.allen_sauer.gwt.log.client.Log;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
public class NetworkButtonBar extends LayoutContainer
{
private static final Messages MSGS = GWT.create(Messages.class);
private final GwtSecurityTokenServiceAsync gwtXSRFService = GWT.create(GwtSecurityTokenService.class);
private final GwtNetworkServiceAsync gwtNetworkService = GWT.create(GwtNetworkService.class);
@SuppressWarnings("unused")
private GwtSession m_currentSession;
private NetworkPanel m_netPanel;
private NetworkInterfacesTable m_netTable;
private NetInterfaceConfigTabs m_netTabs;
private ToolBar m_buttonBar;
private Button m_applyButton;
public NetworkButtonBar(GwtSession currentSession,
NetworkPanel netPanel,
NetworkInterfacesTable netTable,
NetInterfaceConfigTabs netTabs)
{
m_currentSession = currentSession;
m_netPanel = netPanel;
m_netTable = netTable;
m_netTabs = netTabs;
m_netTable.addListener(Events.Change, new Listener<BaseEvent>() {
public void handleEvent(BaseEvent be) {
Log.debug("Enabling Button Bar because of " + be.getSource().toString() + " :: " + be.toString());
if(m_buttonBar == null) {
Log.debug("ButtonBar is null");
}
m_applyButton.enable();
}
});
m_netTabs.addListener(Events.Change, new Listener<BaseEvent>() {
public void handleEvent(BaseEvent be) {
Log.debug("Enabling Button Bar because of " + be.getSource().toString() + " :: " + be.toString());
if(m_buttonBar == null) {
Log.debug("ButtonBar is null");
}
m_applyButton.enable();
}
});
}
protected void onRender(Element parent, int index)
{
super.onRender(parent, index);
setLayout(new FitLayout());
setId("network-buttons");
m_buttonBar = new ToolBar();
m_buttonBar.setHeight(20);
m_buttonBar.setAlignment(HorizontalAlignment.LEFT);
m_applyButton = new Button(MSGS.netApply(),
AbstractImagePrototype.create(Resources.INSTANCE.accept()),
new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
if (m_netTabs.isValid()) {
GwtNetInterfaceConfig prevNetIf = m_netTable.getSelectedNetInterfaceConfig();
Log.debug("about to getUpdatedNetInterface()");
final GwtNetInterfaceConfig updatedNetIf = m_netTabs.getUpdatedNetInterface();
// Submit updated NetInterfaceConfig and priorities
if(prevNetIf != null && prevNetIf.equals(updatedNetIf)) {
Log.debug("net interface config matches the previous one");
m_netTable.refresh();
m_applyButton.disable();
} else {
String newNetwork = calculateNetwork(updatedNetIf.getIpAddress(), updatedNetIf.getSubnetMask());
String prevNetwork = Window.Location.getHost();
try {
prevNetwork = calculateNetwork(Window.Location.getHost(), updatedNetIf.getSubnetMask());
} catch (Exception e) {
Log.debug("calculateNetwork() failed for ipAddress: " + Window.Location.getHost() + ", and subnet: " + updatedNetIf.getSubnetMask());
}
if (newNetwork != null) {
//if a static IP assigned, re-direct to the new location
if (updatedNetIf.getConfigMode().equals(GwtNetIfConfigMode.netIPv4ConfigModeManual.name()) &&
newNetwork.equals(prevNetwork) &&
Window.Location.getHost().equals(prevNetIf.getIpAddress())) {
Timer t = new Timer () {
public void run () {
Log.debug("redirecting to new address: " + updatedNetIf.getIpAddress());
Window.Location.replace("http://" + updatedNetIf.getIpAddress());
}
};
t.schedule(500);
}
}
m_netPanel.mask(MSGS.applying());
Log.debug("updateNetInterfaceConfigurations()");
gwtXSRFService.generateSecurityToken(new AsyncCallback<GwtXSRFToken> () {
@Override
public void onFailure(Throwable ex) {
FailureHandler.handle(ex);
}
@Override
public void onSuccess(GwtXSRFToken token) {
gwtNetworkService.updateNetInterfaceConfigurations(token, updatedNetIf, new AsyncCallback<Void>() {
public void onSuccess(Void result) {
Log.debug("successfully update net interface config");
m_netTable.refresh();
m_applyButton.disable();
m_netPanel.unmask();
}
public void onFailure(Throwable caught) {
Log.debug("caught: " + caught.toString());
FailureHandler.handle(caught);
m_netPanel.unmask();
}
});
}});
}
}
else {
MessageBox.info(MSGS.information(),
MSGS.deviceConfigError(),
null);
}
}
});
Button m_refresh = new Button("Refresh",
AbstractImagePrototype.create(Resources.INSTANCE.refresh()),
new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
// TODO Auto-generated method stub
m_netTable.refresh();
}
});
m_applyButton.setWidth(100);
m_buttonBar.setBorders(true);
m_refresh.setWidth(100);
m_buttonBar.add(m_applyButton);
m_buttonBar.add(new SeparatorToolItem());
m_buttonBar.add(m_refresh);
m_buttonBar.add(new SeparatorToolItem());
m_applyButton.disable();
//m_buttonBar.disable();
add(m_buttonBar);
}
public String calculateNetwork(String ipAddress, String netmask) {
if(ipAddress == null || ipAddress.isEmpty() || netmask == null || netmask.isEmpty()) {
return null;
}
String network = null;
try {
int ipAddressValue = 0;
int netmaskValue = 0;
String[] sa = this.splitIp(ipAddress);
for (int i = 24, t = 0; i >= 0; i -= 8, t++) {
ipAddressValue = ipAddressValue | (Integer.parseInt(sa[t]) << i);
}
sa = this.splitIp(netmask);
for (int i = 24, t = 0; i >= 0; i -= 8, t++) {
netmaskValue = netmaskValue | (Integer.parseInt(sa[t]) << i);
}
network = dottedQuad(ipAddressValue & netmaskValue);
} catch (Exception e) {
Log.warn("Error calculating network for ip address: " + ipAddress + " and netmask: " + netmask, e);
}
return network;
}
private String dottedQuad(int ip) {
StringBuffer sb = new StringBuffer(15);
for (int shift = 24; shift > 0; shift -= 8) {
// process 3 bytes, from high order byte down.
sb.append(Integer.toString((ip >>> shift) & 0xff));
sb.append('.');
}
sb.append(Integer.toString(ip & 0xff));
return sb.toString();
}
private String[] splitIp(String ip) {
String sIp = new String(ip);
String[] ret = new String[4];
int ind = 0;
for (int i = 0; i < 3; i++) {
if ((ind = sIp.indexOf(".")) >= 0) {
ret[i] = sIp.substring(0, ind);
sIp = sIp.substring(ind + 1);
if (i == 2) {
ret[3] = sIp;
}
}
}
return ret;
}
}