VRaptor3 + @ManyToMany + Edição na View

1 resposta
jurado

Senhores,

estou numa situação estranha, com dificuldades para entender como arquitetaria esta solucao.

Basicamente, eu tenho uma relacao ManyToMany entre duas entidades (Período e DiaSemana). Eu preciso que o usuário seja capaz de editar na view os DiaSemana relacionados a um determinado Periodo, porém nao sei exatamente como fazer para que:

  1. A aplicacao liste, de forma ‘Editável’, a relação de DiaSemana de um determinado Período. Já tentei enviando a lista completa, checando apenas os dias que o Periodo se relaciona, mas senti cheiro de gambiarra ao passar uma Collection de Booleans…
  2. Alterar efetivamente no banco os DiaSemana de um determinado Periodo (ou, claro, adicionar um novo Periodo com alguns DiaSemana preenchidos)

Alguem tem alguma sugestão?

Periodo

@Entity
public class Periodo {
	@Id
	@GeneratedValue
	private Long idPeriodo;
	private String nome;
	private String descricao;
	private Date inicio;
	private Date termino;
	private Date criacao;
	private Date modificacao;

	@ManyToMany(targetEntity = net.danieljurado.discadorweb.modelo.DiaSemana.class, cascade = {
			CascadeType.PERSIST, CascadeType.MERGE })
	@JoinTable(name = "periodoDiaSemana", joinColumns = @JoinColumn(name = "idPeriodo"), inverseJoinColumns = @JoinColumn(name = "idDiaSemana"))
	private Collection<DiaSemana> diaSemana;

	public Long getIdPeriodo() {
		return idPeriodo;
	}

	public void setIdPeriodo(Long idPeriodo) {
		this.idPeriodo = idPeriodo;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public Date getInicio() {
		return inicio;
	}

	public void setInicio(Date inicio) {
		this.inicio = inicio;
	}

	public Date getTermino() {
		return termino;
	}

	public void setTermino(Date termino) {
		this.termino = termino;
	}

	public Date getCriacao() {
		return criacao;
	}

	public void setCriacao(Date criacao) {
		this.criacao = criacao;
	}

	public Date getModificacao() {
		return modificacao;
	}

	public void setModificacao(Date modificacao) {
		this.modificacao = modificacao;
	}

	public Collection<DiaSemana> getDiaSemana() {
		return diaSemana;
	}

	public void setDiaSemana(Collection<DiaSemana> diaSemana) {
		this.diaSemana = diaSemana;
	}
}

DiaSemana

@Entity
public class DiaSemana {
	@Id
	private Long idDiaSemana;
	private String nome;
	private Date criacao;
	private Date modificacao;

	@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy = "diaSemana", targetEntity = Periodo.class)
	private Collection<Periodo> periodo;

	public Long getIdDiaSemana() {
		return idDiaSemana;
	}

	public void setIdDiaSemana(Long idDiaSemana) {
		this.idDiaSemana = idDiaSemana;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public Date getCriacao() {
		return criacao;
	}

	public void setCriacao(Date criacao) {
		this.criacao = criacao;
	}

	public Date getModificacao() {
		return modificacao;
	}

	public void setModificacao(Date modificacao) {
		this.modificacao = modificacao;
	}

	public Collection<Periodo> getPeriodo() {
		return periodo;
	}

	public void setPeriodo(Collection<Periodo> periodo) {
		this.periodo = periodo;
	}
}

Controller

@Resource
public class PeriodoController {
	private final DaoFactory daoFactory;
	private final Result result;

	public PeriodoController(DaoFactory daoFactory, Result result) {
		super();
		this.daoFactory = daoFactory;
		this.result = result;
	}

	public Collection<Periodo> list() {
		return this.daoFactory.getPeriodoDao().listaTudo();
	}

	public void delete(Periodo periodo) {
		this.daoFactory.getPeriodoDao().remove(periodo);
		result.use(Results.logic()).redirectTo(PeriodoController.class).list();
	}

