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     */
009    package jcolibri.test.test2;
010    
011    import java.util.Collection;
012    
013    import jcolibri.casebase.LinealCaseBase;
014    import jcolibri.cbraplications.StandardCBRApplication;
015    import jcolibri.cbrcore.Attribute;
016    import jcolibri.cbrcore.CBRCaseBase;
017    import jcolibri.cbrcore.CBRQuery;
018    import jcolibri.cbrcore.Connector;
019    import jcolibri.connector.DataBaseConnector;
020    import jcolibri.exception.ExecutionException;
021    import jcolibri.method.retrieve.RetrievalResult;
022    import jcolibri.method.retrieve.NNretrieval.NNConfig;
023    import jcolibri.method.retrieve.NNretrieval.NNScoringMethod;
024    import jcolibri.method.retrieve.NNretrieval.similarity.global.Average;
025    import jcolibri.method.retrieve.NNretrieval.similarity.local.Equal;
026    import jcolibri.method.retrieve.NNretrieval.similarity.local.Interval;
027    import 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="jcolibri.connector.databaseutils.EnumUserType"&gt;
043     *                      &lt;param name="enumClassName"&gt;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="jcolibri.connector.databaseutils.GenericUserType"&gt;
057     *                      &lt;param name="className"&gt;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 jcolibri.test.test2.TravelDescription
067     * @see jcolibri.test.test2.MyStringType
068     */
069    public 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(jcolibri.util.FileIO.findFile("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                    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                            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    }