3
respostas

Dificulpade para especializar DefaultPathResolver e PathAnnotationRoutesParser

Olá.

Preciso mudar as rotas de alguns controllers e o caminho dos respectivos JSPs. Tentei implementar com base nas informações que encontrei na página Componentes (site do VRaptor) e no javadoc do fw, mas não foi suficiente pra mim.

A ideia seria ter o pacote controller e controller.admin, como segue:

nomesistema.controller

nomesistema.controller.admin

O que estiver em nomesistema.controller deve continuar usando a convenção padrão do VRaptor. Já o que estiver em nomesistema.controller.admin deve buscar os JSPs nas pastas filhas de admin, como no caminho a seguir:

WEB-INF/jsp/admin/nomecontroller/nomemetodo

Ou seja, só adicionei a pasta admin logo abaixo de JSP

Me arrisquei no contrutor de PathAnnotationRoutesParser com o código a seguir, mas recebi vários erros. Se for o caso, eu posto depois. Mas como foi uma tentativa meio que cega, acho melhor esperar uma manifestação de alguém que saiba como isso funciona na versão atual do VRaptor.

@Inject
    public PackageRoutesParser(Router router, ReflectionProvider reflectionProvider) {
        super(router, reflectionProvider);
}

Observações:

No javadoc de PathAnnotationRoutesParses consta que o construtor tem um parâmetro, mas constatei pelo código da classe que há dois. No javadoc de DefaultPathResolver (e da interface PathResolver) as informações também são bem escaças. VRaptor é o primeiro framework MVC que estou estudando. Ainda não consigo me virar muito bem com pouca informação. E também ainda não tenho condições (e tempo disponível) suficiente para entender o código fonte do VRaptor antes de usá-lo. Comprei o livro da casa do código sobre VRaptor do Lucas Cavalcante e também uso como fonte de pesquisa, além do site do vraptor.

Desde já agradeço.

3 respostas

Opa, dá uma olhada aqui => http://www.vraptor.org/en/docs/components/

No fim da página tem um exemplo de customização justamente para o que vc precisa. Claro que sua implementação vai ser diferente da sugerida lá :).

Obrigado Alberto.

Consegui resolver a questão com as duas classes que seguem:

@Specializes
public class CustomPathResolver extends DefaultPathResolver {

    @Inject
    public CustomPathResolver(FormatResolver resolver) {
        super(resolver);
    }

    @Override
    public String pathFor(ControllerMethod method) {
        String name = method.getController().getType().getSimpleName();
        String folderName = extractControllerFromName(name);
        String path = getPrefix() + extractPackage(method) + folderName + "/"
                + method.getMethod().getName() + "." + getExtension();
        return path;
    }

    private String extractPackage(ControllerMethod method) {
        String[] subpackages = method.getController().getPackageName().split("\\.");
        if (subpackages[subpackages.length - 1].equals("controller")) {
            return "";
        }
        return subpackages[subpackages.length - 1] + "/";
    }
}


@Specializes
@ApplicationScoped
public class CustomRoutesParser extends PathAnnotationRoutesParser {

    @Inject
    public CustomRoutesParser(Router router, ReflectionProvider reflectionProvider) {
        super(router, reflectionProvider);
    }

    private String extractSubpackage(Class<?> type) {
        String[] subpackages = type.getPackage().getName().split("\\.");
        if (subpackages[subpackages.length - 1].equals("controller")) {
            return "";
        }
        return "/" + subpackages[subpackages.length - 1];
    }

    @Override
    protected String[] getURIsFor(Method javaMethod, Class<?> type) {
        String[] uris = super.getURIsFor(javaMethod, type);
        for (int i = 0; i < uris.length; i++) {
            uris[i] = extractSubpackage(type) + uris[i];
        }
        return uris;
    }
}

Terias alguma observação ou dica de melhoria no código acima?

Acho que ta ok sim!