/** * 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.management.impl; 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.*; import org.societies.api.identity.IIdentity; import org.societies.api.identity.IIdentityManager; import org.societies.api.identity.InvalidFormatException; import org.societies.api.identity.Requestor; import org.societies.api.internal.context.broker.ICtxBroker; import org.societies.api.internal.personalisation.model.IFeedbackEvent; import org.societies.api.internal.personalisation.model.IOutcome; import org.societies.api.internal.useragent.decisionmaking.IDecisionMaker; import org.societies.api.internal.useragent.monitoring.UIMEvent; import org.societies.api.osgi.event.*; import org.societies.api.personalisation.mgmt.IPersonalisationManager; import org.societies.api.personalisation.model.Action; import org.societies.api.personalisation.model.IAction; import org.societies.api.personalisation.model.IActionConsumer; import org.societies.api.personalisation.model.PersonalisablePreferenceIdentifier; import org.societies.api.schema.servicelifecycle.model.ServiceResourceIdentifier; import org.societies.personalisation.CAUI.api.CAUIPrediction.ICAUIPrediction; import org.societies.personalisation.CAUI.api.model.IUserIntentAction; import org.societies.personalisation.CRIST.api.CRISTUserIntentPrediction.ICRISTUserIntentPrediction; import org.societies.personalisation.CRIST.api.model.CRISTUserAction; import org.societies.personalisation.DIANNE.api.DianneNetwork.IDIANNE; import org.societies.personalisation.DIANNE.api.model.IDIANNEOutcome; import org.societies.personalisation.common.api.management.IInternalPersonalisationManager; import org.societies.personalisation.common.api.model.PersonalisationTypes; import org.societies.personalisation.preference.api.UserPreferenceConditionMonitor.IUserPreferenceConditionMonitor; import org.societies.personalisation.preference.api.model.IPreferenceOutcome; import org.springframework.scheduling.annotation.AsyncResult; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; public class PersonalisationManager extends EventListener implements IPersonalisationManager, IInternalPersonalisationManager, CtxChangeEventListener { // services private ICtxBroker ctxBroker; private Logger logging = LoggerFactory.getLogger(this.getClass()); private IUserPreferenceConditionMonitor pcm; private IDIANNE dianne; private ICAUIPrediction cauiPrediction; private ICRISTUserIntentPrediction cristPrediction; private IIdentityManager idm; private IDecisionMaker decisionMaker; private ICommManager commsMgr; private IEventMgr eventMgr; // data structures ArrayList<CtxAttributeIdentifier> dianneList; ArrayList<CtxAttributeIdentifier> prefMgrList; ArrayList<CtxAttributeIdentifier> cauiList; ArrayList<CtxAttributeIdentifier> cristList; //internal confidence levels for each personalisation source private int dianneConfidenceLevel; private int prefMgrConfidenceLevel; private int cauiConfidenceLevel; private int cristConfidenceLevel; public PersonalisationManager() { this.dianneList = new ArrayList<CtxAttributeIdentifier>(); this.prefMgrList = new ArrayList<CtxAttributeIdentifier>(); this.cauiList = new ArrayList<CtxAttributeIdentifier>(); this.cristList = new ArrayList<CtxAttributeIdentifier>(); this.logging.debug("executed constructor"); } public void initialisePersonalisationManager(ICtxBroker broker, IUserPreferenceConditionMonitor pcm, IDIANNE dianne, ICAUIPrediction cauiPrediction, ICRISTUserIntentPrediction cristPrediction, ICommManager commsMgr, IDecisionMaker decisionMaker) { this.ctxBroker = broker; this.pcm = pcm; this.dianne = dianne; this.cauiPrediction = cauiPrediction; this.cristPrediction = cristPrediction; this.setCommsMgr(commsMgr); this.decisionMaker = decisionMaker; this.idm = this.getCommsMgr().getIdManager(); retrieveConfidenceLevels(); this.registerForUIMEvents(); this.dianne.registerContext(); this.logging.debug("initialisePersonalisationManager(ICtxBroker broker, IUserPreferenceConditionMonitor pcm, IDIANNE dianne, ICAUIPrediction cauiPrediction, ICRISTUserIntentPrediction cristPrediction, ICommManager commsMgr, IDecisionMaker decisionMaker)"); } public void initialisePersonalisationManager() { this.dianneList = new ArrayList<CtxAttributeIdentifier>(); this.prefMgrList = new ArrayList<CtxAttributeIdentifier>(); this.cauiList = new ArrayList<CtxAttributeIdentifier>(); this.cristList = new ArrayList<CtxAttributeIdentifier>(); this.registerForUIMEvents(); retrieveConfidenceLevels(); this.dianne.registerContext(); this.logging.debug("initialisePersonalisationManager()"); } private void registerForUIMEvents() { String eventFilter = "(&" + "(" + CSSEventConstants.EVENT_NAME + "=newaction)" + "(" + CSSEventConstants.EVENT_SOURCE + "=org/societies/useragent/monitoring)" + ")"; this.getEventMgr().subscribeInternalEvent(this, new String[]{EventTypes.UIM_EVENT}, eventFilter); this.logging.debug("Subscribed to " + EventTypes.UIM_EVENT + " events"); } private void retrieveConfidenceLevels() { try { Future<List<CtxIdentifier>> futuredianneConf = this.ctxBroker.lookup(CtxModelType.ATTRIBUTE, "dianneConfidenceLevel"); List<CtxIdentifier> dianneConfs = futuredianneConf.get(); if (dianneConfs.isEmpty()) { this.dianneConfidenceLevel = 50; } else { CtxAttribute tempAttr = (CtxAttribute) this.ctxBroker.retrieve(dianneConfs.get(0)).get(); this.dianneConfidenceLevel = tempAttr.getIntegerValue(); } Future<List<CtxIdentifier>> futureprefMgrConf = this.ctxBroker.lookup(CtxModelType.ATTRIBUTE, "prefMgrConfidenceLevel"); List<CtxIdentifier> prefMgrConf = futureprefMgrConf.get(); if (prefMgrConf.isEmpty()) { this.prefMgrConfidenceLevel = 50; } else { CtxAttribute tempAttr = (CtxAttribute) this.ctxBroker.retrieve(prefMgrConf.get(0)).get(); this.prefMgrConfidenceLevel = tempAttr.getIntegerValue(); } Future<List<CtxIdentifier>> futurecauiConf = this.ctxBroker.lookup(CtxModelType.ATTRIBUTE, "cauiConfidenceLevel"); List<CtxIdentifier> cauiConf = futurecauiConf.get(); if (cauiConf.isEmpty()) { this.cauiConfidenceLevel = 50; } else { CtxAttribute tempAttr = (CtxAttribute) this.ctxBroker.retrieve(cauiConf.get(0)).get(); this.cauiConfidenceLevel = tempAttr.getIntegerValue(); } Future<List<CtxIdentifier>> futurecristConf = this.ctxBroker.lookup(CtxModelType.ATTRIBUTE, "cristConfidenceLevel"); List<CtxIdentifier> cristConf = futurecauiConf.get(); if (cristConf.isEmpty()) { this.cristConfidenceLevel = 50; } else { CtxAttribute tempAttr = (CtxAttribute) this.ctxBroker.retrieve(cristConf.get(0)).get(); this.cristConfidenceLevel = tempAttr.getIntegerValue(); } logging.debug("retrieved confidence levels"); } catch (CtxException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public ICAUIPrediction getCauiPrediction() { return cauiPrediction; } public void setCauiPrediction(ICAUIPrediction cauiPrediction) { this.cauiPrediction = cauiPrediction; } public ICRISTUserIntentPrediction getCristPrediction() { return cristPrediction; } public void setCristPrediction(ICRISTUserIntentPrediction cristPrediction) { this.cristPrediction = cristPrediction; } public IUserPreferenceConditionMonitor getPcm() { System.out.println(this.getClass().getName() + "Return PCM"); return pcm; } public void setPcm(IUserPreferenceConditionMonitor pcm) { System.out.println(this.getClass().getName() + "GOT PCM"); this.pcm = pcm; } public IDIANNE getDianne() { System.out.println(this.getClass().getName() + "Return DIANNE"); return dianne; } public void setDianne(IDIANNE dianne) { System.out.println(this.getClass().getName() + "GOT DIANNE"); this.dianne = dianne; } public ICtxBroker getCtxBroker() { System.out.println(this.getClass().getName() + "Return CtxBroker"); return this.ctxBroker; } public void setCtxBroker(ICtxBroker broker) { System.out.println(this.getClass().getName() + "GOT CtxBroker"); this.ctxBroker = broker; } public IDecisionMaker getDecisionMaker() { return decisionMaker; } public void setDecisionMaker(IDecisionMaker decisionMaker) { this.decisionMaker = decisionMaker; } /** * @return the commsMgr */ public ICommManager getCommsMgr() { return commsMgr; } /** * @param commsMgr the commsMgr to set */ public void setCommsMgr(ICommManager commsMgr) { this.commsMgr = commsMgr; this.idm = commsMgr.getIdManager(); } /** * @return the eventMgr */ public IEventMgr getEventMgr() { return eventMgr; } /** * @param eventMgr the eventMgr to set */ public void setEventMgr(IEventMgr eventMgr) { this.eventMgr = eventMgr; } /* * (non-Javadoc) * * @see org.societies.personalisation.common.api.management. * IInternalPersonalisationManager * #returnFeedback(org.societies.api.internal. * personalisation.model.IFeedbackEvent) */ @Override public void returnFeedback(IFeedbackEvent arg0) { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see org.societies.personalisation.common.api.management. * IInternalPersonalisationManager * #registerForContextUpdate(org.societies.api * .comm.xmpp.datatypes.IIdentity, * org.societies.personalisation.common.api.model.PersonalisationTypes, * org.societies.api.context.model.CtxAttributeIdentifier) */ @Override public void registerForContextUpdate(IIdentity id, PersonalisationTypes type, CtxAttributeIdentifier ctxAttributeId) { try { if (isAlreadyRegistered(ctxAttributeId)) { this.logging.debug(type.toString() + " requested event registration for: " + ctxAttributeId.getType() + " but I'm already registered for it."); } else { this.ctxBroker.registerForChanges(this, ctxAttributeId); this.logging.debug(type.toString() + " requested event registration for: " + ctxAttributeId.getType()); } } catch (CtxException e) { logging.error(e.getMessage()); e.printStackTrace(); } switch (type) { case UserPreference: this.addtoList(ctxAttributeId, prefMgrList); case DIANNE: this.addtoList(ctxAttributeId, dianneList); break; case CAUIIntent: this.addtoList(ctxAttributeId, cauiList); break; case CRISTIntent: this.addtoList(ctxAttributeId, cristList); break; default: return; } } private boolean isAlreadyRegistered(CtxAttributeIdentifier id) { for (CtxAttributeIdentifier ctxAttrId : this.prefMgrList) { if (ctxAttrId.equals(id)) { return true; } } for (CtxAttributeIdentifier ctxAttrId : this.dianneList) { if (ctxAttrId.equals(id)) { return true; } } for (CtxAttributeIdentifier ctxAttrId : this.cauiList) { if (ctxAttrId.equals(id)) { return true; } } for (CtxAttributeIdentifier ctxAttrId : this.cristList) { if (ctxAttrId.equals(id)) { return true; } } return false; } private void addtoList(CtxAttributeIdentifier ctxId, List<CtxAttributeIdentifier> list) { for (CtxAttributeIdentifier Id : list) { if (ctxId.equals(Id)) { return; } } list.add(ctxId); } /* * (non-Javadoc) * * @see org.societies.personalisation.common.api.management. * IInternalPersonalisationManager * #getPreference(org.societies.api.comm.xmpp.datatypes.IIdentity, * java.lang.String, * org.societies.api.servicelifecycle.model.ServiceResourceIdentifier, * java.lang.String, * org.societies.api.personalisation.mgmt.IPersonalisationCallback) */ @Override public Future<IAction> getPreference(IIdentity ownerID, String serviceType, ServiceResourceIdentifier serviceID, String preferenceName) { this.logging.debug("Processing request for preference: " + preferenceName + " for serviceType: " + serviceType + " and serviceID " + serviceID.getServiceInstanceIdentifier()); Future<List<IDIANNEOutcome>> futureDianneOuts; futureDianneOuts = this.dianne.getOutcome(ownerID, serviceID, preferenceName); if (futureDianneOuts == null) { futureDianneOuts = new AsyncResult<List<IDIANNEOutcome>>(new ArrayList<IDIANNEOutcome>()); this.logging.debug(".getPreference(...): DIANNE returned null list"); } Future<IOutcome> futurePrefOuts; futurePrefOuts = this.pcm.getOutcome(ownerID, serviceID, preferenceName); if (futurePrefOuts == null) { futurePrefOuts = new AsyncResult<IOutcome>(null); this.logging.debug(".getPreference(...): PCM returned null list"); } IAction action; try { List<IDIANNEOutcome> dianneOutList = futureDianneOuts.get(); if (dianneOutList.size() > 0) { IDIANNEOutcome dianneOut = dianneOutList.get(0); this.logging.debug(".getPreference(...): DIANNE returned an outcome: " + dianneOut.toString()); IPreferenceOutcome prefOut = (IPreferenceOutcome) futurePrefOuts.get(); if (null == prefOut) { this.logging.debug(".getPreference(...): PCM didn't return an outcome. Returning DIANNE's outcome: " + dianneOut.toString()); return new AsyncResult<IAction>(dianneOut); } this.logging.debug(".getPreference(...): PCM returned an outcome " + prefOut.toString()); if (dianneOut.getvalue().equalsIgnoreCase(prefOut.getvalue())) { action = new Action(serviceID, serviceType, preferenceName, prefOut.getvalue()); action.setServiceID(serviceID); action.setServiceType(serviceType); this.logging.debug(".getPreference(...): returning action: " + action.toString()); return new AsyncResult<IAction>(action); } else { this.logging.debug(".getPreference(...): conflict between pcm and dianne."); return new AsyncResult<IAction>(this.resolvePreferenceConflicts(dianneOut, prefOut)); } } else { IPreferenceOutcome prefOut = (IPreferenceOutcome) futurePrefOuts.get(); if (prefOut != null) { this.logging.debug(".getPreference(...): DIANNE didn't return an outcome. Returning PCM's outcome: " + prefOut.toString()); return new AsyncResult<IAction>(prefOut); } } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.logging.debug(".getPreference(...): Returning null action"); return new AsyncResult<IAction>(null); } /* * (non-Javadoc) * * @see org.societies.api.personalisation.mgmt.IPersonalisationManager# * getIntentAction(org.societies.api.comm.xmpp.datatypes.IIdentity, * org.societies.api.comm.xmpp.datatypes.IIdentity, * org.societies.api.servicelifecycle.model.ServiceResourceIdentifier, * java.lang.String, * org.societies.api.personalisation.mgmt.IPersonalisationCallback) */ @Override public Future<IAction> getIntentAction(Requestor requestor, IIdentity ownerID, ServiceResourceIdentifier serviceID, String preferenceName) { return this.getIntentAction(ownerID, serviceID, preferenceName); } /* * (non-Javadoc) * @see org.societies.api.personalisation.mgmt.IPersonalisationManager#getPreference(org.societies.api.identity.Requestor, org.societies.api.identity.IIdentity, java.lang.String, org.societies.api.schema.servicelifecycle.model.ServiceResourceIdentifier, java.lang.String) */ @Override public Future<IAction> getPreference(Requestor requestor, IIdentity ownerID, String serviceType, ServiceResourceIdentifier serviceID, String preferenceName) { //check with access control return this.getPreference(ownerID, serviceType, serviceID, preferenceName); } @Override public void registerPersonalisableService(IActionConsumer actionConsumer) { if (actionConsumer == null) throw new IllegalArgumentException("actionConsumer cannot be null"); List<PersonalisablePreferenceIdentifier> preferenceIdentifiers = actionConsumer.getPersonalisablePreferences(); if (preferenceIdentifiers == null) { throw new IllegalArgumentException("actionConsumer.getPersonalisablePreferences() must return a list of personalisable preferences"); } for (PersonalisablePreferenceIdentifier pref : preferenceIdentifiers) { this.pcm.getPreferenceManager().registerPersonalisableService(actionConsumer, pref); } } /* * (non-Javadoc) * @see org.societies.personalisation.common.api.management.IInternalPersonalisationManager#getIntentAction(org.societies.api.identity.IIdentity, org.societies.api.schema.servicelifecycle.model.ServiceResourceIdentifier, java.lang.String) */ @Override public Future<IAction> getIntentAction(IIdentity ownerID, ServiceResourceIdentifier serviceID, String preferenceName) { Future<IUserIntentAction> futureCAUIOuts; try { futureCAUIOuts = this.cauiPrediction.getCurrentIntentAction(ownerID, serviceID, preferenceName); } catch (Exception e) { e.printStackTrace(); futureCAUIOuts = new AsyncResult<IUserIntentAction>(null); } Future<CRISTUserAction> futureCRISTOuts; try { futureCRISTOuts = this.cristPrediction.getCurrentUserIntentAction(ownerID, serviceID, preferenceName); } catch (Exception e) { e.printStackTrace(); futureCRISTOuts = new AsyncResult<CRISTUserAction>(null); } IAction action; try { IUserIntentAction cauiOut = futureCAUIOuts.get(); CRISTUserAction cristOut = futureCRISTOuts.get(); if (cauiOut == null) { if (cristOut == null) { return new AsyncResult<IAction>(null); } else { return new AsyncResult<IAction>(cristOut); } } else { if (cristOut == null) { return new AsyncResult<IAction>(cauiOut); } } if (cauiOut.getvalue().equalsIgnoreCase(cristOut.getvalue())) { action = new Action(serviceID, "", preferenceName, cauiOut.getvalue()); return new AsyncResult<IAction>(action); } else { return new AsyncResult<IAction>(this.resolveIntentConflicts(cristOut, cauiOut)); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } return new AsyncResult<IAction>(null); } private boolean containsCtxId(CtxAttributeIdentifier ctxId, List<CtxAttributeIdentifier> list) { for (CtxAttributeIdentifier id : list) { if (ctxId.equals(id)) { return true; } } return false; } @Override public void onCreation(CtxChangeEvent arg0) { // TODO Auto-generated method stub } @Override public void onModification(final CtxChangeEvent event) { this.logging.debug("Received context event: " + event.getId().getType()); new Thread() { public void run() { CtxIdentifier ctxIdentifier = event.getId(); try { Thread.sleep(10); Future<CtxModelObject> futureAttribute = ctxBroker.retrieve(ctxIdentifier); CtxAttribute ctxAttribute = (CtxAttribute) futureAttribute.get(); if (null != ctxAttribute) { if (ctxAttribute instanceof CtxAttribute) { logging.debug("Received event and retrieved value " + ctxAttribute.getStringValue() + " for context attribute: " + ctxAttribute.getType()); CtxAttributeIdentifier ctxId = (CtxAttributeIdentifier) ctxAttribute.getId(); IIdentity userId = idm.fromJid(ctxId.getOperatorId()); List<IOutcome> preferenceOutcomes = processPreferences(userId, ctxAttribute); List<IOutcome> intentOutcomes = processIntent(userId, ctxAttribute); if (preferenceOutcomes.size() == 0 && intentOutcomes.size() == 0) { logging.debug("Nothing to send to decisionMaker"); return; } else { for (int i = 0; i < preferenceOutcomes.size(); i++) { logging.debug("Pref Outcome " + i + " :" + preferenceOutcomes.get(i)); } for (int i = 0; i < intentOutcomes.size(); i++) { logging.debug("Intent Outcome " + i + " :" + intentOutcomes.get(i)); } } logging.debug("Sending " + preferenceOutcomes.size() + " preference outcomes and " + intentOutcomes.size() + " intent outcomes to decisionMaker"); decisionMaker.makeDecision(intentOutcomes, preferenceOutcomes); } else { logging.debug("retrieved attribute but was not instanceof CtxAttribute"); } } else { logging.debug("Tried to retrieve ctxAttribute from ctxDB onModification() but the attribute is null"); } } catch (CtxException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }.start(); } private List<IOutcome> processIntent(IIdentity userId, CtxAttribute ctxAttribute) { this.logging.debug("Processing intent"); List<IOutcome> results = new ArrayList<IOutcome>(); CtxAttributeIdentifier ctxId = ctxAttribute.getId(); try { if (this.containsCtxId(ctxId, cauiList)) { this.logging.debug("caui is registered for events of: " + ctxId.toUriString()); Future<List<IUserIntentAction>> futureCauiActions = this.cauiPrediction.getPrediction(userId, ctxAttribute); if (this.containsCtxId(ctxId, cristList)) { this.logging.debug("crist is registered for events of: " + ctxId.toUriString()); Future<List<CRISTUserAction>> futureCristActions = this.cristPrediction.getCRISTPrediction(userId, ctxAttribute); return this.compareIntentConflicts(futureCauiActions.get(), futureCristActions.get()); } else { this.logging.debug("crist is NOT registered for events of: " + ctxId.toUriString()); List<IUserIntentAction> cauiActions = futureCauiActions.get(); for (IUserIntentAction cauiAction : cauiActions) { CRISTUserAction cristAction = this.cristPrediction.getCurrentUserIntentAction(userId, cauiAction.getServiceID(), cauiAction.getparameterName()).get(); if (null == cristAction) { results.add(cauiAction); } else { if (cristAction.getvalue().equalsIgnoreCase(cauiAction.getvalue())) { results.add(cauiAction); } else { results.add(this.resolveIntentConflicts(cristAction, cauiAction)); } } } } } else if (this.containsCtxId(ctxId, cristList)) { this.logging.debug("crist is registered for events of: " + ctxId.toUriString()); Future<List<CRISTUserAction>> futureCristActions = this.cristPrediction.getCRISTPrediction(userId, ctxAttribute); if (this.containsCtxId(ctxId, cauiList)) { this.logging.debug("caui is registered for events of: " + ctxId.toUriString()); Future<List<IUserIntentAction>> futureCauiActions = this.cauiPrediction.getPrediction(userId, ctxAttribute); return this.compareIntentConflicts(futureCauiActions.get(), futureCristActions.get()); } else { this.logging.debug("caui is NOT registered for events of: " + ctxId.toUriString()); List<CRISTUserAction> cristActions = futureCristActions.get(); for (CRISTUserAction cristAction : cristActions) { IUserIntentAction cauiAction = this.cauiPrediction.getCurrentIntentAction(userId, cristAction.getServiceID(), cristAction.getparameterName()).get(); if (null == cauiAction) { results.add(cristAction); } else { if (cauiAction.getvalue().equalsIgnoreCase(cristAction.getvalue())) { results.add(cristAction); } else { results.add(this.resolveIntentConflicts(cristAction, cauiAction)); } } } } } else { this.logging.debug("Context attribute: " + ctxAttribute.getType() + " not affecting intent models"); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } return results; } private List<IOutcome> processPreferences(IIdentity userId, CtxAttribute ctxAttribute) { this.logging.debug("Processing preferences after receiving context event"); List<IOutcome> results = new ArrayList<IOutcome>(); /* * List<IPreferenceOutcome> pcmResults = new * ArrayList<IPreferenceOutcome>(); List<IDIANNEOutcome> dianneResults = * new ArrayList<IDIANNEOutcome>(); */ try { CtxAttributeIdentifier ctxId = (CtxAttributeIdentifier) ctxAttribute.getId(); if (this.containsCtxId(ctxId, dianneList)) { this.logging.debug("dianne is registered for events of: " + ctxId.toUriString()); Future<List<IDIANNEOutcome>> futureDianneOutcomes = this.dianne.getOutcome(userId, (CtxAttribute) ctxAttribute); if (this.containsCtxId(ctxId, prefMgrList)) { this.logging.debug("pcm is registered for events of: " + ctxId.toUriString()); Future<List<IPreferenceOutcome>> futurePrefOutcomes = this.pcm.getOutcome(userId, ctxAttribute); return this.comparePreferenceConflicts(futureDianneOutcomes.get(), futurePrefOutcomes.get()); } else { this.logging.debug("pcm is NOT registered for events of: " + ctxId.toUriString()); List<IDIANNEOutcome> dianneOutcomes; dianneOutcomes = futureDianneOutcomes.get(); this.logging.debug("Received " + dianneOutcomes.size() + " outcomes from dianne after receiving context event: " + ctxAttribute.getType()); for (IDIANNEOutcome dOut : dianneOutcomes) { IPreferenceOutcome pOut = (IPreferenceOutcome) this.pcm.getOutcome(userId, dOut.getServiceID(), dOut.getparameterName()).get(); if (null == pOut) { results.add(dOut); } else { if (pOut.getvalue().equalsIgnoreCase(dOut.getvalue())) { results.add(dOut); } else { results.add(this.resolvePreferenceConflicts(dOut, pOut)); } } } } } else if (this.containsCtxId(ctxId, prefMgrList)) { this.logging.debug("pcm is registered for events of: " + ctxId.toUriString()); Future<List<IPreferenceOutcome>> futurePcmOutcomes = this.pcm.getOutcome(userId, ctxAttribute); if (this.containsCtxId(ctxId, dianneList)) { this.logging.debug("dianne is registered for events of: " + ctxId.toUriString()); Future<List<IDIANNEOutcome>> futureDianneOutcomes = this.dianne.getOutcome(userId, (CtxAttribute) ctxAttribute); return this.comparePreferenceConflicts(futureDianneOutcomes.get(), futurePcmOutcomes.get()); } else { this.logging.debug("dianne is NOT registered for events of: " + ctxId.toUriString()); List<IPreferenceOutcome> pcmOutcomes = futurePcmOutcomes.get(); this.logging.debug("Received " + pcmOutcomes.size() + " outcomes from pcm after receiving context event: " + ctxAttribute.getType()); for (IPreferenceOutcome pOut : pcmOutcomes) { IDIANNEOutcome dOut = this.dianne.getOutcome(userId, pOut.getServiceID(), pOut.getparameterName()).get().get(0); if (null == dOut) { results.add(pOut); } else { if (dOut.getvalue().equalsIgnoreCase(pOut.getvalue())) { results.add(pOut); } else { results.add(this.resolvePreferenceConflicts(dOut, pOut)); } } } } } else { this.logging.debug("Context attribute: " + ctxAttribute.getType() + " not affecting any preferences"); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } return results; } private List<IOutcome> comparePreferenceConflicts(List<IDIANNEOutcome> dOuts, List<IPreferenceOutcome> pOuts) { this.logging.debug("Finding conflicts between dianne and pcm"); List<IOutcome> result = new ArrayList<IOutcome>(); for (IDIANNEOutcome dOut : dOuts) { boolean matches = false; IPreferenceOutcome matchedOutcome = null; for (IPreferenceOutcome pOut : pOuts) { if (dOut.getparameterName().equalsIgnoreCase(pOut.getparameterName())) { matches = true; matchedOutcome = pOut; } else { matches = false; } } if (!matches) { result.add(dOut); } else { result.add(this.resolvePreferenceConflicts(dOut, matchedOutcome)); } } for (IPreferenceOutcome pOut : pOuts) { IOutcome out = matches(pOut, result); if (out == null) { result.add(pOut); } } return result; } private IOutcome matches(IOutcome outcome, List<IOutcome> outcomes) { for (IOutcome out : outcomes) { if (outcome.getServiceID().equals(out.getServiceID())) { if (outcome.getparameterName().equalsIgnoreCase(out.getparameterName())) { return out; } } } return null; } private List<IOutcome> compareIntentConflicts(List<IUserIntentAction> cauiOuts, List<CRISTUserAction> cristOuts) { this.logging.debug("Finding conflicts between caui and crist"); List<IOutcome> result = new ArrayList<IOutcome>(); for (IUserIntentAction cauiOut : cauiOuts) { boolean matches = false; CRISTUserAction matchedOutcome = null; for (CRISTUserAction cristOut : cristOuts) { if (cauiOut.getparameterName().equalsIgnoreCase(cristOut.getparameterName())) { matches = true; matchedOutcome = cristOut; } else { matches = false; } } if (!matches) { result.add(cauiOut); } else { result.add(this.resolveIntentConflicts(matchedOutcome, cauiOut)); } } for (CRISTUserAction cristOut : cristOuts) { IOutcome out = matches(cristOut, result); if (out == null) { result.add(cristOut); } } return result; } private IOutcome resolvePreferenceConflicts(IDIANNEOutcome dOut, IPreferenceOutcome pOut) { this.logging.debug("Resolving preference conflicts between dianne and pcm"); int dConf = this.dianneConfidenceLevel * dOut.getConfidenceLevel(); int pConf = this.prefMgrConfidenceLevel * pOut.getConfidenceLevel(); if (dConf > pConf) { this.logging.debug("Conflict Resolved. Returning dianne's outcome: " + dOut.toString()); return dOut; } else { this.logging.debug("Conflict Resolved. Returning pcm's outcome:" + pOut.toString()); return pOut; } } private IOutcome resolveIntentConflicts(CRISTUserAction cristAction, IUserIntentAction cauiAction) { this.logging.debug("Resolving intent conflicts between crist and caui"); int cauiConf = this.cauiConfidenceLevel * cauiAction.getConfidenceLevel(); int cristConf = this.cristConfidenceLevel * cristAction.getConfidenceLevel(); if (cauiConf > cristConf) { this.logging.debug("Conflict Resolved. Returning caui's outcome: " + cauiAction.toString()); return cauiAction; } else { this.logging.debug("Conflict Resolved. Returning crist's outcome: " + cristAction.toString()); return cristAction; } } @Override public void onRemoval(CtxChangeEvent arg0) { // TODO Auto-generated method stub } @Override public void onUpdate(CtxChangeEvent arg0) { // TODO Auto-generated method stub } @Override public void handleInternalEvent(final InternalEvent event) { this.logging.debug("Received UIM event:"); this.logging.debug("Event name " + event.geteventName() + "Event info: " + event.geteventInfo().toString() + "Event source: " + event.geteventSource() + "Event type: " + event.geteventType()); new Thread() { public void run() { try { if (event.geteventType().equals(EventTypes.UIM_EVENT)) { UIMEvent uimEvent = (UIMEvent) event.geteventInfo(); Future<List<IUserIntentAction>> futureCauiActions = cauiPrediction.getPrediction(uimEvent.getUserId(), uimEvent.getAction()); logging.debug("Requested caui prediction"); List<IUserIntentAction> cauiActions = futureCauiActions.get(); logging.debug("cauiPrediction returned: " + cauiActions.size() + " outcomes"); Future<List<CRISTUserAction>> futureCristActions = cristPrediction.getCRISTPrediction(uimEvent.getUserId(), uimEvent.getAction()); logging.debug("Requested crist prediction"); /* List<CRISTUserAction> cristActions = futureCristActions.get(); logging.debug("cristPrediction returned: " + cristActions.size() + " outcomes"); for (CRISTUserAction action : cristActions) { logging.debug("Crist outcome - parameter: " + action.getparameterName() + " - value: " + action.getvalue()); } */ /** * get intent outcomes */ Hashtable<IUserIntentAction, CRISTUserAction> overlapping = new Hashtable<IUserIntentAction, CRISTUserAction>(); List<IOutcome> intentNonOverlapping = new ArrayList<IOutcome>(); // first change intentNonOverlapping.addAll(cauiActions); /* for (IUserIntentAction caui : cauiActions) { CRISTUserAction crist = exists(cristActions, caui); if (null == crist) { intentNonOverlapping.add(caui); } else { overlapping.put(caui, crist); } } for (CRISTUserAction crist : cristActions) { IUserIntentAction caui = exists(cauiActions, crist); if (null == caui) { intentNonOverlapping.add(crist); } } Enumeration<IUserIntentAction> cauiEnum = overlapping.keys(); while (cauiEnum.hasMoreElements()) { IUserIntentAction caui = cauiEnum.nextElement(); CRISTUserAction crist = overlapping.get(caui); intentNonOverlapping.add(resolveIntentConflicts(crist, caui)); } */ /** * get preference outcomes */ Future<List<IDIANNEOutcome>> futureDianneActions = dianne.getOutcome(uimEvent.getUserId(), uimEvent.getAction()); logging.debug("Requested outcome from dianne"); List<IDIANNEOutcome> dianneActions = futureDianneActions.get(); logging.debug("DIANNE returned: " + dianneActions.size() + " outcomes"); Future<List<IPreferenceOutcome>> futurePreferenceActions = pcm.getOutcome(uimEvent.getUserId(), uimEvent.getAction()); logging.debug("Requested preference outcome"); List<IPreferenceOutcome> prefActions = futurePreferenceActions.get(); logging.debug("PCM returned: " + prefActions.size() + " outcomes"); Hashtable<IPreferenceOutcome, IDIANNEOutcome> prefOverlapping = new Hashtable<IPreferenceOutcome, IDIANNEOutcome>(); List<IOutcome> prefNonOverlapping = new ArrayList<IOutcome>(); for (IDIANNEOutcome d : dianneActions) { IPreferenceOutcome p = exists(prefActions, d); if (null == p) { prefNonOverlapping.add(d); } else { prefOverlapping.put(p, d); } } for (IPreferenceOutcome p : prefActions) { IDIANNEOutcome d = exists(dianneActions, p); if (null == d) { prefNonOverlapping.add(p); } } Enumeration<IPreferenceOutcome> prefEnum = prefOverlapping.keys(); while (prefEnum.hasMoreElements()) { IPreferenceOutcome pref = prefEnum.nextElement(); IDIANNEOutcome dianne = prefOverlapping.get(pref); prefNonOverlapping.add(resolvePreferenceConflicts(dianne, pref)); } if (intentNonOverlapping.size() == 0 & prefNonOverlapping.size() == 0) { logging.debug("Action Event-> Nothing to send to decisionMaker"); return; } else { for (int i = 0; i < prefNonOverlapping.size(); i++) { logging.debug("Preference Outcome " + i + " :" + prefNonOverlapping.get(i)); } for (int i = 0; i < intentNonOverlapping.size(); i++) { logging.debug("Intent Outcome " + i + " :" + intentNonOverlapping.get(i)); } } // second change // set null preferences //prefNonOverlapping = new ArrayList<IOutcome>(); decisionMaker.makeDecision(intentNonOverlapping, prefNonOverlapping); } else { logging.debug("event: " + event.geteventType() + " not a " + EventTypes.UIM_EVENT); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } logging.debug("Thread of handleInternalEvent finished executing"); } }.start(); } private IUserIntentAction exists(List<IUserIntentAction> cauiActions, CRISTUserAction crist) { for (IUserIntentAction o : cauiActions) { if (this.outcomesMatch(o, crist)) { return o; } } return null; } private CRISTUserAction exists(List<CRISTUserAction> cristActions, IUserIntentAction caui) { for (CRISTUserAction o : cristActions) { if (this.outcomesMatch(o, caui)) { return o; } } return null; } private IDIANNEOutcome exists(List<IDIANNEOutcome> dianneActions, IPreferenceOutcome prefOutcome) { for (IDIANNEOutcome d : dianneActions) { if (this.outcomesMatch(d, prefOutcome)) { return d; } } return null; } private IPreferenceOutcome exists(List<IPreferenceOutcome> prefActions, IDIANNEOutcome dianneOutcome) { for (IPreferenceOutcome p : prefActions) { if (this.outcomesMatch(p, dianneOutcome)) { return p; } } return null; } private boolean outcomesMatch(IOutcome outcome1, IOutcome outcome2) { if (outcome1.getServiceID().getServiceInstanceIdentifier().equalsIgnoreCase(outcome2.getServiceID().getServiceInstanceIdentifier())) { if (outcome1.getparameterName().equalsIgnoreCase(outcome2.getparameterName())) { return true; } } return false; } @Override public void handleExternalEvent(CSSEvent arg0) { // TODO Auto-generated method stub } }