<commit_before>== Developing Forge

Now that you've installed JBoss Forge, played with it a bit (either with CLI or JBDS), it's time to quickly develop a real web application and extend it by adding Hibernate Envers. In this section you will execute a JBoss Forge script and learn how to develop add-ons.

=== Developing a Java EE 7 web application in few seconds

As you've seen in the previous section, with Forge you can enter a few commands, and you'll get code generated. With scaffolding you can even quickly generate a set of JSF pages and REST endpoints to have CRUD capabilities. So, even if you type on your keyboard very quickly, how can you develop an entire Java EE 7 web application in a few seconds? The answer is simple: by running a Forge script! 

A forge script is just a file that contains a set of commands. The commands below create a new `Country` entity with a set of fields. As you can see we can even have comments that start with the `#` symbol. You can end you lines with a `;` but you don't have to :

[source, console]
----
#  Country entity
#  ############
jpa-new-entity --named Country ;
jpa-new-field --named isoCode --length 2 --columnName iso_code --not-nullable ;
jpa-new-field --named name --length 80 --not-nullable ;
jpa-new-field --named printableName --length 80 --columnName printable_name --not-nullable ;
jpa-new-field --named iso3 --length 3 ;
jpa-new-field --named numcode --length 3 ;
----

If you save these commands into a file called `country.fsh` then, you just have to execute with : 

[source, console]
----
[cdbookstore]$ run country.fsh
----

You will see Forge executing line by line each command in a few seconds. So what about running a bigger script?

==== The famous Java Petstore is back

The good thing about the http://www.oracle.com/technetwork/java/petstore1-3-1-02-139690.html[Java Petstore] is that we don't have to explain it much: most of us have heard about it. Haven't You? 

image::developing/petstore-splash.png[title="Petstore splash" align="center"]

The Java Petstore was a sample application created by Sun for its http://www.oracle.com/technetwork/java/javaee/blueprints/index.html[Java BluePrints] program. The Java Petstore was designed to illustrate how J2EE (and then Java EE) could be used to develop an eCommerce web application. Yes, the point of the Petstore is to sell pets online. The Petstore had a huge momentum and we started to see plenty of Petstore-like applications flourish. The idea was to build an application with a certain technology. Let's face it, the J2EE version was far too complex using plenty of (today outdated) http://java.sun.com/blueprints/corej2eepatterns/[design patterns]. 

With a single Forge script, you will generate a CRUD application that will let you manage the Pet's back-end catalog. 

==== Executing the script

First of all, download the script from https://github.com/forge/docs/blob/master/tutorials/forge-hol/script/generate.fsh. You can have a look into it. As you can see, the script:

- creates and sets up the project (a Java EE 7 one)
- creates the domain model with entities, embeddables, constraints and enums. Most of the entities have relationships (One-to-One, Many-to-One...) with others
- creates utility classes, exceptions, CDI qualifiers, interceptors
- adds a service layer with EJBs
- scaffolds JSF pages and creates new JSF beans
- generates REST endpoints
- cleans the `pom.xml` to get rid of some dependencies and add new ones

Now execute the script with :

[source, console]
----
[temps]$ run generate.fsh
----

Depending on the location of the script file, you can also run : 

[source, console]
----
[temps]$ run ../../code/script/generate.fsh
----

You will see hundreds of lines of code scrolling. Once the project is successfully created, have a look at the thousands of lines of code (Java, XML, HTML, CSS...) that Forge generated. The only missing feature today in Forge is the ability to generate methods. That's why some classes are just empty (e.g. the service tier). But adding method is in the roadmap. 

And the best of all, is that it works! To build the application, just do it in Forge :

[source, console]
----
[petstore]$ build
----

==== Running the application

Before deploying the application on http://www.wildfly.org/[WildFly] you can grab the SQL script https://github.com/forge/docs/blob/master/tutorials/forge-hol/script/import.sql and copy it to `petstore/src/main/resources`. This will add data to the database.

Then, just deploy the war file into WildFly, go to the URL http://localhost:8080/petstore and you should see the following homepage :

