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    }