Package com.ubx1.pdpscanner.server.services

Source Code of com.ubx1.pdpscanner.server.services.ProjectServiceImpl

package com.ubx1.pdpscanner.server.services;

import java.sql.ResultSet;
import java.util.ArrayList;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.BasicAuthenticationManager;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.wc.ISVNInfoHandler;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNInfo;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNWCClient;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.ubx1.pdpscanner.client.FindbugsCategory;
import com.ubx1.pdpscanner.client.services.ProjectService;
import com.ubx1.pdpscanner.server.database.BCrypt;
import com.ubx1.pdpscanner.server.database.MySQLConnection;
import com.ubx1.pdpscanner.shared.FindbugsBugInstance;
import com.ubx1.pdpscanner.shared.Project;
import com.ubx1.pdpscanner.shared.UserRole;
import com.ubx1.pdpscanner.shared.exceptions.BadProjectNameException;
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.validation.Validator;

/**
* The project service implementation
*
* @author wbraik
*
*/
public class ProjectServiceImpl extends RemoteServiceServlet implements
    ProjectService {

  private static final long serialVersionUID = 1L;

  /**
   * Obtain the list of all projects from the database
   *
   * @return an array containing all projects, each of them encapsulated in a
   *         Project object
   */
  @Override
  public Project[] fetchProjects() throws Exception {

    MySQLConnection conn = new MySQLConnection();
    conn.connect();

    ResultSet rs1 = conn
        .SQLSelect("SELECT * FROM projects JOIN users_in_projects ON projects.id = users_in_projects.project "
            + "JOIN users ON "
            + "users_in_projects.user = users.id "
            + "WHERE users_in_projects.project = projects.id"
            + " AND users_in_projects.role = "
            + UserRole.OWNER.code());

    ArrayList<Project> projectsList = new ArrayList<>();

    while (rs1.next()) {

      Project p = new Project(rs1.getInt("id"),
          rs1.getString("users.name"),
          rs1.getString("projects.name"), rs1.getString("repos_url"),
          rs1.getString("repos_user"),
          rs1.getString("repos_password"), rs1.getDate(
              "creation_date").toString()
              + " " + rs1.getTime("creation_date").toString());

      // Get project's loc stat for all versions
      ResultSet rs2 = conn
          .SQLSelect("SELECT * FROM versions JOIN general_stats "
              + "ON versions.project = " + rs1.getInt("id")
              + " AND general_stats.version = versions.id "
              + "ORDER BY versions.version");

      while (rs2.next()) {
        int nloc = rs2.getInt("nloc");
        if (!rs2.wasNull())
          p.addNloc(nloc);
        else
          p.addNloc(-1);
      }

      projectsList.add(p);
    }

    conn.disconnect();

    return projectsList.toArray(new Project[0]);
  }

  /**
   * Add a new project to the database
   *
   * @param name
   *            the name of the new project
   * @param svnUrl
   *            the repository location for 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
   */
  @Override
  public String addProject(String name, String svnUrl, String svnUser,
      String svnPassword, String creationDate) throws Exception {

    if (getThreadLocalRequest().isRequestedSessionIdValid()) {

      int ownerId = Integer.parseInt((String) getThreadLocalRequest()
          .getSession().getAttribute("id"));

      /*
       * Validate project
       */
      Validator.validateProject(name, svnUrl, svnUser, svnPassword);

      try {
        SVNURL.parseURIDecoded(svnUrl);
      } catch (SVNException e) {

        throw new BadReposUrlException(svnUrl,
            "Invalid repository url format");
      }

      try {
        checkProjectRepository(svnUrl, svnUser, svnPassword);

        MySQLConnection conn = new MySQLConnection();
        conn.connect();

        ResultSet rs = conn.SQLSelect("SELECT * FROM projects");

        // Check project name unicity
        while (rs.next()) {

          String s = rs.getString("name");

          if (s.equals(name)) {

            throw new BadProjectNameException(name,
                "Project name already exists");
          }
        }

        // Prepare insert sql statement
        name = "'" + name + "'";
        svnUrl = "'" + svnUrl + "'";

        if (!svnUser.isEmpty())
          svnUser = "'" + svnUser + "'";
        else
          svnUser = "NULL";

        if (!svnPassword.isEmpty()) {
          svnPassword = "'"
              + BCrypt.hashpw(svnPassword, BCrypt.gensalt())
              + "'";
        } else
          svnPassword = "NULL";

        creationDate = "'" + creationDate + "'";

        int projectId = conn
            .SQLUpdate("INSERT INTO projects (name,repos_url,repos_user,repos_password,creation_date)"
                + " VALUES ("
                + name
                + ","
                + svnUrl
                + ","
                + svnUser
                + ","
                + svnPassword
                + ","
                + creationDate + ")");

        conn.SQLUpdate("INSERT INTO users_in_projects (user,project,role)"
            + " VALUES ("
            + ownerId
            + ","
            + projectId
            + ","
            + UserRole.OWNER.code() + ")");

        conn.disconnect();
      } catch (SVNException e) {

        throw new RepositoryException(svnUrl, svnUser, svnPassword,
            "Project repository couldn't be reached (svn info)");
      }

      return null;
    } else {

      throw new InvalidSessionException();
    }
  }

  /**
   * Delete a project from the databse
   *
   * @param id
   *            the id of the project to delete
   * @return a null String object
   */
  public String deleteProject(int id) throws Exception {

    MySQLConnection conn = new MySQLConnection();
    conn.connect();

    // First delete the associated stats
    conn.SQLUpdate("DELETE FROM general_stats "
        + "USING versions,general_stats " + "WHERE versions.project = "
        + id + " AND general_stats.version = versions.id");

    conn.SQLUpdate("DELETE FROM test_stats " + "USING versions,test_stats "
        + "WHERE versions.project = " + id
        + " AND test_stats.version = versions.id");

    conn.SQLUpdate("DELETE FROM findbugs_stats "
        + "USING versions,findbugs_stats "
        + "WHERE versions.project = " + id
        + " AND findbugs_stats.version = versions.id");

    // Then delete the project's users
    conn.SQLUpdate("DELETE FROM users_in_projects "
        + "WHERE users_in_projects.project = " + id);

    // Then delete the project's versions
    conn.SQLUpdate("DELETE FROM versions WHERE project = " + id);

    // Finally delete the project itself
    conn.SQLUpdate("DELETE FROM projects WHERE id = " + id);

    conn.disconnect();

    return null;
  }

  /**
   * Obtain the statistics for a particular project from the database
   *
   * @param p
   *            the project for which to retrieve the stats
   * @return the modified Project object, which now contains the stats
   */
  @Override
  public Project fetchStats(Project p) throws Exception {

    MySQLConnection conn = new MySQLConnection();
    conn.connect();

    // Get project's stats for all versions
    ResultSet rs1 = conn
        .SQLSelect("SELECT * FROM versions JOIN general_stats "
            + "ON general_stats.version = versions.id "
            + "WHERE versions.project = " + p.getId()
            + " ORDER BY versions.version");

    ResultSet rs2 = conn
        .SQLSelect("SELECT * FROM versions JOIN test_stats "
            + "ON test_stats.version = versions.id "
            + "WHERE versions.project = " + p.getId()
            + " ORDER BY versions.version");

    ResultSet rs3 = conn
        .SQLSelect("SELECT * FROM versions JOIN findbugs_stats "
            + "ON findbugs_stats.version = versions.id "
            + "WHERE versions.project = " + p.getId()
            + " ORDER BY versions.version");

    // fetchProjects() already fetched the nlocs which now might be from an
    // old version, so clear them then fetch them again
    p.clearNlocs();

    // Get project's general stats
    while (rs1.next()) {

      int nloc = rs1.getInt("nloc");
      if (!rs1.wasNull())
        p.addNloc(nloc);
      else
        p.addNloc(-1);

      int npkg = rs1.getInt("npkg");
      if (!rs1.wasNull())
        p.addNpkg(npkg);
      else
        p.addNpkg(-1);

      int nfile = rs1.getInt("nfile");
      if (!rs1.wasNull())
        p.addNfile(nfile);
      else
        p.addNfile(-1);

      int nfunc = rs1.getInt("nfunc");
      if (!rs1.wasNull())
        p.addNfunc(nfunc);
      else
        p.addNfunc(-1);

      int ncl = rs1.getInt("ncl");
      if (!rs1.wasNull())
        p.addNcl(ncl);
      else
        p.addNcl(-1);

      int ncom = rs1.getInt("ncom");
      if (!rs1.wasNull())
        p.addNcom(ncom);
      else
        p.addNcom(-1);

      int ndupl = rs1.getInt("ndupl");
      if (!rs1.wasNull())
        p.addNdupl(ndupl);
      else
        p.addNdupl(-1);
    }

    // Get project's test stats
    while (rs2.next()) {

      int ncovl = rs2.getInt("ncovl");
      if (!rs2.wasNull())
        p.addNcovl(ncovl);
      else
        p.addNcovl(-1);
    }

    int currentVersion = 0;

    ArrayList<FindbugsBugInstance> bps = null;
    ArrayList<FindbugsBugInstance> ps = null;

    // Get project's Findbugs bug instances
    while (rs3.next()) {

      int version = rs3.getInt("version");

      // We got to the next version
      if (version > currentVersion) {
        currentVersion++;

        if (bps != null) {
          p.addBp(bps);
          p.addP(ps);
        }

        bps = new ArrayList<FindbugsBugInstance>();
        ps = new ArrayList<FindbugsBugInstance>();

        String category = rs3.getString("category");
        // If category is null, Findbugs bug instances are unavailable
        // for this version
        if (rs3.wasNull()) {

          p.addBp(null);
          p.addP(null);
        } else {

          String abbrev = rs3.getString("abbrev");

          String type = rs3.getString("type");

          String file = rs3.getString("file");
          if (rs3.wasNull())
            file = null;

          int line = rs3.getInt("line");
          if (rs3.wasNull())
            line = -1;

          FindbugsBugInstance fb = new FindbugsBugInstance(category,
              abbrev, type, file, line);

          if (category.equals(FindbugsCategory.BAD_PRACTICE
              .toString())) {

            bps.add(fb);
          } else {
            ps.add(fb);
          }
        }
      }
      // We are reading the same version as in the previous loop, ignore
      // anything but Findbugs
      else {
        // Get project's Findbugs bug instances
        String category = rs3.getString("category");

        String abbrev = rs3.getString("abbrev");

        String type = rs3.getString("type");

        String file = rs3.getString("file");
        if (rs3.wasNull())
          file = null;

        int line = rs3.getInt("line");
        if (rs3.wasNull())
          line = -1;

        FindbugsBugInstance fb = new FindbugsBugInstance(category,
            abbrev, type, file, line);

        if (category.equals(FindbugsCategory.BAD_PRACTICE.toString())) {

          bps.add(fb);
        } else {
          ps.add(fb);
        }
      }
    }

    p.addBp(bps);
    p.addP(ps);

    conn.disconnect();

    return p;
  }

  /**
   * Check access to the project repository to make sure the analyszer will be
   * able to checkout the project later
   *
   * @param svnUrl
   *            the URL from which to checkout the project
   * @param svnUser
   *            used for authentication on the repository's server
   * @param svnPassword
   *            used for authentication on the repository's server
   */
  private void checkProjectRepository(String svnUrl, String svnUser,
      String svnPassword) throws SVNException {

    SVNClientManager svnClientManager = SVNClientManager.newInstance();

    if (!svnUser.isEmpty() && !svnPassword.isEmpty()) {

      ISVNAuthenticationManager authManager = new BasicAuthenticationManager(
          svnUser, svnPassword);
      svnClientManager.setAuthenticationManager(authManager);
    }

    SVNWCClient wcClient = svnClientManager.getWCClient();

    wcClient.setIgnoreExternals(false);

    wcClient.doInfo(SVNURL.parseURIDecoded(svnUrl), SVNRevision.HEAD,
        SVNRevision.HEAD, SVNDepth.IMMEDIATES, new ISVNInfoHandler() {

          @Override
          public void handleInfo(SVNInfo info) throws SVNException {

            System.out.println("svn info : " + info.getPath());
          }
        });
  }
}
TOP

Related Classes of com.ubx1.pdpscanner.server.services.ProjectServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.