image::developing/petstore-forge.png[title="Petstore home page" align="center"]

Do not hesitate to browse the database content, create new items, remove customers, filter addresses, update categories... JBoss Forge has just created an entire CRUD web application for our domain model dealing with all the many-to-one, one-to-one... relationships.

Also check the REST interfaces. You can use any REST client (such as Postman for example) to GET/POST/PUT/DELETE data to the database. Got to the following URLs to get a clue :

- http://localhost:8080/petstore/rest/customers
- http://localhost:8080/petstore/rest/customers/1000
- http://localhost:8080/petstore/rest/countries
- http://localhost:8080/petstore/rest/countries/1000
- http://localhost:8080/petstore/rest/countries?max=5

==== Looking at the generated code

Now that you've seen it running, it's time to take a break, fill up a cup of coffee and have a look at the code. This is what you will find in the following packages :

- `constraints` : Bean validation constraints.
- `exceptions` : Application exceptions.
- `model`: The entities, embeddables, enums.
- `rest` : The REST endpoint doing GET/POST/PUT/DELETE operations. Also check the `RestApplication` class.
- `security` : Classes for security mater
- `service` : EJB layer
- `util` : Some CDi qualifiers, interceptors, producers
- `view` : JSF backing beans using CDI conversation, extended persistence context
- `webapp` : JSF pages, Bootstrap 2, templates, css files, images

NOTE: Some of the classes that you've seen are empty or not totally implemented. When you go back home and have time to dig this topic, you can check the final application at https://github.com/agoncal/agoncal-application-petstore-ee7

Now that you have a real application up and running, let's use JBoss Forge to extend it by developping a few add-ons and applying them to the Petstore application.

=== Developing Hibernate Envers addon

http://envers.jboss.org/[Hibernate Envers] is a Hibernate core module that enables auditing of persistence classes.
If you want to audit the history of all the changes made to a certain entity or one of its fields during the web
application runtime, you just need to audit that with `@Audited`. Envers will create a separate table for each such
entity, which will hold the changes made to it. +

In this section we will develop a Forge addon with the following features:

* Setup Envers for the following project by adding its dependency to the POM
* Enable auditing an entity by adding the `@Audited` annotation on class level

==== Creating a new Forge addon

Creating a new Forge addon is similar to any new project that you want to create. You can do it manually, you can copy
and modify an existing project of the same type or you can use a wizard to do it for you. We would certainly recommend
using Forge to help you bootstrap everything for several reasons. It knows exactly which dependencies and artifacts
you need as a start so you will not miss anything. Forge will also not create any garbage in your new project. +

Before creating the Envers addon, you need to start Forge. Please make sure that you have followed the instructions
in <<installing-forge>> before that. You can create a new addon if you run the following command in the Forge CLI: +

[source, console]
----
$ project-new --named envers --type addon --topLevelPackage org.jboss.forge.addon --addons org.jboss.forge.addon:javaee,2.12.0.Final
----

If you run Forge from JBDS, open the Forge wizard (Ctrl + 4 or CMD + 4 on Mac) then select _Project: New_ and specify
_envers_ as project name, _org.jboss.forge.addon_ as top level package, enter project location per your preference and
as a Project type select _Forge Addon_:

image::developing/forge-new-project.png[title="Creating new addon project"]

This will create an empty Maven project that has the following artifacts:

* `pom.xml` where the top level package is the group ID and the project name is the artifact ID. Besides the minimum
Forge dependencies, the command will add also those that you have specified with the `--addons` option in the format
<group-id>:<artifact-id>,<version>
* Standard maven directory structure plus the top level package
* *Empty `beans.xml` in the `src/main/resources/META-INF` directory. This is because Forge and its addons strongly
rely on the CDI development model
* `README.asciidoc` file with a standard skeleton for documenting Forge addons

==== Developing the "Envers: Setup" command

The first command that we are going to create will set up Envers for a project. This basically means that the command
will simply add the Envers library dependency to the current project POM. As with the new Forge addon, we can manually
write the command class, copy and modify an existing command or let Forge itself generated it for us. Here we will go
for the third option.

