2020-01-05 17:24:43 +01:00
/ *
* Copyright ( C ) 2020 Christian Pierre MOMON < christian . momon @devinsy.fr >
*
* This file is part of AgirStatool , simple key value database .
*
* AgirStatool is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation , either version 3 of the
* License , or ( at your option ) any later version .
*
* AgirStatool is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with AgirStatool . If not , see < http : //www.gnu.org/licenses/>.
* /
package org.april.agirstatool.core ;
import java.io.File ;
import java.io.IOException ;
2020-01-18 09:55:56 +01:00
import java.nio.charset.StandardCharsets ;
2020-01-05 17:24:43 +01:00
import java.sql.Connection ;
import java.sql.PreparedStatement ;
import java.sql.ResultSet ;
import java.sql.SQLException ;
2020-01-22 19:10:43 +01:00
import java.time.LocalDateTime ;
import java.time.ZoneOffset ;
2020-01-05 17:24:43 +01:00
import org.apache.commons.io.FileUtils ;
2020-01-21 20:07:49 +01:00
import org.april.agirstatool.charts.DateCount ;
import org.april.agirstatool.charts.DateCountList ;
import org.april.agirstatool.charts.DateCountMap ;
2020-01-05 17:24:43 +01:00
import org.april.agirstatool.cli.SQLUtils ;
2020-01-18 09:55:56 +01:00
import org.april.agirstatool.core.pages.ProjectPage ;
2020-01-05 17:24:43 +01:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import fr.devinsy.strings.StringList ;
/ * *
* The class AgirStatool .
*
* @author Christian Pierre MOMON
* /
public class AgirStatool
{
private static Logger logger = LoggerFactory . getLogger ( AgirStatool . class ) ;
2020-01-20 23:10:41 +01:00
public static final char ALONE_INDICATOR = '@' ;
2020-01-05 17:24:43 +01:00
private Connection connection ;
private File targetDirectory ;
/ * *
2020-01-23 09:00:46 +01:00
* Instantiates a new agir statool .
*
* @param connector
* the connector
* @param targetDirectory
* the target directory
2020-01-05 17:24:43 +01:00
* /
public AgirStatool ( final Connection connector , final File targetDirectory )
{
if ( connector = = null )
{
throw new IllegalArgumentException ( " Null parameter (connector). " ) ;
}
else if ( targetDirectory = = null )
{
throw new IllegalArgumentException ( " Null parameter (target directory). " ) ;
}
else if ( ! targetDirectory . exists ( ) )
{
throw new IllegalArgumentException ( " Target directory does not exist. " ) ;
}
else if ( ! targetDirectory . isDirectory ( ) )
{
throw new IllegalArgumentException ( " Target directory is not a directory. " ) ;
}
else
{
this . connection = connector ;
this . targetDirectory = targetDirectory ;
}
}
/ * *
* Builds the text project extended list .
*
* @return the string list
* @throws AgirStatoolException
* the agir statool exception
* /
public StringList doBuildTextProjectExtendedList ( ) throws AgirStatoolException
{
StringList result ;
result = new StringList ( ) ;
2020-01-20 23:10:41 +01:00
Projects projects = listProjectsWithoutSubStats ( ) . sortByName ( ) ;
2020-01-05 18:31:03 +01:00
String header = String . format ( " %3s %-30s %-30s %s %s %6s %6s %7s %7s %7s %7s %9s %7s %7s " ,
" ID " ,
" Identifier " ,
" Name " ,
" ParentId " ,
" Child " ,
" Count " ,
" New " ,
" Ongoing " ,
" Resolved " ,
" Closed " ,
" Rejected " ,
" Confirmed " ,
" Maybe " ,
" Waiting " ) ;
2020-01-05 17:24:43 +01:00
result . appendln ( header ) ;
for ( Project project : projects )
{
2020-01-05 18:31:03 +01:00
String line = String . format ( " %3d %-30s %-30s %4d %4d %7d %7d %7d %7d %7d %7d %9d %7d %7s " ,
project . getId ( ) ,
project . getIdentifier ( ) ,
project . getName ( ) ,
project . getParentId ( ) ,
project . getChildCount ( ) ,
project . issueStats ( ) . getCount ( ) ,
project . issueStats ( ) . getNewCount ( ) ,
project . issueStats ( ) . getOngoingCount ( ) ,
project . issueStats ( ) . getResolvedCount ( ) ,
project . issueStats ( ) . getClosedCount ( ) ,
project . issueStats ( ) . getRejectedCount ( ) ,
project . issueStats ( ) . getConfirmedCount ( ) ,
project . issueStats ( ) . getMaybeCount ( ) ,
project . issueStats ( ) . getWaitingCount ( ) ) ;
2020-01-05 17:24:43 +01:00
result . appendln ( line ) ;
}
//
return result ;
}
/ * *
2020-01-23 09:00:46 +01:00
* Do build text project list .
2020-01-05 17:24:43 +01:00
*
* @return the string list
2020-01-23 09:00:46 +01:00
* @throws AgirStatoolException
* the agir statool exception
2020-01-05 17:24:43 +01:00
* /
public StringList doBuildTextProjectList ( ) throws AgirStatoolException
{
StringList result ;
result = new StringList ( ) ;
Projects projects = listProjects ( ) . sortByName ( ) ;
String header = String . format ( " %3s %-30s %-30s %s %s " , " ID " , " Identifier " , " Name " , " ParentId " , " ChildCount " ) ;
result . appendln ( header ) ;
for ( Project project : projects )
{
2020-01-05 18:31:03 +01:00
String line = String . format ( " %3d %-30s %-30s %4d %4d " ,
project . getId ( ) ,
project . getIdentifier ( ) ,
project . getName ( ) ,
project . getParentId ( ) ,
project . getChildCount ( ) ) ;
2020-01-05 17:24:43 +01:00
result . appendln ( line ) ;
}
//
return result ;
}
/ * *
2020-01-23 09:00:46 +01:00
* Do clear all pages .
*
* @throws AgirStatoolException
* the agir statool exception
2020-01-05 17:24:43 +01:00
* /
public void doClearAllPages ( ) throws AgirStatoolException
{
try
{
2020-01-18 09:55:56 +01:00
// TODO: add filter on .xhtml and .css file.
2020-01-05 17:24:43 +01:00
for ( File file : this . targetDirectory . listFiles ( ) )
{
FileUtils . forceDelete ( file ) ;
}
}
catch ( IOException exception )
{
throw new AgirStatoolException ( " Error clearing target directory: " + exception . getMessage ( ) , exception ) ;
}
}
/ * *
2020-01-23 09:00:46 +01:00
* Do refresh pages .
*
* @throws AgirStatoolException
* the agir statool exception
2020-01-05 17:24:43 +01:00
* /
2020-01-18 09:55:56 +01:00
public void doRefreshPages ( ) throws AgirStatoolException
2020-01-05 17:24:43 +01:00
{
try
{
2020-01-06 08:26:13 +01:00
// Copy CSS file.
2020-01-19 23:33:40 +01:00
FileUtils . copyURLToFile ( AgirStatool . class . getResource ( " /org/april/agirstatool/core/pages/index.html " ) , new File ( this . targetDirectory , " index.html " ) ) ;
2020-01-05 17:24:43 +01:00
FileUtils . copyURLToFile ( AgirStatool . class . getResource ( " /org/april/agirstatool/core/pages/agirstatool.css " ) , new File ( this . targetDirectory , " agirstatool.css " ) ) ;
2020-01-18 09:55:56 +01:00
FileUtils . copyURLToFile ( AgirStatool . class . getResource ( " /org/april/agirstatool/core/pages/Chart.bundle.min.js " ) , new File ( this . targetDirectory , " Chart.bundle.min.js " ) ) ;
2020-01-05 17:24:43 +01:00
2020-01-06 08:26:13 +01:00
//
2020-01-18 09:55:56 +01:00
Project root = listProjectsAsTree ( ) ;
2020-01-05 17:24:43 +01:00
// Create welcome page.
2020-01-21 20:07:49 +01:00
refreshPage ( root ) ;
FileUtils . copyFile ( new File ( this . targetDirectory , " all.xhtml " ) , new File ( this . targetDirectory , " index.xhtml " ) ) ;
2020-01-05 17:24:43 +01:00
// Create one page per project.
2020-01-18 09:55:56 +01:00
for ( Project project : root . subProjects ( ) )
2020-01-05 17:24:43 +01:00
{
2020-01-18 09:55:56 +01:00
refreshPage ( project ) ;
for ( Project subProject : project . subProjects ( ) )
{
2020-01-20 23:10:41 +01:00
refreshPage ( subProject ) ;
2020-01-22 11:11:14 +01:00
// if (project.getName().equals("Chapril"))
// {
// System.exit(0);
// }
2020-01-18 09:55:56 +01:00
}
2020-01-05 17:24:43 +01:00
}
}
catch ( IOException exception )
{
throw new AgirStatoolException ( " Error refreshing all: " + exception . getMessage ( ) , exception ) ;
}
}
2020-01-21 20:07:49 +01:00
/ * *
* Fetch week concluded count .
*
* @param project
* the project
* @return the date count map
* @throws AgirStatoolException
* the agir statool exception
* /
2020-01-22 10:39:44 +01:00
public DateCountMap fetchWeekConcludedCount ( final Project project ) throws AgirStatoolException
2020-01-21 20:07:49 +01:00
{
DateCountMap result ;
result = new DateCountMap ( ) ;
//
PreparedStatement statement = null ;
ResultSet resultSet = null ;
try
{
StringList subSql = new StringList ( ) ;
2020-01-22 10:39:44 +01:00
if ( project . getType ( ) = = Project . Type . CONSOLIDATED )
2020-01-21 20:07:49 +01:00
{
subSql . append ( " select " ) ;
subSql . append ( " id " ) ;
subSql . append ( " from " ) ;
subSql . append ( " projects as childProject " ) ;
subSql . append ( " where " ) ;
subSql . append ( " (childProject.id= " + project . getId ( ) + " or childProject.parent_id= " + project . getId ( ) + " ) " ) ;
subSql . append ( " and childProject.status=1 and childProject.is_public=1 " ) ;
}
2020-01-22 10:39:44 +01:00
else if ( project . getType ( ) = = Project . Type . ROOT )
{
subSql . append ( " select " ) ;
subSql . append ( " id " ) ;
subSql . append ( " from " ) ;
subSql . append ( " projects as childProject " ) ;
subSql . append ( " where " ) ;
subSql . append ( " childProject.status=1 and childProject.is_public=1 " ) ;
}
2020-01-21 20:07:49 +01:00
else
{
subSql . append ( project . getId ( ) ) ;
}
StringList sql = new StringList ( ) ;
sql . append ( " SELECT " ) ;
2020-01-22 11:11:14 +01:00
sql . append ( " yearweek(closed_on, 3) as date, " ) ;
2020-01-21 20:07:49 +01:00
sql . append ( " count(*) as count " ) ;
sql . append ( " FROM " ) ;
sql . append ( " issues " ) ;
sql . append ( " WHERE " ) ;
sql . append ( " project_id in ( " + subSql . toString ( ) + " ) and closed_on is not null " ) ;
sql . append ( " GROUP BY " ) ;
sql . append ( " date; " ) ;
// System.out.println(sql.toStringSeparatedBy("\n"));
this . connection . setAutoCommit ( true ) ;
statement = this . connection . prepareStatement ( sql . toString ( ) ) ;
resultSet = statement . executeQuery ( ) ;
while ( resultSet . next ( ) )
{
result . put ( resultSet . getString ( 1 ) , new DateCount ( resultSet . getString ( 1 ) , resultSet . getLong ( 2 ) ) ) ;
}
}
catch ( SQLException exception )
{
throw new AgirStatoolException ( " Error fetching day closed count: " + exception . getMessage ( ) , exception ) ;
}
finally
{
SQLUtils . closeQuietly ( statement , resultSet ) ;
}
//
return result ;
}
/ * *
* Fetch week created count .
*
* @param project
* the project
* @return the date count map
* @throws AgirStatoolException
* the agir statool exception
* /
2020-01-22 10:39:44 +01:00
public DateCountMap fetchWeekCreatedCount ( final Project project ) throws AgirStatoolException
2020-01-21 20:07:49 +01:00
{
DateCountMap result ;
result = new DateCountMap ( ) ;
//
PreparedStatement statement = null ;
ResultSet resultSet = null ;
try
{
StringList subSql = new StringList ( ) ;
2020-01-22 10:39:44 +01:00
if ( project . getType ( ) = = Project . Type . CONSOLIDATED )
2020-01-21 20:07:49 +01:00
{
subSql . append ( " select " ) ;
subSql . append ( " id " ) ;
subSql . append ( " from " ) ;
subSql . append ( " projects as childProject " ) ;
subSql . append ( " where " ) ;
subSql . append ( " (childProject.id= " + project . getId ( ) + " or childProject.parent_id= " + project . getId ( ) + " ) " ) ;
subSql . append ( " and childProject.status=1 and childProject.is_public=1 " ) ;
}
2020-01-22 10:39:44 +01:00
else if ( project . getType ( ) = = Project . Type . ROOT )
{
subSql . append ( " select " ) ;
subSql . append ( " id " ) ;
subSql . append ( " from " ) ;
subSql . append ( " projects as childProject " ) ;
subSql . append ( " where " ) ;
subSql . append ( " childProject.status=1 and childProject.is_public=1 " ) ;
}
2020-01-21 20:07:49 +01:00
else
{
subSql . append ( project . getId ( ) ) ;
}
StringList sql = new StringList ( ) ;
sql . append ( " SELECT " ) ;
2020-01-22 11:11:14 +01:00
sql . append ( " yearweek(created_on,3) as date, " ) ;
2020-01-21 20:07:49 +01:00
sql . append ( " count(*) as count " ) ;
sql . append ( " FROM " ) ;
sql . append ( " issues " ) ;
sql . append ( " WHERE " ) ;
sql . append ( " project_id in ( " + subSql . toString ( ) + " ) " ) ;
sql . append ( " GROUP BY " ) ;
sql . append ( " date; " ) ;
// logger.debug(sql.toStringSeparatedBy("\n"));
this . connection . setAutoCommit ( true ) ;
statement = this . connection . prepareStatement ( sql . toString ( ) ) ;
resultSet = statement . executeQuery ( ) ;
while ( resultSet . next ( ) )
{
result . put ( resultSet . getString ( 1 ) , new DateCount ( resultSet . getString ( 1 ) , resultSet . getLong ( 2 ) ) ) ;
}
}
catch ( SQLException exception )
{
throw new AgirStatoolException ( " Error fetching day created count: " + exception . getMessage ( ) , exception ) ;
}
finally
{
SQLUtils . closeQuietly ( statement , resultSet ) ;
}
//
return result ;
}
2020-01-05 17:24:43 +01:00
/ * *
2020-01-22 19:37:28 +01:00
* Gets the root project .
2020-01-05 17:24:43 +01:00
*
2020-01-22 19:37:28 +01:00
* @return the root project
2020-01-05 17:24:43 +01:00
* @throws AgirStatoolException
* the agir statool exception
* /
public Project getRootProject ( ) throws AgirStatoolException
{
Project result ;
result = null ;
PreparedStatement statement = null ;
ResultSet resultSet = null ;
try
{
StringList subSql = new StringList ( ) ;
subSql . append ( " select " ) ;
subSql . append ( " id " ) ;
subSql . append ( " from " ) ;
subSql . append ( " projects as childProjects " ) ;
subSql . append ( " where " ) ;
subSql . append ( " childProjects.status=1 and childProjects.is_public=1 " ) ;
//
StringList sql = new StringList ( ) ;
sql . append ( " SELECT " ) ;
2020-01-21 20:07:49 +01:00
sql . append ( " 0 as root_project_id, " ) ;
sql . append ( " 'all' as root_project_identifier, " ) ;
sql . append ( " '*' as root_project_name, " ) ;
sql . append ( " null as root_parent_id, " ) ;
2020-01-05 17:24:43 +01:00
sql . append ( " (select count(*) from projects where status = 1 and is_public = 1) as child_count, " ) ;
sql . append ( " (select max(updated_on) from projects where status = 1 and is_public = 1) as last_update, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " )) as issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 1) as new_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 2) as ongoing_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 3) as resolved_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 5) as closed_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 6) as rejected_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 7) as confirmed_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id=15) as maybe_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id=16) as waiting_issue_count, " ) ;
2020-01-20 23:10:41 +01:00
sql . append ( " (select min(created_on) from issues where issues.project_id in ( " + subSql . toString ( ) + " )) as first_issue_create, " ) ;
2020-01-05 17:24:43 +01:00
sql . append ( " (select max(updated_on) from issues where issues.project_id in ( " + subSql . toString ( ) + " )) as last_issue_update " ) ;
// System.out.println(sql.toStringSeparatedBy("\n"));
this . connection . setAutoCommit ( true ) ;
statement = this . connection . prepareStatement ( sql . toString ( ) ) ;
resultSet = statement . executeQuery ( ) ;
while ( resultSet . next ( ) )
{
long id = resultSet . getLong ( 1 ) ;
String identifier = resultSet . getString ( 2 ) ;
String name = resultSet . getString ( 3 ) ;
Long parentId = SQLUtils . getNullableLong ( resultSet , 4 ) ;
result = new Project ( id , identifier , name , parentId ) ;
result . setChildCount ( resultSet . getLong ( 5 ) ) ;
result . setLastUpdate ( AgirStatoolUtils . toLocaleDateTime ( resultSet . getTimestamp ( 6 ) ) ) ;
2020-01-05 18:31:03 +01:00
result . issueStats ( ) . setCount ( resultSet . getLong ( 7 ) ) ;
result . issueStats ( ) . setNewCount ( resultSet . getLong ( 8 ) ) ;
result . issueStats ( ) . setOngoingCount ( resultSet . getLong ( 9 ) ) ;
result . issueStats ( ) . setResolvedCount ( resultSet . getLong ( 10 ) ) ;
result . issueStats ( ) . setClosedCount ( resultSet . getLong ( 11 ) ) ;
result . issueStats ( ) . setRejectedCount ( resultSet . getLong ( 12 ) ) ;
result . issueStats ( ) . setConfirmedCount ( resultSet . getLong ( 13 ) ) ;
result . issueStats ( ) . setMaybeCount ( resultSet . getLong ( 14 ) ) ;
result . issueStats ( ) . setWaitingCount ( resultSet . getLong ( 15 ) ) ;
2020-01-20 23:10:41 +01:00
result . issueStats ( ) . setFirstCreate ( AgirStatoolUtils . toLocaleDateTime ( resultSet . getTimestamp ( 16 ) ) ) ;
result . issueStats ( ) . setLastUpdate ( AgirStatoolUtils . toLocaleDateTime ( resultSet . getTimestamp ( 17 ) ) ) ;
2020-01-05 17:24:43 +01:00
}
}
catch ( SQLException exception )
{
throw new AgirStatoolException ( " Error reading projects extended: " + exception . getMessage ( ) , exception ) ;
}
finally
{
SQLUtils . closeQuietly ( statement , resultSet ) ;
}
//
return result ;
}
2020-01-22 19:10:43 +01:00
/ * *
* Checks for to refresh .
*
* @param project
* the project
* @return true , if successful
* /
public boolean hasToRefresh ( final Project project )
{
boolean result ;
if ( project = = null )
{
result = false ;
}
else
{
File target = new File ( this . targetDirectory , project . getPath ( ) ) ;
if ( target . exists ( ) )
{
if ( project . hasIssue ( ) )
{
LocalDateTime lastFileUpdate = LocalDateTime . ofEpochSecond ( target . lastModified ( ) / 1000 , 0 , ZoneOffset . UTC ) ;
if ( project . issueStats ( ) . getLastUpdate ( ) . isAfter ( lastFileUpdate ) )
{
result = true ;
}
else
{
result = false ;
}
}
else
{
result = false ;
}
}
else
{
result = true ;
}
}
//
return result ;
}
2020-01-05 17:24:43 +01:00
/ * *
* List projects .
*
* @return the projects
* @throws AgirStatoolException
2020-01-23 09:00:46 +01:00
* the agir statool exception
2020-01-05 17:24:43 +01:00
* /
public Projects listProjects ( ) throws AgirStatoolException
{
Projects result ;
result = new Projects ( ) ;
//
PreparedStatement statement = null ;
ResultSet resultSet = null ;
try
{
StringList sql = new StringList ( ) ;
sql . append ( " SELECT " ) ;
sql . append ( " id, " ) ;
sql . append ( " identifier, " ) ;
sql . append ( " name, " ) ;
sql . append ( " parent_id, " ) ;
sql . append ( " ( " ) ;
sql . append ( " select " ) ;
sql . append ( " count(*) " ) ;
sql . append ( " from projects as subprojects " ) ;
sql . append ( " where " ) ;
sql . append ( " subprojects.parent_id = projects.id " ) ;
sql . append ( " and subprojects.status = 1 " ) ;
sql . append ( " and subprojects.is_public = 1 " ) ;
sql . append ( " ) as child_count, " ) ;
sql . append ( " updated_on " ) ;
sql . append ( " from " ) ;
sql . append ( " projects " ) ;
sql . append ( " where " ) ;
sql . append ( " status=1 and is_public=1 " ) ;
// System.out.println(sql.toStringSeparatedBy("\n"));
this . connection . setAutoCommit ( true ) ;
statement = this . connection . prepareStatement ( sql . toString ( ) ) ;
resultSet = statement . executeQuery ( ) ;
while ( resultSet . next ( ) )
{
long id = resultSet . getLong ( 1 ) ;
String identifier = resultSet . getString ( 2 ) ;
String name = resultSet . getString ( 3 ) ;
Long parentId = SQLUtils . getNullableLong ( resultSet , 4 ) ;
Project project = new Project ( id , identifier , name , parentId ) ;
project . setChildCount ( resultSet . getLong ( 5 ) ) ;
project . setLastUpdate ( AgirStatoolUtils . toLocaleDateTime ( resultSet . getTimestamp ( 6 ) ) ) ;
result . add ( project ) ;
}
}
catch ( SQLException exception )
{
logger . error ( " Error getting element. " , exception ) ;
throw new AgirStatoolException ( " Error getting element " , exception ) ;
}
finally
{
SQLUtils . closeQuietly ( statement , resultSet ) ;
}
//
return result ;
}
2020-01-20 23:10:41 +01:00
/ * *
* List projects as tree .
*
* @return the project
* @throws AgirStatoolException
* the agir statool exception
* /
2020-01-18 09:55:56 +01:00
public Project listProjectsAsTree ( ) throws AgirStatoolException
2020-01-06 08:26:13 +01:00
{
2020-01-18 09:55:56 +01:00
Project result ;
2020-01-06 08:26:13 +01:00
2020-01-18 09:55:56 +01:00
// Create a root project.
result = getRootProject ( ) ;
2020-01-06 08:26:13 +01:00
//
Projects projects = listProjectsWithSubStats ( ) ;
// Add parent projects with alone statistics.
2020-01-20 23:10:41 +01:00
for ( Project project : listProjectsWithoutSubStats ( ) )
2020-01-06 08:26:13 +01:00
{
if ( project . hasChild ( ) )
{
2020-01-20 23:10:41 +01:00
project . setName ( ALONE_INDICATOR + project . getName ( ) ) ;
project . setIdentifier ( ALONE_INDICATOR + project . getIdentifier ( ) ) ;
2020-01-06 08:26:13 +01:00
project . setParentId ( project . getId ( ) ) ;
project . setChildCount ( 0 ) ;
projects . add ( project ) ;
}
}
2020-01-21 20:07:49 +01:00
// Fill created and concluded issues history.
2020-01-22 10:39:44 +01:00
{
{
DateCountMap map = fetchWeekCreatedCount ( result ) ;
DateCountList counts = AgirStatoolUtils . normalizedWeekCountList ( map , result . issueStats ( ) . getFirstCreate ( ) . toLocalDate ( ) ) ;
result . issueStats ( ) . setWeekCreatedIssueCounts ( counts ) ;
}
{
DateCountMap map = fetchWeekConcludedCount ( result ) ;
DateCountList counts = AgirStatoolUtils . normalizedWeekCountList ( map , result . issueStats ( ) . getFirstCreate ( ) . toLocalDate ( ) ) ;
result . issueStats ( ) . setWeekConcludedIssueCounts ( counts ) ;
}
}
2020-01-21 20:07:49 +01:00
for ( Project project : projects )
{
2020-01-22 19:10:43 +01:00
logger . debug ( " Fetching Created/Closed history for " + project . getName ( ) ) ;
2020-01-21 20:07:49 +01:00
if ( project . hasIssue ( ) )
{
{
2020-01-22 10:39:44 +01:00
DateCountMap map = fetchWeekCreatedCount ( project ) ;
DateCountList counts = AgirStatoolUtils . normalizedWeekCountList ( map , project . issueStats ( ) . getFirstCreate ( ) . toLocalDate ( ) ) ;
2020-01-21 20:07:49 +01:00
project . issueStats ( ) . setWeekCreatedIssueCounts ( counts ) ;
}
{
2020-01-22 10:39:44 +01:00
DateCountMap map = fetchWeekConcludedCount ( project ) ;
DateCountList counts = AgirStatoolUtils . normalizedWeekCountList ( map , project . issueStats ( ) . getFirstCreate ( ) . toLocalDate ( ) ) ;
project . issueStats ( ) . setWeekConcludedIssueCounts ( counts ) ;
2020-01-21 20:07:49 +01:00
}
}
}
2020-01-22 19:10:43 +01:00
logger . debug ( " Fetching Created/Closed history done. " ) ;
2020-01-21 20:07:49 +01:00
2020-01-06 08:26:13 +01:00
// Transform as tree.
for ( Project project : projects )
{
2020-01-18 09:55:56 +01:00
if ( ( project . getParentId ( ) = = null ) | | ( project . getId ( ) = = 0 ) )
2020-01-06 08:26:13 +01:00
{
2020-01-18 09:55:56 +01:00
result . subProjects ( ) . add ( project ) ;
2020-01-06 08:26:13 +01:00
Projects subProjects = projects . getByParent ( project . getId ( ) ) ;
subProjects . sortByName ( ) ;
project . subProjects ( ) . addAll ( subProjects ) ;
}
}
2020-01-18 09:55:56 +01:00
result . subProjects ( ) . sortByName ( ) ;
2020-01-06 08:26:13 +01:00
//
return result ;
}
2020-01-05 17:24:43 +01:00
/ * *
* List projects extended .
*
* @return the projects
* @throws AgirStatoolException
* the agir statool exception
* /
2020-01-20 23:10:41 +01:00
public Projects listProjectsWithoutSubStats ( ) throws AgirStatoolException
2020-01-05 17:24:43 +01:00
{
Projects result ;
2020-01-22 10:39:44 +01:00
result = listProjectsWithStats ( Project . Type . ALONE ) ;
2020-01-05 17:24:43 +01:00
//
return result ;
}
/ * *
2020-01-22 19:37:28 +01:00
* List projects with stats .
2020-01-05 17:24:43 +01:00
*
2020-01-22 19:37:28 +01:00
* @param type
* the type
2020-01-05 17:24:43 +01:00
* @return the projects
* @throws AgirStatoolException
* the agir statool exception
* /
2020-01-22 10:39:44 +01:00
public Projects listProjectsWithStats ( final Project . Type type ) throws AgirStatoolException
2020-01-05 17:24:43 +01:00
{
Projects result ;
result = new Projects ( ) ;
//
PreparedStatement statement = null ;
ResultSet resultSet = null ;
try
{
StringList subSql = new StringList ( ) ;
2020-01-22 10:39:44 +01:00
if ( type = = Project . Type . CONSOLIDATED )
2020-01-05 17:24:43 +01:00
{
subSql . append ( " select " ) ;
subSql . append ( " id " ) ;
subSql . append ( " from " ) ;
subSql . append ( " projects as childProject " ) ;
subSql . append ( " where " ) ;
subSql . append ( " (childProject.id=currentProject.id or childProject.parent_id=currentProject.id) " ) ;
subSql . append ( " and childProject.status=1 and childProject.is_public=1 " ) ;
}
else
{
subSql . append ( " currentProject.id " ) ;
}
StringList sql = new StringList ( ) ;
sql . append ( " SELECT " ) ;
sql . append ( " id, " ) ;
sql . append ( " identifier, " ) ;
sql . append ( " name, " ) ;
sql . append ( " parent_id, " ) ;
sql . append ( " (select count(*) from projects as subproject where subproject.parent_id=currentProject.id and subproject.status = 1 and subproject.is_public = 1) as child_count, " ) ;
sql . append ( " updated_on, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " )) as issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 1) as new_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 2) as ongoing_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 3) as resolved_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 5) as closed_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 6) as rejected_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 7) as confirmed_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id=15) as maybe_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id=16) as waiting_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.assigned_to_id is null) as unassigned_issue_count, " ) ;
sql . append (
" (select count(*) from issues where issues.project_id in ( " + subSql . toString ( ) + " ) and issues.status_id= 1 and issues.assigned_to_id is null) as unassigned_new_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( )
+ " ) and issues.status_id= 2 and issues.assigned_to_id is null) as unassigned_ongoing_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( )
+ " ) and issues.status_id= 3 and issues.assigned_to_id is null) as unassigned_resolved_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( )
+ " ) and issues.status_id= 5 and issues.assigned_to_id is null) as unassigned_closed_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( )
+ " ) and issues.status_id= 6 and issues.assigned_to_id is null) as unassigned_rejected_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( )
+ " ) and issues.status_id= 7 and issues.assigned_to_id is null) as unassigned_confirmed_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( )
+ " ) and issues.status_id=15 and issues.assigned_to_id is null) as unassigned_maybe_issue_count, " ) ;
sql . append ( " (select count(*) from issues where issues.project_id in ( " + subSql . toString ( )
+ " ) and issues.status_id=16 and issues.assigned_to_id is null) as unassigned_waiting_issue_count, " ) ;
2020-01-20 23:10:41 +01:00
sql . append ( " (select min(created_on) from issues where issues.project_id in ( " + subSql . toString ( ) + " )) as first_issue_create, " ) ;
2020-01-05 17:24:43 +01:00
sql . append ( " (select max(updated_on) from issues where issues.project_id in ( " + subSql . toString ( ) + " )) as last_issue_update " ) ;
sql . append ( " FROM " ) ;
sql . append ( " projects as currentProject " ) ;
sql . append ( " WHERE " ) ;
sql . append ( " currentProject.status=1 and currentProject.is_public=1; " ) ;
// System.out.println(sql.toStringSeparatedBy("\n"));
this . connection . setAutoCommit ( true ) ;
statement = this . connection . prepareStatement ( sql . toString ( ) ) ;
resultSet = statement . executeQuery ( ) ;
while ( resultSet . next ( ) )
{
long id = resultSet . getLong ( 1 ) ;
String identifier = resultSet . getString ( 2 ) ;
String name = resultSet . getString ( 3 ) ;
Long parentId = SQLUtils . getNullableLong ( resultSet , 4 ) ;
Project project = new Project ( id , identifier , name , parentId ) ;
project . setChildCount ( resultSet . getLong ( 5 ) ) ;
project . setLastUpdate ( AgirStatoolUtils . toLocaleDateTime ( resultSet . getTimestamp ( 6 ) ) ) ;
2020-01-05 18:31:03 +01:00
project . issueStats ( ) . setCount ( resultSet . getLong ( 7 ) ) ;
project . issueStats ( ) . setNewCount ( resultSet . getLong ( 8 ) ) ;
project . issueStats ( ) . setOngoingCount ( resultSet . getLong ( 9 ) ) ;
project . issueStats ( ) . setResolvedCount ( resultSet . getLong ( 10 ) ) ;
project . issueStats ( ) . setClosedCount ( resultSet . getLong ( 11 ) ) ;
project . issueStats ( ) . setRejectedCount ( resultSet . getLong ( 12 ) ) ;
project . issueStats ( ) . setConfirmedCount ( resultSet . getLong ( 13 ) ) ;
project . issueStats ( ) . setMaybeCount ( resultSet . getLong ( 14 ) ) ;
project . issueStats ( ) . setWaitingCount ( resultSet . getLong ( 15 ) ) ;
project . issueStats ( ) . setUnassignedCount ( resultSet . getLong ( 16 ) ) ;
project . issueStats ( ) . setUnassignedNewCount ( resultSet . getLong ( 17 ) ) ;
project . issueStats ( ) . setUnassignedOngoingCount ( resultSet . getLong ( 18 ) ) ;
project . issueStats ( ) . setUnassignedResolvedCount ( resultSet . getLong ( 19 ) ) ;
project . issueStats ( ) . setUnassignedClosedCount ( resultSet . getLong ( 20 ) ) ;
project . issueStats ( ) . setUnassignedRejectedCount ( resultSet . getLong ( 21 ) ) ;
project . issueStats ( ) . setUnassignedConfirmedCount ( resultSet . getLong ( 22 ) ) ;
project . issueStats ( ) . setUnassignedMaybeCount ( resultSet . getLong ( 23 ) ) ;
project . issueStats ( ) . setUnassignedWaitingCount ( resultSet . getLong ( 24 ) ) ;
2020-01-20 23:10:41 +01:00
project . issueStats ( ) . setFirstCreate ( AgirStatoolUtils . toLocaleDateTime ( resultSet . getTimestamp ( 25 ) ) ) ;
project . issueStats ( ) . setLastUpdate ( AgirStatoolUtils . toLocaleDateTime ( resultSet . getTimestamp ( 26 ) ) ) ;
2020-01-05 17:24:43 +01:00
result . add ( project ) ;
}
}
catch ( SQLException exception )
{
throw new AgirStatoolException ( " Error reading projects extended: " + exception . getMessage ( ) , exception ) ;
}
finally
{
SQLUtils . closeQuietly ( statement , resultSet ) ;
}
//
return result ;
}
/ * *
* List projects consolidated .
*
* @return the projects
* @throws AgirStatoolException
* the agir statool exception
* /
public Projects listProjectsWithSubStats ( ) throws AgirStatoolException
{
Projects result ;
2020-01-22 10:39:44 +01:00
result = listProjectsWithStats ( Project . Type . CONSOLIDATED ) ;
2020-01-20 23:10:41 +01:00
2020-01-05 17:24:43 +01:00
//
return result ;
}
public void putTouchFile ( )
{
}
/ * *
* Refresh .
*
* @param projectId
* the project id
* @throws AgirStatoolException
2020-01-23 09:00:46 +01:00
* the agir statool exception
2020-01-05 17:24:43 +01:00
* /
public void refresh ( final String projectId ) throws AgirStatoolException
{
}
/ * *
* Update .
* /
public void refreshChangedProjects ( )
{
}
2020-01-18 09:55:56 +01:00
/ * *
* Refresh page .
*
* @param project
* the project
* @throws AgirStatoolException
* the agir statool exception
* /
public void refreshPage ( final Project project ) throws AgirStatoolException
{
try
{
2020-01-22 19:10:43 +01:00
if ( hasToRefresh ( project ) )
2020-01-18 09:55:56 +01:00
{
2020-01-22 19:10:43 +01:00
logger . info ( " Refresh project page for {} " , project . getName ( ) ) ;
2020-01-18 09:55:56 +01:00
String page = ProjectPage . build ( project ) ;
FileUtils . write ( new File ( this . targetDirectory , project . getIdentifier ( ) + " .xhtml " ) , page , StandardCharsets . UTF_8 ) ;
}
}
catch ( IOException exception )
{
throw new AgirStatoolException ( " Error refreshing page: " + exception . getMessage ( ) , exception ) ;
}
}
2020-01-05 17:24:43 +01:00
}