O plugin que criamos serve somente para retornar temas que são aplicados no HTML de cada capítulo.
São comuns plugins mais alinhados ao ciclo de vida da aplicação, também chamados de hooks (ganchos, em inglês).
No caso do Cotuba, seria interessante ter um plugin para ser chamado logo depois do ebook ser gerado.
Adicione um método aposGeracao
ao plugin do Cotuba, que recebe o ebook que acabou de ser gerado.
Acrescente também um método estático gerou
que, usando a Service Loader API, invoca todos os plugins.
Na classe Cotuba
, invoque o novo método estático, logo depois da geração do ebook.
- Defina um método chamado
aposGeracao
, que recebe umEbook
como parâmetro, na interfacePlugin
:
####### cotuba.plugin.Plugin
// outros imports...
public interface Plugin {
String cssDoTema();
static List<String> listaDeTemas() {
// código omitido...
}
void aposGeracao(Ebook ebook); // inserido
}
Defina o novo import:
####### cotuba.plugin.Plugin
import cotuba.domain.Ebook;
- Inclua, em
Plugin
, um método estáticogerou
, que recebe umEbook
. Use umServiceLoader
para obter todos os service providers, invocando o métodoaposGeracao
:
####### cotuba.plugin.Plugin
public interface Plugin {
// código omitido...
static void gerou(Ebook ebook) {
ServiceLoader<Plugin> loader = ServiceLoader.load(Plugin.class);
for (Plugin plugin : loader) {
plugin.aposGeracao(ebook);
}
}
}
- Na classe
Cotuba
, invoque o métodogerou
dePlugin
, logo após a geração do ebook:
####### cotuba.application.Cotuba
// outros imports...
public class Cotuba {
public void executa(ParametrosCotuba parametros) {
// código omitido...
GeradorEbook gerador = GeradorEbook.cria(formato);
gerador.gera(ebook);
Plugin.gerou(ebook); // inserido
}
}
Insira o import a seguir:
####### cotuba.application.Cotuba
import cotuba.plugin.Plugin;
-
(opcional) Use recursos do Java 8 como Lambdas e Streams para trabalhar com o
ServiceLoader
. -
(desafio) Otimize a chamada ao método estático
load
, da classeServiceLoader
, armazenando a instância deServiceLoader
retornada.
No momento em que colocamos mais um método na interface Plugin
do Cotuba, ocorreu um erro de compilação.
A classe TemaParadizo
do projeto tema-paradizo
, um service provider, precisa implementar todos os métodos declarados na SPI Plugin
.
Por isso, precisamos declarar uma implementação para o novo método aposGeracao
de Plugin
.
O que fazer na classe de tema, ao final da geração do ebook?
A resposta é fácil: nada!
Faça com que a classe TemaParadizo
não apresente erros de compilação.
- No projeto
tema-paradizo
, faça com que a classeTemaParadizo
implemente o novo métodoaposGeracao
dePlugin
.
Dica: digite CTRL + 1 em cima do nome da classe e escolha a opção Add unimplemented methods.
O resultado deve ser o seguinte:
####### br.com.paradizo.tema.TemaParadizo
public class TemaParadizo implements Plugin {
@Override
public String cssDoTema() {
return FileUtils.getResourceContents("/tema.css");
}
@Override
public void aposGeracao(Ebook ebook) { // inserido
}
}
Acrescente o import:
####### br.com.paradizo.tema.TemaParadizo
import cotuba.domain.Ebook;
Se testarmos a geração de ebooks, nada deve ser alterado.
Quais as palavras mais comuns no ebook?
A empresa Cognitio quer saber!
Para implementar a contagem de palavras, usarão o novo plugin, que é chamado após a geração do livro.
Para descobrir quais são as palavras do ebook, os desenvolvedores da Cognitio precisam:
- percorrer a lista de capítulos
- obter o HTML de cada capítulo
- remover as tags HTML, deixando só o texto
Por enquanto, apenas listarão as palavras. A contagem em si ficará para depois.
Crie um outro projeto Maven chamado estatisticas-ebook
.
Adicione como dependência o projeto cotuba-cli
.
Insira também uma dependência à biblioteca Jsoup, que será usada para remover as tags HTML.
Crie uma classe CalculadoraEstatisticas
, que servirá como service provider para a SPI Plugin
.
No método aposGeracao
, imprima no Console todas as palavras de todos os capítulos.
- No Eclipse, vá em File > New > Maven Project.
Marque a opção Create a simple project (skip archetype selection).
Desmarque a opção Use default Workspace location.
Em Location, coloque /home/<usuario-do-curso>/estatisticas-ebook
.
Não esqueça de trocar <usuario-do-curso>
pelo nome de usuário do curso.
Clique em Next.
Na próxima tela, preencha:
- Group Id:
br.com.cognitio
- Artifact Id:
estatisticas-ebook
Deixe o campo Version como 0.0.1-SNAPSHOT
e Packaging como jar
.
Os demais campos podem ficar vazios.
Clique em Finish.
- No
pom.xml
do projetoestatisticas-ebook
, corrija a codificação de caracteres e a versão do Java.
Como dependências, declare o projeto Cotuba e a biblioteca Jsoup.
####### estatisticas-ebook/pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>cotuba</groupId>
<artifactId>cotuba-cli</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.2</version>
</dependency>
</dependencies>
Clique com o botão direito no projeto estatisticas-ebook
e vá em Maven > Update project....
Selecione o projeto estatisticas-ebook
e clique em OK.
Assim, as mudanças no pom.xml
terão efeito.
- Crie, no pacote
br.com.cognitio.estatisticas
, a classeCalculadoraEstatisticas
. Implemente a interfacePlugin
de Cotuba, definindo os métodos necessários.
####### br.com.cognitio.estatisticas.CalculadoraEstatisticas
package br.com.cognitio.estatisticas;
import cotuba.domain.Ebook;
import cotuba.plugin.Plugin;
public class CalculadoraEstatisticas implements Plugin {
@Override
public String cssDoTema() {
return null;
}
@Override
public void aposGeracao(Ebook ebook) {
}
}
- Implemente o método
aposGeracao
, percorrendo a lista deCapitulo
doEbook
, obtendo o HTML de cada capítulo e extraindo as palavras, com a ajuda da biblioteca Jsoup.
Dica: o método split
de String
quebra um texto de acordo com uma expressão regular. A expressão regular \s+
pega vários espaços adjacentes.
####### br.com.cognitio.estatisticas.CalculadoraEstatisticas
for (Capitulo capitulo : ebook.getCapitulos()) {
String html = capitulo.getConteudoHTML();
Document doc = Jsoup.parse(html);
String textoDoCapitulo = doc.body().text();
String[] palavras = textoDoCapitulo.split("\\s+");
for (String palavra : palavras) {
System.out.println(palavra);
}
}
Realize os imports necessários:
####### br.com.cognitio.estatisticas.CalculadoraEstatisticas
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import cotuba.domain.Capitulo;
- Crie os subdiretórios
META-INF
eservices
no diretóriosrc/main/resources
.
Dentro, adicione um arquivo cotuba.plugin.Plugin
e defina o nome do service provider:
####### src/main/resources/META-INF/services/cotuba.plugin.Plugin
br.com.cognitio.estatisticas.CalculadoraEstatisticas
Gere os JARs dos projetos cotuba-cli
, tema-paradizo
e estatisticas-ebook
.
Teste a geração de um ebook e veja se as palavras são impressas no console.
- Abra um Terminal e entre na pasta do projeto
cotuba-cli
:
cd ~/cotuba
- Faça o build do
cotuba-cli
usando o Maven:
mvn install
- Descompacte o
.zip
gerado para o seu Desktop com o comando:
unzip -o target/cotuba-*-distribution.zip -d ~/Desktop
- Vá até a pasta do projeto
tema-paradizo
:
cd ~/tema-paradizo
- Faça o build do
tema-paradizo
usando o Maven:
mvn install
- Copie o JAR do plugin
tema-paradizo
para a pastalibs
do Cotuba, que está no Desktop:
cp target/tema-paradizo-*.jar ~/Desktop/libs/
- Vá até a pasta do projeto
estatisticas-ebook
:
cd ~/estatisticas-ebook
- Faça o build do
estatisticas-ebook
usando o Maven:
mvn install
- Copie o JAR do plugin
estatisticas-ebook
para a pastalibs
do Cotuba, que está no Desktop:
cp target/estatisticas-ebook-*.jar ~/Desktop/libs/
- Vá até o Desktop:
cd ~/Desktop
- Gere o PDF:
./cotuba.sh -d ~/cotuba/exemplo -f pdf
Verifique se cada palavra do ebook foi impressa.