If you are running from the command line interface, type in: +

[source, console]
----
[envers]$ addon-new-ui-command --named EnversSetupCommand --commandName "Envers: Setup" --categories "Auditing"
----

While from the JBDS, after opening the Forge wizard (Ctrl + 4 or CMD + 4 on Mac), you should choose _Addon: New UI Command_
and enter _EnversSetupCommand_ in the Type Name field, _Envers: Setup_ in the Command name field and add _Auditing_ to
the Categories list box: +

image::developing/forge-envers-setup-command.png[title="Creating _Envers: Setup_ command"]

This will generate `EnversSetupCommand` class in the `org.jboss.forge.addon.commands` package (unless you didn't specify
explicitly anything else). Forge makes this class extend `AbstractUICommand`, which provides some basic functionality
like configuring the command name, the command dialog and the command execution. We will go through these in this and
the next few sections. +

The `getMetadata()` method should be already implemented by Forge:

[source, java]
----
   @Override
   public UICommandMetadata getMetadata(UIContext context)
   {
      return Metadata.forCommand(EnversSetupCommand.class).name(
            "Envers: Setup").category(Categories.create("Auditing"));
   }
----

This will basically create a command that can be called _envers-setup_ from the CLI (note the substitution of colons and
spaces by hyphens) and as _Envers: Setup_ in the _Auditing_ category in the Forge wizard +

As the newly created command will not require any input from the user, we will leave the `initializeUI` method empty.
However, in order to implement the command execution, we will need to change a little bit our class. More precisely we
will have to extend from another abstract command class. The rationale behind this is that we want to update the
*current* project POM. Extending `org.jboss.forge.addon.projects.ui.AbstractProjectCommand` instead of `AbstractUICommand` will give us some handy
methods to access and manipulate the project configuration:

[source, java]
----
public class EnversSetupCommand extends AbstractProjectCommand
{
----

We will have to implement two more abstract methods coming from this parent class:

[source, java]
----
   @Override
   protected boolean isProjectRequired() 
   {
      return true;
   }

   @Inject
   private ProjectFactory projectFactory;

