/** * Copyright (c) 2011, SOCIETIES Consortium (WATERFORD INSTITUTE OF TECHNOLOGY (TSSG), HERIOT-WATT UNIVERSITY (HWU), SOLUTA.NET * (SN), GERMAN AEROSPACE CENTRE (Deutsches Zentrum fuer Luft- und Raumfahrt e.V.) (DLR), Zavod za varnostne tehnologije * informacijske družbe in elektronsko poslovanje (SETCCE), INSTITUTE OF COMMUNICATION AND COMPUTER SYSTEMS (ICCS), LAKE * COMMUNICATIONS (LAKE), INTEL PERFORMANCE LEARNING SOLUTIONS LTD (INTEL), PORTUGAL TELECOM INOVAÇÃO, SA (PTIN), IBM Corp., * INSTITUT TELECOM (ITSUD), AMITEC DIACHYTI EFYIA PLIROFORIKI KAI EPIKINONIES ETERIA PERIORISMENIS EFTHINIS (AMITEC), TELECOM * ITALIA S.p.a.(TI), TRIALOG (TRIALOG), Stiftelsen SINTEF (SINTEF), NEC EUROPE LTD (NEC)) * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.societies.context.location.management.impl; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.societies.api.comm.xmpp.interfaces.ICommManager; import org.societies.api.context.CtxException; import org.societies.api.context.event.CtxChangeEvent; import org.societies.api.context.event.CtxChangeEventListener; import org.societies.api.context.model.CtxAttribute; import org.societies.api.context.model.CtxAttributeTypes; import org.societies.api.context.model.CtxAttributeValueType; import org.societies.api.context.model.CtxEntity; import org.societies.api.context.model.CtxEntityIdentifier; import org.societies.api.context.model.CtxIdentifier; import org.societies.api.context.model.CtxModelObject; import org.societies.api.context.model.CtxModelType; import org.societies.api.context.model.CtxOriginType; import org.societies.api.context.source.ICtxSourceMgr; import org.societies.api.context.source.CtxSourceNames; import org.societies.api.identity.INetworkNode; import org.societies.api.internal.context.broker.ICtxBroker; import org.societies.context.location.management.api.IUserLocation; /** * * ToDO * 1) The CSM API has to be changed to be able to update atrr on a specific CSS node * 2) Who creates the GPS attributes in the CSM ? * Describe your class here... * * @author Guy Feigenblat (guyf@il.ibm.com) * */ public class LocationManagementContextAccessor { /** The logging facility. */ private static final Logger log = LoggerFactory.getLogger(LocationManagementContextAccessor.class); private final static String CSM_PZ_SOURCE = CtxSourceNames.PZ; private final static String CSM_GPS_SOURCE = CtxSourceNames.GPS; private final static String LOCATION_TYPE_FUSED = "location_fused"; private ICtxSourceMgr contextSourceManagement; private ICtxBroker contextBroker; private ICommManager commManager; private final static Map<String,DeviceInternalObject> deviceMapping = new HashMap<String,DeviceInternalObject>(); public void init(ICtxSourceMgr contextSourceManagement, ICtxBroker contextBroker, ICommManager commManager){ if (contextSourceManagement == null || contextBroker == null || commManager == null){ throw new NullPointerException("contextSourceManagement or contextBroker or commManager is NULL" ); } this.contextSourceManagement = contextSourceManagement; this.contextBroker = contextBroker; this.commManager = commManager; } public void addDevice(INetworkNode cssNodeId,String macAddress){ try { CtxEntity ctxEntity = getCtxEntity(cssNodeId); Future<String> id = contextSourceManagement.register(cssNodeId,CSM_PZ_SOURCE, CtxAttributeTypes.LOCATION_COORDINATES); String csmLocationTypeGlobal_internalId = id.get(); id = contextSourceManagement.register(cssNodeId,CSM_PZ_SOURCE, CtxAttributeTypes.LOCATION_SYMBOLIC); String csmLocationTypeSymbolic_internalId = id.get(); id = contextSourceManagement.register(cssNodeId,CSM_PZ_SOURCE, CtxAttributeTypes.LOCATION_PUBLIC_TAGS); String csmLocationTypePublicTags_internalId = id.get(); id = contextSourceManagement.register(cssNodeId,CSM_PZ_SOURCE, CtxAttributeTypes.LOCATION_PERSONAL_TAGS); String csmLocationTypePersonalTag_internalId = id.get(); id = contextSourceManagement.register(cssNodeId,CSM_PZ_SOURCE, CtxAttributeTypes.LOCATION_ID); String csmLocationTypeZoneId_internalId = id.get(); id = contextSourceManagement.register(cssNodeId,CSM_PZ_SOURCE, CtxAttributeTypes.LOCATION_TYPE); String csmLocationTypeZoneType_internalId = id.get(); id = contextSourceManagement.register(cssNodeId,CSM_PZ_SOURCE, CtxAttributeTypes.LOCATION_PARENT_ID); String csmLocationTypeParent_internalId = id.get(); addToDeviceMapping(macAddress,cssNodeId, csmLocationTypeGlobal_internalId,csmLocationTypeSymbolic_internalId, csmLocationTypePublicTags_internalId,csmLocationTypePersonalTag_internalId, csmLocationTypeZoneId_internalId,csmLocationTypeZoneType_internalId, csmLocationTypeParent_internalId); createInferredLocationAttribute(ctxEntity); //currently only the Location coordinates can be changed by another source contextBroker.registerForChanges(new MyCtxChangeEventListener(),ctxEntity.getId(),CtxAttributeTypes.LOCATION_COORDINATES); } catch (InterruptedException e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } catch (ExecutionException e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } catch (CtxException e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } } public void removeDevice(String macAddress){ removeFromDeviceMapping(macAddress); } private void updatedFusedLocationAttr(CtxAttribute fusedAtrr,CtxAttribute gpsAttr,CtxAttribute pzAttr){ CtxAttribute attrToBeUpdated; try{ //gpsAttr = getAttribute(networkNode,CtxAttributeTypes.LOCATION_COORDINATES,CSM_GPS_SOURCE, CtxOriginType.SENSED); //pzAttr = getAttribute(networkNode,CtxAttributeTypes.LOCATION_COORDINATES, CSM_PZ_SOURCE, CtxOriginType.SENSED); attrToBeUpdated = pzAttr; if (gpsAttr != null && gpsAttr.getLastModified().after(pzAttr.getLastModified())){ attrToBeUpdated = gpsAttr; }else{ attrToBeUpdated = pzAttr; } fusedAtrr.setStringValue(attrToBeUpdated.getStringValue()); try { contextBroker.update(fusedAtrr); } catch (CtxException e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } }catch (Exception e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } } public void updateCSM(IUserLocation userLocation,INetworkNode networkNode,int contextUpdateInterval){ try{ float contextUpdateIntervalHz = 1/(float)contextUpdateInterval ; String locationString = LMDataEncoding.encodeCoordinates(userLocation); String symbolicLocationString = LMDataEncoding.encodeLocationSymbolic(userLocation); DeviceInternalObject deviceInternalObject = getNodeObject(networkNode); CtxEntity ctxEntity = getCtxEntity(deviceInternalObject.getCssNodeId()); String csmLocationTypeGlobal = deviceInternalObject.csmLocationTypeGlobal_internalId; String csmLocationTypeSymbolic = deviceInternalObject.csmLocationTypeSymbolic_internalId; contextSourceManagement.sendUpdate(csmLocationTypeGlobal,locationString, ctxEntity,false , 0, contextUpdateIntervalHz); contextSourceManagement.sendUpdate(csmLocationTypeSymbolic,symbolicLocationString, ctxEntity,false , 0, contextUpdateIntervalHz); String presonalTagValue = LMDataEncoding.encodePersonalTags(userLocation); String tagsValue = LMDataEncoding.encodePublicTags(userLocation); String zonesValue = LMDataEncoding.encodeZones(userLocation); String zoneTypeValue = LMDataEncoding.encodeZoneType(userLocation); String parentZoneValue = LMDataEncoding.encodeParentZones(userLocation); String csmLocationType_personalTag = deviceInternalObject.csmLocationTypePersonalTag_internalId; String csmLocationType_tags = deviceInternalObject.csmLocationTypePublicTags_internalId; String csmLocationType_zonesId = deviceInternalObject.csmLocationTypeZoneId_internalId; String csmLocationType_zoneType = deviceInternalObject.csmLocationTypeZoneType_internalId; String csmLocationType_parentId = deviceInternalObject.csmLocationTypeParent_internalId; contextSourceManagement.sendUpdate(csmLocationType_personalTag,presonalTagValue, ctxEntity,false , 0, contextUpdateIntervalHz); contextSourceManagement.sendUpdate(csmLocationType_tags,tagsValue, ctxEntity,false , 0, contextUpdateIntervalHz); contextSourceManagement.sendUpdate(csmLocationType_zonesId,zonesValue, ctxEntity,false , 0, contextUpdateIntervalHz); contextSourceManagement.sendUpdate(csmLocationType_zoneType,zoneTypeValue, ctxEntity,false , 0, contextUpdateIntervalHz); contextSourceManagement.sendUpdate(csmLocationType_parentId,parentZoneValue, ctxEntity,false , 0, contextUpdateIntervalHz); }catch (Exception e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } } private void createInferredLocationAttribute(CtxEntity ctxEntity){ try { /* CtxAttribute ctxAttribute=null; CtxIdentifier ctxIdentifier = ctxEntity.getId(); Future<CtxModelObject> futureCtxModelObject; futureCtxModelObject = contextBroker.retrieve(ctxIdentifier); ctxAttribute = (CtxAttribute)futureCtxModelObject.get(); CtxEntityIdentifier ctxEntityIdentifier = ctxAttribute.getScope(); */ Future<List<CtxIdentifier>> futureAttributeIds = contextBroker.lookup(ctxEntity.getId(), CtxModelType.ATTRIBUTE, LOCATION_TYPE_FUSED); List<CtxIdentifier> attributeIds = futureAttributeIds.get(); if (attributeIds.size() > 0){ log.debug("no need to create LOCATION_TYPE_FUSED attribute as it already exists"); return; } CtxAttribute deviceTempAttr = contextBroker.createAttribute(ctxEntity.getId(),LOCATION_TYPE_FUSED).get(); deviceTempAttr.setValueType(CtxAttributeValueType.STRING); deviceTempAttr.getQuality().setOriginType(CtxOriginType.INFERRED); deviceTempAttr.setStringValue(""); deviceTempAttr.setSourceId(""); contextBroker.update(deviceTempAttr); } catch (CtxException e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } catch (InterruptedException e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } catch (ExecutionException e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } } private class MyCtxChangeEventListener implements CtxChangeEventListener{ @Override public void onCreation(CtxChangeEvent arg0) { //updateFusedAtrr(arg0); } @Override public void onModification(CtxChangeEvent arg0) { //updateFusedAtrr(arg0); } @Override public void onRemoval(CtxChangeEvent arg0) { //updateFusedAtrr(arg0); } @Override public void onUpdate(CtxChangeEvent arg0) { updateFusedAtrr(arg0); } private void updateFusedAtrr(CtxChangeEvent arg0){ CtxAttribute ctxAttribute=null; CtxIdentifier ctxIdentifier = arg0.getId(); Future<CtxModelObject> futureCtxModelObject; try { futureCtxModelObject = contextBroker.retrieve(ctxIdentifier); ctxAttribute = (CtxAttribute)futureCtxModelObject.get(); CtxEntityIdentifier ctxEntityIdentifier = ctxAttribute.getScope(); Future<List<CtxIdentifier>> futureAttributeIds = contextBroker.lookup(ctxEntityIdentifier, CtxModelType.ATTRIBUTE, LOCATION_TYPE_FUSED); List<CtxIdentifier> attributeIds = futureAttributeIds.get(); if (attributeIds.size() > 1){ log.error("ERROR !!! more than one location type fused attribute"); }else if (attributeIds.size() == 0){ log.error("ERROR !!! LOCATION_TYPE_FUSED wasn't found"); return; } futureCtxModelObject = contextBroker.retrieve (attributeIds.get(0)); CtxAttribute locationTypeFusedAttribute = (CtxAttribute)futureCtxModelObject.get(); futureAttributeIds = contextBroker.lookup(ctxEntityIdentifier, CtxModelType.ATTRIBUTE, CtxAttributeTypes.LOCATION_COORDINATES); attributeIds = futureAttributeIds.get(); CtxAttribute gpsAttribute=null,pzAttribute=null,buffer; for (final CtxIdentifier attributeId : attributeIds){ futureCtxModelObject = contextBroker.retrieve (attributeId); buffer = (CtxAttribute)futureCtxModelObject.get(); if (ctxAttribute.getQuality().getOriginType() == CtxOriginType.SENSED){ if (ctxAttribute.getSourceId().startsWith(CSM_GPS_SOURCE)) { gpsAttribute = buffer; }else if (ctxAttribute.getSourceId().startsWith(CSM_PZ_SOURCE)) { pzAttribute = buffer; } } } updatedFusedLocationAttr(locationTypeFusedAttribute,gpsAttribute,pzAttribute); } catch (CtxException e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } catch (InterruptedException e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } catch (ExecutionException e) { log.error("Exception msg: "+e.getMessage()+" \t exception cause: "+e.getCause(),e); } } } /***** Helper methods *****/ private INetworkNode getNetworkNodeByDevice(String macAddress){ synchronized (deviceMapping) { return deviceMapping.get(macAddress).getCssNodeId(); } } private DeviceInternalObject getNodeObject(INetworkNode networkNodeId){ synchronized (deviceMapping) { for (Map.Entry<String, DeviceInternalObject> entry : deviceMapping.entrySet()){ if (entry.getValue().getCssNodeId().equals(networkNodeId)){ return entry.getValue(); } } } log.error("Couldn't find DeviceInternalObject for node - "+ networkNodeId); return null; } private void addToDeviceMapping(String macAddress, INetworkNode networkNodeId, String csmLocationTypeGlobal_internalId, String csmLocationTypeSymbolic_internalId, String csmLocationTypePublicTags_internalId, String csmLocationTypePersonalTag_internalId, String csmLocationTypeZoneId_internalId, String csmLocationTypeZoneType_internalId, String csmLocationTypeParent_internalId){ synchronized (deviceMapping) { DeviceInternalObject deviceObject = new DeviceInternalObject(); deviceObject.setCsmLocationTypeGlobal_internalId(csmLocationTypeGlobal_internalId); deviceObject.setCsmLocationTypeSymbolic_internalId(csmLocationTypeSymbolic_internalId); deviceObject.setCsmLocationTypePublicTags_internalId(csmLocationTypePublicTags_internalId); deviceObject.setCsmLocationTypePersonalTag_internalId(csmLocationTypePersonalTag_internalId); deviceObject.setCsmLocationTypeZoneId_internalId(csmLocationTypeZoneId_internalId); deviceObject.setCsmLocationTypeZoneType_internalId(csmLocationTypeZoneType_internalId); deviceObject.setCsmLocationTypeParent_internalId(csmLocationTypeParent_internalId); deviceObject.setCssNodeId(networkNodeId); deviceObject.setMacAddress(macAddress); deviceMapping.put(networkNodeId.getJid(),deviceObject); } } private void removeFromDeviceMapping(String macAddress){ synchronized (deviceMapping) { deviceMapping.remove(macAddress); } } public Collection<INetworkNode> getAllRegisteredEntites(){ List<INetworkNode> networkNodes = new ArrayList<INetworkNode>(); synchronized (deviceMapping) { for (Map.Entry<String, DeviceInternalObject> entries: deviceMapping.entrySet()){ networkNodes.add(entries.getValue().getCssNodeId()); } } return networkNodes; } /** * Describe your class here... * * @author guyf * */ private class DeviceInternalObject{ private INetworkNode cssNodeId; private String macAddress; private String csmLocationTypeGlobal_internalId; private String csmLocationTypeSymbolic_internalId; private String csmLocationTypePublicTags_internalId; private String csmLocationTypePersonalTag_internalId; private String csmLocationTypeZoneType_internalId; private String csmLocationTypeZoneId_internalId; private String csmLocationTypeParent_internalId; public void setCsmLocationTypeZoneType_internalId(String csmLocationTypeZoneType_internalId) { this.csmLocationTypeZoneType_internalId = csmLocationTypeZoneType_internalId; } public INetworkNode getCssNodeId() { return cssNodeId; } public void setCssNodeId(INetworkNode cssNodeId) { this.cssNodeId = cssNodeId; } public void setMacAddress(String macAddress) { this.macAddress = macAddress; } public void setCsmLocationTypeGlobal_internalId(String csmLocationTypeGlobal_internalId) { this.csmLocationTypeGlobal_internalId = csmLocationTypeGlobal_internalId; } public void setCsmLocationTypeSymbolic_internalId(String csmLocationTypeSymbolic_internalId) { this.csmLocationTypeSymbolic_internalId = csmLocationTypeSymbolic_internalId; } public void setCsmLocationTypePublicTags_internalId( String csmLocationTypePublicTags_internalId) { this.csmLocationTypePublicTags_internalId = csmLocationTypePublicTags_internalId; } public void setCsmLocationTypePersonalTag_internalId( String csmLocationTypePersonalTag_internalId) { this.csmLocationTypePersonalTag_internalId = csmLocationTypePersonalTag_internalId; } public void setCsmLocationTypeZoneId_internalId( String csmLocationTypeZoneId_internalId) { this.csmLocationTypeZoneId_internalId = csmLocationTypeZoneId_internalId; } public void setCsmLocationTypeParent_internalId(String csmLocationTypeParent_internalId) { this.csmLocationTypeParent_internalId = csmLocationTypeParent_internalId; } } private CtxEntity getCtxEntity(INetworkNode cssNodeId) throws CtxException, InterruptedException, ExecutionException{ Future<CtxEntity> futureCtxEntity = contextBroker.retrieveCssNode(cssNodeId); CtxEntity ctxEntity = futureCtxEntity.get(); return ctxEntity; } /* private Requestor getRequestor(){ IIdentity identity = getIIdentity(); return new Requestor(identity); } private IIdentity getIIdentity(){ IIdentityManager iIdentityManager; iIdentityManager = commManager.getIdManager(); return iIdentityManager.getThisNetworkNode(); } */ }