/*
* Copyright Ericsson AB 2011-2014. All Rights Reserved.
*
* The contents of this file are subject to the Lesser GNU Public License,
* (the "License"), either version 2.1 of the License, or
* (at your option) any later version.; you may not use this file except in
* compliance with the License. You should have received a copy of the
* License along with this software. If not, it can be
* retrieved online at https://www.gnu.org/licenses/lgpl.html. Moreover
* it could also be requested from Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
* WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
* EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
* OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
* LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE,
* YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
*
* IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
* WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
* REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
* DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
* DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
* (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
* INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE
* OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
* HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
*/
package com.ericsson.deviceaccess.spi.impl;
import com.ericsson.common.util.serialization.Format;
import com.ericsson.common.util.serialization.SerializationException;
import com.ericsson.common.util.serialization.SerializationUtil;
import com.ericsson.common.util.serialization.View;
import com.ericsson.deviceaccess.api.Constants;
import com.ericsson.deviceaccess.api.genericdevice.GDAccessPermission.Type;
import com.ericsson.deviceaccess.api.genericdevice.GDEventListener;
import com.ericsson.deviceaccess.api.genericdevice.GDException;
import com.ericsson.deviceaccess.api.genericdevice.GDService;
import com.ericsson.deviceaccess.spi.GenericDevice;
import static com.ericsson.deviceaccess.spi.genericdevice.GDAccessSecurity.checkPermission;
import static com.ericsson.deviceaccess.spi.genericdevice.GDActivator.getEventManager;
import com.ericsson.deviceaccess.spi.impl.genericdevice.GDServiceImpl;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.HashMap;
import java.util.Map;
public abstract class GenericDeviceImpl extends GenericDevice.Stub implements GenericDevice {
/**
* Static utility method which generates a Properties object from
* GenericDevice object. It is for making it easy to register the instance
* to OSGi framework as a service.
*
* @param dev device to generate properties from
* @return Properties object that can be used in registerService() method.
*/
public static Map<String, Object> getDeviceProperties(com.ericsson.deviceaccess.api.GenericDevice dev) {
checkPermission(GenericDevice.class, Type.GET);
Map<String, Object> props = new HashMap<>();
if (dev.getURN() != null) {
props.put(Constants.PARAM_DEVICE_URN, dev.getURN());
}
if (dev.getId() != null) {
props.put(Constants.PARAM_DEVICE_ID, dev.getId());
}
if (dev.getType() != null) {
props.put(Constants.PARAM_DEVICE_TYPE, dev.getType());
}
if (dev.getProtocol() != null) {
props.put(Constants.PARAM_DEVICE_PROTOCOL, dev.getProtocol());
}
return props;
}
private String id = "";
private String urn = "";
private String name = "";
private String type = "";
private String protocol = "";
private String location = "";
private boolean online;
private String icon = "";
private String path = "";
private String contact = "";
private String manufacturer = "";
private String modelName = "";
private String description = "";
private String serialNumber = "";
private String productClass = "";
private State state = State.READY;
private Map<String, GDService> service = new HashMap<>();
private transient boolean isReady = false;
/**
*
*/
protected GenericDeviceImpl() {
}
/**
* Returns a service instance if the device has a service with the specified
* name or null, otherwise.
*
* @param name The name of service that is in question.
* @return device instance or null
*/
@Override
public GDService getService(String name) {
checkPermission(GenericDevice.class, Type.GET);
return service.get(name);
}
public GDServiceImpl getServiceImpl(String svcName) {
checkPermission(GenericDevice.class, Type.GET);
return (GDServiceImpl) service.get(name);
}
/**
* Returns a Map of all the services that the device instance has.
*
* @return Map of service instances with their names as key.
*/
@Override
public Map<String, GDService> getServices() {
checkPermission(GenericDevice.class, Type.GET);
return new HashMap<>(service);
}
/**
* Puts an instance of a service. If an instance which has the same name is
* already registered, the instance is updated.
*
* @param svc A service instance which is being put.
*/
@Override
public void putService(GDService svc) {
checkPermission(GenericDevice.class, Type.SET);
service.put(svc.getName(), svc);
svc.updatePath(getPath(true));
((com.ericsson.deviceaccess.spi.genericdevice.GDService) svc).setParentDevice(this);
isReady = true;
}
@Override
public void setId(String id) {
checkPermission(GenericDevice.class, Type.SET);
this.id = id;
}
@Override
public String getId() {
checkPermission(GenericDevice.class, Type.GET);
return id;
}
@Override
public String getURN() {
checkPermission(GenericDevice.class, Type.SET);
return urn;
}
@Override
public void setURN(String urn) {
checkPermission(GenericDevice.class, Type.SET);
if (urn == null) {
throw new IllegalArgumentException("URN may not be null");
}
String oldUrn = this.urn;
this.urn = urn;
if (isReady && !urn.equals(oldUrn)) {
notifyEvent("DeviceProperties", new HashMap() {
{
put(GDEventListener.DEVICE_URN, GenericDeviceImpl.this.urn);
}
});
}
}
@Override
public void setName(String name) {
checkPermission(GenericDevice.class, Type.SET);
if (name == null) {
throw new IllegalArgumentException("Name may not be null");
}
String oldName = this.name;
this.name = name;
if (isReady && !name.equals(oldName)) {
notifyEvent("DeviceProperties", new HashMap() {
{
put(GDEventListener.DEVICE_NAME, GenericDeviceImpl.this.name);
}
});
}
}
@Override
public String getName() {
checkPermission(GenericDevice.class, Type.GET);
return name;
}
@Override
public void setType(String type) {
checkPermission(GenericDevice.class, Type.SET);
this.type = type;
}
@Override
public String getType() {
checkPermission(GenericDevice.class, Type.GET);
return type;
}
@Override
public void setProtocol(String protocol) {
checkPermission(GenericDevice.class, Type.SET);
this.protocol = protocol;
}
@Override
public String getProtocol() {
checkPermission(GenericDevice.class, Type.GET);
return protocol;
}
@Override
public void setLocation(String location) {
checkPermission(GenericDevice.class, Type.SET);
this.location = location;
}
@Override
public String getLocation() {
checkPermission(GenericDevice.class, Type.GET);
return location;
}
@Override
public void setOnline(boolean online) {
checkPermission(GenericDevice.class, Type.SET);
boolean oldOnline = this.online;
this.online = online;
if (isReady && online != oldOnline) {
notifyEvent("DeviceProperties", new HashMap() {
{
put(GDEventListener.DEVICE_ONLINE, GenericDeviceImpl.this.online);
}
});
}
}
@Override
public boolean isOnline() {
checkPermission(GenericDevice.class, Type.GET);
return online;
}
@Override
public void setIcon(String icon) {
checkPermission(GenericDevice.class, Type.SET);
this.icon = icon;
}
@Override
public String getIcon() {
checkPermission(GenericDevice.class, Type.GET);
return icon;
}
@Override
public State getState() {
checkPermission(GenericDevice.class, Type.GET);
return state;
}
public void setState(State state) {
checkPermission(GenericDevice.class, Type.SET);
State oldState = this.state;
this.state = state;
if (isReady && (state == null && oldState != null || state != null && !state.equals(oldState))) {
notifyEvent("DeviceProperties", new HashMap() {
{
put(GDEventListener.DEVICE_STATE, GenericDeviceImpl.this.state);
}
});
}
}
@Override
public String getPath(boolean isAbsolute) {
checkPermission(GenericDevice.class, Type.GET);
return path + "/" + this.getId();
}
@Override
public String getPath() {
checkPermission(GenericDevice.class, Type.GET);
return path + "/" + this.getId();
}
@Override
public void updatePath(String path) {
checkPermission(GenericDevice.class, Type.SET);
this.path = path;
service.forEach((k, svc) -> svc.updatePath(getPath(true)));
}
@Override
public void setContact(String contact) {
checkPermission(GenericDevice.class, Type.SET);
this.contact = contact;
}
@Override
public String getContact() {
checkPermission(GenericDevice.class, Type.GET);
return contact;
}
/**
* Sets the list of services in the device instance. Returns a HashMap of
* all the services that the device has.
*
* @param service map of service instances with their names as key.
*/
public void setService(Map service) {
checkPermission(GenericDevice.class, Type.SET);
if (service == null) {
throw new NullPointerException("Map cannot be null");
}
this.service = service;
}
@Override
public void setManufacturer(String manufacturer) {
checkPermission(GenericDevice.class, Type.SET);
this.manufacturer = manufacturer;
}
@Override
public String getManufacturer() {
checkPermission(GenericDevice.class, Type.GET);
return manufacturer;
}
@Override
public void setModelName(String modelName) {
checkPermission(GenericDevice.class, Type.SET);
this.modelName = modelName;
}
@Override
public String getModelName() {
checkPermission(GenericDevice.class, Type.GET);
return modelName;
}
@Override
public void setDescription(String description) {
checkPermission(GenericDevice.class, Type.SET);
this.description = description;
}
@Override
public String getDescription() {
checkPermission(GenericDevice.class, Type.GET);
return description;
}
@Override
public void setSerialNumber(String serialNumber) {
checkPermission(GenericDevice.class, Type.SET);
this.serialNumber = serialNumber;
}
@Override
public String getSerialNumber() {
checkPermission(GenericDevice.class, Type.GET);
return serialNumber;
}
@Override
public void setProductClass(String productClass) {
checkPermission(GenericDevice.class, Type.SET);
this.productClass = productClass;
}
@Override
public String getProductClass() {
checkPermission(GenericDevice.class, Type.GET);
return productClass;
}
@Override
public String serialize(Format format) throws GDException {
checkPermission(GenericDevice.class, Type.GET);
try {
return SerializationUtil.execute(format, mapper -> mapper.writerWithView(View.ID.Ignore.class).writeValueAsString(this));
} catch (SerializationException ex) {
throw new GDException(ex.getMessage(), ex);
}
}
@Override
public String serializeState() throws GDException {
try {
return SerializationUtil.execute(Format.JSON, mapper -> mapper.writerWithView(View.StatelessID.Ignore.class).writeValueAsString(this));
} catch (SerializationException ex) {
throw new GDException(ex.getMessage(), ex);
}
}
@Override
public String getSerializedNode(String path, Format format) throws GDException {
checkPermission(GenericDevice.class, Type.GET);
try {
return SerializationUtil.serializeAccordingPath(format, path, Constants.PATH_DELIMITER, this);
} catch (SerializationException ex) {
throw new GDException(404, ex.getMessage(), ex);
}
}
/**
* A utility method to get device property dictionary which contains
* parameters such as device.id, device.type and so on. The dictionary
* object is meant to be used as OSGi service properties.
*
* @return
*/
@JsonIgnore
public Map<String, Object> getDeviceProperties() {
return getDeviceProperties(this);
}
public void notifyEvent(String serviceId, final Map<String, Object> parameters) {
getEventManager().addPropertyEvent(id, serviceId, parameters);
}
public void notifyEventRemoved(String serviceId, String propertyId) {
getEventManager().addStateEvent(id, serviceId, propertyId, GDEventListener.Type.REMOVED);
}
public void notifyEventAdded(String serviceId, String propertyId) {
getEventManager().addStateEvent(id, serviceId, propertyId, GDEventListener.Type.ADDED);
}
}