   @Override
   protected ProjectFactory getProjectFactory() 
   {
       return projectFactory;
   }
----

After having specified _Envers: Setup_ as a project command, we can proceed to implementing the `execute` method.
Usually this is called when the user clicks _Finish_ on the command dialog or in our case where we don't require input:
when the user selects the command from the Forge wizard. +

As we mentioned earlier, the command will have to add the Hibernate Envers dependency to the project. We are going to
build the Forge representation of this dependency using the DependencyBuilder's utility methods:

[source, java]
----
   @Override
   public Result execute(UIExecutionContext context) throws Exception
   {
      Dependency dependency = 
            DependencyBuilder.create("org.hibernate")
                             .setArtifactId("hibernate-envers")
                             .setVersion("4.3.6.Final")
                             .setScopeType("provided");
   }

----

Speaking in Maven terms, this is a dependency to artifact with ID +hibernate-envers+, coming from the +org.hibernate+
group, having version 4.3.6.Final and going into the project's _provided_ scope. +

After we have specified our dependency, we will have to add it to the project model. For that purpose we will use the
`org.jboss.forge.addon.projects.dependencies.DependencyInstaller` utility, coming from the projects addon:

[source, java]
----
   @Inject
   private DependencyInstaller dependencyInstaller;
----

Forge 2.0 is based on modular runtime called _Furnace_. The core of Furnace itself is not bound to any development model,
so the addons can decide which of the Furnace implementations it wants to use. We created our addon with the default
configuration which enables the CDI development model. That is why we asked in the code snippet above Forge to provide
us with the dependency installer for the current project build system. +

Now it is time to install our dependency:

[source, java]
----<commit_msg>Minor changes<commit_after>== Developing Forge

Now that you've installed JBoss Forge, played with it a bit (either with CLI or JBDS), it's time to quickly develop a real web application and extend it by adding Hibernate Envers. In this section you will execute a JBoss Forge script and learn how to develop add-ons.

=== Developing a Java EE 7 web application in few seconds

As you've seen in the previous section, with Forge you can enter a few commands, and you'll get code generated. With scaffolding you can even quickly generate a set of JSF pages and REST endpoints to have CRUD capabilities. So, even if you type on your keyboard very quickly, how can you develop an entire Java EE 7 web application in a few seconds? The answer is simple: by running a Forge script! 

A forge script is just a file that contains a set of commands. The commands below create a new `Country` entity with a set of fields. As you can see we can even have comments that start with the `#` symbol. You can end you lines with a `;` but you don't have to :

[source, console]
----
#  Country entity
#  ############
jpa-new-entity --named Country ;
jpa-new-field --named isoCode --length 2 --columnName iso_code --not-nullable ;
jpa-new-field --named name --length 80 --not-nullable ;
jpa-new-field --named printableName --length 80 --columnName printable_name --not-nullable ;
jpa-new-field --named iso3 --length 3 ;
jpa-new-field --named numcode --length 3 ;
----

If you save these commands into a file called `country.fsh` then, you just have to execute with : 

[source, console]
----
[cdbookstore]$ run country.fsh
----

You will see Forge executing line by line each command in a few seconds. So what about running a bigger script?

==== The famous Java Petstore is back

The good thing about the http://www.oracle.com/technetwork/java/petstore1-3-1-02-139690.html[Java Petstore] is that we don't have to explain it much: most of us have heard about it. Haven't You? 

image::developing/petstore-splash.png[title="Petstore splash" align="center"]

The Java Petstore was a sample application created by Sun for its http://www.oracle.com/technetwork/java/javaee/blueprints/index.html[Java BluePrints] program. The Java Petstore was designed to illustrate how J2EE (and then Java EE) could be used to develop an eCommerce web application. Yes, the point of the Petstore is to sell pets online. The Petstore had a huge momentum and we started to see plenty of Petstore-like applications flourish. The idea was to build an application with a certain technology. Let's face it, the J2EE version was far too complex using plenty of (today outdated) http://java.sun.com/blueprints/corej2eepatterns/[design patterns]. 

With a single Forge script, you will generate a CRUD application that will let you manage the Pet's back-end catalog. 

==== Executing the script

First of all, download the script from https://github.com/forge/docs/blob/master/tutorials/forge-hol/script/generate.fsh. You can have a look into it. As you can see, the script:

- creates and sets up the project (a Java EE 7 one)
- creates the domain model with entities, embeddables, constraints and enums. Most of the entities have relationships (One-to-One, Many-to-One...) with others
- creates utility classes, exceptions, CDI qualifiers, interceptors
- adds a service layer with EJBs
- scaffolds JSF pages and creates new JSF beans
- generates REST endpoints
- cleans the `pom.xml` to get rid of some dependencies and add new ones

Now execute the script with :

[source, console]
----
[temps]$ run generate.fsh
----

Depending on the location of the script file, you can also run : 

[source, console]
----
[temps]$ run ../../code/script/generate.fsh
----

You will see hundreds of lines of code scrolling. Once the project is successfully created, have a look at the thousands of lines of code (Java, XML, HTML, CSS...) that Forge generated. The only missing feature today in Forge is the ability to generate methods. That's why some classes are just empty (e.g. the service tier). But adding method is in the roadmap. 

And the best of all, is that it works! To build the application, just do it in Forge :

[source, console]
----
[petstore]$ build
----

==== Running the application

Before deploying the application on http://www.wildfly.org/[WildFly] you can grab the SQL script https://github.com/forge/docs/blob/master/tutorials/forge-hol/script/import.sql and copy it to `petstore/src/main/resources`. This will add data to the database.

Then, just deploy the war file into WildFly, go to the URL http://localhost:8080/petstore and you should see the following homepage :

image::developing/petstore-forge.png[title="Petstore home page" align="center"]

Do not hesitate to browse the database content, create new items, remove customers, filter addresses, update categories... JBoss Forge has just created an entire CRUD web application for our domain model dealing with all the many-to-one, one-to-one... relationships.

Also check the REST interfaces. You can use any REST client (such as Postman for example) to GET/POST/PUT/DELETE data to the database. Got to the following URLs to get a clue :

- http://localhost:8080/petstore/rest/customers
- http://localhost:8080/petstore/rest/customers/1000
- http://localhost:8080/petstore/rest/countries
- http://localhost:8080/petstore/rest/countries/1000
- http://localhost:8080/petstore/rest/countries?max=5

==== Looking at the generated code

Now that you've seen it running, it's time to take a break, fill up a cup of coffee and have a look at the code. This is what you will find in the following packages :

- `constraints` : Bean validation constraints.
- `exceptions` : Application exceptions.
- `model`: The entities, embeddables, enums.
- `rest` : The REST endpoint doing GET/POST/PUT/DELETE operations. Also check the `RestApplication` class.
- `security` : Classes for security mater
- `service` : EJB layer
- `util` : Some CDi qualifiers, interceptors, producers
- `view` : JSF backing beans using CDI conversation, extended persistence context
- `webapp` : JSF pages, Bootstrap 2, templates, css files, images

NOTE: Some of the classes that you've seen are empty or not totally implemented. When you go back home and have time to dig this topic, you can check the final application at https://github.com/agoncal/agoncal-application-petstore-ee7

Now that you have a real application up and running, let's use JBoss Forge to extend it by developping a few add-ons and applying them to the Petstore application.

=== Developing Hibernate Envers addon

http://envers.jboss.org/[Hibernate Envers] is a Hibernate core module that enables auditing of persistence classes.
If you want to audit the history of all the changes made to a certain entity or one of its fields during the web
application runtime, you just need to audit that with `@Audited`. Envers will create a separate table for each such
entity, which will hold the changes made to it. +

In this section we will develop a Forge addon with the following features:

* Setup Envers for the following project by adding its dependency to the POM
* Enable auditing an entity by adding the `@Audited` annotation on class level

==== Creating a new Forge addon

Creating a new Forge addon is similar to any new project that you want to create. You can do it manually, you can copy
and modify an existing project of the same type or you can use a wizard to do it for you. We would certainly recommend
using Forge to help you bootstrap everything for several reasons. It knows exactly which dependencies and artifacts
you need as a start so you will not miss anything. Forge will also not create any garbage in your new project. +

Before creating the Envers addon, you need to start Forge. Please make sure that you have followed the instructions
in <<installing-forge>> before that. You can create a new addon if you run the following command in the Forge CLI: +

[source, console]
----
$ project-new --named envers --type addon --topLevelPackage org.jboss.forge.addon --addons org.jboss.forge.addon:javaee,2.12.0.Final
----

If you run Forge from JBDS, open the Forge wizard (Ctrl + 4 or CMD + 4 on Mac) then select _Project: New_ and specify
_envers_ as project name, _org.jboss.forge.addon_ as top level package, enter project location per your preference and
as a Project type select _Forge Addon_:

image::developing/forge-new-project.png[title="Creating new addon project"]

This will create an empty Maven project that has the following artifacts:

* `pom.xml` where the top level package is the group ID and the project name is the artifact ID. Besides the minimum
Forge dependencies, the command will add also those that you have specified with the `--addons` option in the format
<group-id>:<artifact-id>,<version>
* Standard maven directory structure plus the top level package
* *Empty `beans.xml` in the `src/main/resources/META-INF` directory. This is because Forge and its addons strongly
rely on the CDI development model
* `README.asciidoc` file with a standard skeleton for documenting Forge addons

==== Developing the "Envers: Setup" command

The first command that we are going to create will set up Envers for a project. This basically means that the command
will simply add the Envers library dependency to the current project POM. As with the new Forge addon, we can manually
write the command class, copy and modify an existing command or let Forge itself generated it for us. Here we will go
for the third option.

If you are running from the command line interface, type in: +

[source, console]
----
[envers]$ addon-new-ui-command --named EnversSetupCommand --commandName "Envers: Setup" --categories "Auditing"
----

While from the JBDS, after opening the Forge wizard (Ctrl + 4 or CMD + 4 on Mac), you should choose _Addon: New UI Command_
and enter _EnversSetupCommand_ in the Type Name field, _Envers: Setup_ in the Command name field and add _Auditing_ to
the Categories list box: +

image::developing/forge-envers-setup-command.png[title="Creating _Envers: Setup_ command"]

This will generate `EnversSetupCommand` class in the `org.jboss.forge.addon.commands` package (unless you didn't specify
explicitly anything else). Forge makes this class extend `AbstractUICommand`, which provides some basic functionality
like configuring the command name, the command dialog and the command execution. We will go through these in this and
the next few sections. +

The `getMetadata()` method should be already implemented by Forge:

[source, java]
----
   @Override
   public UICommandMetadata getMetadata(UIContext context)
   {
      return Metadata.forCommand(EnversSetupCommand.class).name(
            "Envers: Setup").category(Categories.create("Auditing"));
   }
----

This will basically create a command that can be called _envers-setup_ from the CLI (note the substitution of colons and
spaces by hyphens) and as _Envers: Setup_ in the _Auditing_ category in the Forge wizard +

As the newly created command will not require any input from the user, we will leave the `initializeUI` method empty.
However, in order to implement the command execution, we will need to change a little bit our class. More precisely we
will have to extend from another abstract command class. The rationale behind this is that we want to update the
*current* project POM. Extending `org.jboss.forge.addon.projects.ui.AbstractProjectCommand` instead of `AbstractUICommand` will give us some handy
methods to access and manipulate the project configuration:

[source, java]
----
public class EnversSetupCommand extends AbstractProjectCommand
{
----

We will have to implement two more abstract methods coming from this parent class:

[source, java]
----
   @Override
   protected boolean isProjectRequired() 
   {
      return true;
   }

