package com.ubx1.pdpscanner.client.views.home;
import java.util.Date;
import java.util.Iterator;
import java.util.Map.Entry;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.ubx1.pdpscanner.client.PdpScanner;
import com.ubx1.pdpscanner.client.views.AbstractView;
import com.ubx1.pdpscanner.shared.Project;
import com.ubx1.pdpscanner.shared.exceptions.BadProjectNameException;
import com.ubx1.pdpscanner.shared.exceptions.BadReposAuthException;
import com.ubx1.pdpscanner.shared.exceptions.BadReposUrlException;
import com.ubx1.pdpscanner.shared.exceptions.InvalidSessionException;
import com.ubx1.pdpscanner.shared.exceptions.RepositoryException;
import com.ubx1.pdpscanner.shared.exceptions.RequiredFieldException;
import com.ubx1.pdpscanner.shared.validation.Validator;
/**
* The home view
*
* @author wbraik
*
*/
public class HomeView extends AbstractView {
// View components
private final FlexTable projectTable = new FlexTable();
private final Button addProjectButton = new Button();
private final PopupPanel addProjectPopup = new PopupPanel(false, true);
final VerticalPanel popupContents = new VerticalPanel();
Hyperlink instructionsLink = new Hyperlink("Voir les instructions", "Tips");
final Label nameLabel = new Label("Nom du projet *");
final TextBox nameTextBox = new TextBox();
final Label svnUrlLabel = new Label("URL du projet *");
final TextBox svnUrlTextBox = new TextBox();
final Label svnUserLabel = new Label("Utilisateur dépôt");
final TextBox svnUserTextBox = new TextBox();
final Label svnPasswordLabel = new Label("Mot de passe dépôt");
final PasswordTextBox svnPasswordTextBox = new PasswordTextBox();
final HorizontalPanel buttonPanel = new HorizontalPanel();
final Button okButton = new Button("OK");
final Button cancelButton = new Button("Annuler");
final HorizontalPanel loadingPanel = new HorizontalPanel();
final Image loadingImg = new Image("images/loading.gif");
final Label loadingLabel = new Label("Lecture du dépôt...");
/**
* 1 day in millis
*/
final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
/**
* The home view constructor
*/
public HomeView() {
super(new VerticalPanel());
nameTextBox.setMaxLength(255);
svnUrlTextBox.setMaxLength(255);
svnUserTextBox.setMaxLength(255);
svnPasswordTextBox.setMaxLength(255);
loadingPanel.setSpacing(5);
buttonPanel.setSpacing(5);
projectTable.setCellPadding(6);
projectTable.getRowFormatter().addStyleName(0, "projectsListHeader");
projectTable.addStyleName("projectsList");
projectTable.getCellFormatter().addStyleName(0, 0,
"projectsListLargeColumn");
projectTable.getCellFormatter().addStyleName(0, 1,
"projectsListSmallColumn");
projectTable.getCellFormatter().addStyleName(0, 2,
"projectsListSmallColumn");
projectTable.getCellFormatter().addStyleName(0, 3,
"projectsListLargeColumn");
projectTable.getCellFormatter().addStyleName(0, 4,
"projectsListSmallerColumn");
instructionsLink.setStyleDependentName("instructions", true);
}
@Override
public void buildView() {
// Initialize the project table
projectTable.setText(0, 0, "Nom du projet (créateur)");
projectTable.setText(0, 1, "Jours");
projectTable.setText(0, 2, "Lignes de code");
projectTable.setText(0, 3, "Date de création");
projectTable.setText(0, 4, "Supprimer");
// Add a new project button
addProjectButton.setText("Ajouter un projet");
addProjectButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
nameTextBox.setText("");
svnUrlTextBox.setText("");
svnUserTextBox.setText("");
svnPasswordTextBox.setText("");
loadingPanel.add(loadingImg);
loadingPanel.add(loadingLabel);
loadingPanel.setVisible(false);
// Fill popup contents
popupContents.add(instructionsLink);
popupContents.add(nameLabel);
popupContents.add(nameTextBox);
popupContents.add(svnUrlLabel);
popupContents.add(svnUrlTextBox);
popupContents.add(svnUserLabel);
popupContents.add(svnUserTextBox);
popupContents.add(svnPasswordLabel);
popupContents.add(svnPasswordTextBox);
buttonPanel.add(okButton);
buttonPanel.add(cancelButton);
popupContents.add(buttonPanel);
popupContents.add(loadingPanel);
addProjectPopup.setWidget(popupContents);
// Popup ok button
okButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
// Retrieve field values
String name = nameTextBox.getText().trim();
String svnUrl = svnUrlTextBox.getText().trim();
String svnUser = svnUserTextBox.getText().trim();
String svnPassword = svnPasswordTextBox.getText()
.trim();
// Get the current date and format it
DateTimeFormat dateFormatter = new DateTimeFormat(
"yyyy-MM-dd HH:mm:ss") {
};
String creationDate = dateFormatter.format(new Date());
// Validate field values
try {
if (PdpScanner.projects.containsKey(name)) {
throw new BadProjectNameException(name,
"Project name already exists");
} else {
Validator.validateProject(name, svnUrl,
svnUser, svnPassword);
okButton.setEnabled(false);
cancelButton.setEnabled(false);
instructionsLink.setVisible(false);
loadingPanel.setVisible(true);
// Add the new project
addProject(name, svnUrl, svnUser, svnPassword,
creationDate);
}
} catch (Exception caught) {
System.err.println(caught.getClass().getName()
+ " :: " + caught.getMessage());
// caught.printStackTrace();
if (caught instanceof RequiredFieldException) {
Window.alert(PdpScanner.REQUIRED_FIELDS_ERROR);
}
if (caught instanceof BadProjectNameException) {
Window.alert(PdpScanner.BAD_NAME_ERROR);
}
else if (caught instanceof BadReposUrlException) {
Window.alert(PdpScanner.BAD_URL_ERROR);
}
else if (caught instanceof BadReposAuthException) {
Window.alert(PdpScanner.BAD_PROJECT_REPOSITORY_CRENDENTIALS_ERROR);
}
}
}
});
// Popup svn url textbox
svnUrlTextBox.addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
if (event.getCharCode() == 13) {
okButton.click();
}
}
});
// Popup svn password textbox
svnPasswordTextBox.addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
if (event.getCharCode() == 13) {
okButton.click();
}
}
});
// Popup cancel button
cancelButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
// Close popup
addProjectPopup.hide();
}
});
// Show popup
addProjectPopup.center();
nameTextBox.setFocus(true);
}
});
// Set the home page layout
viewPanel.add(projectTable);
viewPanel.add(addProjectButton);
viewPanel.setStyleName("homeViewPanel");
}
/**
* Fill the project table
*/
public void fillProjectTable() {
// Empty the projects table in case it's a refresh
for (int i = 1; i < projectTable.getRowCount(); i++)
projectTable.removeRow(i);
int row = 1; // The row counter for the projects table
// The iterator, used to iterate over the projects hashmap
Iterator<Entry<String, Project>> it = PdpScanner.projects.entrySet()
.iterator();
while (it.hasNext()) {
final Project p = it.next().getValue();
// Add project to projects table
Hyperlink projectLink = new Hyperlink(p.getName() + " ("
+ p.getOwner() + ")", "Project~" + p.getName());
projectTable.setWidget(row, 0, projectLink);
// Compute the number of days elapsed between the project
// creation date and now
DateTimeFormat dateFormatter = new DateTimeFormat(
"yyyy-MM-dd HH:mm:ss") {
};
Date d1 = dateFormatter.parse(p.getCreationDate());
Date d2 = new Date();
String days = String.valueOf((d2.getTime() - d1.getTime())
/ MILLIS_PER_DAY);
projectTable.setText(row, 1, days);
if (p.getNloc(p.getVersionCount()) == -1)
projectTable.setText(row, 2, "--");
else
projectTable.setText(row, 2,
String.valueOf(p.getNloc(p.getVersionCount())));
dateFormatter = new DateTimeFormat("dd/MM/yyyy, à HH:mm") {
};
projectTable.setText(row, 3, dateFormatter.format(d1));
// Remove project button
Button removeProjectButton = new Button("x");
removeProjectButton.addStyleDependentName("remove");
removeProjectButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
// Ask confirmation before deleting the project
if (Window.confirm(PdpScanner.DELETE_PROJECT_CONFIRM)) {
HomeView.this.deleteProject(p);
}
}
});
projectTable.setWidget(row, 4, removeProjectButton);
// Update the row counter
row++;
}
}
/**
* Fetch the list of projects, and fill the project map
*/
public void fetchProjects() {
// Prepare callback
AsyncCallback<Project[]> callback = new AsyncCallback<Project[]>() {
@Override
public void onFailure(Throwable caught) {
System.err.println(caught.getClass().getName() + " :: "
+ caught.getMessage());
// caught.printStackTrace();
if (caught instanceof InvalidSessionException) {
History.newItem("Disconnected");
} else {
Window.alert(PdpScanner.FETCH_PROJECTS_ERROR);
}
}
@Override
public void onSuccess(Project[] result) {
// Clear the project hashmap
PdpScanner.projects.clear();
// Add projects to hashmap
for (int i = 0; i < result.length; i++) {
Project p = result[i];
PdpScanner.projects.put(p.getName(), p);
}
HomeView.this.fillProjectTable();
}
};
// Tell the server to fetch the project list in the database
PdpScanner.projectService.fetchProjects(callback);
}
/**
* Add a new project
*
* @param name
* the name of the new project
* @param svnUrl
* the repository's url of the new project
* @param svnUser
* username, used for authentication on the repository's server
* @param svnPassword
* password, used for authentication on the repository's server
* @param creationDate
* the creation date of the new project
*/
public void addProject(final String name, final String svnUrl,
final String svnUser, final String svnPassword,
final String creationDate) {
// Prepare callback
AsyncCallback<String> callback = new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
System.err.println(caught.getClass().getName() + " :: "
+ caught.getMessage());
// caught.printStackTrace();
if (caught instanceof BadReposUrlException)
Window.alert(PdpScanner.BAD_URL_ERROR);
else if (caught instanceof RepositoryException)
Window.alert(PdpScanner.CHECK_PROJECT_REPOSITORY_ERROR);
else
Window.alert(PdpScanner.ADD_PROJECT_ERROR);
okButton.setEnabled(true);
cancelButton.setEnabled(true);
loadingPanel.setVisible(false);
}
@Override
public void onSuccess(String result) { // WARN : result is null
Window.alert(PdpScanner.ADD_PROJECT_SUCCESS);
HomeView.this.addProjectPopup.hide();
okButton.setEnabled(true);
cancelButton.setEnabled(true);
instructionsLink.setVisible(true);
loadingPanel.setVisible(false);
fetchProjects();
}
};
// Tell the server to add the new project to the database
PdpScanner.projectService.addProject(name, svnUrl, svnUser,
svnPassword, creationDate, callback);
}
/**
* Delete a project
*
* @param p
* the project to delete
*/
private void deleteProject(Project p) {
// Prepare callback
AsyncCallback<String> callback = new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
System.err.println(caught.getClass().getName() + " :: "
+ caught.getMessage());
// caught.printStackTrace();
Window.alert(PdpScanner.DELETE_PROJECT_ERROR);
}
@Override
public void onSuccess(String result) {
Window.alert(PdpScanner.DELETE_PROJECT_SUCCESS);
HomeView.this.fetchProjects();
}
};
// Tell the project to delete the project from the database
PdpScanner.projectService.deleteProject(p.getId(), callback);
}
}