SearchController.java
package com.is.findyourplace.controller.gestioneRicerca;
import com.is.findyourplace.persistence.dto.LuogoDto;
import com.is.findyourplace.persistence.dto.RicercaDto;
import com.is.findyourplace.persistence.entity.LuogoTrovato;
import com.is.findyourplace.persistence.entity.Preferiti;
import com.is.findyourplace.service.gestioneRicerca.SavedPlacesService;
import com.is.findyourplace.service.gestioneRicerca.SearchService;
import com.is.findyourplace.service.gestioneUtenza.AccountService;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Gestisce la Ricerca.
*/
@Controller
public class SearchController {
/**
* Template per le chiamate REST utilizzato
* per comunicare con il server Flask.
*/
private final RestTemplate restTemplate = new RestTemplate();
/**
* Service usato per la ricerca.
*/
private final SearchService searchService;
/**
* Service dei luoghi preferiti.
*/
private final SavedPlacesService savedPlacesService;
/**
* Service per la gestione degli account.
*/
private final AccountService accountService;
/**
* Variabile usata per definire quando questo controller
* viene usato per un test.
*/
@Value("${app.testMode:false}")
private boolean testMode;
/**
* Costruttore del controller.
*
* @param searchService searchService
* @param savedPlacesService savedPlacesService
* @param accountService accountService
*/
public SearchController(final SearchService searchService,
final SavedPlacesService savedPlacesService,
final AccountService accountService) {
this.searchService = searchService;
this.savedPlacesService = savedPlacesService;
this.accountService = accountService;
}
/**
* Pagina che effettua la ricerca.
* @param ricercaDto Parametri passati dal form
* @param result Contiene gli errori
* @return 201 CREATED / 400 BAD REQUEST
*/
@PostMapping("/search")
@ResponseBody
public ResponseEntity<Map<String, Object>> search(
@Valid @ModelAttribute("ricerca") final RicercaDto ricercaDto,
final BindingResult result) {
Map<String, Object> response = new HashMap<>();
if (ricercaDto.getNumAbitantiMin() >= ricercaDto.getNumAbitantiMax()) {
result.rejectValue("numAbitantiMin", "null",
"Maggiore del numero abitanti massimo!");
result.rejectValue("numAbitantiMax", "null",
"Minore del numero abitanti minimo!");
}
if (result.hasErrors()) {
response.put("errors", result.getAllErrors());
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
Long idRicerca = searchService.saveRicerca(ricercaDto);
//Call al modulo di IA
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<RicercaDto> entity = new HttpEntity<>(ricercaDto, headers);
String flaskServerUrl = "http://127.0.0.1:5000/search-luoghi";
ResponseEntity<List<Map<String, Object>>> responseEntity;
if (!testMode) {
// Effettua una chiamata REST al server Flask
responseEntity =
restTemplate.exchange(
flaskServerUrl,
HttpMethod.POST,
entity,
new ParameterizedTypeReference<>() { }
);
} else {
responseEntity = ResponseEntity.ok()
.body(List.of(
new HashMap<>() {{
put("costoVita", "BASSO");
put("danger", 39.54139399955827);
put("latitude", 40.9045572);
put("longitude", 14.2901223);
put("nome", "Test");
put("numAbitanti", 74268);
put("numNegozi", 112);
put("numRistoranti", 96);
put("numScuole", 23);
put("qualityIndex", 37.66);
}})
);
}
List<Map<String, Object>> responseBody = responseEntity.getBody();
if (responseBody == null) {
return new ResponseEntity<>(response,
HttpStatus.INTERNAL_SERVER_ERROR);
}
for (Map<String, Object> luogo : responseBody) {
LuogoDto luogoDto = new LuogoDto();
luogoDto.setIdRicerca(idRicerca);
luogoDto.setNome((String) luogo.get("nome"));
luogoDto.setLatitude(
((Double) luogo.get("latitude")).floatValue());
luogoDto.setLongitude(
((Double) luogo.get("longitude")).floatValue());
luogoDto.setQualityIndex(
((Double) luogo.get("qualityIndex")).floatValue());
String costovita = (String) luogo.get("costoVita");
if (costovita.equals("BASSO")) {
luogoDto.setCostoVita(LuogoTrovato.CostoVita.BASSO);
} else if (costovita.equals("MEDIO")) {
luogoDto.setCostoVita(LuogoTrovato.CostoVita.MEDIO);
} else {
luogoDto.setCostoVita(LuogoTrovato.CostoVita.ALTO);
}
luogoDto.setDanger(((Double) luogo.get("danger")).floatValue());
luogoDto.setNumAbitanti((Integer) luogo.get("numAbitanti"));
luogoDto.setNumNegozi((Integer) luogo.get("numNegozi"));
luogoDto.setNumRistoranti((Integer) luogo.get("numRistoranti"));
luogoDto.setNumScuole((Integer) luogo.get("numScuole"));
searchService.saveLuogoDto(luogoDto);
}
response.put("ricerca", idRicerca);
return new ResponseEntity<>(response, HttpStatus.CREATED);
}
/**
* Pagina del risultato della ricerca effettuata.
* @param ricerca Id della ricerca
* @param model Model
* @return ricerca/ricercaResult.html
*/
@GetMapping("/searchResult")
public String searchResult(
@Valid @RequestParam final Long ricerca,
final Model model) {
Preferiti preferito;
List<LuogoDto> luoghi = searchService.findLuoghiByIdRicerca(ricerca);
if (luoghi.isEmpty()) {
model.addAttribute("errorMessage",
"La ricerca non possiede risultati!");
return "error";
}
Authentication auth =
SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth instanceof AnonymousAuthenticationToken) {
preferito = null;
} else {
preferito = savedPlacesService.findPreferito(
accountService.findByUsernameOrEmail(
auth.getName()
).getIdUtente(),
luoghi.get(0).getIdLuogo()
);
}
model.addAttribute("preferito", preferito);
model.addAttribute("luoghi", luoghi);
return "ricerca/ricercaResult";
}
}