AirSched Logo  0.1.4
C++ Simulated Airline Schedule Manager Library
AIRSCHED_Service.cpp
Go to the documentation of this file.
00001 // //////////////////////////////////////////////////////////////////////
00002 // Import section
00003 // //////////////////////////////////////////////////////////////////////
00004 // STL
00005 #include <cassert>
00006 #include <sstream>
00007 // Boost
00008 #include <boost/make_shared.hpp>
00009 // StdAir
00010 #include <stdair/basic/BasChronometer.hpp>
00011 #include <stdair/bom/BomManager.hpp> 
00012 #include <stdair/bom/BookingRequestStruct.hpp>
00013 #include <stdair/bom/TravelSolutionStruct.hpp>
00014 #include <stdair/service/Logger.hpp>
00015 #include <stdair/STDAIR_Service.hpp>
00016 // AirSched
00017 #include <airsched/basic/BasConst_AIRSCHED_Service.hpp>
00018 #include <airsched/factory/FacAIRSCHEDServiceContext.hpp>
00019 #include <airsched/command/Simulator.hpp>
00020 #include <airsched/command/ScheduleParser.hpp>
00021 #include <airsched/command/OnDParser.hpp>
00022 #include <airsched/command/SegmentPathProvider.hpp>
00023 #include <airsched/command/InventoryGenerator.hpp>
00024 #include <airsched/command/SegmentPathGenerator.hpp>
00025 #include <airsched/service/AIRSCHED_ServiceContext.hpp>
00026 #include <airsched/AIRSCHED_Service.hpp>
00027 
00028 namespace AIRSCHED {
00029 
00030   // ////////////////////////////////////////////////////////////////////
00031   AIRSCHED_Service::AIRSCHED_Service() : _airschedServiceContext (NULL) {
00032     assert (false);
00033   }
00034 
00035   // ////////////////////////////////////////////////////////////////////
00036   AIRSCHED_Service::AIRSCHED_Service (const AIRSCHED_Service& iService)
00037     : _airschedServiceContext (NULL) {
00038     assert (false);
00039   }
00040 
00041   // ////////////////////////////////////////////////////////////////////
00042   AIRSCHED_Service::AIRSCHED_Service (const stdair::BasLogParams& iLogParams) 
00043     : _airschedServiceContext (NULL) {
00044     
00045     // Initialise the STDAIR service handler
00046     stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
00047       initStdAirService (iLogParams);
00048     
00049     // Initialise the service context
00050     initServiceContext();
00051     
00052     // Add the StdAir service context to the AirSched service context
00053     // \note AirSched owns the STDAIR service resources here.
00054     const bool ownStdairService = true;
00055     addStdAirService (lSTDAIR_Service_ptr, ownStdairService);
00056     
00057     // Initialise the (remaining of the) context
00058     initAirschedService();
00059   }
00060 
00061   // ////////////////////////////////////////////////////////////////////
00062   AIRSCHED_Service::AIRSCHED_Service (const stdair::BasLogParams& iLogParams,
00063                                       const stdair::BasDBParams& iDBParams) 
00064     : _airschedServiceContext (NULL) {
00065     
00066     // Initialise the STDAIR service handler
00067     stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
00068       initStdAirService (iLogParams, iDBParams);
00069     
00070     // Initialise the service context
00071     initServiceContext();
00072     
00073     // Add the StdAir service context to the AirSched service context
00074     // \note AirSched owns the STDAIR service resources here.
00075     const bool ownStdairService = true;
00076     addStdAirService (lSTDAIR_Service_ptr, ownStdairService);
00077     
00078     // Initialise the (remaining of the) context
00079     initAirschedService();
00080   }
00081 
00082   // ////////////////////////////////////////////////////////////////////
00083   AIRSCHED_Service::
00084   AIRSCHED_Service (stdair::STDAIR_ServicePtr_T ioSTDAIRServicePtr)
00085     : _airschedServiceContext (NULL) {
00086 
00087     // Initialise the service context
00088     initServiceContext();
00089     
00090     // Add the StdAir service context to the AirSched service context.
00091     // \note AirSched does not own the STDAIR service resources here.
00092     const bool doesNotOwnStdairService = false;
00093     addStdAirService (ioSTDAIRServicePtr, doesNotOwnStdairService);
00094     
00095     // Initialise the context
00096     initAirschedService();
00097   }
00098 
00099   // ////////////////////////////////////////////////////////////////////
00100   AIRSCHED_Service::~AIRSCHED_Service() {
00101     // Delete/Clean all the objects from memory
00102     finalise();
00103   }
00104 
00105   // ////////////////////////////////////////////////////////////////////
00106   void AIRSCHED_Service::finalise() {
00107     assert (_airschedServiceContext != NULL);
00108     // Reset the (Boost.)Smart pointer pointing on the STDAIR_Service object.
00109     _airschedServiceContext->reset();
00110   }
00111 
00112   // //////////////////////////////////////////////////////////////////////
00113   void AIRSCHED_Service::initServiceContext() {
00114     // Initialise the service context
00115     AIRSCHED_ServiceContext& lAIRSCHED_ServiceContext = 
00116       FacAIRSCHEDServiceContext::instance().create();
00117     _airschedServiceContext = &lAIRSCHED_ServiceContext;
00118   }
00119 
00120   // ////////////////////////////////////////////////////////////////////
00121   void AIRSCHED_Service::
00122   addStdAirService (stdair::STDAIR_ServicePtr_T ioSTDAIR_Service_ptr,
00123                     const bool iOwnStdairService) {
00124 
00125     // Retrieve the AirSched service context
00126     assert (_airschedServiceContext != NULL);
00127     AIRSCHED_ServiceContext& lAIRSCHED_ServiceContext =
00128       *_airschedServiceContext;
00129 
00130     // Store the STDAIR service object within the (AirSched) service context
00131     lAIRSCHED_ServiceContext.setSTDAIR_Service (ioSTDAIR_Service_ptr,
00132                                                 iOwnStdairService);
00133   }
00134 
00135   // //////////////////////////////////////////////////////////////////////
00136   stdair::STDAIR_ServicePtr_T AIRSCHED_Service::
00137   initStdAirService (const stdair::BasLogParams& iLogParams) {
00138 
00146     stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr = 
00147       boost::make_shared<stdair::STDAIR_Service> (iLogParams);
00148 
00149     return lSTDAIR_Service_ptr;
00150   }
00151   
00152   // //////////////////////////////////////////////////////////////////////
00153   stdair::STDAIR_ServicePtr_T AIRSCHED_Service::
00154   initStdAirService (const stdair::BasLogParams& iLogParams,
00155                      const stdair::BasDBParams& iDBParams) {
00156 
00164     stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr = 
00165       boost::make_shared<stdair::STDAIR_Service> (iLogParams, iDBParams);
00166 
00167     return lSTDAIR_Service_ptr;
00168   }
00169   
00170   // ////////////////////////////////////////////////////////////////////
00171   void AIRSCHED_Service::initAirschedService() {
00172     // Do nothing at this stage. A sample BOM tree may be built by
00173     // calling the buildSampleBom() method
00174   }
00175 
00176   // ////////////////////////////////////////////////////////////////////
00177   void AIRSCHED_Service::
00178   parseAndLoad (const stdair::Filename_T& iScheduleInputFilename) {
00179 
00180     // Retrieve the BOM root object.
00181     assert (_airschedServiceContext != NULL);
00182     AIRSCHED_ServiceContext& lAIRSCHED_ServiceContext =
00183       *_airschedServiceContext;
00184     stdair::STDAIR_Service& lSTDAIR_Service =
00185       lAIRSCHED_ServiceContext.getSTDAIR_Service();
00186     stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
00187 
00188     // Parse the schedule input file, and generate the Inventories
00189     stdair::BasChronometer lINVGeneration; lINVGeneration.start();
00190     ScheduleParser::generateInventories (iScheduleInputFilename, lBomRoot);
00191     const double lGenerationMeasure = lINVGeneration.elapsed();
00192 
00193     // DEBUG
00194     STDAIR_LOG_DEBUG ("Inventory generation time: " << lGenerationMeasure);
00195   }
00196   
00197   // ////////////////////////////////////////////////////////////////////
00198   void AIRSCHED_Service::
00199   parseAndLoad (const stdair::Filename_T& iScheduleInputFilename,
00200                 const stdair::Filename_T& iODInputFilename) {
00201 
00202     // First, build the airline inventories from the schedule file
00203     parseAndLoad (iScheduleInputFilename);
00204 
00205     // Retrieve the BOM tree root
00206     assert (_airschedServiceContext != NULL);
00207     AIRSCHED_ServiceContext& lAIRSCHED_ServiceContext =
00208       *_airschedServiceContext;
00209     stdair::STDAIR_Service& lSTDAIR_Service =
00210       lAIRSCHED_ServiceContext.getSTDAIR_Service();
00211     stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
00212 
00213     // Parse the O&D input file, and generate the O&D periods
00214     stdair::BasChronometer lOnDGeneration; lOnDGeneration.start();
00215     OnDParser::generateOnDPeriods (iODInputFilename, lBomRoot);
00216     const double lGenerationMeasure = lOnDGeneration.elapsed();
00217 
00218     // DEBUG
00219     STDAIR_LOG_DEBUG ("O&D generation time: " << lGenerationMeasure);
00220   }
00221   
00222   // //////////////////////////////////////////////////////////////////////
00223   void AIRSCHED_Service::buildSampleBom() {
00224 
00225     // Retrieve the AirSched service context
00226     if (_airschedServiceContext == NULL) {
00227       throw stdair::NonInitialisedServiceException ("The AirSched service has "
00228                                                     "not been initialised");
00229     }
00230     assert (_airschedServiceContext != NULL);
00231 
00232     // Retrieve the AirSched service context and whether it owns the Stdair
00233     // service
00234     AIRSCHED_ServiceContext& lAIRSCHED_ServiceContext =
00235       *_airschedServiceContext;
00236     const bool doesOwnStdairService =
00237       lAIRSCHED_ServiceContext.getOwnStdairServiceFlag();
00238 
00239     // Retrieve the StdAir service object from the (AirSched) service context
00240     stdair::STDAIR_Service& lSTDAIR_Service =
00241       lAIRSCHED_ServiceContext.getSTDAIR_Service();
00242 
00247     if (doesOwnStdairService == true) {
00248       //
00249       lSTDAIR_Service.buildSampleBom();
00250     }
00251 
00268     stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
00269     SegmentPathGenerator::createSegmentPathNetwork (lBomRoot);
00270   }
00271 
00272   // ////////////////////////////////////////////////////////////////////
00273   std::string AIRSCHED_Service::
00274   jsonExport (const stdair::AirlineCode_T& iAirlineCode,
00275               const stdair::FlightNumber_T& iFlightNumber,
00276               const stdair::Date_T& iDepartureDate) const {
00277 
00278     // Retrieve the AirSched service context
00279     if (_airschedServiceContext == NULL) {
00280       throw stdair::NonInitialisedServiceException ("The AirSched service "
00281                                                     "has not been initialised");
00282     }
00283     assert (_airschedServiceContext != NULL);
00284 
00285     // Retrieve the StdAir service object from the (AirSched) service context
00286     AIRSCHED_ServiceContext& lAIRSCHED_ServiceContext =
00287       *_airschedServiceContext;
00288     stdair::STDAIR_Service& lSTDAIR_Service =
00289       lAIRSCHED_ServiceContext.getSTDAIR_Service();
00290 
00291     // Delegate the JSON export to the dedicated service
00292     return lSTDAIR_Service.jsonExport (iAirlineCode, iFlightNumber,
00293                                        iDepartureDate);
00294   }
00295   
00296   // //////////////////////////////////////////////////////////////////////
00297   std::string AIRSCHED_Service::csvDisplay() const {
00298 
00299     // Retrieve the AirSched service context
00300     if (_airschedServiceContext == NULL) {
00301       throw stdair::NonInitialisedServiceException ("The AirSched service has "
00302                                                     "not been initialised");
00303     }
00304     assert (_airschedServiceContext != NULL);
00305 
00306     // Retrieve the STDAIR service object from the (AirSched) service context
00307     AIRSCHED_ServiceContext& lAIRSCHED_ServiceContext =
00308       *_airschedServiceContext;
00309     stdair::STDAIR_Service& lSTDAIR_Service =
00310       lAIRSCHED_ServiceContext.getSTDAIR_Service();
00311 
00312     // Delegate the BOM building to the dedicated service
00313     return lSTDAIR_Service.csvDisplay();
00314   }
00315   
00316   // ////////////////////////////////////////////////////////////////////
00317   std::string AIRSCHED_Service::
00318   csvDisplay (const stdair::AirlineCode_T& iAirlineCode,
00319               const stdair::FlightNumber_T& iFlightNumber,
00320               const stdair::Date_T& iDepartureDate) const {
00321 
00322     // Retrieve the AirSched service context
00323     if (_airschedServiceContext == NULL) {
00324       throw stdair::NonInitialisedServiceException ("The AirSched service has "
00325                                                     "not been initialised");
00326     }
00327     assert (_airschedServiceContext != NULL);
00328 
00329     // Retrieve the STDAIR service object from the (AirSched) service context
00330     AIRSCHED_ServiceContext& lAIRSCHED_ServiceContext =
00331       *_airschedServiceContext;
00332     stdair::STDAIR_Service& lSTDAIR_Service =
00333       lAIRSCHED_ServiceContext.getSTDAIR_Service();
00334 
00335     // Delegate the BOM display to the dedicated service
00336     return lSTDAIR_Service.csvDisplay (iAirlineCode, iFlightNumber,
00337                                        iDepartureDate);
00338   }
00339   
00340   // ////////////////////////////////////////////////////////////////////
00341   void AIRSCHED_Service::simulate() {
00342 
00343     // Retrieve the AirSched service context
00344     if (_airschedServiceContext == NULL) {
00345       throw stdair::NonInitialisedServiceException ("The AirSched service has "
00346                                                     "not been initialised");
00347     }
00348     assert (_airschedServiceContext != NULL);
00349 
00350     // Retrieve the BOM tree root
00351     AIRSCHED_ServiceContext& lAIRSCHED_ServiceContext =
00352       *_airschedServiceContext;
00353     stdair::STDAIR_Service& lSTDAIR_Service =
00354       lAIRSCHED_ServiceContext.getSTDAIR_Service();
00355     stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
00356 
00357     // Call the underlying Use Case (command)
00358     stdair::BasChronometer lSimulateChronometer; lSimulateChronometer.start();
00359     Simulator::simulate (lBomRoot);
00360     const double lSimulateMeasure = lSimulateChronometer.elapsed();
00361 
00362     // DEBUG
00363     STDAIR_LOG_DEBUG ("Simulation: " << lSimulateMeasure << " - "
00364                       << lAIRSCHED_ServiceContext.display());
00365   }
00366 
00367   // ////////////////////////////////////////////////////////////////////
00368   void AIRSCHED_Service::
00369   buildSegmentPathList (stdair::TravelSolutionList_T& ioTravelSolutionList,
00370                         const stdair::BookingRequestStruct& iBookingRequest) {
00371 
00372     if (_airschedServiceContext == NULL) {
00373       throw stdair::NonInitialisedServiceException ("The AirSched service has "
00374                                                     "not been initialised");
00375     }
00376     assert (_airschedServiceContext != NULL);
00377 
00378     // Retrieve the BOM tree root
00379     AIRSCHED_ServiceContext& lAIRSCHED_ServiceContext =
00380       *_airschedServiceContext;
00381     stdair::STDAIR_Service& lSTDAIR_Service =
00382       lAIRSCHED_ServiceContext.getSTDAIR_Service();
00383     stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
00384     
00385     // Delegate the call to the dedicated command
00386     stdair::BasChronometer lBuildChronometer; lBuildChronometer.start();
00387     SegmentPathProvider::buildSegmentPathList (ioTravelSolutionList,
00388                                                lBomRoot, iBookingRequest);
00389     const double lBuildMeasure = lBuildChronometer.elapsed();
00390 
00391     // DEBUG
00392     STDAIR_LOG_DEBUG ("Segment-path build: " << lBuildMeasure << " - "
00393                       << lAIRSCHED_ServiceContext.display());
00394   }
00395 
00396 }