Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Rubén Ramírez
/
MangAffinity
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
98238240
authored
Mar 09, 2025
by
Rubén Ramírez
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
feat: [Capitulo]: Añadidos métodos para obtener y trabajar con capítulos
parent
1f435592
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
296 additions
and
57 deletions
src/main/java/com/ujaen/tfg/mangaffinity/entidades/Recurso.java
src/main/java/com/ujaen/tfg/mangaffinity/repositorios/RepositorioRecurso.java
src/main/java/com/ujaen/tfg/mangaffinity/rest/RecursosController.java
src/main/java/com/ujaen/tfg/mangaffinity/seguridad/ServicioSeguridad.java
src/main/java/com/ujaen/tfg/mangaffinity/servicios/ServicioRecursos.java
src/main/java/com/ujaen/tfg/mangaffinity/entidades/Recurso.java
View file @
98238240
...
@@ -49,9 +49,11 @@ public class Recurso {
...
@@ -49,9 +49,11 @@ public class Recurso {
private
Set
<
Genero
>
generos
=
new
HashSet
<>();
private
Set
<
Genero
>
generos
=
new
HashSet
<>();
// Relación con Capítulo; un recurso tiene varios capítulos
@OneToMany
(
mappedBy
=
"recurso"
,
cascade
=
CascadeType
.
ALL
,
orphanRemoval
=
true
)
@OneToMany
(
mappedBy
=
"recurso"
)
private
List
<
Capitulo
>
capitulosManga
=
new
ArrayList
<>();
private
List
<
Capitulo
>
capitulos
=
new
ArrayList
<>();
@OneToMany
(
mappedBy
=
"recurso"
,
cascade
=
CascadeType
.
ALL
,
orphanRemoval
=
true
)
private
List
<
Capitulo
>
capitulosAnime
=
new
ArrayList
<>();
public
Recurso
(
String
titulo
,
String
descripcion
,
LocalDate
fechaPublicacion
,
String
autor
,
String
fotoUrl
)
{
public
Recurso
(
String
titulo
,
String
descripcion
,
LocalDate
fechaPublicacion
,
String
autor
,
String
fotoUrl
)
{
this
.
titulo
=
titulo
;
this
.
titulo
=
titulo
;
...
...
src/main/java/com/ujaen/tfg/mangaffinity/repositorios/RepositorioRecurso.java
View file @
98238240
...
@@ -70,6 +70,9 @@ public class RepositorioRecurso {
...
@@ -70,6 +70,9 @@ public class RepositorioRecurso {
@Transactional
@Transactional
public
void
borrarRecurso
(
Recurso
recurso
)
{
public
void
borrarRecurso
(
Recurso
recurso
)
{
recurso
=
em
.
merge
(
recurso
);
recurso
=
em
.
merge
(
recurso
);
recurso
.
getCapitulosManga
().
clear
();
recurso
.
getCapitulosAnime
().
clear
();
em
.
flush
();
em
.
remove
(
recurso
);
em
.
remove
(
recurso
);
}
}
...
@@ -80,8 +83,6 @@ public class RepositorioRecurso {
...
@@ -80,8 +83,6 @@ public class RepositorioRecurso {
@Transactional
(
readOnly
=
true
)
@Transactional
(
readOnly
=
true
)
public
List
<
Recurso
>
listarRecursos
()
{
public
List
<
Recurso
>
listarRecursos
()
{
return
em
.
createQuery
(
"SELECT r FROM Recurso r"
,
Recurso
.
class
)
return
em
.
createQuery
(
"SELECT r FROM Recurso r"
,
Recurso
.
class
).
getResultList
();
.
setMaxResults
(
15
)
.
getResultList
();
}
}
}
}
\ No newline at end of file
src/main/java/com/ujaen/tfg/mangaffinity/rest/RecursosController.java
View file @
98238240
...
@@ -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.Capitulo
;
import
com.ujaen.tfg.mangaffinity.entidades.Capitulo
;
import
com.ujaen.tfg.mangaffinity.entidades.Genero
;
import
com.ujaen.tfg.mangaffinity.entidades.Genero
;
import
com.ujaen.tfg.mangaffinity.entidades.Recurso
;
import
com.ujaen.tfg.mangaffinity.entidades.Recurso
;
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.rest.DTO.DTOCapitulo
;
import
com.ujaen.tfg.mangaffinity.rest.DTO.DTOCapitulo
;
import
com.ujaen.tfg.mangaffinity.rest.DTO.DTORecurso
;
import
com.ujaen.tfg.mangaffinity.rest.DTO.DTORecurso
;
...
@@ -32,12 +33,23 @@ import java.io.File;
...
@@ -32,12 +33,23 @@ import java.io.File;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.nio.file.*
;
import
java.nio.file.*
;
import
java.time.LocalDate
;
import
java.time.LocalDate
;
import
java.util.UUID
;
import
java.util.UUID
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.io.IOException
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.nio.file.StandardCopyOption
;
@RestController
@RestController
@RequestMapping
(
"/recursos"
)
@RequestMapping
(
"/recursos"
)
public
class
RecursosController
{
public
class
RecursosController
{
@Autowired
@Autowired
private
ServicioRecursos
servicioRecursos
;
private
ServicioRecursos
servicioRecursos
;
@Autowired
@Autowired
...
@@ -49,20 +61,26 @@ public class RecursosController {
...
@@ -49,20 +61,26 @@ public class RecursosController {
@RequestPart
(
value
=
"foto"
,
required
=
false
)
MultipartFile
foto
)
{
@RequestPart
(
value
=
"foto"
,
required
=
false
)
MultipartFile
foto
)
{
try
{
try
{
String
f
otoUrl
=
null
;
String
f
ileName
=
null
;
// Verificar
tipo de archivo (solo imágenes)
// Verificar
si se adjuntó una imagen y si es un tipo válido
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
.
status
(
HttpStatus
.
BAD_REQUEST
).
body
(
"Solo se permiten imágenes JPEG o PNG."
);
}
}
// Renombrar el archivo con un nombre único
// Obtener el nombre original y limpiar el nombre del archivo
String
fileName
=
UUID
.
randomUUID
().
toString
()
+
"_"
+
foto
.
getOriginalFilename
();
String
originalFileName
=
foto
.
getOriginalFilename
();
Path
uploadsPath
=
Paths
.
get
(
"uploads/"
);
if
(
originalFileName
!=
null
)
{
// Reemplazar espacios y caracteres especiales en el nombre
fileName
=
originalFileName
.
replaceAll
(
"\\s+"
,
"_"
).
replaceAll
(
"[^a-zA-Z0-9._-]"
,
""
);
}
else
{
fileName
=
"imagen_predeterminada.png"
;
}
// Crear directorio si no existe
// Ruta de almacenamiento
Path
uploadsPath
=
Paths
.
get
(
"uploads/"
);
if
(!
Files
.
exists
(
uploadsPath
))
{
if
(!
Files
.
exists
(
uploadsPath
))
{
Files
.
createDirectories
(
uploadsPath
);
Files
.
createDirectories
(
uploadsPath
);
}
}
...
@@ -71,32 +89,30 @@ public class RecursosController {
...
@@ -71,32 +89,30 @@ public class RecursosController {
Path
filePath
=
uploadsPath
.
resolve
(
fileName
);
Path
filePath
=
uploadsPath
.
resolve
(
fileName
);
Files
.
copy
(
foto
.
getInputStream
(),
filePath
,
StandardCopyOption
.
REPLACE_EXISTING
);
Files
.
copy
(
foto
.
getInputStream
(),
filePath
,
StandardCopyOption
.
REPLACE_EXISTING
);
// Crear la URL completa de la imagen
String
urlBase
=
"http://localhost:8080"
;
fotoUrl
=
urlBase
+
"/uploads/"
+
fileName
.
replace
(
" "
,
"_"
);
}
}
// Crear el recurso con
la imagen (si hay)
// Crear el recurso con
solo el nombre del archivo en la BD
Recurso
nuevoRecurso
=
new
Recurso
(
Recurso
nuevoRecurso
=
new
Recurso
(
recursoDTO
.
getTitulo
(),
recursoDTO
.
getTitulo
(),
recursoDTO
.
getDescripcion
(),
recursoDTO
.
getDescripcion
(),
recursoDTO
.
getFechaPublicacion
(),
recursoDTO
.
getFechaPublicacion
(),
recursoDTO
.
getAutor
(),
recursoDTO
.
getAutor
(),
f
otoUrl
f
ileName
// Guardamos solo el nombre del archivo
);
);
nuevoRecurso
.
setGeneros
(
recursoDTO
.
getGeneros
());
servicioRecursos
.
crearRecurso
(
nuevoRecurso
);
servicioRecursos
.
crearRecurso
(
nuevoRecurso
);
return
ResponseEntity
.
status
(
HttpStatus
.
CREATED
).
b
ody
(
"Recurso creado correctamente"
);
return
ResponseEntity
.
status
(
HttpStatus
.
CREATED
).
b
uild
(
);
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
b
ody
(
"Error al subir la imagen"
);
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
b
uild
(
);
}
}
}
}
@GetMapping
(
"/titulo/{titulo}"
)
@GetMapping
(
"/titulo/{titulo}"
)
public
ResponseEntity
<
List
<
DTORecurso
>>
buscarPorTitulo
(
@PathVariable
String
titulo
)
{
public
ResponseEntity
<
List
<
DTORecurso
>>
buscarPorTitulo
(
@PathVariable
String
titulo
)
{
try
{
try
{
...
@@ -165,6 +181,7 @@ public class RecursosController {
...
@@ -165,6 +181,7 @@ public class RecursosController {
@DeleteMapping
(
"/{id}"
)
@DeleteMapping
(
"/{id}"
)
public
ResponseEntity
<
Void
>
borrarRecurso
(
@PathVariable
Long
id
)
{
public
ResponseEntity
<
Void
>
borrarRecurso
(
@PathVariable
Long
id
)
{
try
{
try
{
...
@@ -178,37 +195,84 @@ public class RecursosController {
...
@@ -178,37 +195,84 @@ public class RecursosController {
if
(
recurso
.
getFotoUrl
()
!=
null
&&
!
recurso
.
getFotoUrl
().
isEmpty
())
{
if
(
recurso
.
getFotoUrl
()
!=
null
&&
!
recurso
.
getFotoUrl
().
isEmpty
())
{
Path
imagePath
=
Paths
.
get
(
"uploads/"
,
recurso
.
getFotoUrl
().
replace
(
"/uploads/"
,
""
));
Path
imagePath
=
Paths
.
get
(
"uploads/"
,
recurso
.
getFotoUrl
().
replace
(
"/uploads/"
,
""
));
// Eliminar l
a imagen asociada
si existe
// Eliminar l
imagen
si existe
if
(
Files
.
exists
(
imagePath
))
{
if
(
Files
.
exists
(
imagePath
))
{
try
{
try
{
Files
.
delete
(
imagePath
);
// Eliminar la imagen
Files
.
delete
(
imagePath
);
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
build
();
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
build
();
}
}
}
}
}
}
// Eliminar el recurso de la base de datos
servicioRecursos
.
borrarRecurso
(
id
);
servicioRecursos
.
borrarRecurso
(
id
);
// Responder con éxito
return
ResponseEntity
.
noContent
().
build
();
return
ResponseEntity
.
noContent
().
build
();
}
catch
(
SecurityException
e
)
{
}
catch
(
SecurityException
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
UNAUTHORIZED
).
build
();
// En caso de que el usuario no tenga permiso
return
ResponseEntity
.
status
(
HttpStatus
.
UNAUTHORIZED
).
build
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
build
();
// Error inesperado
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
build
();
}
}
}
}
@PutMapping
(
"/{id}"
)
@PutMapping
(
value
=
"/{id}"
,
consumes
=
{
"multipart/form-data"
})
public
ResponseEntity
<
DTORecurso
>
modificarRecurso
(
@PathVariable
Long
id
,
@RequestBody
DTORecurso
dtoRecurso
)
{
public
ResponseEntity
<
DTORecurso
>
modificarRecurso
(
@PathVariable
Long
id
,
@RequestPart
(
"recurso"
)
DTORecurso
dtoRecurso
,
@RequestPart
(
value
=
"foto"
,
required
=
false
)
MultipartFile
foto
)
{
try
{
try
{
Recurso
nuevosDatos
=
mapper
.
entity
(
dtoRecurso
);
Recurso
recursoExistente
=
servicioRecursos
.
buscarRecursoPorId
(
id
);
Recurso
recursoModificado
=
servicioRecursos
.
modificarRecurso
(
id
,
nuevosDatos
);
if
(
recursoExistente
==
null
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
).
build
();
}
String
fileName
=
recursoExistente
.
getFotoUrl
();
// Mantener la imagen actual por defecto
// Si se adjunta una nueva imagen, la procesamos
if
(
foto
!=
null
&&
!
foto
.
isEmpty
())
{
String
mimeType
=
foto
.
getContentType
();
if
(
mimeType
==
null
||
(!
mimeType
.
equals
(
"image/jpeg"
)
&&
!
mimeType
.
equals
(
"image/png"
)))
{
return
ResponseEntity
.
status
(
HttpStatus
.
BAD_REQUEST
).
body
(
null
);
}
// Eliminar la imagen anterior si existe
if
(
fileName
!=
null
&&
!
fileName
.
isEmpty
())
{
Path
oldFilePath
=
Paths
.
get
(
"uploads/"
,
fileName
);
if
(
Files
.
exists
(
oldFilePath
))
{
Files
.
delete
(
oldFilePath
);
}
}
// Guardar la nueva imagen
String
originalFileName
=
foto
.
getOriginalFilename
();
if
(
originalFileName
!=
null
)
{
fileName
=
originalFileName
.
replaceAll
(
"\\s+"
,
"_"
).
replaceAll
(
"[^a-zA-Z0-9._-]"
,
""
);
}
Path
uploadsPath
=
Paths
.
get
(
"uploads/"
);
if
(!
Files
.
exists
(
uploadsPath
))
{
Files
.
createDirectories
(
uploadsPath
);
}
Path
filePath
=
uploadsPath
.
resolve
(
fileName
);
Files
.
copy
(
foto
.
getInputStream
(),
filePath
,
StandardCopyOption
.
REPLACE_EXISTING
);
}
// Actualizar los datos del recurso
recursoExistente
.
setTitulo
(
dtoRecurso
.
getTitulo
());
recursoExistente
.
setDescripcion
(
dtoRecurso
.
getDescripcion
());
recursoExistente
.
setFechaPublicacion
(
dtoRecurso
.
getFechaPublicacion
());
recursoExistente
.
setAutor
(
dtoRecurso
.
getAutor
());
recursoExistente
.
setGeneros
(
dtoRecurso
.
getGeneros
());
// Asignar correctamente los géneros
recursoExistente
.
setFotoUrl
(
fileName
);
// Asignar nueva imagen (o mantener la actual)
// Guardar cambios en la BD
Recurso
recursoModificado
=
servicioRecursos
.
modificarRecurso
(
id
,
recursoExistente
);
return
ResponseEntity
.
ok
(
mapper
.
dto
(
recursoModificado
));
return
ResponseEntity
.
ok
(
mapper
.
dto
(
recursoModificado
));
}
catch
(
RecursoNoExiste
e
)
{
}
catch
(
RecursoNoExiste
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
).
build
();
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
).
build
();
}
catch
(
IOException
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
body
(
null
);
}
catch
(
SecurityException
e
)
{
}
catch
(
SecurityException
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
UNAUTHORIZED
).
build
();
return
ResponseEntity
.
status
(
HttpStatus
.
UNAUTHORIZED
).
build
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
...
@@ -231,13 +295,16 @@ public class RecursosController {
...
@@ -231,13 +295,16 @@ public class RecursosController {
@PostMapping
(
"/{id}/capitulos"
)
@PostMapping
(
"/{id}/capitulos"
)
public
ResponseEntity
<
String
>
anadirCapitulo
(
@PathVariable
Long
id
,
@RequestBody
DTOCapitulo
dtoCapitulo
)
{
public
ResponseEntity
<
String
>
anadirCapitulo
(
@PathVariable
Long
id
,
@RequestBody
DTOCapitulo
dtoCapitulo
)
{
try
{
try
{
Capitulo
nuevoCapitulo
=
mapper
.
entity
(
dtoCapitulo
,
servicioRecursos
.
buscarRecursoPorId
(
id
));
Recurso
recurso
=
servicioRecursos
.
buscarRecursoPorId
(
id
);
if
(
recurso
==
null
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
).
build
();
}
Capitulo
nuevoCapitulo
=
mapper
.
entity
(
dtoCapitulo
,
recurso
);
servicioRecursos
.
anadirCapitulo
(
id
,
nuevoCapitulo
);
servicioRecursos
.
anadirCapitulo
(
id
,
nuevoCapitulo
);
return
ResponseEntity
.
status
(
HttpStatus
.
CREATED
).
build
();
return
ResponseEntity
.
status
(
HttpStatus
.
CREATED
).
build
();
}
catch
(
RecursoNoExiste
e
)
{
}
catch
(
RecursoNoExiste
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
).
body
(
"El recurso no existe."
);
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
).
build
();
}
catch
(
SecurityException
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
UNAUTHORIZED
).
build
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
build
();
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
build
();
}
}
...
@@ -247,13 +314,86 @@ public class RecursosController {
...
@@ -247,13 +314,86 @@ public class RecursosController {
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
);
if
(
capitulos
.
isEmpty
())
{
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
).
build
();
}
List
<
DTOCapitulo
>
dtoCapitulos
=
capitulos
.
stream
().
map
(
mapper:
:
dto
).
toList
();
List
<
DTOCapitulo
>
dtoCapitulos
=
capitulos
.
stream
().
map
(
mapper:
:
dto
).
toList
();
return
ResponseEntity
.
ok
(
dtoCapitulos
);
return
ResponseEntity
.
ok
(
dtoCapitulos
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
build
();
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
build
();
}
}
}
}
@PutMapping
(
"/{recursoId}/capitulos/{id}"
)
public
ResponseEntity
<
Void
>
modificarCapitulo
(
@PathVariable
Long
id
,
@RequestBody
DTOCapitulo
dtoCapitulo
)
{
try
{
if
(!
id
.
equals
(
dtoCapitulo
.
getId
()))
{
return
ResponseEntity
.
badRequest
().
build
();
}
Capitulo
capituloExistente
=
servicioRecursos
.
buscarCapituloPorId
(
id
);
if
(
capituloExistente
==
null
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
).
build
();
}
Capitulo
capituloModificado
=
mapper
.
entity
(
dtoCapitulo
,
capituloExistente
.
getRecurso
());
capituloModificado
.
setId
(
id
);
servicioRecursos
.
modificarCapitulo
(
capituloModificado
);
return
ResponseEntity
.
noContent
().
build
();
}
catch
(
CapituloNoExiste
e
)
{
return
ResponseEntity
.
notFound
().
build
();
}
catch
(
IllegalStateException
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
CONFLICT
).
build
();
}
catch
(
SecurityException
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
UNAUTHORIZED
).
build
();
}
catch
(
Exception
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
build
();
}
}
@GetMapping
(
"/{recursoId}/capitulos/{capituloId}"
)
public
ResponseEntity
<
DTOCapitulo
>
obtenerCapituloPorId
(
@PathVariable
Long
recursoId
,
@PathVariable
Long
capituloId
)
{
try
{
// Verificar si el recurso existe
Recurso
recurso
=
servicioRecursos
.
buscarRecursoPorId
(
recursoId
);
if
(
recurso
==
null
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
)
.
build
();
// Recurso no encontrado
}
// Buscar el capítulo dentro del recurso
Capitulo
capitulo
=
servicioRecursos
.
buscarCapituloPorId
(
capituloId
);
if
(
capitulo
==
null
||
!
capitulo
.
getRecurso
().
getId
().
equals
(
recursoId
))
{
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
)
.
build
();
// Capítulo no encontrado o no pertenece al recurso
}
// Convertir a DTO y devolver
return
ResponseEntity
.
ok
(
mapper
.
dto
(
capitulo
));
}
catch
(
Exception
e
)
{
// Loguear el error para diagnóstico
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
build
();
// Error interno del servidor
}
}
@GetMapping
(
"/generos"
)
public
ResponseEntity
<
List
<
String
>>
obtenerGeneros
()
{
try
{
List
<
String
>
generos
=
servicioRecursos
.
obtenerGeneros
();
return
ResponseEntity
.
ok
(
generos
);
}
catch
(
Exception
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
).
build
();
}
}
}
}
\ No newline at end of file
src/main/java/com/ujaen/tfg/mangaffinity/seguridad/ServicioSeguridad.java
View file @
98238240
...
@@ -47,6 +47,7 @@ public class ServicioSeguridad {
...
@@ -47,6 +47,7 @@ public class ServicioSeguridad {
.
requestMatchers
(
HttpMethod
.
GET
,
"/recursos/genero/**"
).
permitAll
()
.
requestMatchers
(
HttpMethod
.
GET
,
"/recursos/genero/**"
).
permitAll
()
.
requestMatchers
(
HttpMethod
.
GET
,
"/recursos/fecha"
).
permitAll
()
.
requestMatchers
(
HttpMethod
.
GET
,
"/recursos/fecha"
).
permitAll
()
.
requestMatchers
(
HttpMethod
.
GET
,
"/recursos/{id}"
).
permitAll
()
.
requestMatchers
(
HttpMethod
.
GET
,
"/recursos/{id}"
).
permitAll
()
.
requestMatchers
(
HttpMethod
.
GET
,
"/recursos/generos"
).
permitAll
()
.
requestMatchers
(
HttpMethod
.
GET
,
"/recursos"
).
permitAll
()
.
requestMatchers
(
HttpMethod
.
GET
,
"/recursos"
).
permitAll
()
.
requestMatchers
(
HttpMethod
.
POST
,
"/recursos/"
).
hasAuthority
(
"ROLE_ADMIN"
)
.
requestMatchers
(
HttpMethod
.
POST
,
"/recursos/"
).
hasAuthority
(
"ROLE_ADMIN"
)
.
requestMatchers
(
HttpMethod
.
PUT
,
"/recursos/{id}"
).
hasAuthority
(
"ROLE_ADMIN"
)
.
requestMatchers
(
HttpMethod
.
PUT
,
"/recursos/{id}"
).
hasAuthority
(
"ROLE_ADMIN"
)
...
@@ -58,7 +59,10 @@ public class ServicioSeguridad {
...
@@ -58,7 +59,10 @@ public class ServicioSeguridad {
.
requestMatchers
(
HttpMethod
.
GET
,
"/biblioteca/{usuarioId}/recursos/categoria/{categoria}"
).
authenticated
()
.
requestMatchers
(
HttpMethod
.
GET
,
"/biblioteca/{usuarioId}/recursos/categoria/{categoria}"
).
authenticated
()
.
requestMatchers
(
HttpMethod
.
DELETE
,
"/biblioteca/{usuarioId}/recursos/{recursoId}"
).
authenticated
()
.
requestMatchers
(
HttpMethod
.
DELETE
,
"/biblioteca/{usuarioId}/recursos/{recursoId}"
).
authenticated
()
.
requestMatchers
(
HttpMethod
.
PUT
,
"/biblioteca/{usuarioId}/recursos/{recursoId}/categoria"
).
authenticated
()
.
requestMatchers
(
HttpMethod
.
PUT
,
"/biblioteca/{usuarioId}/recursos/{recursoId}/categoria"
).
authenticated
()
.
anyRequest
().
authenticated
()
// Todo lo demás requiere autenticación
.
requestMatchers
(
HttpMethod
.
GET
,
"/recursos/{recursoId}/capitulos/{capituloId}"
).
permitAll
()
.
requestMatchers
(
HttpMethod
.
PUT
,
"/recursos/{recursoId}/capitulos/{capituloId}"
).
hasAuthority
(
"ROLE_ADMIN"
)
.
anyRequest
().
authenticated
()
)
)
.
addFilterBefore
(
new
JwtFilter
(
jwtUtil
),
UsernamePasswordAuthenticationFilter
.
class
)
// Usar solo JWT
.
addFilterBefore
(
new
JwtFilter
(
jwtUtil
),
UsernamePasswordAuthenticationFilter
.
class
)
// Usar solo JWT
.
build
();
.
build
();
...
...
src/main/java/com/ujaen/tfg/mangaffinity/servicios/ServicioRecursos.java
View file @
98238240
package
com
.
ujaen
.
tfg
.
mangaffinity
.
servicios
;
package
com
.
ujaen
.
tfg
.
mangaffinity
.
servicios
;
import
com.ujaen.tfg.mangaffinity.entidades.Capitulo
;
import
com.ujaen.tfg.mangaffinity.entidades.*
;
import
com.ujaen.tfg.mangaffinity.entidades.FuenteCapitulo
;
import
com.ujaen.tfg.mangaffinity.excepciones.CapituloNoExiste
;
import
com.ujaen.tfg.mangaffinity.entidades.Genero
;
import
com.ujaen.tfg.mangaffinity.entidades.Recurso
;
import
com.ujaen.tfg.mangaffinity.excepciones.RecursoNoExiste
;
import
com.ujaen.tfg.mangaffinity.excepciones.RecursoNoExiste
;
import
com.ujaen.tfg.mangaffinity.repositorios.RepositorioCapitulo
;
import
com.ujaen.tfg.mangaffinity.repositorios.RepositorioCapitulo
;
import
com.ujaen.tfg.mangaffinity.repositorios.RepositorioRecurso
;
import
com.ujaen.tfg.mangaffinity.repositorios.RepositorioRecurso
;
...
@@ -15,7 +13,11 @@ import org.springframework.transaction.annotation.Transactional;
...
@@ -15,7 +13,11 @@ import org.springframework.transaction.annotation.Transactional;
import
java.time.LocalDate
;
import
java.time.LocalDate
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
@Service
@Service
public
class
ServicioRecursos
{
public
class
ServicioRecursos
{
@Autowired
@Autowired
...
@@ -100,32 +102,120 @@ public class ServicioRecursos {
...
@@ -100,32 +102,120 @@ public class ServicioRecursos {
if
(
recurso
==
null
)
{
if
(
recurso
==
null
)
{
throw
new
RecursoNoExiste
();
throw
new
RecursoNoExiste
();
}
}
List
<
Capitulo
>
capitulos
=
repositorioCapitulo
.
obtenerCapitulosRecurso
(
recursoId
);
if
(
capitulos
.
size
()
<
4
)
{
List
<
Capitulo
>
listaCapitulos
=
(
nuevoCapitulo
.
getTipo
()
==
TipoRecurso
.
MANGA
)
repositorioCapitulo
.
crearCapitulo
(
nuevoCapitulo
);
?
recurso
.
getCapitulosManga
()
:
recurso
.
getCapitulosAnime
();
// Asociar fuentes al capítulo
for
(
FuenteCapitulo
fuente
:
nuevoCapitulo
.
getFuentes
())
{
fuente
.
setCapitulo
(
nuevoCapitulo
);
}
if
(
listaCapitulos
.
size
()
<
4
)
{
listaCapitulos
.
add
(
nuevoCapitulo
);
}
else
{
}
else
{
Capitulo
penultimo
=
capitulos
.
get
(
2
);
Capitulo
penultimo
=
listaCapitulos
.
get
(
2
);
Capitulo
ultimo
=
capitulos
.
get
(
3
);
Capitulo
ultimo
=
listaCapitulos
.
get
(
3
);
List
<
FuenteCapitulo
>
nuevasFuentes
=
new
ArrayList
<>();
List
<
FuenteCapitulo
>
nuevasFuentes
=
new
ArrayList
<>();
for
(
FuenteCapitulo
fuente
:
ultimo
.
getFuentes
())
{
for
(
FuenteCapitulo
fuente
:
ultimo
.
getFuentes
())
{
nuevasFuentes
.
add
(
new
FuenteCapitulo
(
fuente
.
getNombreFuente
(),
fuente
.
getUrlFuente
()));
FuenteCapitulo
nuevaFuente
=
new
FuenteCapitulo
(
null
,
fuente
.
getNombreFuente
(),
fuente
.
getUrlFuente
(),
penultimo
);
nuevasFuentes
.
add
(
nuevaFuente
);
}
}
penultimo
.
setNumero
(
ultimo
.
getNumero
());
penultimo
.
setNumero
(
ultimo
.
getNumero
());
penultimo
.
setTitulo
(
ultimo
.
getTitulo
());
penultimo
.
setTitulo
(
ultimo
.
getTitulo
());
penultimo
.
setTipo
(
ultimo
.
getTipo
());
penultimo
.
setTipo
(
ultimo
.
getTipo
());
penultimo
.
setFuentes
(
nuevasFuentes
);
penultimo
.
setFuentes
(
nuevasFuentes
);
repositorioCapitulo
.
borrarCapitulo
(
ultimo
);
repositorioCapitulo
.
actualizarCapitulo
(
pen
ultimo
);
listaCapitulos
.
remove
(
ultimo
);
repositorioCapitulo
.
crearCapitulo
(
nuevoCapitulo
);
listaCapitulos
.
add
(
nuevoCapitulo
);
}
}
repositorioRecurso
.
merge
(
recurso
);
}
}
@Transactional
@Transactional
public
List
<
Capitulo
>
obtenerCapitulosDeRecurso
(
Long
recursoId
)
{
public
List
<
Capitulo
>
obtenerCapitulosDeRecurso
(
Long
recursoId
)
{
List
<
Capitulo
>
capitulos
=
repositorioCapitulo
.
obtenerCapitulosRecurso
(
recursoId
);
List
<
Capitulo
>
capitulos
=
repositorioCapitulo
.
obtenerCapitulosRecurso
(
recursoId
);
capitulos
.
forEach
(
capitulo
->
capitulo
.
getFuentes
().
size
());
capitulos
.
forEach
(
capitulo
->
capitulo
.
getFuentes
().
size
());
return
capitulos
;
return
capitulos
;
}
}
public
List
<
String
>
obtenerGeneros
()
{
return
Arrays
.
stream
(
Genero
.
values
())
.
map
(
Enum:
:
name
)
.
collect
(
Collectors
.
toList
());
}
@Transactional
public
void
modificarCapitulo
(
Capitulo
capituloModificado
)
{
Capitulo
capitulo
=
repositorioCapitulo
.
buscarPorId
(
capituloModificado
.
getId
());
if
(
capitulo
==
null
)
{
throw
new
CapituloNoExiste
();
}
// Asegurar que el capítulo pertenece a un recurso antes de modificarlo
if
(
capitulo
.
getRecurso
()
==
null
)
{
throw
new
IllegalStateException
(
"El capítulo no está asociado a ningún recurso."
);
}
// Modificar solo si los valores no son nulos o inválidos
if
(
capituloModificado
.
getNumero
()
>
0
)
{
capitulo
.
setNumero
(
capituloModificado
.
getNumero
());
}
if
(
capituloModificado
.
getTitulo
()
!=
null
&&
!
capituloModificado
.
getTitulo
().
isBlank
())
{
capitulo
.
setTitulo
(
capituloModificado
.
getTitulo
());
}
if
(
capituloModificado
.
getTipo
()
!=
null
)
{
capitulo
.
setTipo
(
capituloModificado
.
getTipo
());
}
if
(
capituloModificado
.
getFuentes
()
!=
null
)
{
// Crear un mapa con las fuentes existentes para facilitar la comparación
Map
<
Long
,
FuenteCapitulo
>
fuentesExistentes
=
capitulo
.
getFuentes
().
stream
()
.
collect
(
Collectors
.
toMap
(
FuenteCapitulo:
:
getId
,
f
->
f
));
List
<
FuenteCapitulo
>
nuevasFuentes
=
new
ArrayList
<>();
for
(
FuenteCapitulo
fuenteNueva
:
capituloModificado
.
getFuentes
())
{
if
(
fuenteNueva
.
getId
()
!=
null
&&
fuentesExistentes
.
containsKey
(
fuenteNueva
.
getId
()))
{
// Si la fuente ya existe, actualizamos su información
FuenteCapitulo
fuenteExistente
=
fuentesExistentes
.
get
(
fuenteNueva
.
getId
());
fuenteExistente
.
setNombreFuente
(
fuenteNueva
.
getNombreFuente
());
fuenteExistente
.
setUrlFuente
(
fuenteNueva
.
getUrlFuente
());
nuevasFuentes
.
add
(
fuenteExistente
);
}
else
{
// Si la fuente es nueva, la agregamos correctamente
fuenteNueva
.
setCapitulo
(
capitulo
);
nuevasFuentes
.
add
(
fuenteNueva
);
}
}
// Remover las fuentes que no están en la nueva lista
capitulo
.
getFuentes
().
clear
();
capitulo
.
getFuentes
().
addAll
(
nuevasFuentes
);
}
repositorioCapitulo
.
actualizarCapitulo
(
capitulo
);
}
@Transactional
(
readOnly
=
true
)
public
Capitulo
buscarCapituloPorId
(
Long
id
)
{
Capitulo
capitulo
=
repositorioCapitulo
.
buscarPorId
(
id
);
if
(
capitulo
==
null
)
{
throw
new
CapituloNoExiste
();
}
return
capitulo
;
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment