Home | Tutorials | Smart-Cloud | Smart-EIS | License | FAQ | Contact

Last Updated: March 26, 2021

The requirement of having Git Data Access is limited to very few use-cases and not designed to be scalable. Use-cases includes configuration management and data that needs to be versioned and rollbacked, so be sure to know when to use it.

Smart-Cloud Web project simplifies building Java database driven web applications based on JSF and PrimeFaces and Git. This example will create CRUD (Create, Read, Update, Delete) operations of Person information.

Pre-Requisite:

  1. Create GitHub Repository

  2. Create GitHub Access Token

  3. Have the repository url, branch, username,and password (or preferably access token) ready

If you have enabled 2-factor authentication on your Git account, you need to create a Personal Access Token and use it as your password.

Steps:

  1. Create Maven project with the following pom.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>com.jalalkiswani</groupId>
	<version>4.0.4-SNAPSHOT</version>
	<artifactId>smart-cloud-webstack-git-example</artifactId>
	<packaging>war</packaging>
	<properties>
		<smart-cloud.version>4.0.8</smart-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>com.jalalkiswani</groupId>
			<artifactId>smart-cloud-webstack</artifactId>
			<version>${smart-cloud.version}</version>
		</dependency>

		<dependency>
			<groupId>com.jalalkiswani</groupId>
			<artifactId>smart-cloud-standalone</artifactId>
			<version>${smart-cloud.version}</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>

	<build>
		<finalName>app</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>3.3.1</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

If you are using Eclipse, be sure to refresh your project (select your project→ right click→ Maven→ Update Project)

  1. Create config file at src/main/resources/config.properties with the following contents:

git-url=yourRepositoryUrl
git-username=yourRepositoryUserName
git-password=
git-password-plain=yourRepositoryPassword
git-branch=master
git.localpath=${env:user.home}/git-test
  1. Create Model class at src/main/java/com/app/person.Model.java with the following contents:

package com.app.person;

import java.io.Serializable;

public class Model implements Serializable {
	private String id;
	private String nationalId;
	private String name;
	private String email;
	private String address;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void setNationalId(String nationalId){
	  this.nationalId=nationalId;
	}

	public String getNationalId(){
	 return this.nationalId;
	}

	public void setName(String name){
	  this.name=name;
	}

	public String getName(){
	 return this.name;
	}

	public void setEmail(String email){
	  this.email=email;
	}

	public String getEmail(){
	 return this.email;
	}

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

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


	@Override
	public boolean equals(Object obj) {
	  if (obj == null) {
		return false;
	  }
	  return this.getId().equals(((Model) obj).getId());
	}

	@Override
	public int hashCode() {
	  if(this.id==null) {
	    return toString().hashCode();
	   }
	  return this.id.hashCode();
	}

	@Override
	public String toString(){
	  StringBuffer buf=new StringBuffer();
	  buf.append(this.id).append(",");
	  buf.append(this.nationalId).append(",");
	  buf.append(this.name).append(",");
	  buf.append(this.email).append(",");
	  buf.append(this.address).append(",");
	  return buf.toString();
	}
}
  1. Create DataAccess class at src/main/java/com/app/person.DataAccess.java with the following contents:

package com.app.person;

import java.util.*;

import org.eclipse.jgit.api.Git;

import com.jk.util.JKIOUtil;
import com.jk.util.JKObjectUtil;
import com.jk.util.activedirectory.JKGitWrapper;
import com.jk.util.config.JKConfig;

public class DataAccess {
	private static final String ID_FIELD_NAME = "id";
	private static JKGitWrapper gw = new JKGitWrapper();

	private static Git git= gw.password(JKConfig.getDefaultInstance().getProperty("git-password-plain")).cloneRepo();

	/////////////////////////////////////////
	public <T> void insert(T record) {
		List<T> list = getList((Class<T>) record.getClass());
		list.add(record);
		save((Class<T>)record.getClass(), list);
	}

	/////////////////////////////////////////
	public <T> T find(Class<T> clas, Object id) {
		List<T> list = getList(clas);
		for (T t : list) {
			if (JKObjectUtil.getFieldValue(t, ID_FIELD_NAME).equals(id)) {
				return t;
			}
		}
		return null;
	}

	/////////////////////////////////////////
	public <T> void update(T record) {
		List<T> list = (List<T>) getList(record.getClass());
		for (int i=0;i<list.size();i++) {
			T t = list.get(i);
			Object sourceId = JKObjectUtil.getFieldValue(record, ID_FIELD_NAME);
			Object currentId = JKObjectUtil.getFieldValue(t, ID_FIELD_NAME);
			if (currentId.equals(sourceId)) {
				list.set(i, record);
				save((Class<T>)record.getClass(), list);
				return;
			}
		}
	}

	/////////////////////////////////////////
	public <T> void delete(T record) {
		List<T> list = (List<T>) getList(record.getClass());
		for (int i=0;i<list.size();i++) {
			T t = list.get(i);
			Object sourceId = JKObjectUtil.getFieldValue(record, ID_FIELD_NAME);
			Object currentId = JKObjectUtil.getFieldValue(t, ID_FIELD_NAME);
			if (currentId.equals(sourceId)) {
				list.remove(i);
				save((Class<T>)record.getClass(), list);
				return;
			}
		}
	}

	/////////////////////////////////////////
	public <T> List<T> getList(Class<T> clas) {
		String filePath = getFilePath(clas);
		String fileContents = JKIOUtil.readFile(filePath);
		if(fileContents==null) {
			return new Vector<>();
		}
		List<T> all = (List<T>) JKObjectUtil.jsonToObjectList(fileContents, clas);
		return all;
	}

	/////////////////////////////////////////
	protected <T> void save(Class<T> clas, List<T> list) {
		String contents = JKObjectUtil.toJson(list);
		JKIOUtil.writeDataToFile(contents, getFilePath(clas));
		gw.addCommitPush(git);
	}

	/////////////////////////////////////////
	protected <T> String getFilePath(Class<T> clas) {
		String fileName = clas.getName() + ".json";
		String filePath = gw.getLocalPath() + "/" + fileName;
		return filePath;
	}

}
  1. Create controller (JSF Managed Bean) at src/main/java/com/app/person/Controller.java with the following contents:

package com.app.person;

import java.util.List;
import java.util.UUID;
import java.util.Vector;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import com.jk.web.faces.mb.JKManagedBean;

@ManagedBean(name = "controller")
@ViewScoped
public class Controller extends JKManagedBean {
	DataAccess da = new DataAccess();
	Model model;
	List<Model> modelList;
	List<Model> filterList;

	public boolean isAllowAdd() {
		return getModel().getId() == null;
	}

	public String add() {
		model.setId(UUID.randomUUID().toString());
		da.insert(model);
		refresh();
		success("Added Successfully");
		return null;
	}

	public boolean isAllowUpdate() {
		return getModel().getId() != null;
	}

	public String update() {
		da.update(model);
		String id=getModel().getId();
		success("Updated Successfully");
		refresh();
		//to ensure getting updated version from DB
		this.model=da.find(Model.class, id);
		return null;
	}

	public boolean isAllowDelete() {
		return getModel().getId() != null;
	}

	public String delete() {
		da.delete(getModel());
		success("Deleted Successfully");
		refresh();
		return null;
	}

	public String reset() {
		setModel(null);
		return null;
	}

	public Model getModel() {
		if (model == null) {
			model = new Model();
		}
		return model;
	}

	public void setModel(Model model) {
		this.model = model;
	}

	public List<Model> getModelList() {
		if (modelList == null) {
			modelList = da.getList(Model.class);
		}
		return modelList;
	}

	public List<Model> getFilterList() {
		return filterList;
	}

