Skip to content

Commit

Permalink
AUT-CURSOS-0003: Spring services. Done. And MVC modified
Browse files Browse the repository at this point in the history
· Fixed: pageable query: service, repository and test modified.
· It shouldn't be done yet: implemented a basic list view
· Fixed: removed (commented) the Validation API, because there is no
bean validation provider in the classpath (I think it's out of the
bounds of this project)
  • Loading branch information
jbbarquero committed Sep 21, 2013
1 parent 39eba35 commit 36ac115
Show file tree
Hide file tree
Showing 14 changed files with 309 additions and 28 deletions.
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@
<version>${org.springframework-version}</version>
</dependency>

<!-- Validation -->
<!-- Validation
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
-->

<!-- H2 -->
<dependency>
Expand Down
15 changes: 6 additions & 9 deletions src/main/java/com/malsolo/autentia/cursos/domain/Curso.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
import java.io.Serializable;
import java.util.Objects;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class Curso implements Serializable {

public static final Integer NIVEL_BASICO = 0;
Expand All @@ -17,20 +14,20 @@ public class Curso implements Serializable {

private Long id;

@NotNull
@Size(max = 100)
// @NotNull
// @Size(max = 100)
private String titulo;

@NotNull
// @NotNull
private Integer nivel;

@NotNull
// @NotNull
private Integer horas;

@NotNull
// @NotNull
private Boolean activo;

@NotNull
// @NotNull
private Profesor profesor;

public Long getId() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@
import java.io.Serializable;
import java.util.Objects;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class Profesor implements Serializable {

/** serialVersionUID */
private static final long serialVersionUID = -8249851878435018619L;

private Long id;
@NotNull
@Size(max = 100)
// @NotNull
// @Size(max = 100)
private String nombre;

public Long getId() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@ public interface CursoMapper {

public void delete(Long id);

public List<Curso> findEntries(OrderType orderType, RowBounds rowBounds);
/** For the time being: only active courses :( */
public List<Curso> findActiveEntries(OrderType orderType, RowBounds rowBounds);

public long count();

/** For the time being: only active courses :( */
public long countActiveEntries();

public Curso findByActivo(Boolean activo);

public long countByActivo(Boolean activo);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,45 @@
package com.malsolo.autentia.cursos.service;

import java.util.List;

import com.malsolo.autentia.cursos.domain.Curso;
import com.malsolo.autentia.cursos.persistence.OrderType;


public interface CursoService {

/**
* Como usuario, quiero poder acceder al catálogo de cursos disponibles en el sistema:
* <ul>
* <li>Sólo se mostrarán los cursos marcados como activos</li>
* <li>El listado mostrará el título del curso, el nivel y el número de horas del mismo</li>
* <li>Se podrá ordenar la tabla por la columna del título de curso</li>
* <li>El listado será paginado</li>
* </ul>
* @param orderType el tipo de orden, para título por ahora.
* @param numeroPagina el número de página, 1 es la primera
* @param registrosPorPagina pues eso.
* @return
*/
public List<Curso> catalogo(OrderType orderType, int numeroPagina, int registrosPorPagina);

/**
* Como usuario quiero poder dar de alta nuevos cursos, la información sobre los mismos será la siguiente:
* <ul>
* <li>Si está activo o no,</li>
* <li>El profesor que imparte el curso, se podrá seleccionar de entre uno de los existentes en el sistema (no será una tabla administrable),</li>
* <li>Título</li>
* <li>Número de horas,</li>
* <li>Nivel del curso, pudiendo seleccionar entre: básico, intermedio y avanzado</li>
* </ul>
* @param curso
*/
public void alta(Curso curso);

/**
* Como programador quiero todos los cursos para comenzar la maqueta web.
* @return
*/
public List<Curso> todos();

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,54 @@
package com.malsolo.autentia.cursos.service;

import java.util.List;

import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.base.Preconditions;
import com.malsolo.autentia.cursos.domain.Curso;
import com.malsolo.autentia.cursos.persistence.CursoMapper;
import com.malsolo.autentia.cursos.persistence.OrderType;
import com.malsolo.autentia.cursos.persistence.ProfesorMapper;

@Service("cursoService")
public class CursoServiceWithCursoMapperImpl implements CursoService {

//TODO: añadir adjuntar y descargar fichero con temario.

@Autowired
private CursoMapper cursoMapper;

@Autowired
private ProfesorMapper profesorMapper;

@Transactional(readOnly=true)
@Override
public List<Curso> catalogo(OrderType orderType, int numeroPagina, int registrosPorPagina) {
Preconditions.checkNotNull(orderType, "Error al consultar el catalogo, orden incorrecto (null)");
Preconditions.checkArgument(numeroPagina>0, "Error al consultar el catalogo, número de página incorrecto: %d", numeroPagina);
Preconditions.checkArgument(numeroPagina>0, "Error al consultar el catalogo, número de registros por página incorrecto: %d", registrosPorPagina);
int primero = (numeroPagina-1)*registrosPorPagina;
return this.cursoMapper.findActiveEntries(orderType, new RowBounds(primero, registrosPorPagina));
}

@Transactional
@Override
public void alta(Curso curso) {
Preconditions.checkNotNull(curso, "Error al crear un curso, curso incorrecto (null)");
Preconditions.checkArgument((curso.getNivel()==Curso.NIVEL_BASICO) || (curso.getNivel()==Curso.NIVEL_INTERMEDIO) || (curso.getNivel()==Curso.NIVEL_AVANZADO), "Error al crear un curso, nivel incorrecto: %d", curso.getNivel());
Preconditions.checkNotNull(curso.getProfesor(), "Error al crear un curso, profesor incorrecto (null)");
Preconditions.checkNotNull(curso.getProfesor().getId(), "Error al crear un curso, profesor incorrecto (su ID es null)");
Preconditions.checkNotNull(profesorMapper.findById(curso.getProfesor().getId()), "Error al crear un curso, profesor inexistente ID: %d ", curso.getProfesor().getId());
cursoMapper.insert(curso);
}

@Transactional(readOnly=true)
@Override
public List<Curso> todos() {
return cursoMapper.findAll();
}

}
37 changes: 37 additions & 0 deletions src/main/java/com/malsolo/autentia/cursos/web/CursoController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.malsolo.autentia.cursos.web;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.malsolo.autentia.cursos.domain.Curso;
import com.malsolo.autentia.cursos.service.CursoService;

@Controller
@RequestMapping("/catalogo")
public class CursoController {

private static final Logger logger = LoggerFactory.getLogger(CursoController.class);

@Autowired
private CursoService cursoService;

@RequestMapping(method = RequestMethod.GET)
public String todos(Model uiModel) {
logger.info("Todos los cursos");

List<Curso> cursos = this.cursoService.todos();
uiModel.addAttribute("cursos", cursos);

logger.info("Todos los cursos son {} ", cursos==null?0:cursos.size());

return "catalogo/todos";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,20 @@
delete from cursos where id = #{id}
</delete>

<select id="findEntries" parameterType="com.malsolo.autentia.cursos.persistence.OrderType" resultMap="cursoResultMap">
<select id="findActiveEntries" parameterType="com.malsolo.autentia.cursos.persistence.OrderType" resultMap="cursoResultMap">
select c.id, titulo, nivel, horas, activo, profesor_id, p.nombre
from cursos c
left outer join profesores p
on p.id = c.profesor_id
where activo = true
order by titulo ${order}
</select>

<select id="count" resultType="long">
select count(*) from cursos
</select>

<select id="countActiveEntries" resultType="long">
select count(*) from cursos where activo = true
</select>
</mapper>
4 changes: 3 additions & 1 deletion src/main/resources/h2/test-data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ insert into profesores (nombre) values ('Javier Beneito Barquero');
insert into profesores (nombre) values ('Isabel Rodríguez');

insert into cursos (profesor_id, titulo, nivel, horas, activo) values (1, 'Introducción a JSF2', 5, 25, true);
insert into cursos (profesor_id, titulo, nivel, horas, activo) values (2, 'Novedades en Spring 3', 5, 15, true);
insert into cursos (profesor_id, titulo, nivel, horas, activo) values (3, 'Aprende a trabajar en Autentia', 0, 10, true);
insert into cursos (profesor_id, titulo, nivel, horas, activo) values (2, 'Novedades en Spring 4', 5, 15, false);

insert into cursos (profesor_id, titulo, nivel, horas, activo) values (2, 'Filostros y Forlayos in a Nutshell', 10, 100, false);
34 changes: 34 additions & 0 deletions src/main/webapp/WEB-INF/views/catalogo/todos.jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Catálogo de cursos: todos</title>
</head>
<body>
<h1>
Todos los cursos
</h1>

<c:if test="${not empty cursos}">
<table border="1">
<thead>
<tr>
<th>Título</th>
<th>Nivel</th>
<th>Horas</th>
</tr>
</thead>
<tbody>
<c:forEach items="${cursos}" var="curso">
<tr>
<td>${curso.titulo}</td>
<td>${curso.nivel}</td>
<td>${curso.horas}</td>
</tr>
</c:forEach>
</tbody>
</table>
</c:if>

</body>
</html>
25 changes: 24 additions & 1 deletion src/main/webapp/WEB-INF/web.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,36 @@
<display-name>cursos</display-name>

<description>Web application for courses management</description>

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>

<!-- Spring MVC filters -->
<filter><!-- This filter is used to specify the character encoding for request. -->
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>

<filter><!-- This filter provides support for HTTP methods other than GET and POST (for example, PUT). -->
<filter-name>HttpMethodFilter</filter-name>
<filter-class>
org.springframework.web.filter.HiddenHttpMethodFilter
</filter-class>
</filter>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
Expand Down
Loading

0 comments on commit 36ac115

Please sign in to comment.