test_class.declarator: router
test_class.modifier: @Mock
      private
test_class.original_string: @Mock
      private Router router;
test_class.type: Router
test_class.var_name: router
test_class.declarator: routingPlanConsumer
test_class.modifier: @Mock
      private
test_class.original_string: @Mock
      private RoutingPlanConsumer routingPlanConsumer;
test_class.type: RoutingPlanConsumer
test_class.var_name: routingPlanConsumer
test_class.declarator: vehicleRepository
test_class.modifier: @Mock
      private
test_class.original_string: @Mock
      private VehicleRepository vehicleRepository;
test_class.type: VehicleRepository
test_class.var_name: vehicleRepository
test_class.declarator: locationRepository
test_class.modifier: @Mock
      private
test_class.original_string: @Mock
      private LocationRepository locationRepository;
test_class.type: LocationRepository
test_class.var_name: locationRepository
test_class.declarator: routeArgumentCaptor
test_class.modifier: @Captor
      private
test_class.original_string: @Captor
      private ArgumentCaptor<RoutingPlan> routeArgumentCaptor;
test_class.type: ArgumentCaptor<RoutingPlan>
test_class.var_name: routeArgumentCaptor
test_class.declarator: routeListener
test_class.modifier: @InjectMocks
      private
test_class.original_string: @InjectMocks
      private RouteListener routeListener;
test_class.type: RouteListener
test_class.var_name: routeListener
test_class.file: optaweb-vehicle-routing-backend/src/test/java/org/optaweb/vehiclerouting/service/route/RouteListenerTest.java
test_class.identifier: RouteListenerTest
test_case.body: @Test
      void event_with_no_routes_should_be_consumed_as_an_empty_routing_plan() {
          final long vehicleId = 12;
          final Vehicle vehicle = VehicleFactory.testVehicle(vehicleId);
          when(vehicleRepository.find(vehicleId)).thenReturn(Optional.of(vehicle));
          RouteChangedEvent event = new RouteChangedEvent(
                  this,
                  Distance.ZERO,
                  singletonList(vehicleId),
                  null,
                  emptyList(),
                  emptyList());
          routeListener.onApplicationEvent(event);
          verifyNoInteractions(router);
  
          RoutingPlan routingPlan = verifyAndCaptureConsumedPlan();
          assertThat(routingPlan.vehicles()).containsExactly(vehicle);
          assertThat(routingPlan.depot()).isEmpty();
          assertThat(routingPlan.visits()).isEmpty();
          assertThat(routingPlan.routes()).isEmpty();
      }
test_case.class_method_signature: RouteListenerTest.event_with_no_routes_should_be_consumed_as_an_empty_routing_plan()
test_case.full_signature: @Test void event_with_no_routes_should_be_consumed_as_an_empty_routing_plan()
test_case.identifier: event_with_no_routes_should_be_consumed_as_an_empty_routing_plan
test_case.invocations: testVehicle thenReturn when find of singletonList emptyList emptyList onApplicationEvent verifyNoInteractions verifyAndCaptureConsumedPlan containsExactly assertThat vehicles isEmpty assertThat depot isEmpty assertThat visits isEmpty assertThat routes
test_case.modifiers: @Test
test_case.parameters: ()
test_case.return: void
test_case.signature: void event_with_no_routes_should_be_consumed_as_an_empty_routing_plan()
focal_class.declarator: logger = LoggerFactory.getLogger(RouteListener.class)
focal_class.modifier: private static final
focal_class.original_string: private static final Logger logger = LoggerFactory.getLogger(RouteListener.class);
focal_class.type: Logger
focal_class.var_name: logger
focal_class.declarator: router
focal_class.modifier: private final
focal_class.original_string: private final Router router;
focal_class.type: Router
focal_class.var_name: router
focal_class.declarator: routingPlanConsumer
focal_class.modifier: private final
focal_class.original_string: private final RoutingPlanConsumer routingPlanConsumer;
focal_class.type: RoutingPlanConsumer
focal_class.var_name: routingPlanConsumer
focal_class.declarator: vehicleRepository
focal_class.modifier: private final
focal_class.original_string: private final VehicleRepository vehicleRepository;
focal_class.type: VehicleRepository
focal_class.var_name: vehicleRepository
focal_class.declarator: locationRepository
focal_class.modifier: private final
focal_class.original_string: private final LocationRepository locationRepository;
focal_class.type: LocationRepository
focal_class.var_name: locationRepository
focal_class.declarator: bestRoutingPlan
focal_class.modifier: private
focal_class.original_string: private RoutingPlan bestRoutingPlan;
focal_class.type: RoutingPlan
focal_class.var_name: bestRoutingPlan
focal_class.file: optaweb-vehicle-routing-backend/src/main/java/org/optaweb/vehiclerouting/service/route/RouteListener.java
focal_class.identifier: RouteListener
focal_class.interfaces: implements ApplicationListener<RouteChangedEvent>
focal_class.class_method_signature: RouteListener.RouteListener(
              Router router,
              RoutingPlanConsumer routingPlanConsumer,
              VehicleRepository vehicleRepository,
              LocationRepository locationRepository)