	public void edit(Periodo periodo, String inicio, String termino) {
		Date dtInicio = null;
		Date dtTermino = null;
		try {
			dtInicio = new SimpleDateFormat("HH:mm:ss").parse(inicio);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		try {
			dtTermino = new SimpleDateFormat("HH:mm:ss").parse(termino);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		periodo.setInicio(dtInicio);
		periodo.setTermino(dtTermino);
		this.daoFactory.getPeriodoDao().atualiza(periodo);
		result.use(Results.logic()).redirectTo(PeriodoController.class).list();
	}

	public void editar(Periodo periodo) {
		periodo = this.daoFactory.getPeriodoDao().procura(
				periodo.getIdPeriodo());
		String inicio = new SimpleDateFormat("HH:mm:ss").format(periodo
				.getInicio());
		String termino = new SimpleDateFormat("HH:mm:ss").format(periodo
				.getTermino());
		result.use(Results.logic()).forwardTo(PeriodoController.class)
				.formularioPeriodo("edit", periodo, inicio, termino);
	}

	public void adicionar() {
		result.use(Results.logic()).redirectTo(PeriodoController.class)
				.formularioPeriodo("add", null, "", "");
	}

	public void add(Periodo periodo, String inicio, String termino) {
		Date dtInicio = null;
		Date dtTermino = null;
		try {
			dtInicio = new SimpleDateFormat("HH:mm:ss").parse(inicio);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		try {
			dtTermino = new SimpleDateFormat("HH:mm:ss").parse(termino);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		periodo.setInicio(dtInicio);
		periodo.setTermino(dtTermino);
		this.daoFactory.getPeriodoDao().adiciona(periodo);
		result.use(Results.logic()).redirectTo(PeriodoController.class).list();
	}

	public void formularioPeriodo(String action, Periodo periodo,
			String inicio, String termino) {
		result.include("inicio", inicio);
		result.include("termino", termino);
		result.include("horariosPermitidos", horariosPermitidos());
		result.include("formAction", action);
		result.include("periodo", periodo);
	}

	private Collection<String> horariosPermitidos() {
		LinkedList<String> result = new LinkedList<String>();
		for (Integer i = 0; i < 24; i++) {
			for (Integer j = 0; j < 1; j++) {
				String hora = i < 10 ? "0".concat(i.toString()) : i.toString();
				String minuto = j == 0 ? "00" : "30";
				String segundo = "00";
				result.add(hora.concat(":").concat(minuto).concat(":").concat(
						segundo));
			}
		}
		return result;
	}
}

View

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ include file="../MiniMenu.jsp"%>
<h1>Período</h1>
<form action="${formAction}" method="post"><input type="hidden"
	name="periodo.idPeriodo" value="${periodo.idPeriodo}" />Nome:<input
	name="periodo.nome" value="${periodo.nome}" /><br>
Descricao:<input name="periodo.descricao" value="${periodo.descricao}" /><br>

Inicio: <select name="inicio">
	<c:forEach var="horario" items="${horariosPermitidos}">
		<option value="${horario}"
			<c:if test="${inicio == horario}">selected="true"</c:if>>
		${horario}</option>
	</c:forEach>
</select><br>
Termino: <select name="termino">
	<c:forEach var="horario" items="${horariosPermitidos}">
		<option value="${horario}"
			<c:if test="${termino == horario}">selected="true"</c:if>>
		${horario}</option>
	</c:forEach>
</select><br>
<input type="submit" /></form>

Estou usando VRaptor3 Beta5.

Em tempo: para limitar os horários em que um período inicia e termina, estou arbitrariamente enviando uma Collection de Strings para a view. Esta é a melhor forma? Ouvi dizer que SimpleDateFormat nao é uma boa… Mas pelo menos funciona :slight_smile:

Obrigado, pessoal!

1 Resposta

Lucas_Cavalcanti

pra editar você pode mostrar todos os dias da semana como checkbox, marcar os que já estão marcados no período… daí quando vc manda pra lógica vc sobrescreve
a collection de dias que está no banco…

o problema eh que fazer isso na jsp fica meio zuadinho pq vc não pode ficar chamando métodos… só getters…
mas vc pode usar o f:contains (das taglibs padrão)

Criado 22 de setembro de 2009
Ultima resposta 22 de set. de 2009
Respostas 1
Participantes 2