   @Inject
   private ProjectFactory projectFactory;

   @Override
   protected ProjectFactory getProjectFactory() 
   {
       return projectFactory;
   }
----

The `org.jboss.forge.addon.projects.ProjectFactory` interface is used to create new or obtain references to existing project.

After having specified _Envers: Setup_ as a project command, we can proceed to implementing the `execute` method.
Usually this is called when the user clicks _Finish_ on the command dialog or in our case where we don't require input:
when the user selects the command from the Forge wizard. +

As we mentioned earlier, the command will have to add the Hibernate Envers dependency to the project. We are going to
build the Forge representation of this dependency using the DependencyBuilder's utility methods:

[source, java]
----
   @Override
   public Result execute(UIExecutionContext context) throws Exception
   {
      Dependency dependency = 
            DependencyBuilder.create("org.hibernate")
                             .setArtifactId("hibernate-envers")
                             .setVersion("4.3.6.Final")
                             .setScopeType("provided");
   }

----

Speaking in Maven terms, this is a dependency to artifact with ID +hibernate-envers+, coming from the +org.hibernate+
group, having version 4.3.6.Final and going into the project's _provided_ scope. +

After we have specified our dependency, we will have to add it to the project model. For that purpose we will use the
`org.jboss.forge.addon.projects.dependencies.DependencyInstaller` utility, responsible for installing a given dependency into the project :

[source, java]
----
   @Inject
   private DependencyInstaller dependencyInstaller;
----

Forge 2.0 is based on modular runtime called _Furnace_. The core of Furnace itself is not bound to any development model,
so the addons can decide which of the Furnace implementations it wants to use. We created our addon with the default
configuration which enables the CDI development model. That is why we asked in the code snippet above Forge to provide
us with the dependency installer for the current project build system. +

Now it is time to install our dependency:

[source, java]
----
{'fraction_non_alphanumeric': 0.07146945199599371, 'fraction_numerical': 0.005437115467162685, 'mean_word_length': 3.9923214285714286, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 6, 'lorem ipsum': 0, 'www.': 6, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3307858', 'n_tokens_mistral': 7665, 'n_tokens_neox': 7245, 'n_words': 3843}