focal_class.full_signature: @Autowired  RouteListener(
              Router router,
              RoutingPlanConsumer routingPlanConsumer,
              VehicleRepository vehicleRepository,
              LocationRepository locationRepository)
focal_class.identifier: RouteListener
focal_class.modifiers: @Autowired
focal_class.parameters: (
              Router router,
              RoutingPlanConsumer routingPlanConsumer,
              VehicleRepository vehicleRepository,
              LocationRepository locationRepository)
focal_class.signature:  RouteListener(
              Router router,
              RoutingPlanConsumer routingPlanConsumer,
              VehicleRepository vehicleRepository,
              LocationRepository locationRepository)
focal_class.class_method_signature: RouteListener.onApplicationEvent(RouteChangedEvent event)
focal_class.full_signature: @Override public void onApplicationEvent(RouteChangedEvent event)
focal_class.identifier: onApplicationEvent
focal_class.modifiers: @Override public
focal_class.parameters: (RouteChangedEvent event)
focal_class.return: void
focal_class.signature: void onApplicationEvent(RouteChangedEvent event)
focal_class.class_method_signature: RouteListener.findVehicleById(long id)
focal_class.full_signature: private Vehicle findVehicleById(long id)
focal_class.identifier: findVehicleById
focal_class.modifiers: private
focal_class.parameters: (long id)
focal_class.return: Vehicle
focal_class.signature: Vehicle findVehicleById(long id)
focal_class.class_method_signature: RouteListener.findLocationById(long id)
focal_class.full_signature: private Location findLocationById(long id)
focal_class.identifier: findLocationById
focal_class.modifiers: private
focal_class.parameters: (long id)
focal_class.return: Location
focal_class.signature: Location findLocationById(long id)
focal_class.class_method_signature: RouteListener.track(Location depot, List<Location> route)
focal_class.full_signature: private List<List<Coordinates>> track(Location depot, List<Location> route)
focal_class.identifier: track
focal_class.modifiers: private
focal_class.parameters: (Location depot, List<Location> route)
focal_class.return: List<List<Coordinates>>
focal_class.signature: List<List<Coordinates>> track(Location depot, List<Location> route)
focal_class.class_method_signature: RouteListener.getBestRoutingPlan()
focal_class.full_signature: public RoutingPlan getBestRoutingPlan()
focal_class.identifier: getBestRoutingPlan
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: RoutingPlan
focal_class.signature: RoutingPlan getBestRoutingPlan()
focal_method.body: @Override
      public void onApplicationEvent(RouteChangedEvent event) {
          // TODO persist the best solution
          Location depot = event.depotId().flatMap(locationRepository::find).orElse(null);
          try {
              // TODO Introduce problem revision (every modification increases revision number, event will only
              //  be published if revision numbers match) to avoid looking for missing/extra vehicles/visits.
              //  This will also make it possible to get rid of the try-catch approach.
              Map<Long, Vehicle> vehicleMap = event.vehicleIds().stream()
                      .collect(toMap(vehicleId -> vehicleId, this::findVehicleById));
              Map<Long, Location> visitMap = event.visitIds().stream()
                      .collect(toMap(visitId -> visitId, this::findLocationById));
  
              List<RouteWithTrack> routes = event.routes().stream()
                      // list of deep locations
                      .map(shallowRoute -> new Route(
                              vehicleMap.get(shallowRoute.vehicleId),
                              findLocationById(shallowRoute.depotId),
                              shallowRoute.visitIds.stream()
                                      .map(visitMap::get)
                                      .collect(toList())))
                      // add tracks
                      .map(route -> new RouteWithTrack(route, track(route.depot(), route.visits())))
                      .collect(toList());
              bestRoutingPlan = new RoutingPlan(
                      event.distance(),
                      new ArrayList<>(vehicleMap.values()),
                      depot,
                      new ArrayList<>(visitMap.values()),
                      routes);
              routingPlanConsumer.consumePlan(bestRoutingPlan);
          } catch (IllegalStateException e) {
              logger.warn("Discarding an outdated routing plan: {}", e.toString());
          }
      }
focal_method.class_method_signature: RouteListener.onApplicationEvent(RouteChangedEvent event)
focal_method.full_signature: @Override public void onApplicationEvent(RouteChangedEvent event)
focal_method.identifier: onApplicationEvent
focal_method.invocations: orElse flatMap depotId collect stream vehicleIds toMap collect stream visitIds toMap collect map map stream routes get findLocationById collect map stream toList track depot visits toList distance values values consumePlan warn toString
focal_method.modifiers: @Override public
focal_method.parameters: (RouteChangedEvent event)
focal_method.return: void
focal_method.signature: void onApplicationEvent(RouteChangedEvent event)