Commit d91eb063 by Rubén Ramírez

fix: [RecursosController]: Corregido el controlador debido a la incorrecta división por capas

parent 069bc18e
...@@ -3,6 +3,7 @@ package com.ujaen.tfg.mangaffinity.rest; ...@@ -3,6 +3,7 @@ package com.ujaen.tfg.mangaffinity.rest;
import com.ujaen.tfg.mangaffinity.entidades.*; import com.ujaen.tfg.mangaffinity.entidades.*;
import com.ujaen.tfg.mangaffinity.excepciones.CapituloNoExiste; import com.ujaen.tfg.mangaffinity.excepciones.CapituloNoExiste;
import com.ujaen.tfg.mangaffinity.excepciones.RecursoNoExiste; import com.ujaen.tfg.mangaffinity.excepciones.RecursoNoExiste;
import com.ujaen.tfg.mangaffinity.excepciones.RecursoYaExiste;
import com.ujaen.tfg.mangaffinity.rest.DTO.*; import com.ujaen.tfg.mangaffinity.rest.DTO.*;
import com.ujaen.tfg.mangaffinity.servicios.ServicioRecursos; import com.ujaen.tfg.mangaffinity.servicios.ServicioRecursos;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -26,8 +27,17 @@ public class RecursosController { ...@@ -26,8 +27,17 @@ public class RecursosController {
@Autowired @Autowired
private Mapper mapper; private Mapper mapper;
/**
* Crea un nuevo recurso en el sistema.
* Devuelve:
* - 201 CREATED si el recurso se crea correctamente.
* - 400 BAD REQUEST si el formato de la imagen no es válido.
* - 409 CONFLICT si el recurso ya existe.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
* Permite cargar una imagen opcional en formato JPEG o PNG junto con los datos del recurso.
*/
@PostMapping(value = "/", consumes = {"multipart/form-data"}) @PostMapping(value = "/", consumes = {"multipart/form-data"})
public ResponseEntity<String> crearRecurso( public ResponseEntity<Void> crearRecurso(
@RequestPart("recurso") DTORecurso recursoDTO, @RequestPart("recurso") DTORecurso recursoDTO,
@RequestPart(value = "foto", required = false) MultipartFile foto) { @RequestPart(value = "foto", required = false) MultipartFile foto) {
try { try {
...@@ -36,89 +46,146 @@ public class RecursosController { ...@@ -36,89 +46,146 @@ public class RecursosController {
if (foto != null && !foto.isEmpty()) { if (foto != null && !foto.isEmpty()) {
String mimeType = foto.getContentType(); String mimeType = foto.getContentType();
if (mimeType == null || (!mimeType.equals("image/jpeg") && !mimeType.equals("image/png"))) { if (mimeType == null || (!mimeType.equals("image/jpeg") && !mimeType.equals("image/png"))) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Solo se permiten imágenes JPEG o PNG."); return ResponseEntity.badRequest().build();
} }
fotoBytes = foto.getBytes(); fotoBytes = foto.getBytes();
} }
Recurso nuevoRecurso = new Recurso( Recurso nuevoRecurso = mapper.entity(recursoDTO);
recursoDTO.getTitulo(), nuevoRecurso.setFoto(fotoBytes);
recursoDTO.getDescripcion(),
recursoDTO.getFechaPublicacion(),
recursoDTO.getAutor(),
fotoBytes
);
nuevoRecurso.setGeneros(recursoDTO.getGeneros());
servicioRecursos.crearRecurso(nuevoRecurso); servicioRecursos.crearRecurso(nuevoRecurso);
return ResponseEntity.status(HttpStatus.CREATED).build(); return ResponseEntity.status(HttpStatus.CREATED).build();
} catch (RecursoYaExiste e) {
return ResponseEntity.status(HttpStatus.CONFLICT).build();
} catch (IOException e) { } catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} }
} }
/**
* Busca recursos por título.
* Devuelve:
* - 200 OK con la lista de recursos si hay coincidencias.
* - 204 NO CONTENT si no se encuentran recursos con ese título.
* Convierte los recursos encontrados a DTO antes de retornarlos.
*/
@GetMapping("/titulo/{titulo}") @GetMapping("/titulo/{titulo}")
public ResponseEntity<List<DTORecurso>> buscarPorTitulo(@PathVariable String titulo) { public ResponseEntity<List<DTORecurso>> buscarPorTitulo(@PathVariable String titulo) {
try {
List<Recurso> recursos = servicioRecursos.buscarRecursoPorTitulo(titulo); List<Recurso> recursos = servicioRecursos.buscarRecursoPorTitulo(titulo);
if (recursos.isEmpty()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Collections.emptyList()); if (recursos.isEmpty()) return ResponseEntity.noContent().build();
}
List<DTORecurso> dtoRecursos = recursos.stream().map(mapper::dto).toList(); List<DTORecurso> dtoRecursos = recursos.stream().map(mapper::dto).toList();
return ResponseEntity.ok(dtoRecursos); return ResponseEntity.ok(dtoRecursos);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
} }
/**
* Obtiene los capítulos de un recurso separados por tipo (MANGA o ANIME).
* Devuelve:
* - 200 OK con los capítulos organizados en un mapa por tipo.
* - 204 NO CONTENT si el recurso no tiene capítulos de ningún tipo.
* - 404 NOT FOUND si el recurso no existe.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
*/
@GetMapping("/{id}/capitulos/tipos") @GetMapping("/{id}/capitulos/tipos")
public ResponseEntity<Map<String, List<DTOCapitulo>>> obtenerCapitulosPorTipo(@PathVariable Long id) { public ResponseEntity<Map<String, List<DTOCapitulo>>> obtenerCapitulosPorTipo(@PathVariable Long id) {
try { try {
if (!servicioRecursos.existeRecurso(id)) return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); // 404 Not Found
List<Capitulo> capitulosManga = servicioRecursos.obtenerCapitulosDeRecursoPorTipo(id, TipoRecurso.MANGA); List<Capitulo> capitulosManga = servicioRecursos.obtenerCapitulosDeRecursoPorTipo(id, TipoRecurso.MANGA);
List<Capitulo> capitulosAnime = servicioRecursos.obtenerCapitulosDeRecursoPorTipo(id, TipoRecurso.ANIME); List<Capitulo> capitulosAnime = servicioRecursos.obtenerCapitulosDeRecursoPorTipo(id, TipoRecurso.ANIME);
if (capitulosManga.isEmpty() && capitulosAnime.isEmpty()) return ResponseEntity.noContent().build();
Map<String, List<DTOCapitulo>> response = Map.of( Map<String, List<DTOCapitulo>> response = Map.of(
"MANGA", capitulosManga.stream().map(mapper::dto).toList(), "MANGA", capitulosManga.stream().map(mapper::dto).toList(),
"ANIME", capitulosAnime.stream().map(mapper::dto).toList() "ANIME", capitulosAnime.stream().map(mapper::dto).toList()
); );
return ResponseEntity.ok(response); return ResponseEntity.ok(response);
} catch (RecursoNoExiste e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
} catch (Exception e) { } catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} }
} }
/**
* Busca recursos por género.
* Devuelve:
* - 200 OK con la lista de recursos si hay coincidencias.
* - 204 NO CONTENT si no se encuentran recursos en el género especificado.
* - 400 BAD REQUEST si el género proporcionado no es válido.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
*/
@GetMapping("/genero/{genero}") @GetMapping("/genero/{genero}")
public ResponseEntity<List<DTORecurso>> buscarPorGenero(@PathVariable Genero genero) { public ResponseEntity<List<DTORecurso>> buscarPorGenero(@PathVariable String genero) {
try {
Genero generoEnum;
try { try {
List<Recurso> recursos = servicioRecursos.buscarRecursoPorGenero(genero); generoEnum = Genero.valueOf(genero.toUpperCase());
} catch (IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
List<Recurso> recursos = servicioRecursos.buscarRecursoPorGenero(generoEnum);
if (recursos.isEmpty()) return ResponseEntity.noContent().build();
List<DTORecurso> dtoRecursos = recursos.stream().map(mapper::dto).toList(); List<DTORecurso> dtoRecursos = recursos.stream().map(mapper::dto).toList();
return ResponseEntity.ok(dtoRecursos); return ResponseEntity.ok(dtoRecursos);
} catch (Exception e) { } catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} }
} }
/**
* Busca recursos publicados dentro de un rango de fechas.
* Devuelve:
* - 200 OK con la lista de recursos si hay coincidencias.
* - 204 NO CONTENT si no se encuentran recursos en el rango especificado.
* - 400 BAD REQUEST si la fecha de inicio es posterior a la fecha de fin.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
*/
@GetMapping("/fecha") @GetMapping("/fecha")
public ResponseEntity<List<DTORecurso>> buscarPorRangoFechas(@RequestParam LocalDate inicio, @RequestParam LocalDate fin) { public ResponseEntity<List<DTORecurso>> buscarPorRangoFechas(
@RequestParam(required = false) LocalDate inicio,
@RequestParam(required = false) LocalDate fin) {
try { try {
if (inicio == null) inicio = LocalDate.of(1900, 1, 1);
if (fin == null) fin = LocalDate.now();
if (inicio.isAfter(fin)) return ResponseEntity.badRequest().build();
List<Recurso> recursos = servicioRecursos.buscarRecursoPorRangoFechas(inicio, fin); List<Recurso> recursos = servicioRecursos.buscarRecursoPorRangoFechas(inicio, fin);
if (recursos.isEmpty()) return ResponseEntity.noContent().build();
List<DTORecurso> dtoRecursos = recursos.stream().map(mapper::dto).toList(); List<DTORecurso> dtoRecursos = recursos.stream().map(mapper::dto).toList();
return ResponseEntity.ok(dtoRecursos); return ResponseEntity.ok(dtoRecursos);
} catch (Exception e) { } catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} }
} }
/**
* Busca recursos por autor.
* Devuelve:
* - 200 OK con la lista de recursos si hay coincidencias.
* - 204 NO CONTENT si no se encuentran recursos del autor especificado.
* - 400 BAD REQUEST si el nombre del autor es nulo o vacío.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
*/
@GetMapping("/autor/{autor}") @GetMapping("/autor/{autor}")
public ResponseEntity<List<DTORecurso>> buscarPorAutor(@PathVariable String autor) { public ResponseEntity<List<DTORecurso>> buscarPorAutor(@PathVariable String autor) {
try { try {
if (autor == null || autor.trim().isEmpty()) return ResponseEntity.badRequest().build();
List<Recurso> recursos = servicioRecursos.buscarRecursoPorAutor(autor); List<Recurso> recursos = servicioRecursos.buscarRecursoPorAutor(autor);
if (recursos.isEmpty()) return ResponseEntity.noContent().build();
List<DTORecurso> dtoRecursos = recursos.stream().map(mapper::dto).toList(); List<DTORecurso> dtoRecursos = recursos.stream().map(mapper::dto).toList();
return ResponseEntity.ok(dtoRecursos); return ResponseEntity.ok(dtoRecursos);
} catch (Exception e) { } catch (Exception e) {
...@@ -126,78 +193,99 @@ public class RecursosController { ...@@ -126,78 +193,99 @@ public class RecursosController {
} }
} }
/**
* Busca un recurso por su ID.
* Devuelve:
* - 200 OK con el recurso si existe.
* - 404 NOT FOUND si el recurso no está registrado.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
*/
@GetMapping("/{id}") @GetMapping("/{id}")
public ResponseEntity<DTORecurso> buscarRecursoPorId(@PathVariable Long id) { public ResponseEntity<DTORecurso> buscarRecursoPorId(@PathVariable Long id) {
try { try {
Recurso recurso = servicioRecursos.buscarRecursoPorId(id); Recurso recurso = servicioRecursos.buscarRecursoPorId(id);
if (recurso == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
return ResponseEntity.ok(mapper.dto(recurso)); return ResponseEntity.ok(mapper.dto(recurso));
} catch (RecursoNoExiste e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
} catch (Exception e) { } catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} }
} }
/**
* Elimina un recurso del sistema por su ID.
* Devuelve:
* - 204 NO CONTENT si el recurso se elimina correctamente.
* - 404 NOT FOUND si el recurso no existe.
* - 403 FORBIDDEN si el usuario no tiene permisos para eliminarlo.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
*/
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ResponseEntity<Void> borrarRecurso(@PathVariable Long id) { public ResponseEntity<Void> borrarRecurso(@PathVariable Long id) {
try { try {
Recurso recurso = servicioRecursos.buscarRecursoPorId(id);
if (recurso == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
servicioRecursos.borrarRecurso(id); servicioRecursos.borrarRecurso(id);
return ResponseEntity.noContent().build(); return ResponseEntity.noContent().build();
} catch (RecursoNoExiste e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
} catch (SecurityException e) { } catch (SecurityException e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
} catch (Exception e) { } catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} }
} }
/**
* Modifica un recurso existente en el sistema.
* Devuelve:
* - 200 OK con el recurso modificado si la actualización es exitosa.
* - 400 BAD REQUEST si el formato de la imagen no es válido.
* - 404 NOT FOUND si el recurso no existe.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
*/
@PutMapping(value = "/{id}", consumes = {"multipart/form-data"}) @PutMapping(value = "/{id}", consumes = {"multipart/form-data"})
public ResponseEntity<DTORecurso> modificarRecurso( public ResponseEntity<DTORecurso> modificarRecurso(
@PathVariable Long id, @PathVariable Long id,
@RequestPart("recurso") DTORecurso dtoRecurso, @RequestPart("recurso") DTORecurso dtoRecurso,
@RequestPart(value = "foto", required = false) MultipartFile foto) { @RequestPart(value = "foto", required = false) MultipartFile foto) {
try { try {
Recurso recursoExistente = servicioRecursos.buscarRecursoPorId(id); byte[] fotoBytes = null;
if (recursoExistente == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
// Si hay una nueva imagen, actualizarla
if (foto != null && !foto.isEmpty()) { if (foto != null && !foto.isEmpty()) {
String mimeType = foto.getContentType(); String mimeType = Optional.ofNullable(foto.getContentType()).orElse("");
if (mimeType == null || (!mimeType.equals("image/jpeg") && !mimeType.equals("image/png"))) { if (!mimeType.equals("image/jpeg") && !mimeType.equals("image/png")) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); return ResponseEntity.badRequest().build();
} }
recursoExistente.setFoto(foto.getBytes()); fotoBytes = foto.getBytes();
} }
// Actualizar otros campos Recurso recursoModificado = servicioRecursos.modificarRecurso(
recursoExistente.setTitulo(dtoRecurso.getTitulo()); id,
recursoExistente.setDescripcion(dtoRecurso.getDescripcion()); mapper.entity(dtoRecurso),
recursoExistente.setFechaPublicacion(dtoRecurso.getFechaPublicacion()); fotoBytes
recursoExistente.setAutor(dtoRecurso.getAutor()); );
recursoExistente.setGeneros(dtoRecurso.getGeneros());
// Guardar cambios en la BD
Recurso recursoModificado = servicioRecursos.modificarRecurso(id, recursoExistente);
return ResponseEntity.ok(mapper.dto(recursoModificado)); return ResponseEntity.ok(mapper.dto(recursoModificado));
} catch (IOException e) { } catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} catch (RecursoNoExiste e) { } catch (RecursoNoExiste e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); return ResponseEntity.notFound().build();
} }
} }
/**
* Obtiene la lista de todos los recursos disponibles.
* Devuelve:
* - 200 OK con la lista de recursos si existen.
* - 204 NO CONTENT si no hay recursos disponibles.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
*/
@GetMapping @GetMapping
public ResponseEntity<List<DTORecurso>> obtenerRecursos() { public ResponseEntity<List<DTORecurso>> obtenerRecursos() {
try { try {
List<Recurso> recursos = servicioRecursos.obtenerListadoRecursos(); List<Recurso> recursos = servicioRecursos.obtenerListadoRecursos();
if (recursos.isEmpty()) return ResponseEntity.noContent().build();
List<DTORecurso> dtoRecursos = recursos.stream().map(mapper::dto).toList(); List<DTORecurso> dtoRecursos = recursos.stream().map(mapper::dto).toList();
return ResponseEntity.ok(dtoRecursos); return ResponseEntity.ok(dtoRecursos);
} catch (Exception e) { } catch (Exception e) {
...@@ -205,33 +293,46 @@ public class RecursosController { ...@@ -205,33 +293,46 @@ public class RecursosController {
} }
} }
/**
* Añade un nuevo capítulo a un recurso.
* Devuelve:
* - 201 CREATED si el capítulo se añade correctamente.
* - 404 NOT FOUND si el recurso no existe.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
*/
@PostMapping("/{id}/capitulos") @PostMapping("/{id}/capitulos")
public ResponseEntity<String> anadirCapitulo(@PathVariable Long id, @RequestBody DTOCapitulo dtoCapitulo) { public ResponseEntity<Void> anadirCapitulo(@PathVariable Long id, @RequestBody DTOCapitulo dtoCapitulo) {
try { try {
Recurso recurso = servicioRecursos.buscarRecursoPorId(id); Recurso recurso = servicioRecursos.buscarRecursoPorId(id);
if (recurso == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Recurso no encontrado");
}
Capitulo nuevoCapitulo = mapper.entity(dtoCapitulo, recurso); Capitulo nuevoCapitulo = mapper.entity(dtoCapitulo, recurso);
servicioRecursos.anadirCapitulo(id, nuevoCapitulo); servicioRecursos.anadirCapitulo(id, nuevoCapitulo);
return ResponseEntity.status(HttpStatus.CREATED).body("Capítulo añadido correctamente"); return ResponseEntity.status(HttpStatus.CREATED).build();
} catch (RecursoNoExiste e) { } catch (RecursoNoExiste e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Recurso no existe"); return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error interno del servidor: " + e.getMessage());
} }
} }
/**
* Obtiene la lista de capítulos de un recurso.
* Devuelve:
* - 200 OK con la lista de capítulos si existen.
* - 204 NO CONTENT si el recurso no tiene capítulos.
* - 404 NOT FOUND si el recurso no existe.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
*/
@GetMapping("/{id}/capitulos") @GetMapping("/{id}/capitulos")
public ResponseEntity<List<DTOCapitulo>> obtenerCapitulosDeRecurso(@PathVariable Long id) { public ResponseEntity<List<DTOCapitulo>> obtenerCapitulosDeRecurso(@PathVariable Long id) {
try { try {
List<Capitulo> capitulos = servicioRecursos.obtenerCapitulosDeRecurso(id); List<Capitulo> capitulos = servicioRecursos.obtenerCapitulosDeRecurso(id);
List<DTOCapitulo> dtoCapitulos = capitulos.stream().map(mapper::dto).toList(); if (capitulos.isEmpty()) return ResponseEntity.noContent().build();
List<DTOCapitulo> dtoCapitulos = capitulos.stream().map(mapper::dto).toList();
return ResponseEntity.ok(dtoCapitulos); return ResponseEntity.ok(dtoCapitulos);
} catch (RecursoNoExiste e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Collections.emptyList());
} catch (Exception e) { } catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} }
...@@ -242,113 +343,61 @@ public class RecursosController { ...@@ -242,113 +343,61 @@ public class RecursosController {
@PathVariable Long recursoId, @PathVariable Long recursoId,
@PathVariable Long id, @PathVariable Long id,
@RequestBody DTOCapitulo dtoCapitulo) { @RequestBody DTOCapitulo dtoCapitulo) {
if (!id.equals(dtoCapitulo.getId())) return ResponseEntity.badRequest().build();
if (!id.equals(dtoCapitulo.getId())) {
return ResponseEntity.badRequest().build();
}
try { try {
Recurso recurso = servicioRecursos.buscarRecursoPorId(recursoId); Capitulo capituloModificado = mapper.entity(dtoCapitulo, servicioRecursos.buscarRecursoPorId(recursoId));
if (recurso == null) { servicioRecursos.modificarCapitulo(recursoId, capituloModificado);
return ResponseEntity.notFound().build(); return ResponseEntity.ok(mapper.dto(capituloModificado));
} } catch (RecursoNoExiste | CapituloNoExiste e) {
Capitulo capitulo = servicioRecursos.buscarCapituloPorId(id);
capitulo.setNumero(dtoCapitulo.getNumero());
capitulo.setTitulo(dtoCapitulo.getTitulo());
capitulo.setTipo(dtoCapitulo.getTipo());
capitulo.setActivo(dtoCapitulo.getActivo());
List<FuenteCapitulo> fuentesActuales = new ArrayList<>(capitulo.getFuentes());
List<FuenteCapitulo> fuentesAEliminar = new ArrayList<>();
for (FuenteCapitulo fuenteExistente : fuentesActuales) {
boolean sigueExistiendo = dtoCapitulo.getFuentes().stream()
.anyMatch(f -> f.getNombreFuente().equals(fuenteExistente.getNombreFuente()));
if (!sigueExistiendo) {
fuentesAEliminar.add(fuenteExistente);
}
}
for (FuenteCapitulo fuente : fuentesAEliminar) {
capitulo.getFuentes().remove(fuente);
servicioRecursos.eliminarFuente(fuente.getId());
}
for (DTOFuenteCapitulo dtoFuente : dtoCapitulo.getFuentes()) {
FuenteCapitulo fuenteExistente = fuentesActuales.stream()
.filter(f -> f.getNombreFuente().equals(dtoFuente.getNombreFuente()))
.findFirst()
.orElse(null);
if (fuenteExistente != null) {
if (!fuenteExistente.getUrlFuente().equals(dtoFuente.getUrlFuente())) {
fuenteExistente.setUrlFuente(dtoFuente.getUrlFuente());
servicioRecursos.actualizarFuente(fuenteExistente);
}
} else {
FuenteCapitulo nuevaFuente = new FuenteCapitulo();
nuevaFuente.setNombreFuente(dtoFuente.getNombreFuente());
nuevaFuente.setUrlFuente(dtoFuente.getUrlFuente());
nuevaFuente.setCapitulo(capitulo);
servicioRecursos.agregarFuente(nuevaFuente);
capitulo.getFuentes().add(nuevaFuente);
}
}
servicioRecursos.modificarCapitulo(capitulo);
return ResponseEntity.ok(mapper.dto(capitulo));
} catch (CapituloNoExiste e) {
return ResponseEntity.notFound().build(); return ResponseEntity.notFound().build();
} catch (Exception e) { } catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} }
} }
/**
* Obtiene un capítulo específico de un recurso por su ID.
* Devuelve:
* - 200 OK con el capítulo si existe.
* - 404 NOT FOUND si el recurso o el capítulo no existen, o si el capítulo no pertenece al recurso indicado.
* - 500 INTERNAL SERVER ERROR en caso de error inesperado.
*/
@GetMapping("/{recursoId}/capitulos/{capituloId}") @GetMapping("/{recursoId}/capitulos/{capituloId}")
public ResponseEntity<DTOCapitulo> obtenerCapituloPorId( public ResponseEntity<DTOCapitulo> obtenerCapituloPorId(
@PathVariable Long recursoId, @PathVariable Long recursoId,
@PathVariable Long capituloId) { @PathVariable Long capituloId) {
try { try {
// Verificar si el recurso existe
Recurso recurso = servicioRecursos.buscarRecursoPorId(recursoId); Recurso recurso = servicioRecursos.buscarRecursoPorId(recursoId);
if (recurso == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.build(); // Recurso no encontrado
}
Capitulo capitulo = servicioRecursos.buscarCapituloPorId(capituloId); Capitulo capitulo = servicioRecursos.buscarCapituloPorId(capituloId);
if (capitulo == null || !capitulo.getRecurso().getId().equals(recursoId)) { if (!capitulo.getRecurso().getId().equals(recursoId)) return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.build(); // Capítulo no encontrado o no pertenece al recurso
}
return ResponseEntity.ok(mapper.dto(capitulo)); return ResponseEntity.ok(mapper.dto(capitulo));
} catch (RecursoNoExiste | CapituloNoExiste e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
} catch (Exception e) { } catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); // Error interno del servidor
} }
} }
/**
* Obtiene la lista de todos los géneros disponibles.
* Devuelve:
* - 200 OK con la lista de géneros si existen.
* - 204 NO CONTENT si no hay géneros disponibles.
* - 500 INTERNAL SERVER ERROR en caso de fallo inesperado.
*/
@GetMapping("/generos") @GetMapping("/generos")
public ResponseEntity<List<String>> obtenerGeneros() { public ResponseEntity<List<String>> obtenerGeneros() {
try { try {
List<String> generos = servicioRecursos.obtenerGeneros(); List<String> generos = servicioRecursos.obtenerGeneros();
if (generos.isEmpty()) return ResponseEntity.noContent().build();
return ResponseEntity.ok(generos); return ResponseEntity.ok(generos);
} catch (Exception e) { } catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} }
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment