== EAR with JMS and PgSQL ==
{{attachment:earFile.png}}

=== Setup postgresql in docker ===
{{{#!highlight bash
cd /app/jboss-5.1.0.GA/server/default/lib
wget https://jdbc.postgresql.org/download/postgresql-9.3-1103.jdbc3.jar
apt install postgresql-9.5

su postgres
mkdir -p /var/run/postgresql/9.5-main.pg_stat_tmp/
/usr/lib/postgresql/9.5/bin/postgres -D /var/lib/postgresql/9.5/main -c config_file=/etc/postgresql/9.5/main/postgresql.conf

su postgres
psql

create user appuser with login password '12345678';
create database app;
grant all privileges on database app to appuser;
\q

Datasource in Jboss , Local Tx Datasources
PostgresDS
org.postgresql.Driver
jdbc:postgresql://localhost/app?user=appuser&password=12345678

/app/jboss-5.1.0.GA/server/default/deploy# cat PostgresDS-ds.xml 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<datasources>
    <local-tx-datasource>
        <jndi-name>PostgresDS</jndi-name>
        <rar-name>jboss-local-jdbc.rar</rar-name>
        <use-java-context>true</use-java-context>
        <connection-definition>javax.sql.DataSource</connection-definition>
        <jmx-invoker-name>jboss:service=invoker,type=jrmp</jmx-invoker-name>
        <min-pool-size>0</min-pool-size>
        <max-pool-size>10</max-pool-size>
        <blocking-timeout-millis>30000</blocking-timeout-millis>
        <idle-timeout-minutes>30</idle-timeout-minutes>
        <prefill>false</prefill>
        <background-validation>false</background-validation>
        <background-validation-millis>0</background-validation-millis>
        <validate-on-match>true</validate-on-match>
        <statistics-formatter>org.jboss.resource.statistic.pool.JBossDefaultSubPoolStatisticFormatter</statistics-formatter>
        <isSameRM-override-value>false</isSameRM-override-value>
        <allocation-retry>0</allocation-retry>
        <allocation-retry-wait-millis>5000</allocation-retry-wait-millis>
        <security-domain xsi:type="securityMetaData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
        <metadata/>
        <local-transaction/>
        <prepared-statement-cache-size>0</prepared-statement-cache-size>
        <share-prepared-statements>false</share-prepared-statements>
        <set-tx-query-timeout>false</set-tx-query-timeout>
        <query-timeout>0</query-timeout>
        <use-try-lock>0</use-try-lock>
        <driver-class>org.postgresql.Driver</driver-class>
        <connection-url>jdbc:postgresql://localhost/app?user=appuser&amp;password=12345678</connection-url>
    </local-tx-datasource>
</datasources>
}}}

=== Create JMS queue ===
{{{#!highlight bash
mkdir -p /app/jboss-5.1.0.GA/server/default/deploy/queue
nano /app/jboss-5.1.0.GA/server/default/deploy/queue/ContactsQueue-service.xml 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<server>
    <mbean xmbean-dd="xmdesc/Queue-xmbean.xml" name="jboss.messaging.destination:service=Queue,name=ContactsQueue" code="org.jboss.jms.server.destination.QueueService">
        <attribute name="JNDIName">/queue/ContactsQueue</attribute>
        <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
        <depends>jboss.messaging:service=PostOffice</depends>
    </mbean>
</server>
}}}

=== Structure ===
{{{
.
├── deploy_to_target.sh
├── earcontacts
│   └── pom.xml
│
├── ejbcontacts
│   ├── pom.xml
│   └── src
│       └── main
│           ├── java
│           │   └── org
│           │       └── allowed
│           │           └── bitarus
│           │               ├── ContactEntity.java
│           │               ├── ContactsLocal.java
│           │               ├── ContactsMDB.java
│           │               ├── ContactsRemote.java
│           │               └── ContactsWS.java
│           └── resources
│               └── META-INF
│                   ├── ejb-jar.xml
│                   └── persistence.xml
├── pom.xml
└── warcontacts
    ├── pom.xml
    └── src
        └── main
            ├── java
            │   └── org
            │       └── allowed
            │           └── bitarus
            │               └── Handler.java
            └── webapp
                ├── add.jsp
                ├── css
                │   ├── bootstrap.min.css
                │   └── warcontacts.css
                ├── delete.jsp
                ├── head.jsp
                ├── index.jsp
                ├── js
                │   ├── bootstrap.min.js
                │   └── jquery-3.5.1.min.js
                ├── nav.jsp
                ├── update.jsp
                ├── view.jsp
                └── WEB-INF
                    └── web.xml
}}}

=== deploy_to_target.sh ===
{{{#!highlight bash
#!/bin/sh
rm ../contacts.tgz
tar cvzf ../contacts.tgz ../contacts
cp ../contacts.tgz ../target/
docker exec -it jboss5_container /bin/sh -c 'cd /app;rm -rf contacts; tar xvzf contacts.tgz'
docker exec -it jboss5_container /bin/sh -c 'cd /app/contacts; rm  /app/jboss-5.1.0.GA/server/default/deploy/earcontacts-0.0.1.ear; mvn clean install;'
docker exec -it jboss5_container /bin/sh -c 'cp  /app/contacts/earcontacts/target/earcontacts-0.0.1.ear /app/jboss-5.1.0.GA/server/default/deploy'
}}}

=== pom.xml ===
{{{#!highlight xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.allowed.bitarus</groupId>
	<artifactId>contacts</artifactId>
	<version>1.0</version>
	<packaging>pom</packaging>
	<modules>
		<module>ejbcontacts</module>
		<module>warcontacts</module>
		<module>earcontacts</module>
	</modules>
</project>
}}}

=== earcontacts/pom.xml ===
{{{#!highlight xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.allowed.bitarus</groupId>
	<artifactId>earcontacts</artifactId>
	<version>0.0.1</version>
	<packaging>ear</packaging>
	<dependencies>
		<dependency>
			<groupId>org.allowed.bitarus</groupId>
			<artifactId>warcontacts</artifactId>
			<version>0.0.1</version>
			<type>war</type>
		</dependency>
		<dependency>
			<groupId>org.allowed.bitarus</groupId>
			<artifactId>ejbcontacts</artifactId>
			<version>0.0.1</version>
			<type>ejb</type>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-ear-plugin</artifactId>
				<version>2.10.1</version>
				<configuration>
					<version>5</version>
					<defaultLibBundleDir>lib</defaultLibBundleDir>
					<filtering>true</filtering>
					<modules>
						<ejbModule>
							<groupId>org.allowed.bitarus</groupId>
							<artifactId>ejbcontacts</artifactId>
							<bundleDir>/</bundleDir>
						</ejbModule>
						<webModule>
							<groupId>org.allowed.bitarus</groupId>
							<artifactId>warcontacts</artifactId>
							<bundleDir>/</bundleDir>
						</webModule>
					</modules>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.5</source>
					<target>1.5</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>
}}}

=== ejbcontacts/pom.xml ===
{{{#!highlight xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.allowed.bitarus</groupId>
	<artifactId>ejbcontacts</artifactId>
	<version>0.0.1</version>
	<packaging>ejb</packaging>
	<dependencies>
		<dependency>
			<groupId>javaee</groupId>
			<artifactId>javaee-api</artifactId>
			<version>5</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.5</source>
					<target>1.5</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>
}}}

=== ejbcontacts/src/main/java/org/allowed/bitarus/ContactEntity.java ===
{{{#!highlight java
package org.allowed.bitarus;

import java.util.Date;
import javax.persistence.Id;
import javax.persistence.Entity;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.TemporalType;
import javax.persistence.Temporal;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;

@Entity
@NamedQueries( { @NamedQuery(name="Contacts.byId",query="select a from ContactEntity a where a.id = :id")   } )
public class ContactEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private long id;

    @Column
    @Temporal(TemporalType.TIMESTAMP) 
    private Date creationDate;

    @Column
    private String firstName;

    @Column
    private String lastName;

    @Column
    private String address;

    @Column
    private String phoneNumber;

    public void setId(long id){this.id=id;}
    public long getId(){return this.id;}

    public void setCreationDate(Date creationDate){this.creationDate=creationDate;}
    public Date getCreationDate(){return this.creationDate;}

    public void setFirstName(String firstName){this.firstName=firstName;}
    public String getFirstName(){return this.firstName;}

    public void setLastName(String lastName){this.lastName=lastName;}
    public String  getLastName(){return this.lastName;}

    public void setAddress(String address){this.address=address;}
    public String getAddress(){return this.address;}

    public void setPhoneNumber(String phoneNumber){this.phoneNumber=phoneNumber;}
    public String getPhoneNumber(){return this.phoneNumber;}

}
}}}

=== ejbcontacts/src/main/java/org/allowed/bitarus/ContactsLocal.java ===
{{{#!highlight java
package org.allowed.bitarus;

import javax.ejb.Local;
import java.util.List;

@Local
public interface ContactsLocal {
	void add(String firstName, String lastName, String address, String phoneNumber);

	List<ContactEntity> getAll();

	ContactEntity get(long id);

	void remove(long id);

	void edit(long id, String firstName, String lastName, String address, String phoneNumber);

	void sendMessage(String message);
}
}}}

=== ejbcontacts/src/main/java/org/allowed/bitarus/ContactsMDB.java ===
{{{#!highlight java
package org.allowed.bitarus;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

/*
mkdir -p /app/jboss-5.1.0.GA/server/default/deploy/queue
nano ContactsQueue-service.xml 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<server>
    <mbean xmbean-dd="xmdesc/Queue-xmbean.xml" name="jboss.messaging.destination:service=Queue,name=ContactsQueue" code="org.jboss.jms.server.destination.QueueService">
        <attribute name="JNDIName">/queue/ContactsQueue</attribute>
        <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
        <depends>jboss.messaging:service=PostOffice</depends>
    </mbean>
</server> 
 * */
@MessageDriven(mappedName = "queue/ContactsQueue", messageListenerInterface = MessageListener.class, activationConfig = {
		@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
		@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/ContactsQueue") })
public class ContactsMDB implements MessageListener {

	public void onMessage(Message inMessage) {
		try {
			String text = ((TextMessage) inMessage).getText();
			System.out.println(String.format("Got message %s", text));
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}
}}}

=== ejbcontacts/src/main/java/org/allowed/bitarus/ContactsRemote.java ===
{{{#!highlight java
package org.allowed.bitarus;

import javax.ejb.Remote;
import java.util.List;

@Remote
public interface ContactsRemote {
	void add(String firstName, String lastName, String address, String phoneNumber);

	List<ContactEntity> getAll();

	ContactEntity get(long id);

	void remove(long id);

	void edit(long id, String firstName, String lastName, String address, String phoneNumber);

	void sendMessage(String message);
}
}}}

=== ejbcontacts/src/main/java/org/allowed/bitarus/ContactsWS.java ===
{{{#!highlight java
package org.allowed.bitarus;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jws.WebMethod;
import javax.jws.WebService;
import org.allowed.bitarus.ContactsRemote;
import javax.persistence.PersistenceContext;
import javax.persistence.EntityManager;
import java.util.List;
import javax.persistence.NamedQuery;

@Stateless
@WebService
public class ContactsWS implements ContactsRemote, ContactsLocal {
	@PersistenceContext(unitName = "puContactsDefaultDS")
	EntityManager em;
	@Resource(mappedName = "ConnectionFactory")
	private ConnectionFactory connectionFactory;
	@Resource(mappedName = "queue/ContactsQueue")
	private Queue queue;

	@WebMethod
	public void add(String firstName, String lastName, String address, String phoneNumber) {
		ContactEntity c = new ContactEntity();
		c.setFirstName(firstName);
		c.setLastName(lastName);
		c.setAddress(address);
		c.setPhoneNumber(phoneNumber);
		c.setCreationDate(new java.util.Date());
		em.persist(c);
	}

	@WebMethod
	public List<ContactEntity> getAll() {
		return em.createQuery("select a from ContactEntity a ").getResultList();
	}

	@WebMethod
	public ContactEntity get(long id) {
		// return (ContactEntity) em.createQuery("select a from ContactEntity a where
		// a.id = :id").setParameter("id", id).getSingleResult();
		return (ContactEntity) em.createNamedQuery("Contacts.byId").setParameter("id", id).getSingleResult();
	}

	@WebMethod
	public void remove(long id) {
		ContactEntity ent = (ContactEntity) em.createNamedQuery("Contacts.byId").setParameter("id", id)
				.getSingleResult();
		em.remove(ent);
	}

	@WebMethod
	public void edit(long id, String firstName, String lastName, String address, String phoneNumber) {
		ContactEntity ent = (ContactEntity) em.createNamedQuery("Contacts.byId").setParameter("id", id)
				.getSingleResult();
		ent.setFirstName(firstName);
		ent.setLastName(lastName);
		ent.setAddress(address);
		ent.setPhoneNumber(phoneNumber);
		em.persist(ent);
	}

	@WebMethod
	public void sendMessage(String message) {
		try {
			Connection connection = connectionFactory.createConnection();
			Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
			MessageProducer messageProducer = session.createProducer(queue);
			TextMessage textMessage = session.createTextMessage();
			textMessage.setText(message);
			messageProducer.send(textMessage);
			messageProducer.close();
			session.close();
			connection.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}
}}}

=== ejbcontacts/src/main/resources/META-INF/ejb-jar.xml ===
{{{#!highlight xml
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
        version="3.0">
        <enterprise-beans>
                <session>
                        <ejb-name>ContactsWS</ejb-name>
                        <business-local>org.allowed.bitarus.ContactsLocal</business-local>
                        <business-remote>org.allowed.bitarus.ContactsRemote</business-remote>
                        <ejb-class>org.allowed.bitarus.ContactsWS</ejb-class>
                        <session-type>Stateless</session-type>
                        <transaction-type>Container</transaction-type>
                </session>
        </enterprise-beans>
</ejb-jar>
}}}

=== ejbcontacts/src/main/resources/META-INF/persistence.xml ===
{{{#!highlight xml
<persistence version="1.0"
	xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
	<persistence-unit name="puContactsDefaultDS"
		transaction-type="JTA">
		<jta-data-source>java:/PostgresDS</jta-data-source>
		<properties>
			<property name="hibernate.show_sql" value="true" />
			<property name="hibernate.format_sql" value="true" />
			<property name="hibernate.dialect"
				value="org.hibernate.dialect.PostgreSQLDialect" />
			<property name="hibernate.hbm2ddl.auto" value="update" />
		</properties>
	</persistence-unit>
</persistence>
}}}

=== warcontacts/pom.xml ===
{{{#!highlight xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.allowed.bitarus</groupId>
	<artifactId>warcontacts</artifactId>
	<version>0.0.1</version>
	<packaging>war</packaging>
	<dependencies>
		<dependency>
			<groupId>javaee</groupId>
			<artifactId>javaee-api</artifactId>
			<version>5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.allowed.bitarus</groupId>
			<artifactId>ejbcontacts</artifactId>
			<version>0.0.1</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.5</source>
					<target>1.5</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>
}}}

=== warcontacts/src/main/java/org/allowed/bitarus/Handler.java ===
{{{#!highlight java
package org.allowed.bitarus;

import java.util.logging.Logger;
import java.util.logging.Level;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.naming.InitialContext;

import java.io.IOException;
import java.util.List;
import javax.naming.NamingEnumeration;
import javax.naming.NameClassPair;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

public class Handler {	
	private static final String CONTACTS_WS_LOCAL = "earcontacts-0.0.1/ContactsWS/local";
	private ServletRequest request;
	private ServletResponse response;
	private JspWriter out;

	public Handler(ServletRequest request, ServletResponse response, JspWriter out) {
		this.request = request;
		this.response = response;
		this.out = out;
	}

	public Handler(PageContext pageContext) {
		this.request = pageContext.getRequest();
		this.response = pageContext.getResponse();
		this.out = (JspWriter) pageContext.getAttribute(PageContext.OUT);

		HttpServletRequest hsr = (HttpServletRequest) this.request;
		System.out.println(String.format("Current method %s", hsr.getMethod()));
		System.out.println(String.format("Path %s", hsr.getServletPath()));

		if ("POST".equals(hsr.getMethod())) {
			Map<String, String> params = hsr.getParameterMap();
			for (String key : params.keySet()) {
				System.out.println(String.format("%s:%s", key, hsr.getParameter(key)));
			}

			handleAddPost(hsr);
			handleDeletePost(hsr);
			handleUpdatePost(hsr);
		}
	}

	private void handleUpdatePost(HttpServletRequest hsr) {
		if ("/update.jsp".equals(hsr.getServletPath())) {
			try {
				InitialContext context = new InitialContext();
				ContactsLocal contacts = (ContactsLocal) context.lookup(CONTACTS_WS_LOCAL);
				long id = Integer.parseInt(hsr.getParameter("cid"));
				String firstName = hsr.getParameter("firstname");
				String lastName = hsr.getParameter("lastname");
				String address = hsr.getParameter("address");
				String phoneNumber = hsr.getParameter("phonenumber");
				contacts.edit(id, firstName, lastName, address, phoneNumber);
				redirectToIndex(hsr);
			} catch (Exception ex) {
			}
		}
	}

	private void handleDeletePost(HttpServletRequest hsr) {
		if ("/delete.jsp".equals(hsr.getServletPath())) {
			try {
				InitialContext context = new InitialContext();
				ContactsLocal contacts = (ContactsLocal) context.lookup(CONTACTS_WS_LOCAL);
				contacts.remove(Integer.parseInt(hsr.getParameter("id")));
				redirectToIndex(hsr);
			} catch (Exception ex) {
			}
		}
	}

	private void handleAddPost(HttpServletRequest hsr) {
		if ("/add.jsp".equals(hsr.getServletPath())) {
			try {
				InitialContext context = new InitialContext();
				ContactsLocal contacts = (ContactsLocal) context.lookup(CONTACTS_WS_LOCAL);
				contacts.add(hsr.getParameter("firstname"), hsr.getParameter("lastname"), hsr.getParameter("address"),
						hsr.getParameter("phonenumber"));
				redirectToIndex(hsr);
			} catch (Exception ex) {
			}
		}
	}

	private void redirectToIndex(HttpServletRequest hsr) throws IOException {
		((HttpServletResponse) this.response).sendRedirect(hsr.getContextPath() + "/index.jsp");
	}

	public void writeHandler() {
		try {
			this.out.println(String.format("<p>Handler up %s</p>", this.request.getParameter("user")));
		} catch (Exception ex) {
		}
	}

	public void writeIP() {
		try {
			this.out.print("!!! Your IP address is " + this.request.getRemoteAddr());
		} catch (Exception ex) {
		}
	}

	public List<ContactEntity> getAllContacts() {
		List<ContactEntity> ret = null;
		try {
			InitialContext context = new InitialContext();

			ContactsLocal contacts = (ContactsLocal) context.lookup(CONTACTS_WS_LOCAL);
			ret = contacts.getAll();
		} catch (Exception ex) {
		}
		return ret;
	}

	public ContactEntity getContact(long id) {

		ContactEntity ret = null;
		try {
			InitialContext context = new InitialContext();

			ContactsLocal contacts = (ContactsLocal) context.lookup(CONTACTS_WS_LOCAL);
			ret = contacts.get(id);
		} catch (Exception ex) {
		}

		return ret;
	}
}
}}}

=== warcontacts/src/main/webapp/add.jsp ===
{{{#!highlight xml
<%@page import="org.allowed.bitarus.Handler, java.util.List, org.allowed.bitarus.ContactEntity" %>
<% Handler h = new Handler(pageContext); %>
<html>
    <head>
        <jsp:include page="head.jsp" />  
    </head>
    <body>       
        <jsp:include page="nav.jsp" />
        <div class="container topspace">
            <div class="row"> 
                <div class="col-sm-2"></div>
                <div class="col-sm-8">    
                    <form  action="add.jsp" method="post"  >
                        <label for="firstname">First name:</label><br/>
                        <input type="text" id="firstname" name="firstname" class="form-control"><br/>
                        <label for="lastname">Last name:</label><br/>
                        <input type="text" id="lastname" name="lastname" class="form-control"><br/>
                        <label for="address">Address::</label><br/>
                        <input type="text" id="Address:" name="address" class="form-control"><br/>
                        <label for="phonenumber">Phone number:</label><br/>
                        <input type="text" id="phonenumber" name="phonenumber" class="form-control"><br/>
                        <input type="submit" value="Add"  class="form-control btn btn-primary button"/>
                    </form>    
                </div> 
                <div class="col-sm-2"></div>   
            </div>
        </div>          
    </body>
</html>
}}}

=== warcontacts/src/main/webapp/css/bootstrap.min.css ===

=== warcontacts/src/main/webapp/css/warcontacts.css ===
{{{#!highlight css
.button{margin-top:2px; margin-bottom:2px;}
.topspace { padding-top: 10px; }    2020-06-24T18:20:45 [vitor@debian:3 ~/JBoss5Docker/contacts]
}}}

=== warcontacts/src/main/webapp/delete.jsp ===
{{{#!highlight xml
<%@page import="org.allowed.bitarus.Handler, java.util.List, org.allowed.bitarus.ContactEntity" %>
<% Handler h = new Handler(pageContext); %>
<html>
    <head>
        <jsp:include page="head.jsp" />  
    </head>
    <body>       
        <% ContactEntity ci = h.getContact( Integer.parseInt( request.getParameter("id") ) );  %> 
        <jsp:include page="nav.jsp" />
        <div class="container  topspace">
            <div class="row"> 
                <div class="col-sm-2"></div>
                <div class="col-sm-8">         
                    <% if(ci!=null) { %>
                        <p><strong>Id:</strong>  <%= ci.getId() %></p>
                        <p><strong>First name:</strong>  <%= ci.getFirstName() %></p>
                        <p><strong>Last name:</strong>  <%= ci.getLastName() %></p>
                        <p><strong>Creation date:</strong> <%= ci.getCreationDate() %></p>
                        <p><strong>Address:</strong>  <%= ci.getAddress() %></p>
                        <p><strong>Phone:</strong>  <%= ci.getPhoneNumber() %></p>

                        <form action="delete.jsp" method="post">
                            <input type="hidden" id="id" name="id" value="<%=ci.getId()%>"  />
                            <input type="submit" class="form-control btn btn-primary button" value="Delete">
                        </form>
                    <% }  %>
                </div> 
                <div class="col-sm-2"></div>   
            </div>
        </div>              
    </body>
</html>
}}}

=== warcontacts/src/main/webapp/head.jsp ===
{{{#!highlight xml
  <link rel="stylesheet" href="css/bootstrap.min.css"/>
  <link rel="stylesheet" href="css/warcontacts.css"/>
  <script src="js/jquery-3.5.1.min.js"></script>
  <script src="js/bootstrap.min.js" ></script>
}}}

=== warcontacts/src/main/webapp/index.jsp ===
{{{#!highlight xml
<%@page import="org.allowed.bitarus.Handler, java.util.List, org.allowed.bitarus.ContactEntity" %>
<% Handler h = new Handler(pageContext); %>
<html>
	<head>
  		<jsp:include page="head.jsp" />  
	</head>
    <body>        
        <jsp:include page="nav.jsp" />      
 		<div class="container topspace">
    		<div class="row"> 
        		<div class="col-sm-2"></div>
        		<div class="col-sm-8">
        			<% List<ContactEntity> contacts = h.getAllContacts(); %>
        			<a href="add.jsp" class="btn btn-primary button">Add</a>
			        <table class="table table-stripped" >
			            <tr>
							<th>FirstName</th>
							<th>LastName</th>
							<th>Actions</th>
            			</tr>
         				<% for(int i=0; i<contacts.size() ;i++){  %>
            				<tr>
								<% ContactEntity contact = ((ContactEntity)contacts.get(i));  %>
								<td><%= contact.getFirstName() %></td>
								<td><%= contact.getLastName() %></td>
								<td>
    								<a href="view.jsp?id=<%=contact.getId()%>" class="btn btn-primary button">View</a>
   									<a href="update.jsp?id=<%=contact.getId()%>" class="btn btn-primary button">Update</a>
   									<a href="delete.jsp?id=<%=contact.getId()%>" class="btn btn-primary button">Delete</a>     
								</td>
            				</tr>
        				<%}%>
			       </table>
       			</div> 
       			<div class="col-sm-2"></div>   
     		</div>
   		</div> 
	</body>
</html>
}}}

=== warcontacts/src/main/webapp/js/bootstrap.min.js ===
=== warcontacts/src/main/webapp/js/jquery-3.5.1.min.js ===

=== warcontacts/src/main/webapp/nav.jsp ===
{{{#!highlight xml
<nav class="navbar navbar-dark bg-dark navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="index.jsp">Contacts</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
              <li class="active"><a href="index.jsp">List</a></li>
          </ul>
        </div>
    </div>
</nav>
}}}

=== warcontacts/src/main/webapp/update.jsp ===
{{{#!highlight xml
<%@page import="org.allowed.bitarus.Handler, java.util.List, org.allowed.bitarus.ContactEntity" %>
<% Handler h = new Handler(pageContext); %>
<html>
    <head>
        <jsp:include page="head.jsp" />  
    </head>
    <body>       
        <jsp:include page="nav.jsp" />
        <div class="container topspace">
            <div class="row"> 
                <div class="col-sm-2"></div>
                <div class="col-sm-8">              
					<% if( request.getParameter("id") != null ) { %>
					<% ContactEntity ci = h.getContact( Integer.parseInt( request.getParameter("id") ) );  %>
						<form  action="update.jsp" method="post"  >
  							<label for="firstname">First name:</label><br/>
  							<input class="form-control" type="text" id="firstname" name="firstname" value="<%= ci.getFirstName() %>"/><br/>
  							<label for="lastname">Last name:</label><br/>
  							<input class="form-control" type="text" id="lastname" name="lastname" value="<%= ci.getLastName() %>" /><br/>
  							<label for="address">Address::</label><br/>
  							<input class="form-control" type="text" id="Address:" name="address" value="<%= ci.getAddress() %>"/><br/>
  							<label for="phonenumber">Phone number:</label><br/>
  							<input class="form-control" type="text" id="phonenumber" name="phonenumber" value="<%= ci.getPhoneNumber() %>"/><br/>
  							<input class="form-control" type="hidden" id="cid" name="cid" value="<%=ci.getId()%>"/> 
 							<input type="submit" value="Update" class="form-control btn btn-primary button" >
						</form>
					<% } %>	
                </div> 
                <div class="col-sm-2"></div>   
            </div>
        </div>                   
    </body>
</html>
}}}

=== warcontacts/src/main/webapp/view.jsp ===
{{{#!highlight xml
<%@page import="org.allowed.bitarus.Handler, java.util.List, org.allowed.bitarus.ContactEntity" %>
<% Handler h = new Handler(pageContext); %>
<html>
    <head>
        <jsp:include page="head.jsp" />  
    </head>
    <body>       
        <jsp:include page="nav.jsp" />
        <div class="container topspace">
            <div class="row"> 
                <div class="col-sm-2"></div>
                <div class="col-sm-8">    
                    <% ContactEntity ci = h.getContact( Integer.parseInt( request.getParameter("id") ) );  %> 
                    <p><strong>Id:</strong>  <%= ci.getId() %></p>
                    <p><strong>First name:</strong>  <%= ci.getFirstName() %></p>
                    <p><strong>Last name:</strong>  <%= ci.getLastName() %></p>
                    <p><strong>Creation date:</strong> <%= ci.getCreationDate() %></p>
                    <p><strong>Address:</strong>  <%= ci.getAddress() %></p>
                    <p><strong>Phone:</strong>  <%= ci.getPhoneNumber() %></p>
                </div> 
                <div class="col-sm-2"></div>   
            </div>
        </div>         
    </body>
</html>
}}}

=== warcontacts/src/main/webapp/WEB-INF/web.xml ===
{{{#!highlight xml
<?xml version="1.0"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
</web-app>
}}}