blob: 8dd503c44d27959620e270e7d5a35d00e8d382f6 [file] [log] [blame]
/**
* Copyright (c) 2018 CEA.
* 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:
* CEA - initial API and implementation and/or initial documentation
*/
package org.eclipse.sensinact.studio.model.manager.listener.devicelocation;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.INotifyChangedListener;
import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelUpdater;
import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
import org.eclipse.sensinact.studio.model.resource.utils.GPSparsingException;
import org.eclipse.sensinact.studio.resource.Device;
import org.eclipse.sensinact.studio.resource.Gateway;
import org.eclipse.sensinact.studio.resource.Service;
/**
* @author Etienne Gandrille
* @contributor Christophe Munilla
*/
public class DeviceUpdateManager implements INotifyChangedListener {
private static DeviceUpdateManager INSTANCE = null;
private static final Logger logger = Logger.getLogger(DeviceUpdateManager.class);
private final Set<DeviceLocationListener> locationListeners = new HashSet<DeviceLocationListener>();
private final Set<DeviceIconListener> iconListeners = new HashSet<DeviceIconListener>();
private final Set<DeviceSelectionListener> selectionListeners = new HashSet<DeviceSelectionListener>();
public synchronized static DeviceUpdateManager getInstance() {
if (INSTANCE == null)
INSTANCE = new DeviceUpdateManager();
return INSTANCE;
}
DeviceUpdateManager() {
ModelEditor.getInstance().addNotifyChangedListener(this);
}
@Override
public void notifyChanged(Notification arg0) {
if(arg0.getEventType() == Notification.SET && arg0.getFeature() instanceof EAttribute) {
if("location".equals(((EAttribute)arg0.getFeature()).getName())) {
try {
DeviceDescriptor descriptor = new DeviceDescriptor(((Gateway)((EObject)
arg0.getNotifier()).eContainer()).getName(), ((Device)arg0.getNotifier()
).getName());
descriptor.setIcon(((Device)arg0.getNotifier()).getIcon());
descriptor.setLocation((String) arg0.getNewValue());
GPScoordinates gps = new GPScoordinates((String) arg0.getNewValue());
for (DeviceLocationListener listener : locationListeners) {
listener.deviceLocationUpdated(gps,descriptor);
}
} catch (GPSparsingException e) {
logger.error(e.getMessage(),e);
}
}
if("icon".equals(((EAttribute)arg0.getFeature()).getName())) {
DeviceDescriptor descriptor = new DeviceDescriptor(((Gateway)((EObject)
arg0.getNotifier()).eContainer()).getName(), ((Device)arg0.getNotifier()
).getName());
descriptor.setLocation(((Device)arg0.getNotifier()).getLocation());
descriptor.setIcon((String) arg0.getNewValue());
for (DeviceIconListener listener : iconListeners) {
listener.deviceIconUpdated(descriptor);
}
}
} else if(arg0.getEventType() == Notification.REMOVE
&& arg0.getNotifier() instanceof Gateway
&& arg0.getOldValue() instanceof Device){
DeviceDescriptor descriptor = new DeviceDescriptor(((Gateway)
arg0.getNotifier()).getName(), ((Device)arg0.getOldValue()
).getName());
for (DeviceLocationListener listener : locationListeners) {
listener.deviceRemoved(descriptor);
}
} else if(arg0.getEventType() == Notification.ADD) {
if(arg0.getNotifier() instanceof Gateway && arg0.getNewValue() instanceof Device){
DeviceDescriptor descriptor = new DeviceDescriptor(((Gateway)
arg0.getNotifier()).getName(), ((Device)arg0.getNewValue()
).getName());
String location = ((Device)arg0.getNewValue()).getLocation();
String icon = ((Device)arg0.getNewValue()).getIcon();
descriptor.setIcon(icon);
descriptor.setLocation(location);
if(location != null && !"null".equals(location)) {
GPScoordinates gps = null;
try {
gps = new GPScoordinates(((Device)arg0.getNewValue()).getLocation());
} catch (GPSparsingException e) {
e.printStackTrace();
}
for (DeviceLocationListener listener : locationListeners) {
listener.deviceLocationUpdated(gps, descriptor);;
}
}
if(icon != null && !"null".equals(icon)) {
for (DeviceIconListener listener : iconListeners) {
listener.deviceIconUpdated(descriptor);
}
}
try {
ModelUpdater.getInstance().updateServices(((Gateway)
arg0.getNotifier()).getName(), ((Device)arg0.getNewValue()
).getName());
} catch (IOException e) {
e.printStackTrace();
}
}
else if(arg0.getNotifier() instanceof Device && arg0.getNewValue() instanceof Service){
try {
ModelUpdater.getInstance().updateResources(((Gateway)((Device)(arg0.getNotifier())).eContainer()).getName(),
((Device)arg0.getNotifier()).getName(), ((Service)arg0.getNewValue()
).getName());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
*
* @param deviceDescriptor
* @param newCoordinates
* @return true if success, false if update location failed. It happens when the location is not updatable.
*/
public boolean updateLocationInServer(DeviceDescriptor deviceDescriptor, GPScoordinates newCoordinates) {
if (needUpdate(deviceDescriptor, newCoordinates)) {
if (ModelUpdater.getInstance().updateLocationOnServer(deviceDescriptor, newCoordinates)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
public void updateDeviceSelection(GPScoordinates coordinates) {
for (DeviceSelectionListener listener : selectionListeners) {
listener.deviceSelected(coordinates);
}
}
private boolean needUpdate(DeviceDescriptor deviceDescriptor, GPScoordinates newCoordinates) {
GPScoordinates oldCoordinates = ModelEditor.getInstance().getLocation(deviceDescriptor);
return (! newCoordinates.equals(oldCoordinates));
}
public void removeDeviceIconListener(DeviceIconListener listener) {
iconListeners.remove(listener);
}
public void addDeviceIconListener(DeviceIconListener listener) {
iconListeners.add(listener);
}
public void removeDeviceLocationListener(DeviceLocationListener listener) {
locationListeners.remove(listener);
}
public void addDeviceLocationListener(DeviceLocationListener listener) {
locationListeners.add(listener);
}
public void removeDeviceSelectionListener(DeviceSelectionListener listener) {
selectionListeners.remove(listener);
}
public void addDeviceSelectionListener(DeviceSelectionListener listener) {
selectionListeners.add(listener);
}
public void deleteDeviceInStudio(DeviceDescriptor deviceDescriptor) {
if(deviceDescriptor == null)
return;
logger.debug("Device location removed for " + deviceDescriptor + ". Notification fired (" + locationListeners.size() + " listeners");
for (DeviceLocationListener listener : locationListeners) {
listener.deviceRemoved(deviceDescriptor);
}
}
public void deleteGatewayInStudio(String gatewayName) {
// for iterating safely over the keyset while deleting elements in the map
List<String> list = ModelEditor.getInstance().getDevicesId(gatewayName);
list.stream().forEach(d -> deleteDeviceInStudio(ModelEditor.getInstance().getDeviceDescriptor(gatewayName, d)));
}
public GPScoordinates getKnownLocation(DeviceDescriptor deviceDescriptor) {
DeviceDescriptor desc = ModelEditor.getInstance().getDeviceDescriptor(deviceDescriptor.getGateway(),deviceDescriptor.getDevice());
if(desc == null )
return null;
String location = desc.getLocation();
if(location == null)
return null;
String[] coordinates = location.split(":");
if(coordinates.length != 2)
return null;
try {
return new GPScoordinates(Double.parseDouble(coordinates[0]),Double.parseDouble(coordinates[1]));
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
}