/** * 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.personalisation.UserPreferenceManagement.impl.monitoring; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Future; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.societies.api.cis.management.ICisManager; import org.societies.api.comm.xmpp.interfaces.ICommManager; import org.societies.api.context.model.CtxAttribute; import org.societies.api.context.model.CtxAttributeIdentifier; import org.societies.api.context.model.CtxIdentifier; import org.societies.api.identity.IIdentity; import org.societies.api.internal.context.broker.ICtxBroker; import org.societies.api.internal.personalisation.model.IOutcome; import org.societies.api.internal.personalisation.model.PreferenceDetails; import org.societies.api.internal.servicelifecycle.IServiceDiscovery; import org.societies.api.internal.servicelifecycle.ServiceModelUtils; import org.societies.api.internal.useragent.feedback.IUserFeedback; import org.societies.api.internal.useragent.monitoring.UIMEvent; import org.societies.api.osgi.event.CSSEvent; import org.societies.api.osgi.event.CSSEventConstants; import org.societies.api.osgi.event.EventListener; import org.societies.api.osgi.event.EventTypes; import org.societies.api.osgi.event.IEventMgr; import org.societies.api.osgi.event.InternalEvent; import org.societies.api.personalisation.model.Action; import org.societies.api.personalisation.model.IAction; import org.societies.api.schema.servicelifecycle.model.ServiceResourceIdentifier; import org.societies.personalisation.UserPreferenceManagement.impl.UserPreferenceManagement; import org.societies.personalisation.UserPreferenceManagement.impl.cis.CisEventListener; import org.societies.personalisation.UserPreferenceManagement.impl.cis.CommunitiesHandler; import org.societies.personalisation.UserPreferenceManagement.impl.merging.MergingManager; import org.societies.personalisation.common.api.management.IInternalPersonalisationManager; import org.societies.personalisation.common.api.model.PersonalisationTypes; import org.societies.personalisation.preference.api.CommunityPreferenceManagement.ICommunityPreferenceManager; import org.societies.personalisation.preference.api.UserPreferenceConditionMonitor.IUserPreferenceConditionMonitor; import org.societies.personalisation.preference.api.UserPreferenceLearning.IC45Learning; import org.societies.personalisation.preference.api.model.IPreferenceConditionIOutcomeName; import org.societies.personalisation.preference.api.model.IPreferenceOutcome; import org.societies.personalisation.preference.api.model.PreferenceOutcome; import org.societies.personalisation.preference.api.model.PreferenceTreeNode; import org.springframework.scheduling.annotation.AsyncResult; /** * Describe your class here... * * @author Eliza * */ public class UserPreferenceConditionMonitor extends EventListener implements IUserPreferenceConditionMonitor{ private MonitoringTable mt; private Logger logging = LoggerFactory.getLogger(this.getClass()); private List<CtxAttributeIdentifier> registered; private ICtxBroker ctxBroker; private UserPreferenceManagement prefMgr; private IInternalPersonalisationManager persoMgr; private MergingManager merging; private IC45Learning userPrefLearning; private IEventMgr eventMgr; private ICommManager commManager; private IUserFeedback userFeedbackMgr; private ICommunityPreferenceManager communityPreferenceMgr; private CisEventListener cisEventListener; private IServiceDiscovery serviceDiscovery; private ICisManager cisManager; private CommunitiesHandler communitiesHandler; public UserPreferenceConditionMonitor(){ } public ICtxBroker getCtxBroker() { logging.debug(this.getClass().getName()+": Return ctxBroker"); return ctxBroker; } public void setCtxBroker(ICtxBroker ctxBroker) { logging.debug(this.getClass().getName()+": Got ctxBroker"); this.ctxBroker = ctxBroker; } public IInternalPersonalisationManager getPersoMgr() { logging.debug(this.getClass().getName()+": Return persoMgr"); return persoMgr; } public void setPersoMgr(IInternalPersonalisationManager persoMgr) { logging.debug(this.getClass().getName()+": Got persoMgr"); this.persoMgr = persoMgr; } /** * @return the userPrefLearning */ public IC45Learning getUserPrefLearning() { return userPrefLearning; } /** * @param userPrefLearning the userPrefLearning to set */ public void setUserPrefLearning(IC45Learning userPrefLearning) { this.userPrefLearning = userPrefLearning; } public IEventMgr getEventMgr() { return eventMgr; } public void setEventMgr(IEventMgr eventMgr) { this.eventMgr = eventMgr; } public void initialisePreferenceManagement(){ this.prefMgr = new UserPreferenceManagement(this.getCtxBroker()); mt = new MonitoringTable(); registered = new ArrayList<CtxAttributeIdentifier>(); merging = new MergingManager(getUserPrefLearning(), prefMgr, this); this.subscribeForStaticUIMEvents(); logging.debug(this.getClass().toString()+": INITIALISED"); this.cisEventListener = new CisEventListener(this); communitiesHandler = new CommunitiesHandler(this); communitiesHandler.scheduleTasks(); } private void subscribeForStaticUIMEvents() { String eventFilter = "(&" + "(" + CSSEventConstants.EVENT_NAME + "=staticaction)" + "(" + CSSEventConstants.EVENT_SOURCE + "=org/societies/useragent/monitoring)" + ")"; this.getEventMgr().subscribeInternalEvent(this, new String[]{EventTypes.UIM_STATIC_ACTION}, eventFilter); this.logging.debug("Subscribed to " + EventTypes.UIM_STATIC_ACTION + " events"); } /** * * @param ownerId * @param attribute * @param callback * @return */ @Override public Future<List<IPreferenceOutcome>> getOutcome(IIdentity ownerId, CtxAttribute attribute){ this.prefMgr.updateContext(attribute); /* * in this method, we need to check what preferences are affected, request re-evaluation of them, compare last ioutcome with new and send it to * the proactivity decision maker component */ logging.debug("Processing context event : "+attribute.getType()); List<PreferenceDetails> affectedPreferences = this.mt.getAffectedPreferences(attribute.getId()); if (affectedPreferences.size()==0){ //JOptionPane.showMessageDialog(null, "no affected preferences found for ctxID: "+ctxAttr.getCtxIdentifier().toUriString()+",\n ignoring event"); logging.debug("no affected preferences found for ctxID: "+attribute.getId().toString()+", ignoring event"); this.logging.debug("no affected preferences found for ctxID: "+attribute.getId().toString()+", ignoring event"); return new AsyncResult<List<IPreferenceOutcome>>(new ArrayList<IPreferenceOutcome>()); }else{ logging.debug("found affected preferences"); this.logging.debug("found affected preferences"); if (null == this.prefMgr){ this.logging.debug(UserPreferenceManagement.class.getName()+" not found"); return new AsyncResult<List<IPreferenceOutcome>>(new ArrayList<IPreferenceOutcome>()); }else{ this.logging.debug(UserPreferenceManagement.class.getName()+" Found"); } List<IPreferenceOutcome> outcomes = prefMgr.reEvaluatePreferences(ownerId,attribute, affectedPreferences); logging.debug("requested re-evaluation of preferences"); logging.debug("requested re-evaluation of preferences"); logging.debug("Returning outcome"); return new AsyncResult<List<IPreferenceOutcome>>(outcomes); } } /** * * @param ownerId * @param action * @param callback * @return */ @Override public Future<List<IPreferenceOutcome>> getOutcome(IIdentity ownerId, IAction action){ /* * an action describes a personalisable parameter that the user (manually) or the User Agent (proactively) changed. * An action does not describe a change in the state of the service. i.e. starting or stopping a service. Therefore, * PCM returns the value of the personalisable parameter that was last applied or is currently applicable. * * The PCM is notified of changes in the personalisable parameters of a service using context. the User Action Monitor * populates the context database with this information as soon as it receives an action from a service. */ if (!this.mt.isServiceRunning(action.getServiceType(), action.getServiceID())){ this.processServiceStarted(ownerId, action.getServiceType(), action.getServiceID()); } this.logging.debug("request for outcome with input: "+ownerId.getJid()+"\n"+action.toString()); this.merging.processActionReceived(ownerId, action); List<IPreferenceOutcome> outcomes = new ArrayList<IPreferenceOutcome>(); IPreferenceOutcome outcome = this.prefMgr.getPreference(ownerId, action.getServiceType(), action.getServiceID(), action.getparameterName()); if (outcome!=null){ outcomes.add(outcome); } return new AsyncResult<List<IPreferenceOutcome>>(outcomes); } public void processServiceStarted(IIdentity userId, String serviceType, ServiceResourceIdentifier serviceID){ //JOptionPaneshowMessageDialog(null, "Processing service started event: "+serviceID.toUriString()); this.logging.debug("Adding "+ServiceModelUtils.serviceResourceIdentifierToString(serviceID)+" preference details to tables"); List<IPreferenceConditionIOutcomeName> conditionIOutcomeName = this.prefMgr.getPreferenceConditions(userId, serviceType, serviceID); //JOptionPaneshowMessageDialog(null, this.myUSERDPI.toUriString()+" received "+conditionIOutcomeName.size()+" preferenceConditions from PrefMgr"); for (IPreferenceConditionIOutcomeName info : conditionIOutcomeName){ this.mt.addInfo(info.getICtxIdentifier(), serviceID, serviceType, info.getPreferenceName()); this.logging.debug("Added: "+info.getICtxIdentifier().toString()+" to"+serviceID.toString()+" affecting preference: "+info.getPreferenceName()); //JOptionPaneshowMessageDialog(null, this.myUSERDPI.toUriString()+"Added: "+info.getCtxIdentifier().toUriString()+" to"+serviceID.toUriString()+" affecting preference: "+info.getPreferenceName()); if (this.registered.contains(info.getICtxIdentifier())){ this.logging.debug("Already subscribed for: "+info.getICtxIdentifier().toUriString()); }else{ this.persoMgr.registerForContextUpdate(userId, PersonalisationTypes.UserPreference, info.getICtxIdentifier()); //this.registerForContextEvent((CtxAttributeIdentifier) info.getICtxIdentifier()); this.registered.add((CtxAttributeIdentifier) info.getICtxIdentifier()); this.logging.debug(userId.getJid()+" Registered for :"+info.getICtxIdentifier().toUriString()); } } } public void processServiceStopped(IIdentity userId, String serviceType, ServiceResourceIdentifier serviceID){ if (this.mt.isServiceRunning(serviceType, serviceID)){ mt.removeServiceInfo(serviceType, serviceID); }else{ logging.debug("The details of this service were not properly loaded. Nothing to do!"); } } public void processPreferenceChanged(IIdentity userID, ServiceResourceIdentifier serviceId, String serviceType, String preferenceName){ List<CtxIdentifier> ctxIDs = this.prefMgr.getPreferenceConditions(userID, serviceType, serviceId, preferenceName); for (CtxIdentifier id : ctxIDs){ this.mt.addInfo(id, serviceId, serviceType, preferenceName); if (this.registered.contains(id)){ this.logging.debug("Already subscribed for: "+id.toUriString()); }else{ //this.registerForContextEvent((CtxAttributeIdentifier) id); this.registered.add((CtxAttributeIdentifier) id); this.persoMgr.registerForContextUpdate(userID, PersonalisationTypes.UserPreference, (CtxAttributeIdentifier) id); } } /*IOutcome out = this.prefMgr.getPreference(this.getMyUSERDPI(), serviceType, serviceId, prefName); if (out==null){ this.logging.debug("Preference Manager returned no new outcomes for serviceType:"+serviceType+" and serviceID: "+serviceId); }else{ this.sendToDM(serviceType, serviceId, prefName, out); }*/ } @Override public Future<IOutcome> getOutcome(IIdentity ownerID, ServiceResourceIdentifier serviceID, String preferenceName) { return new AsyncResult<IOutcome> (this.prefMgr.getPreference(ownerID, "", serviceID, preferenceName)); } /** * @return the prefMgr */ @Override public UserPreferenceManagement getPreferenceManager() { return prefMgr; } @Override public void handleExternalEvent(CSSEvent arg0) { // TODO Auto-generated method stub } @Override public void handleInternalEvent(InternalEvent internalEvent) { UIMEvent uimEvent = (UIMEvent) internalEvent.geteventInfo(); Action action = (Action) uimEvent.getAction(); PreferenceDetails details = new PreferenceDetails(); PreferenceOutcome outcome = new PreferenceOutcome(action.getServiceID(), action.getServiceType(), action.getparameterName(), action.getvalue(), action.isImplementable(), action.isProactive(), action.isContextDependent()); details.setServiceID(action.getServiceID()); details.setServiceType(action.getServiceType()); outcome.setServiceType(action.getServiceType()); details.setPreferenceName(action.getparameterName()); outcome.setparameterName(action.getparameterName()); outcome.setvalue(action.getvalue()); PreferenceTreeNode preference = new PreferenceTreeNode(outcome); this.prefMgr.storePreference(uimEvent.getUserId(), details, preference); } public ICommManager getCommManager() { return commManager; } public void setCommManager(ICommManager commManager) { this.commManager = commManager; } public IUserFeedback getUserFeedbackMgr() { return userFeedbackMgr; } public void setUserFeedbackMgr(IUserFeedback userFeedbackMgr) { this.userFeedbackMgr = userFeedbackMgr; } public ICommunityPreferenceManager getCommunityPreferenceMgr() { return communityPreferenceMgr; } public void setCommunityPreferenceMgr(ICommunityPreferenceManager communityPreferenceMgr) { this.communityPreferenceMgr = communityPreferenceMgr; } public CisEventListener getCisEventListener() { return cisEventListener; } public void setCisEventListener(CisEventListener cisEventListener) { this.cisEventListener = cisEventListener; } public IServiceDiscovery getServiceDiscovery() { return serviceDiscovery; } public void setServiceDiscovery(IServiceDiscovery serviceDiscovery) { this.serviceDiscovery = serviceDiscovery; } public ICisManager getCisManager() { return cisManager; } public void setCisManager(ICisManager cisManager) { this.cisManager = cisManager; } public CommunitiesHandler getCommunitiesHandler() { // TODO Auto-generated method stub return this.communitiesHandler; } }