001/**
002 * Test2.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 * 28/11/2006
008 */
009package es.ucm.fdi.gaia.jcolibri.test.test2;
010
011import java.util.Collection;
012
013import es.ucm.fdi.gaia.jcolibri.casebase.LinealCaseBase;
014import es.ucm.fdi.gaia.jcolibri.cbraplications.StandardCBRApplication;
015import es.ucm.fdi.gaia.jcolibri.cbrcore.Attribute;
016import es.ucm.fdi.gaia.jcolibri.cbrcore.CBRCaseBase;
017import es.ucm.fdi.gaia.jcolibri.cbrcore.CBRQuery;
018import es.ucm.fdi.gaia.jcolibri.cbrcore.Connector;
019import es.ucm.fdi.gaia.jcolibri.connector.DataBaseConnector;
020import es.ucm.fdi.gaia.jcolibri.exception.ExecutionException;
021import es.ucm.fdi.gaia.jcolibri.method.retrieve.RetrievalResult;
022import es.ucm.fdi.gaia.jcolibri.method.retrieve.NNretrieval.NNConfig;
023import es.ucm.fdi.gaia.jcolibri.method.retrieve.NNretrieval.NNScoringMethod;
024import es.ucm.fdi.gaia.jcolibri.method.retrieve.NNretrieval.similarity.global.Average;
025import es.ucm.fdi.gaia.jcolibri.method.retrieve.NNretrieval.similarity.local.Equal;
026import es.ucm.fdi.gaia.jcolibri.method.retrieve.NNretrieval.similarity.local.Interval;
027import es.ucm.fdi.gaia.jcolibri.method.retrieve.selection.SelectCases;
028
029/**
030 * This second test shows how to use enumerated values and user defined data types as attributes.<br>
031 * <ul>
032 * <li><b>Enums:</b><br>
033 * In the TravelDescription class we define the enumeration:
034 * <pre>
035 * enum AccommodationTypes  { OneStar, TwoStars, ThreeStars, HolidayFlat, FourStars, FiveStars};
036 * </pre>
037 * for the accomodation attribute. To manage that attribute we only have to modify the <b>TravelDescription.hbm.xml</b>
038 * with the following code:
039 * <pre>
040 *  ...
041 *      &lt;property name="Accommodation" column="Accommodation"&gt;
042 *              &lt;type name="es.ucm.fdi.gaia.jcolibri.connector.databaseutils.EnumUserType"&gt;
043 *                      &lt;param name="enumClassName"&gt;es.ucm.fdi.gaia.jcolibri.test.test2.TravelDescription$AccommodationTypes&lt;/param&gt;
044 *      &lt;/type&gt;
045 *      &lt;/property&gt;
046 *      ...
047 * </pre>
048 * The EnumUserType class is a utility class of the connector that allows managing Enums. It recieves the class name of you enum as parameter.
049 * <li><b>User defined data types:</b><br>
050 * To create your own data type implement the jcolibri.connector.TypeAdaptor interface. MyStringType.java is a simple example were we are wrapping a string.
051 * You have to define the toString(), fromString() and equals() methods. That way the value of your data type will be mapped using a string representation in the presistence media.
052 * <br>
053 * In this example we have typed the "Hotel" attribute of the description as "MyStringType. To manage the attribute we have to modify the <b>TravelDescription.hbm.xml</b> file with:
054 * <pre>
055 *      &lt;property name="Hotel" column="Hotel"&gt;
056 *              &lt;type name="es.ucm.fdi.gaia.jcolibri.connector.databaseutils.GenericUserType"&gt;
057 *                      &lt;param name="className"&gt;es.ucm.fdi.gaia.jcolibri.test.test2.MyStringType&lt;/param&gt;
058 *      &lt;/type&gt;
059 *      &lt;/property&gt;
060 * </pre>
061 * The GenericUserType class is the utility class that allows to manage TypeAdaptor implementations in the data base connector.
062 * 
063 * @author Juan A. Recio-Garcia
064 * @version 1.0
065 * @see jcolibri.connector.TypeAdaptor
066 * @see es.ucm.fdi.gaia.jcolibri.test.test2.TravelDescription
067 * @see es.ucm.fdi.gaia.jcolibri.test.test2.MyStringType
068 */
069public class Test2 implements StandardCBRApplication {
070
071        /** Connector object */
072        Connector _connector;
073        /** CaseBase object */
074        CBRCaseBase _caseBase;
075        
076        /* (non-Javadoc)
077         * @see jcolibri.cbraplications.BasicCBRApplication#configure()
078         */
079        public void configure() throws ExecutionException{
080                try{
081                // Create a data base connector
082                _connector = new DataBaseConnector();
083                // Init the ddbb connector with the config file
084                _connector.initFromXMLfile(es.ucm.fdi.gaia.jcolibri.util.FileIO.findFile("es/ucm/fdi/gaia/jcolibri/test/test2/databaseconfig.xml"));
085                // Create a Lineal case base for in-memory organization
086                _caseBase  = new LinealCaseBase();
087                } catch (Exception e){
088                        throw new ExecutionException(e);
089                }
090        }
091
092        
093        /* (non-Javadoc)
094         * @see jcolibri.cbraplications.BasicCBRApplication#preCycle()
095         */
096        public CBRCaseBase preCycle() throws ExecutionException {
097                // Load cases from connector into the case base
098                _caseBase.init(_connector);             
099                return _caseBase;
100        }
101        
102        /* (non-Javadoc)
103         * @see jcolibri.cbraplications.BasicCBRApplication#cycle()
104         */
105        public void cycle(CBRQuery query) throws ExecutionException 
106        {               
107                // First configure the KNN
108                NNConfig simConfig = new NNConfig();
109                // Set the average() global similarity function for the description of the case
110                simConfig.setDescriptionSimFunction(new Average());
111                // The accomodation attribute uses the equal() local similarity function
112                simConfig.addMapping(new Attribute("Accommodation", TravelDescription.class), new Equal());
113                // For the duration attribute we are going to set its local similarity function and the weight
114                Attribute duration = new Attribute("Duration", TravelDescription.class);
115                simConfig.addMapping(duration, new Interval(31));
116                simConfig.setWeight(duration, 0.5);
117                // HolidayType --> equal()
118                simConfig.addMapping(new Attribute("HolidayType", TravelDescription.class), new Equal());
119                // NumberOfPersons --> equal()
120                simConfig.addMapping(new Attribute("NumberOfPersons", TravelDescription.class), new Equal());
121                // Price --> InrecaLessIsBetter()
122                simConfig.addMapping(new Attribute("Price", TravelDescription.class), new Interval(4000));
123                
124                
125                // A bit of verbose
126                System.out.println("Query Description:");
127                System.out.println(query.getDescription());
128                System.out.println();
129                
130                // Execute NN
131                Collection<RetrievalResult> eval = NNScoringMethod.evaluateSimilarity(_caseBase.getCases(), query, simConfig);
132                
133                // Select k cases
134                eval = SelectCases.selectTopKRR(eval, 5);
135                
136                // Print the retrieval
137                System.out.println("Retrieved cases:");
138                for(RetrievalResult nse: eval)
139                        System.out.println(nse);
140        }
141
142        /* (non-Javadoc)
143         * @see jcolibri.cbraplications.BasicCBRApplication#postCycle()
144         */
145        public void postCycle() throws ExecutionException {
146                this._caseBase.close();
147
148        }
149
150        /**
151         * @param args
152         */
153        public static void main(String[] args) {
154                // Launch DDBB manager
155                es.ucm.fdi.gaia.jcolibri.test.database.HSQLDBserver.init();
156                
157                // Create the application
158                Test2 test2 = new Test2();
159                try {
160                        //Configure it
161                        test2.configure();
162                        // Run the precycle --> load the cases
163                        test2.preCycle();
164                        
165                        //BufferedReader reader  = new BufferedReader(new InputStreamReader(System.in));                        
166                        //do{           
167                                TravelDescription queryDesc = new TravelDescription();
168                                // The accommodation is a value of the Enum
169                                queryDesc.setAccommodation(TravelDescription.AccommodationTypes.ThreeStars);
170                                queryDesc.setDuration(7);
171                                queryDesc.setHolidayType("Recreation");
172                                queryDesc.setNumberOfPersons(2);
173                                queryDesc.setPrice(700);
174                                
175                                CBRQuery query = new CBRQuery();
176                                query.setDescription(queryDesc);
177                                
178                                // Execute query
179                                test2.cycle(query);
180                                
181                        //System.out.println("Cycle finished. Type exit to idem or enter to repeat the cycle");
182                        //}while(!reader.readLine().equals("exit"));
183                        
184                        test2.postCycle();
185                        
186                        //Shutdown DDBB manager
187                        es.ucm.fdi.gaia.jcolibri.test.database.HSQLDBserver.shutDown();
188
189                } catch (ExecutionException e) {
190                        System.out.println(e.getMessage());
191                        e.printStackTrace();
192                } catch (Exception e) {
193                        // TODO Auto-generated catch block
194                        e.printStackTrace();
195                }
196        }
197
198}