001 /** 002 * Travel3.java 003 * jCOLIBRI2 framework. 004 * @author Juan A. Recio-García. 005 * GAIA - Group for Artificial Intelligence Applications 006 * http://gaia.fdi.ucm.es 007 * 23/10/2007 008 */ 009 package jcolibri.test.recommenders.rec3; 010 011 import java.util.ArrayList; 012 import java.util.Collection; 013 import java.util.HashMap; 014 import java.util.Map; 015 016 import jcolibri.casebase.LinealCaseBase; 017 import jcolibri.cbraplications.StandardCBRApplication; 018 import jcolibri.cbrcore.Attribute; 019 import jcolibri.cbrcore.CBRCase; 020 import jcolibri.cbrcore.CBRCaseBase; 021 import jcolibri.cbrcore.CBRQuery; 022 import jcolibri.cbrcore.Connector; 023 import jcolibri.connector.DataBaseConnector; 024 import jcolibri.datatypes.Instance; 025 import jcolibri.exception.ExecutionException; 026 import jcolibri.extensions.recommendation.casesDisplay.DisplayCasesTableMethod; 027 import jcolibri.extensions.recommendation.casesDisplay.UserChoice; 028 import jcolibri.extensions.recommendation.conditionals.BuyOrQuit; 029 import jcolibri.extensions.recommendation.conditionals.ContinueOrFinish; 030 import jcolibri.extensions.recommendation.conditionals.DisplayCasesIfNumber; 031 import jcolibri.method.gui.formFilling.ObtainQueryWithFormMethod; 032 import jcolibri.method.retrieve.FilterBasedRetrieval.FilterBasedRetrievalMethod; 033 import jcolibri.method.retrieve.FilterBasedRetrieval.FilterConfig; 034 import jcolibri.method.retrieve.FilterBasedRetrieval.predicates.Equal; 035 import jcolibri.method.retrieve.FilterBasedRetrieval.predicates.OntologyCompatible; 036 import jcolibri.method.retrieve.FilterBasedRetrieval.predicates.QueryLessOrEqual; 037 import jcolibri.method.retrieve.FilterBasedRetrieval.predicates.QueryMoreOrEqual; 038 import jcolibri.test.recommenders.travelData.TravelDescription; 039 import jcolibri.test.recommenders.travelData.TravelDescription.AccommodationTypes; 040 import jcolibri.test.recommenders.travelData.TravelDescription.Seasons; 041 import jcolibri.util.FileIO; 042 import es.ucm.fdi.gaia.ontobridge.OntoBridge; 043 import es.ucm.fdi.gaia.ontobridge.OntologyDocument; 044 045 /** 046 * Conversational (type B) trips recommender using form-filling and Filter-Based retrieval. 047 * <br> 048 * This recommender obtains the user preferences through a form. Then, it performs the 049 * retrieval filtering the items that obbey the user preferences. If the retrieval set 050 * is small enough, items are shown to the user. If the retrieval set is too big or 051 * the user does not find the desired item, the system presents again a form to modify 052 * the user requirements. The form has some initial values and custom labels. 053 * <ul> 054 * <li>Type: Conversational B 055 * <li>Case base: travel 056 * <li>One off Preference Elicitation: Form Filling with initial values and custom labels 057 * <li>Retrieval: Filter 058 * <li>Display Condition: number of cases (showing messages) 059 * <li>Display: In table with "Edit Query" enabled 060 * <li>Iterated Preference Elicitation: Form Filling with initial values and custom labels 061 * </ul> 062 * This recommender implements the following template:<br> 063 * <center><img src="../Template3_Cycle.jpg"/></center> 064 * 065 * <br>Read the documentation of the recommenders extension for details about templates 066 * and recommender strategies: {@link jcolibri.extensions.recommendation} 067 * 068 * @see jcolibri.method.gui.formFilling.ObtainQueryWithFormMethod 069 * @see jcolibri.method.retrieve.FilterBasedRetrieval.FilterBasedRetrievalMethod 070 * @see jcolibri.extensions.recommendation.conditionals.DisplayCasesIfNumber 071 * @see jcolibri.extensions.recommendation.casesDisplay.DisplayCasesTableMethod 072 * 073 * @author Juan A. Recio-Garcia 074 * @author Developed at University College Cork (Ireland) in collaboration with Derek Bridge. 075 * @version 1.0 076 * 077 */ 078 public class Travel3 implements StandardCBRApplication 079 { 080 /** Connector object */ 081 Connector _connector; 082 /** CaseBase object */ 083 CBRCaseBase _caseBase; 084 085 /** Configuration object for Form Filling */ 086 Map<Attribute,String> labels; 087 /** Configuration object for Form Filling */ 088 ArrayList<Attribute> hiddenAtts; 089 /** Configuration object for Filter Based retrieval*/ 090 FilterConfig filterConfig; 091 092 public void configure() throws ExecutionException 093 { 094 //Emulate data base server 095 jcolibri.test.database.HSQLDBserver.init(); 096 097 // Create a data base connector 098 _connector = new DataBaseConnector(); 099 // Init the ddbb connector with the config file 100 _connector.initFromXMLfile(jcolibri.util.FileIO 101 .findFile("jcolibri/test/recommenders/travelData/databaseconfig.xml")); 102 // Create a Lineal case base for in-memory organization 103 _caseBase = new LinealCaseBase(); 104 105 // Obtain a reference to OntoBridge 106 OntoBridge ob = jcolibri.util.OntoBridgeSingleton.getOntoBridge(); 107 // Configure it to work with the Pellet reasoner 108 ob.initWithPelletReasoner(); 109 // Setup the main ontology 110 OntologyDocument mainOnto = new OntologyDocument("http://gaia.fdi.ucm.es/ontologies/travel-destinations.owl", 111 FileIO.findFile("jcolibri/test/recommenders/travelData/travel-destinations.owl").toExternalForm()); 112 // There are not subontologies 113 ArrayList<OntologyDocument> subOntologies = new ArrayList<OntologyDocument>(); 114 // Load the ontology 115 ob.loadOntology(mainOnto, subOntologies, false); 116 117 hiddenAtts = new ArrayList<Attribute>(); 118 labels = new HashMap<Attribute,String>(); 119 labels.put(new Attribute("Duration", TravelDescription.class), "Min duration"); 120 labels.put(new Attribute("Accommodation", TravelDescription.class), "Min accommodation"); 121 labels.put(new Attribute("Price", TravelDescription.class), "Max price"); 122 123 //Configure the Filter 124 filterConfig = new FilterConfig(); 125 filterConfig.addPredicate(new Attribute("HolidayType", TravelDescription.class), new Equal()); 126 filterConfig.addPredicate(new Attribute("NumberOfPersons", TravelDescription.class), new Equal()); 127 filterConfig.addPredicate(new Attribute("Region", TravelDescription.class), new OntologyCompatible()); 128 filterConfig.addPredicate(new Attribute("Transportation", TravelDescription.class), new Equal()); 129 filterConfig.addPredicate(new Attribute("Duration", TravelDescription.class), new QueryLessOrEqual()); 130 filterConfig.addPredicate(new Attribute("Season", TravelDescription.class), new Equal()); 131 filterConfig.addPredicate(new Attribute("Accommodation", TravelDescription.class), new QueryLessOrEqual()); 132 filterConfig.addPredicate(new Attribute("Price", TravelDescription.class), new QueryMoreOrEqual()); 133 } 134 135 public void cycle(CBRQuery query) throws ExecutionException 136 { 137 // Obtain the query 138 ObtainQueryWithFormMethod.obtainQueryWithInitialValues(query,hiddenAtts,labels); 139 140 141 // Jump to the conversation cycle 142 sequence1(query); 143 } 144 145 146 public void sequence1(CBRQuery query) 147 { 148 // Retrieve using filter based retrieval 149 Collection<CBRCase> retrievedCases = FilterBasedRetrievalMethod.filterCases(_caseBase.getCases(), query, filterConfig); 150 151 // Display condition based on the number of cases. 152 if(DisplayCasesIfNumber.displayCases(50, 1, retrievedCases,true)) 153 sequence2(query, retrievedCases); 154 else 155 sequence3(query); 156 } 157 158 public void sequence2(CBRQuery query, Collection<CBRCase> retrievedCases) 159 { 160 // Display cases in table 161 UserChoice choice = DisplayCasesTableMethod.displayCasesInTableEditQuery(retrievedCases); 162 163 if(ContinueOrFinish.continueOrFinish(choice)) 164 sequence3(query); 165 else 166 sequence4(choice, retrievedCases); 167 } 168 169 170 public void sequence3(CBRQuery query) 171 { 172 // Refine query and back to the main sequence 173 ObtainQueryWithFormMethod.obtainQueryWithInitialValues(query,hiddenAtts,labels); 174 175 sequence1(query); 176 } 177 178 public void sequence4(UserChoice choice, Collection<CBRCase> retrievedCases) 179 { 180 if(BuyOrQuit.buyOrQuit(choice)) 181 System.out.println("Finish - User Buys: "+choice.getSelectedCase()); 182 183 else 184 System.out.println("Finish - User Quits"); 185 } 186 187 public void postCycle() throws ExecutionException 188 { 189 _connector.close(); 190 jcolibri.test.database.HSQLDBserver.shutDown(); 191 } 192 193 public CBRCaseBase preCycle() throws ExecutionException 194 { 195 // Load cases from connector into the case base 196 _caseBase.init(_connector); 197 // Print the cases 198 java.util.Collection<CBRCase> cases = _caseBase.getCases(); 199 for(CBRCase c: cases) 200 System.out.println(c); 201 return _caseBase; 202 } 203 204 public static void main(String[] args) { 205 StandardCBRApplication recommender = new Travel3(); 206 try 207 { 208 recommender.configure(); 209 210 recommender.preCycle(); 211 212 CBRQuery query = new CBRQuery(); 213 214 TravelDescription td = new TravelDescription(); 215 td.setAccommodation(AccommodationTypes.ThreeStars); 216 td.setDuration(7); 217 td.setHolidayType("bathing"); 218 td.setNumberOfPersons(2); 219 td.setRegion(new Instance("Spain")); 220 td.setSeason(Seasons.July); 221 td.setTransportation("plane"); 222 td.setPrice(1000); 223 224 query.setDescription(td); 225 226 recommender.cycle(query); 227 228 recommender.postCycle(); 229 230 System.exit(0); 231 } catch (Exception e) 232 { 233 org.apache.commons.logging.LogFactory.getLog(Travel3.class).error(e); 234 235 } 236 237 238 } 239 240 }