/** * 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.merging; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; import javax.swing.JOptionPane; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.societies.api.identity.IIdentity; import org.societies.api.internal.personalisation.model.IOutcome; import org.societies.api.internal.personalisation.model.PreferenceDetails; import org.societies.api.internal.servicelifecycle.ServiceModelUtils; import org.societies.api.internal.useragent.monitoring.UIMEvent; import org.societies.api.osgi.event.CSSEvent; 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.IAction; import org.societies.api.schema.servicelifecycle.model.ServiceResourceIdentifier; import org.societies.personalisation.UserPreferenceManagement.impl.UserPreferenceManagement; import org.societies.personalisation.UserPreferenceManagement.impl.monitoring.UserPreferenceConditionMonitor; import org.societies.personalisation.preference.api.UserPreferenceLearning.IC45Learning; import org.societies.personalisation.preference.api.model.IC45Consumer; import org.societies.personalisation.preference.api.model.IC45Output; import org.societies.personalisation.preference.api.model.IPreference; import org.societies.personalisation.preference.api.model.IPreferenceTreeModel; import org.societies.api.osgi.event.EventListener; public class MergingManager implements IC45Consumer{ private Logger logging = LoggerFactory.getLogger(this.getClass()); private Hashtable<IIdentity,Hashtable<IAction, Integer>> counters = new Hashtable<IIdentity,Hashtable<IAction, Integer>>();; private UserPreferenceManagement prefImpl; private UserPreferenceConditionMonitor pcm; private IC45Learning c45Learning; public MergingManager(IC45Learning c45Learning, UserPreferenceManagement prefImpl, UserPreferenceConditionMonitor pcm){ this.c45Learning = c45Learning; this.prefImpl = prefImpl; this.pcm = pcm; } public void explicitlyTriggerLearning(Date date){ this.c45Learning.runC45Learning(this, date); } public void explicitlyTriggerLearning(Date date, ServiceResourceIdentifier serviceId, IAction action){ this.c45Learning.runC45Learning(this, date, serviceId, action.getparameterName()); } public void explicitlyTriggerLearning(IIdentity userId, Date date, ServiceResourceIdentifier serviceId, IAction action){ this.c45Learning.runC45Learning(this, date, userId, serviceId, action.getparameterName()); } /* * (non-Javadoc) * @see org.societies.personalisation.preference.api.model.IC45Consumer#handleC45Output(java.util.List) */ @Override public void handleC45Output(List<IC45Output> list) { try{ logging.debug(this.getClass().getName()+ " received C45Output! size of list:" +list.size()); for (IC45Output output : list){ IIdentity identity = output.getOwner(); this.logging.debug("Processing output for user: "+identity.getIdentifier()); ServiceResourceIdentifier serviceID = output.getServiceId(); String serviceType = output.getServiceType(); List<IPreferenceTreeModel> treeList = output.getTreeList(); PreferenceMerger prefMerger = new PreferenceMerger(pcm.getUserFeedbackMgr()); logging.debug("Trees in C45output: "+treeList.size()); for (IPreferenceTreeModel tree : treeList){ logging.debug(tree.toString()); String prefName = tree.getPreferenceDetails().getPreferenceName(); if (prefName==null){ prefName = this.getPreferenceName(tree); } IPreference existingPreference = this.getPreferenceFromPM(identity, serviceType, serviceID, prefName); this.logging.debug("Received preference from PM"); if (existingPreference==null){ logging.debug("STORING NEW PREFERENCE"); PreferenceDetails detail = new PreferenceDetails(output.getServiceType(), serviceID, prefName); this.prefImpl.storePreference(identity, detail, tree.getRootPreference()); this.pcm.processPreferenceChanged(identity, output.getServiceId(), output.getServiceType(), prefName); return; } IPreference mergedTree = prefMerger.mergeTrees(existingPreference, (IPreference) tree.getRootPreference(), ""); if (mergedTree == null){ logging.debug(this.getClass().getName()+ " CONFLICT!!!! RUNNING C45 AGAIN!!!!"); this.c45Learning.runC45Learning(new C45ConflictConsumer(identity, serviceType, serviceID, prefName, this.prefImpl), null, identity, serviceID, prefName); }else{ logging.debug(this.getClass().getName()+" MERGED PREFERENCE: \n"+mergedTree.toTreeString()); PreferenceDetails detail = new PreferenceDetails(output.getServiceType(), serviceID, prefName); this.prefImpl.storePreference(identity, detail, mergedTree); this.pcm.processPreferenceChanged(identity, output.getServiceId(), output.getServiceType(), prefName); } } } } catch (Exception e){ e.printStackTrace(); logging.debug(e.toString()); } } private String getPreferenceName(IPreferenceTreeModel iptm){ IPreference p = iptm.getRootPreference(); Enumeration<IPreference> e = p.preorderEnumeration(); while (e.hasMoreElements()){ IPreference temp = e.nextElement(); if (temp.getUserObject() instanceof IOutcome){ IOutcome o = temp.getOutcome(); return o.getparameterName(); } } return "NO-PREFERENCE-NAME"; } private IPreference getPreferenceFromPM(IIdentity id, String serviceType, ServiceResourceIdentifier serviceID, String parameterName){ IPreferenceTreeModel model =this.prefImpl.getModel(id, serviceType, serviceID, parameterName); if (model==null){ return null; } return model.getRootPreference(); } public void processActionReceived(IIdentity userId, IAction action){ if (this.counters.containsKey(userId)){ logging.debug("hashtable for identity: "+userId.toString()+" exists"); Hashtable<IAction, Integer> tempTable = counters.get(userId); Enumeration<IAction> e = tempTable.keys(); logging.debug(" Processing Action with serviceID: "+action.getServiceID()+ " and identity: "+userId.toString()); boolean actionExists = false; while (e.hasMoreElements()){ IAction tempAction = e.nextElement(); if (tempAction.getServiceID().equals(action.getServiceID()) && tempAction.getparameterName().equals(action.getparameterName())){ logging.debug(this.getClass().getName()+"found inner hashtable for action: "+action.toString()); actionExists = true; int counter = tempTable.get(tempAction); this.logging.debug("Counter for service:"+ServiceModelUtils.serviceResourceIdentifierToString(action.getServiceID())+" parameter: "+action.getparameterName()+" is "+counter); if (counter>=2){ this.logging.debug("Counter reached 2, requesting learning and resetting counter"); tempTable.put(tempAction, new Integer(0)); //reset counter IPreferenceTreeModel iptm = this.prefImpl.getModel(userId, action.getServiceType(), action.getServiceID(), action.getparameterName()); if (iptm==null){ logging.debug(this.getClass().getName()+" runC45Learning!"); this.c45Learning.runC45Learning(this, null, userId, action.getServiceID(), action.getparameterName()); }else{ logging.debug(this.getClass().getName()+" runC45Learning!"); Date d = iptm.getLastModifiedDate(); this.c45Learning.runC45Learning(this, d, userId, action.getServiceID(), action.getparameterName()); } }else{ logging.debug(this.getClass().getName()+" incrementing counter for action: "+action.toString()); counter ++; this.logging.debug("Counter for :"+action.toString()+" is "+counter); tempTable.put(tempAction, new Integer(counter)); } } } if (!actionExists){ tempTable.put(action, new Integer(0)); } }else{ logging.debug(this.getClass().getName()+" adding hashtable for identity: "+userId.toString()); Hashtable<IAction, Integer> table = new Hashtable<IAction, Integer>(); table.put(action, new Integer(0)); this.counters.put(userId, table); } } /* * REPLACE with direct call to PCM */ /* private void sendEvent(IIdentity userId, ServiceResourceIdentifier serviceID, String serviceType, String prefName){ EventSender evSender = new EventSender(this.eventMgr); evSender.sendEvent(userId, serviceID, serviceType, prefName); }*/ /* * (non-Javadoc) * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) @Override public void onApplicationEvent(InternalEvent event) { if (event.getEventNode().equals("UIM_EVENT")){ UIMEvent uimEvent = (UIMEvent) event.getEventInfo(); this.processActionReceived(uimEvent.getAction(), uimEvent.getUserId()); } } */ }