Classe base abstrata de todas as actions de Produto. Centraliza o que DepartamentoProdutoList (e futuras actions concretas) vão precisar compartilhar: o prefixo ROOT de permissão e o objeto WBean da requisição. Quinto arquivo da sequência CRUD READ.
Nota: nesta fase CRUD READ a Action base tem só o ROOT e o proWBean() — é o mínimo que a List precisa. Nas próximas sequências (CREATE, UPDATE, DELETE), ela pode ganhar um proBean() e um helper id_produto() pra formulário compartilhar estado via sessão.
package br.xt.app.departamento.produto;
import br.xt.AppsRootAction;
import br.xt.app.departamento.DepartamentoManager;
public abstract class DepartamentoProdutoAction extends AppsRootAction {
private DepartamentoProdutoWBean wbean = null;
public DepartamentoProdutoWBean proWBean() throws Exception {
if (wbean == null)
wbean = (DepartamentoProdutoWBean) getManager().getInstance(DepartamentoProdutoWBean.class);
return wbean;
}
public static final String ROOT = DepartamentoManager.F_ACESSO_MODULO.concat("__PRODUTO/");
}
abstract?
Uma classe abstract em Java é uma classe que NÃO pode ser instanciada direto — não dá pra fazer new DepartamentoProdutoAction(). Ela só existe pra ser ESTENDIDA por outras classes.
A ideia: a DepartamentoProdutoAction é só um "MOLDE" de comportamento comum. As actions concretas (como DepartamentoProdutoList) estendem dela e ganham esse comportamento de graça.
Ao tornar a classe abstrata, o Java impede que alguém crie uma instância dela por acidente. Isso força o aluno a sempre ter uma classe CONCRETA (List, Form, DeleteFromList, etc.) como destino do pedido do agente.
ROOT e pra que serve?
ROOT é uma constante que guarda o PREFIXO das chaves de permissão e sessão específicas da entidade Produto dentro do módulo Departamento.
ROOT = "XT.PAINEL_CONTROLE.ACESSO_MODULO.DEPARTAMENTO__PRODUTO/"
Todas as actions concretas de Produto (List, futuras Form, DeleteFromList, etc.) usam ROOT como base:
ROOT.concat("__EXCLUIR") — vira "...DEPARTAMENTO__PRODUTO/__EXCLUIR"LIST = ROOT.concat("__LIST/") — vira "...DEPARTAMENTO__PRODUTO/__LIST/"Ter o ROOT centralizado aqui evita repetição. Se um dia o nome do módulo ou da entidade mudar, basta atualizar o ROOT e tudo se ajusta.
proWBean() guarda o WBean em cache?
Em uma requisição, o WBean pode ser consultado várias vezes — a List chama no getFiltro(), depois no setFiltro(), depois pode chamar de novo em alguma subaction. Criar um WBean novo a cada chamada seria desperdício.
O atributo privado wbean começa null. Na primeira chamada ao proWBean(), o framework cria uma instância via getManager().getInstance(...) e guarda no atributo. Nas chamadas seguintes, devolve a mesma instância.
Esse padrão se chama lazy initialization: cria quando precisa, reusa depois. Importante: a instância é CACHED POR REQUISIÇÃO, não entre requisições — a Action inteira é descartada no fim do request (junto com o wbean).
getManager().getInstance() em vez de new DepartamentoProdutoWBean()?
Poderia ser new. Mas o framework Jasap tem um getInstance() que faz a mesma coisa — instancia — e de quebra deixa ganchos pra o framework injetar coisas se precisar (ex: configurar o manager no bean, aplicar regras de proxy, etc.).
Usar getManager().getInstance(Class) é a convenção do projeto. Todo WBean do projeto é criado assim. Ao seguir a convenção, você ganha comportamento padrão do framework de graça sem precisar entender o detalhe.
public abstract class DepartamentoProdutoAction extends AppsRootAction| Elemento | O que significa |
|---|---|
public | Actions concretas de outros pacotes vão estender |
abstract | Classe não pode ser instanciada diretamente — só serve como molde pras actions concretas (List, futura Form, DeleteFromList) |
extends AppsRootAction | Herda toda infraestrutura de action do projeto: ui(), getFactory(), preAjax(), getUser(), ok(), d2()..d7(), etc. |
proWBean() — lazy initialization do WBean| Linha | O que faz |
|---|---|
private DepartamentoProdutoWBean wbean = null | Campo privado de cache. Começa null — nenhum WBean criado ainda |
if (wbean == null) | Primeira chamada: cria o WBean. Chamadas seguintes: pula o if e devolve o que já foi criado |
getManager().getInstance(DepartamentoProdutoWBean.class) | Convenção do projeto — cria instância via framework em vez de new |
return wbean | Devolve a instância (recém-criada ou cacheada) |
ROOT — prefixo de permissões e sessãoConstante que monta o caminho raiz a partir do F_ACESSO_MODULO do Manager do Departamento. Concatena com "__PRODUTO/". Todas as chaves específicas da entidade Produto (permissões, sessão, constantes de tela) partem desse prefixo.
ROOT = "...DEPARTAMENTO__PRODUTO/"
LIST = "...DEPARTAMENTO__PRODUTO/__LIST/"
LIST + "__FILTRO" = "...DEPARTAMENTO__PRODUTO/__LIST/__FILTRO"
ROOT + "__EXCLUIR" = "...DEPARTAMENTO__PRODUTO/__EXCLUIR"