	public void setFilterList(Vector<Model> filterList) {
		this.filterList = filterList;
	}

	protected void refresh() {
		this.modelList = null;
		setModel(null);
	}
}
  1. Create JSF XHTML Page at src/main/webapp/index.xhtml class with the following contents:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:h="http://xmlns.jcp.org/jsf/html"
	xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:p="http://primefaces.org/ui">
<h:head>
	<title>Smart-Cloud Demo</title>
</h:head>
<h:body>
	<h:form id="frmPerson">
		<p:autoUpdate />
		<p:growl />
		<p:panelGrid columns="4" style="margin:auto;" styleClass="shaddow">
			<f:facet name="header">Person Form</f:facet>

			<p:outputLabel value="National Id" for="nationalId" />
			<p:inputText type="text" value="#{controller.model.nationalId}" id="nationalId" placeholder="NationalId" required="true" />

			<p:outputLabel value="Name" for="name" />
			<p:inputText type="text" value="#{controller.model.name}" id="name" placeholder="Name" required="true" />

			<p:outputLabel value="Email" for="email" />
			<p:inputText type="email" value="#{controller.model.email}" id="email" placeholder="Email" required="true" />

			<p:outputLabel value="Address" for="address" />
			<p:inputTextarea id="address" value="#{controller.model.address}" readOnly="false" required="false" placeholder="Address" />
			<f:facet name="footer">
				<div align="center">
					<p:commandButton value="Add" action="#{controller.add}" rendered="#{controller.allowAdd}" process="@form" />
					<p:commandButton value="Update" action="#{controller.update}" rendered="#{controller.allowUpdate}" process="@form" />
					<p:commandButton value="Delete" action="#{controller.delete}" rendered="#{controller.allowDelete}" process="@this" />
					<p:commandButton value="Reset" action="#{controller.reset}" process="@this" />
				</div>
			</f:facet>

		</p:panelGrid>
	</h:form>
	<hr />
	<h:form>
		<p:dataTable value="#{controller.modelList}" var="model" rowKey="#{model.id}" paginator="true" paginatorAlwaysVisible="false"
			paginatorPosition="bottom" selectionMode="single" filteredValue="#{controller.filterList}" selection="#{controller.model}" emptyMessage=""
			rowIndexVar="row" styleClass="shaddow">
			<p:ajax event="rowSelect" />
			<p:autoUpdate />
			<f:facet name="header">Person Data Table</f:facet>
			<p:column headerText="#">#{row+1}</p:column>
			<p:column headerText="national id" sortBy="#{model.nationalId}" filterBy="#{model.nationalId}" filterMatchMode="contains">
				<h:outputText value="#{model.nationalId==null?'-':model.nationalId}" />
			</p:column>
			<p:column headerText="name" sortBy="#{model.name}" filterBy="#{model.name}" filterMatchMode="contains">
				<h:outputText value="#{model.name==null?'-':model.name}" />
			</p:column>
			<p:column headerText="email" sortBy="#{model.email}" filterBy="#{model.email}" filterMatchMode="contains">
				<h:outputText value="#{model.email==null?'-':model.email}" />
			</p:column>
			<p:column headerText="address" sortBy="#{model.address}" filterBy="#{model.address}" filterMatchMode="contains">
				<h:outputText value="#{model.address==null?'-':model.address}" />
			</p:column>
		</p:dataTable>
	</h:form>
</h:body>

</html>
  1. Create App class at src/main/java/com/app/App.java with the following contents:

package com.app;

import com.jk.web.embedded.JKWebApplication;

public class App {
	public static void main(String[] args) {
		JKWebApplication.run(8080);
	}
}

Thats it, now run your App class, in few seconds your browser will open and you should see something like this:

Output

Full example source-code can be found at https://github.com/smartapi-com/smart-cloud-web-git


Home | Tutorials | Smart-Cloud | Smart-EIS | License | FAQ | Contact