Compare commits
156 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
00c214a473 | |
|
|
45a2f5be9b | |
|
|
c657b31416 | |
|
|
7e387eb37a | |
|
|
69d126b2f6 | |
|
|
bd0c90a496 | |
|
|
0421776f81 | |
|
|
5099a0a90a | |
|
|
38d1a432a7 | |
|
|
dd5f1f7fc3 | |
|
|
2f368a2a44 | |
|
|
a40dfb387a | |
|
|
d72dba7f01 | |
|
|
88b3b4cd91 | |
|
|
a0b77d21d6 | |
|
|
172def1186 | |
|
|
53428dc4ac | |
|
|
f968d9c668 | |
|
|
dd684dd6ef | |
|
|
88ec9b0197 | |
|
|
50c14fb136 | |
|
|
611948c914 | |
|
|
4041e767e8 | |
|
|
a70ac2cb64 | |
|
|
3c98a12b58 | |
|
|
ee7523dd5e | |
|
|
09161eff8f | |
|
|
bfc61bfc79 | |
|
|
917632e8a8 | |
|
|
51a2a47748 | |
|
|
00e797b7a6 | |
|
|
24c7240c2b | |
|
|
c002010512 | |
|
|
9100963f74 | |
|
|
20079ce5cd | |
|
|
c4eaae0ae3 | |
|
|
f432c69247 | |
|
|
a8fb88fcce | |
|
|
1889819871 | |
|
|
f4e915fad9 | |
|
|
4161413a2c | |
|
|
b0a9bb6498 | |
|
|
62878d96b7 | |
|
|
1a1dd97dc3 | |
|
|
4e53d32e08 | |
|
|
a52babb07c | |
|
|
6922d0f08a | |
|
|
68f5eeb2bb | |
|
|
1586cb84e5 | |
|
|
3ed1d3237f | |
|
|
dcbf3265f3 | |
|
|
409a655207 | |
|
|
eff035728c | |
|
|
8b5afadb78 | |
|
|
86777e7a7b | |
|
|
931552ecab | |
|
|
31b7863dd8 | |
|
|
7cfce85563 | |
|
|
fe829ca081 | |
|
|
68730a7f50 | |
|
|
32032ceb45 | |
|
|
18c43a7a0b | |
|
|
84ecd6bd01 | |
|
|
d97d33011b | |
|
|
bcf3ebf44b | |
|
|
3d4ad762f0 | |
|
|
315062ff48 | |
|
|
a799a70f9a | |
|
|
d410460795 | |
|
|
0dabd940fa | |
|
|
6e670317b4 | |
|
|
924b333c0f | |
|
|
41655f8156 | |
|
|
25564a9e75 | |
|
|
c5ed615565 | |
|
|
1d7f22a18e | |
|
|
ff8799130b | |
|
|
0eee13f0d1 | |
|
|
ec7da92229 | |
|
|
454833c4fe | |
|
|
95443d066b | |
|
|
974b623867 | |
|
|
1a78551d49 | |
|
|
b16a83e44c | |
|
|
ad4462228d | |
|
|
3cd1113b17 | |
|
|
2af9e0c033 | |
|
|
5295ea916f | |
|
|
63d9cc1247 | |
|
|
e4617f7249 | |
|
|
d21ed60307 | |
|
|
63816225b0 | |
|
|
bfbdc6099b | |
|
|
dba47fee69 | |
|
|
8ae64d86db | |
|
|
fd389367ca | |
|
|
ab589a1ba8 | |
|
|
c3bd36abd9 | |
|
|
27ec41ae72 | |
|
|
3971d7dea2 | |
|
|
21731f2983 | |
|
|
c270bc1650 | |
|
|
5cbb3ac29b | |
|
|
e050cfec84 | |
|
|
a569851c2d | |
|
|
db56dfc451 | |
|
|
c2b3722839 | |
|
|
4975ca72e9 | |
|
|
b5cadf3d2a | |
|
|
2b4a586c55 | |
|
|
4f7cd54856 | |
|
|
60cc1cdebf | |
|
|
ea521a2e4a | |
|
|
647bb9cab0 | |
|
|
b1d6438185 | |
|
|
9445272a6b | |
|
|
d9a6bc9bc8 | |
|
|
27098bcd60 | |
|
|
8d180e763f | |
|
|
0c61b6a2f2 | |
|
|
58a71b2da2 | |
|
|
829621a053 | |
|
|
5210612bd5 | |
|
|
7982974c09 | |
|
|
6e51410e3f | |
|
|
640223040d | |
|
|
14d7115680 | |
|
|
aa1626df4c | |
|
|
5e4718abb3 | |
|
|
b8ff010a98 | |
|
|
fdbf824aaf | |
|
|
5520eab2c1 | |
|
|
2a2941fbbb | |
|
|
6cf2dc26b3 | |
|
|
8d3fa5ba38 | |
|
|
dbc18290a3 | |
|
|
71c0315692 | |
|
|
db52c08cfd | |
|
|
3aaa24c5c3 | |
|
|
a633602a3d | |
|
|
27cabd0230 | |
|
|
c69e77b39c | |
|
|
f43808b999 | |
|
|
820947169f | |
|
|
3015aef071 | |
|
|
912996711b | |
|
|
a56aadba39 | |
|
|
f574aed4f8 | |
|
|
088819cbd8 | |
|
|
fb59e454a1 | |
|
|
354af95c22 | |
|
|
bbe2d5726b | |
|
|
0647389a86 | |
|
|
613116ef54 | |
|
|
c48aa58dce | |
|
|
3665c9f3f8 |
|
|
@ -26,13 +26,13 @@ public class DefaultControllerAdvisor {
|
|||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public R processException(Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
logger.error("DefaultControllerAdvisor#Exception", e);
|
||||
return R.failed(ErrorCodeEnum.EXCEPTION.getValue(),ErrorCodeEnum.EXCEPTION.getDescription());
|
||||
}
|
||||
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
public R processException(BusinessException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
logger.error("DefaultControllerAdvisor#BusinessException", e);
|
||||
return R.failed(e.getErrCode(),e.getMessage());
|
||||
}
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ public class DefaultControllerAdvisor {
|
|||
|
||||
@ExceptionHandler(MissingServletRequestParameterException.class)
|
||||
public R processMissingServletRequestParameterException(MissingServletRequestParameterException e){
|
||||
logger.error(e.getMessage(), e);
|
||||
logger.error("DefaultControllerAdvisor#MissingServletRequestParameterException", e);
|
||||
return R.failed(ErrorCodeEnum.MVC_BIND_EXCEPTION.getValue(),ErrorCodeEnum.MVC_BIND_EXCEPTION.getDescription());
|
||||
}
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ public class DefaultControllerAdvisor {
|
|||
|
||||
@ExceptionHandler(ConstraintViolationException.class)
|
||||
public R processConstraintViolationException(ConstraintViolationException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
logger.error("DefaultControllerAdvisor#ConstraintViolationException", e);
|
||||
return R.failed(ErrorCodeEnum.INVALID_ARG_EXCEPTION.getValue(),ErrorCodeEnum.INVALID_ARG_EXCEPTION.getDescription());
|
||||
}
|
||||
|
||||
|
|
@ -56,15 +56,15 @@ public class DefaultControllerAdvisor {
|
|||
|
||||
@ExceptionHandler(BindException.class)
|
||||
public R processBindException(BindException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return R.failed(ErrorCodeEnum.BIND_EXCEPTION.getValue(),ErrorCodeEnum.BIND_EXCEPTION.getDescription());
|
||||
logger.error("DefaultControllerAdvisor#BindException", e);
|
||||
return R.failed(ErrorCodeEnum.BIND_EXCEPTION.getValue(), e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
|
||||
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
|
||||
public R processHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
logger.error("DefaultControllerAdvisor#HttpRequestMethodNotSupportedException", e);
|
||||
return R.failed(ErrorCodeEnum.METHOD_NOT_ALLOWED_EXCEPTION.getValue(),ErrorCodeEnum.METHOD_NOT_ALLOWED_EXCEPTION.getDescription());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package net.educoder.quality.common.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/21
|
||||
* @Description: 支持跨域
|
||||
*/
|
||||
@Configuration
|
||||
public class CorsConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
//项目中的所有接口都支持跨域
|
||||
registry.addMapping("/**")
|
||||
//所有地址都可以访问,也可以配置具体地址
|
||||
.allowedOriginPatterns("*")
|
||||
.allowCredentials(true)
|
||||
//"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"
|
||||
.allowedMethods("*")
|
||||
// 跨域允许时间
|
||||
.maxAge(3600);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -25,6 +25,8 @@ public class DynamicDataSourceConfig {
|
|||
|
||||
public static final String MASTER = "master";
|
||||
public static final String READONLY = "readonly";
|
||||
public static final String GITEA = "gitea";
|
||||
public static final String SAST = "sast";
|
||||
|
||||
private static final List INIT_SQLS = Arrays.asList("SET NAMES utf8mb4");
|
||||
|
||||
|
|
@ -96,6 +98,77 @@ public class DynamicDataSourceConfig {
|
|||
@Value("${spring.datasource.readonly.druid.test-while-idle}")
|
||||
private boolean readonlyTestWhileIdle;
|
||||
|
||||
|
||||
// --------------------------gitea----------------------------------
|
||||
|
||||
@Value("${spring.datasource.gitea.driver-class-name}")
|
||||
private String giteaDriverClass;
|
||||
|
||||
@Value("${spring.datasource.gitea.url}")
|
||||
private String giteaUrl;
|
||||
|
||||
@Value("${spring.datasource.gitea.username}")
|
||||
private String giteaUsername;
|
||||
|
||||
@Value("${spring.datasource.gitea.password}")
|
||||
private String giteaPassword;
|
||||
|
||||
@Value("${spring.datasource.gitea.druid.initial-size}")
|
||||
private Integer giteaInitialSize;
|
||||
|
||||
@Value("${spring.datasource.gitea.druid.max-active}")
|
||||
private Integer giteaMaxActive;
|
||||
|
||||
@Value("${spring.datasource.gitea.druid.min-idle}")
|
||||
private Integer giteaMinIdle;
|
||||
|
||||
@Value("${spring.datasource.gitea.druid.validation-query}")
|
||||
private String giteaValidationQuery;
|
||||
|
||||
@Value("${spring.datasource.gitea.druid.test-on-borrow}")
|
||||
private boolean giteaTestOnBorrow;
|
||||
|
||||
@Value("${spring.datasource.gitea.druid.test-on-return}")
|
||||
private boolean giteaTestOnReturn;
|
||||
|
||||
@Value("${spring.datasource.gitea.druid.test-while-idle}")
|
||||
private boolean giteaTestWhileIdle;
|
||||
|
||||
// --------------------------sast----------------------------------
|
||||
|
||||
@Value("${spring.datasource.sast.driver-class-name}")
|
||||
private String sastDriverClass;
|
||||
|
||||
@Value("${spring.datasource.sast.url}")
|
||||
private String sastUrl;
|
||||
|
||||
@Value("${spring.datasource.sast.username}")
|
||||
private String sastUsername;
|
||||
|
||||
@Value("${spring.datasource.sast.password}")
|
||||
private String sastPassword;
|
||||
|
||||
@Value("${spring.datasource.sast.druid.initial-size}")
|
||||
private Integer sastInitialSize;
|
||||
|
||||
@Value("${spring.datasource.sast.druid.max-active}")
|
||||
private Integer sastMaxActive;
|
||||
|
||||
@Value("${spring.datasource.sast.druid.min-idle}")
|
||||
private Integer sastMinIdle;
|
||||
|
||||
@Value("${spring.datasource.sast.druid.validation-query}")
|
||||
private String sastValidationQuery;
|
||||
|
||||
@Value("${spring.datasource.sast.druid.test-on-borrow}")
|
||||
private boolean sastTestOnBorrow;
|
||||
|
||||
@Value("${spring.datasource.sast.druid.test-on-return}")
|
||||
private boolean sastTestOnReturn;
|
||||
|
||||
@Value("${spring.datasource.sast.druid.test-while-idle}")
|
||||
private boolean sastTestWhileIdle;
|
||||
|
||||
@Bean("master")
|
||||
public DataSource masterDataSource() {
|
||||
DruidDataSource masterDataSource = new DruidDataSource();
|
||||
|
|
@ -110,6 +183,12 @@ public class DynamicDataSourceConfig {
|
|||
masterDataSource.setTestOnReturn(masterTestOnReturn);
|
||||
masterDataSource.setTestWhileIdle(masterTestWhileIdle);
|
||||
masterDataSource.setValidationQuery(masterValidationQuery);
|
||||
|
||||
// 连接失败后中断---重试10次
|
||||
masterDataSource.setBreakAfterAcquireFailure(true);
|
||||
masterDataSource.setConnectionErrorRetryAttempts(10);
|
||||
// 快速失败
|
||||
masterDataSource.setFailFast(true);
|
||||
return masterDataSource;
|
||||
}
|
||||
|
||||
|
|
@ -127,16 +206,68 @@ public class DynamicDataSourceConfig {
|
|||
readonlyDataSource.setTestOnReturn(readonlyTestOnReturn);
|
||||
readonlyDataSource.setTestWhileIdle(readonlyTestWhileIdle);
|
||||
readonlyDataSource.setValidationQuery(readonlyValidationQuery);
|
||||
// 连接失败后中断---重试10次
|
||||
readonlyDataSource.setBreakAfterAcquireFailure(true);
|
||||
readonlyDataSource.setConnectionErrorRetryAttempts(10);
|
||||
// 快速失败
|
||||
readonlyDataSource.setFailFast(true);
|
||||
return readonlyDataSource;
|
||||
}
|
||||
|
||||
|
||||
@Bean("gitea")
|
||||
public DataSource giteaDataSource() {
|
||||
DruidDataSource giteaDataSource = new DruidDataSource();
|
||||
giteaDataSource.setDriverClassName(giteaDriverClass);
|
||||
giteaDataSource.setUrl(giteaUrl);
|
||||
giteaDataSource.setUsername(giteaUsername);
|
||||
giteaDataSource.setPassword(giteaPassword);
|
||||
giteaDataSource.setMinIdle(giteaMinIdle);
|
||||
giteaDataSource.setMaxActive(giteaMaxActive);
|
||||
giteaDataSource.setMinIdle(giteaMinIdle);
|
||||
giteaDataSource.setTestOnBorrow(giteaTestOnBorrow);
|
||||
giteaDataSource.setTestOnReturn(giteaTestOnReturn);
|
||||
giteaDataSource.setTestWhileIdle(giteaTestWhileIdle);
|
||||
giteaDataSource.setValidationQuery(giteaValidationQuery);
|
||||
// 连接失败后中断---重试10次
|
||||
giteaDataSource.setBreakAfterAcquireFailure(true);
|
||||
giteaDataSource.setConnectionErrorRetryAttempts(10);
|
||||
// 快速失败
|
||||
giteaDataSource.setFailFast(true);
|
||||
return giteaDataSource;
|
||||
}
|
||||
|
||||
@Bean("sast")
|
||||
public DataSource sastDataSource() {
|
||||
DruidDataSource sastDataSource = new DruidDataSource();
|
||||
sastDataSource.setDriverClassName(sastDriverClass);
|
||||
sastDataSource.setUrl(sastUrl);
|
||||
sastDataSource.setUsername(sastUsername);
|
||||
sastDataSource.setPassword(sastPassword);
|
||||
sastDataSource.setMinIdle(sastMinIdle);
|
||||
sastDataSource.setMaxActive(sastMaxActive);
|
||||
sastDataSource.setMinIdle(sastMinIdle);
|
||||
sastDataSource.setTestOnBorrow(sastTestOnBorrow);
|
||||
sastDataSource.setTestOnReturn(sastTestOnReturn);
|
||||
sastDataSource.setTestWhileIdle(sastTestWhileIdle);
|
||||
sastDataSource.setValidationQuery(sastValidationQuery);
|
||||
// 连接失败后中断---重试10次
|
||||
sastDataSource.setBreakAfterAcquireFailure(true);
|
||||
sastDataSource.setConnectionErrorRetryAttempts(10);
|
||||
// 快速失败
|
||||
sastDataSource.setFailFast(true);
|
||||
return sastDataSource;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public DataSource dynamicDataSource() {
|
||||
Map<Object, Object> dataSourceMap = new HashMap<>(2);
|
||||
dataSourceMap.put(MASTER, masterDataSource());
|
||||
dataSourceMap.put(READONLY, slaveDataSource());
|
||||
dataSourceMap.put(GITEA, giteaDataSource());
|
||||
dataSourceMap.put(SAST, sastDataSource());
|
||||
//设置动态数据源
|
||||
DynamicDataSource dynamicDataSource = new DynamicDataSource();
|
||||
dynamicDataSource.setTargetDataSources(dataSourceMap);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
package net.educoder.quality.common.config;
|
||||
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import tk.mybatis.spring.annotation.MapperScan;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/15
|
||||
* @Description:
|
||||
*/
|
||||
@Configuration
|
||||
@MapperScan(basePackages = "net.educoder.quality.mapper.gitea", sqlSessionFactoryRef = "sqlSessionFactoryGiteaDataSource")
|
||||
public class GiteaDatasourceConfig {
|
||||
|
||||
|
||||
@Bean(name = "sqlSessionFactoryGiteaDataSource")
|
||||
public SqlSessionFactory sqlSessionFactoryDdsDataSource(@Qualifier("gitea") DataSource masterDataSource) throws Exception {
|
||||
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
|
||||
factoryBean.setDataSource(masterDataSource);
|
||||
|
||||
//下边两句仅仅用于*.xml文件,如果整个持久层操作不需要使用到xml文件的话(只用注解就可以搞定),则不加
|
||||
//指定entity和mapper。xml的路径
|
||||
factoryBean.setTypeAliasesPackage("net.educoder.quality.entity.gitea");
|
||||
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:gitea.mapper/*Mapper.xml"));
|
||||
return factoryBean.getObject();
|
||||
}
|
||||
|
||||
|
||||
@Bean(name = "giteaPlatformTransactionManager")
|
||||
public PlatformTransactionManager platformTransactionManager(@Qualifier("gitea") DataSource giteaDataSource){
|
||||
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
|
||||
dataSourceTransactionManager.setDataSource(giteaDataSource);
|
||||
return dataSourceTransactionManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package net.educoder.quality.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/10/14
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
public class PropertiesConfig {
|
||||
|
||||
@Value("${sonar.workspace}")
|
||||
private String workspace;
|
||||
|
||||
@Value("${openi.gitUsername}")
|
||||
private String gitUsername;
|
||||
|
||||
@Value("${openi.gitPassword}")
|
||||
private String gitPassword;
|
||||
|
||||
@Value("${nil.mil}")
|
||||
private String mil;
|
||||
|
||||
@Value("${nil.mit}")
|
||||
private String mit;
|
||||
|
||||
@Value("${nil.filtrationThreshold}")
|
||||
private String filtrationThreshold;
|
||||
|
||||
@Value("${nil.verificationThreshold}")
|
||||
private String verificationThreshold;
|
||||
|
||||
@Value("${nil.jarPath}")
|
||||
private String nilJarPath;
|
||||
|
||||
@Value("${sast.driver}")
|
||||
private String sastDriver;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package net.educoder.quality.common.config;
|
||||
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import tk.mybatis.spring.annotation.MapperScan;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@Configuration
|
||||
@MapperScan(basePackages = "net.educoder.quality.mapper.sast", sqlSessionFactoryRef = "sqlSessionFactorySastDataSource")
|
||||
public class SastDatasourceConfig {
|
||||
|
||||
@Bean(name = "sqlSessionFactorySastDataSource")
|
||||
public SqlSessionFactory sqlSessionFactoryDdsDataSource(@Qualifier("sast") DataSource sastDataSource) throws Exception {
|
||||
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
|
||||
factoryBean.setDataSource(sastDataSource);
|
||||
factoryBean.setTypeAliasesPackage("net.educoder.quality.entity.sast");
|
||||
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:sast.mapper/*Mapper.xml"));
|
||||
return factoryBean.getObject();
|
||||
}
|
||||
|
||||
@Bean(name = "sastPlatformTransactionManager")
|
||||
public PlatformTransactionManager platformTransactionManager(@Qualifier("sast") DataSource sastDataSource) {
|
||||
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
|
||||
dataSourceTransactionManager.setDataSource(sastDataSource);
|
||||
return dataSourceTransactionManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
package net.educoder.quality.common.config;
|
||||
|
||||
import net.educoder.quality.common.filter.MdcTaskDecorator;
|
||||
import net.educoder.quality.common.util.mdc.MdcThreadPoolTaskScheduler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -15,7 +18,7 @@ public class ThreadPoolConfig {
|
|||
|
||||
|
||||
@Bean("sonarScannerThreadPool")
|
||||
public ThreadPoolTaskExecutor sonarScannerThreadPool(){
|
||||
public ThreadPoolTaskExecutor sonarScannerThreadPool() {
|
||||
ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
|
||||
threadPoolExecutor.setCorePoolSize(100);
|
||||
threadPoolExecutor.setMaxPoolSize(100);
|
||||
|
|
@ -23,12 +26,26 @@ public class ThreadPoolConfig {
|
|||
threadPoolExecutor.setThreadNamePrefix("sonar-thread-");
|
||||
threadPoolExecutor.setWaitForTasksToCompleteOnShutdown(true);
|
||||
threadPoolExecutor.setAwaitTerminationMillis(5);
|
||||
threadPoolExecutor.setTaskDecorator(new MdcTaskDecorator());
|
||||
return threadPoolExecutor;
|
||||
}
|
||||
|
||||
@Bean("cloneDetectionThreadPool")
|
||||
public ThreadPoolTaskExecutor cloneDetectionThreadPool() {
|
||||
ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
|
||||
threadPoolExecutor.setCorePoolSize(100);
|
||||
threadPoolExecutor.setMaxPoolSize(100);
|
||||
threadPoolExecutor.setQueueCapacity(5000);
|
||||
threadPoolExecutor.setThreadNamePrefix("clone-detection-thread-");
|
||||
threadPoolExecutor.setWaitForTasksToCompleteOnShutdown(true);
|
||||
threadPoolExecutor.setAwaitTerminationMillis(5);
|
||||
threadPoolExecutor.setTaskDecorator(new MdcTaskDecorator());
|
||||
return threadPoolExecutor;
|
||||
}
|
||||
|
||||
|
||||
@Bean("sonarQueryResultThreadPool")
|
||||
public ThreadPoolTaskExecutor sonarQueryResultThreadPool(){
|
||||
public ThreadPoolTaskExecutor sonarQueryResultThreadPool() {
|
||||
ThreadPoolTaskExecutor sonarQueryResultThreadPool = new ThreadPoolTaskExecutor();
|
||||
sonarQueryResultThreadPool.setCorePoolSize(100);
|
||||
sonarQueryResultThreadPool.setMaxPoolSize(100);
|
||||
|
|
@ -36,7 +53,38 @@ public class ThreadPoolConfig {
|
|||
sonarQueryResultThreadPool.setThreadNamePrefix("sonar-result-thread-");
|
||||
sonarQueryResultThreadPool.setWaitForTasksToCompleteOnShutdown(true);
|
||||
sonarQueryResultThreadPool.setAwaitTerminationMillis(5);
|
||||
sonarQueryResultThreadPool.setTaskDecorator(new MdcTaskDecorator());
|
||||
return sonarQueryResultThreadPool;
|
||||
}
|
||||
|
||||
|
||||
@Bean("parseComponentThreadPool")
|
||||
public ThreadPoolTaskExecutor parseComponentThreadPool() {
|
||||
ThreadPoolTaskExecutor parseComponentThreadPool = new ThreadPoolTaskExecutor();
|
||||
parseComponentThreadPool.setCorePoolSize(10);
|
||||
parseComponentThreadPool.setMaxPoolSize(20);
|
||||
parseComponentThreadPool.setQueueCapacity(5000);
|
||||
parseComponentThreadPool.setThreadNamePrefix("parse-component-");
|
||||
parseComponentThreadPool.setWaitForTasksToCompleteOnShutdown(true);
|
||||
parseComponentThreadPool.setAwaitTerminationMillis(5);
|
||||
parseComponentThreadPool.setTaskDecorator(new MdcTaskDecorator());
|
||||
return parseComponentThreadPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置schedule 定时任务多线程处理
|
||||
* beanName必须命名:threadPoolTaskScheduler
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
|
||||
MdcThreadPoolTaskScheduler taskScheduler = new MdcThreadPoolTaskScheduler();
|
||||
//核心线程池数量,方法: 返回可用处理器的Java虚拟机的数量。
|
||||
taskScheduler.setPoolSize(20);
|
||||
taskScheduler.setThreadNamePrefix("schedule-");
|
||||
return taskScheduler;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ public interface QualityConstants {
|
|||
String C = "c";
|
||||
String CXX = "cpp";
|
||||
String CPP = "c++";
|
||||
String NET = "c#";
|
||||
String OTHER = "other";
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package net.educoder.quality.common.enums;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/26
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BugTypeEnum {
|
||||
|
||||
ALL("all", "ALL", "全部"),
|
||||
CRITICAL("critical", "CRITICAL", "严重"),
|
||||
HIGH("high", "BLOCKER", "高危"),
|
||||
MIDDLE("middle", "MAJOR", "中危"),
|
||||
LOW("low", "MINOR", "低危"),
|
||||
;
|
||||
String bugType;
|
||||
String dbValue;
|
||||
String description;
|
||||
|
||||
|
||||
public static BugTypeEnum getBugTypeEnum(String bugType){
|
||||
for (BugTypeEnum bugTypeEnum : BugTypeEnum.values()) {
|
||||
if(bugTypeEnum.bugType.equals(bugType)){
|
||||
return bugTypeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static BugTypeEnum getBugTypeEnumByDbValue(String dbValue){
|
||||
for (BugTypeEnum bugTypeEnum : BugTypeEnum.values()) {
|
||||
if(bugTypeEnum.dbValue.equals(dbValue)){
|
||||
return bugTypeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getDescriptionByDbValue(String dbValue){
|
||||
if (dbValue==null || "".equals(dbValue)){
|
||||
return null;
|
||||
}
|
||||
for (BugTypeEnum bugTypeEnum : BugTypeEnum.values()) {
|
||||
if(bugTypeEnum.dbValue.equals(dbValue)){
|
||||
return bugTypeEnum.description;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
package net.educoder.quality.common.enums;
|
||||
|
||||
/**
|
||||
* 通用状态枚举 0为否定含义,1为肯定含义
|
||||
* @author 威少
|
||||
*/
|
||||
public enum CommonStateEnum {
|
||||
/**
|
||||
* 否定含义
|
||||
*/
|
||||
FALSE(0, false),
|
||||
/**
|
||||
* 肯定含义
|
||||
*/
|
||||
TRUE(1, true);
|
||||
|
||||
int value;
|
||||
|
||||
boolean booleanValue;
|
||||
|
||||
CommonStateEnum(int value, boolean booleanValue) {
|
||||
this.value = value;
|
||||
this.booleanValue = booleanValue;
|
||||
}
|
||||
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean getBooleanValue() {
|
||||
return booleanValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从bool值转换
|
||||
* @param value bool值
|
||||
* @return 肯定为1,否定为0
|
||||
*/
|
||||
public static CommonStateEnum fromBoolean(Boolean value) {
|
||||
return value == null ? FALSE : value ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从整型值转换
|
||||
* @param value 整型值
|
||||
* @return 肯定为1,否定为0
|
||||
*/
|
||||
public static CommonStateEnum fromInteger(Integer value) {
|
||||
return value == null || value == FALSE.getValue() ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,4 +21,15 @@ public enum DetectResultCompareEnum {
|
|||
Integer type;
|
||||
String desc;
|
||||
|
||||
|
||||
public static DetectResultCompareEnum getDetectResultCompareEnum(int type) {
|
||||
for (DetectResultCompareEnum detectResultCompareEnum : DetectResultCompareEnum.values()) {
|
||||
if (detectResultCompareEnum.getType() == type) {
|
||||
return detectResultCompareEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@ public enum ErrorCodeEnum {
|
|||
PARAM_ERROR("000002","传参错误"),
|
||||
FILE_SAVE_ERROR("000003","文件保存失败,请重试"),
|
||||
TEMPLATE_NAME_ALREADY_EXISTS("000004","模板名称已存在"),
|
||||
PROJECT_NOT_SUCCESS("000005","该项目未检测或者未有成功的检测"),
|
||||
PROJECT_NOT_EXISTS("000006","该项目不存在"),
|
||||
BIND_EXCEPTION("000007","参数绑定异常"),
|
||||
NOT_FUND_VULNERABILITY("000008","未找到漏洞信息"),
|
||||
MVC_BIND_EXCEPTION("000014","请求参数绑定异常"),
|
||||
METHOD_NOT_ALLOWED_EXCEPTION("000008","请求方式异常"),
|
||||
EXCEPTION("999999","系统异常"),
|
||||
|
|
@ -25,6 +28,11 @@ public enum ErrorCodeEnum {
|
|||
AFTERMATH_EXP("000013","评测线程出错,善后处理发生异常"),
|
||||
GIT_FAIL("000014","获取git凭证失败: "),
|
||||
GIT_CREDENTIAL_FAIL("000015","设置git凭证失败:"),
|
||||
GIT_CREDENTIAL_INVALID("000016","git账号密码不匹配"),
|
||||
GIT_URL_INVALID("000017","非法的git地址"),
|
||||
COMPONENT_NOT_FOUND("000018","组件未找到"),
|
||||
LICENSE_NOT_FOUND("000019","许可证未找到"),
|
||||
UNDER_DETECTION_ERROR("000020","项目正在检测中,请稍后再试"),
|
||||
;
|
||||
|
||||
String value;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ import lombok.Getter;
|
|||
public enum IssueTypeEnum {
|
||||
|
||||
|
||||
VULNERABILITY(3, "漏洞"),
|
||||
BUG(2, "缺陷")
|
||||
BUG(2, "缺陷"),
|
||||
VULNERABILITY(3, "漏洞")
|
||||
;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -10,13 +10,11 @@ import lombok.Getter;
|
|||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum SourceEnum {
|
||||
public enum TaskInfoStatusEnum {
|
||||
|
||||
LOCAL("local", "本地文件"),
|
||||
GIT("git", "git地址"),
|
||||
SVN("svn", "svn地址");
|
||||
SUCCESS(1, "成功"),
|
||||
FAILED(-1, "失败");
|
||||
|
||||
private String source;
|
||||
private Integer status;
|
||||
private String desc;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package net.educoder.quality.common.filter;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.util.ContentCachingRequestWrapper;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/21
|
||||
* @Description: 缓存request请求流
|
||||
*/
|
||||
@Slf4j
|
||||
@WebFilter(urlPatterns = "/*")
|
||||
public class CachingContentFilter implements Filter {
|
||||
|
||||
private static final String FORM_CONTENT_TYPE = "multipart/form-data";
|
||||
private static final String METHOD_GET = "GET";
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain chain) throws IOException, ServletException {
|
||||
String contentType = request.getContentType();
|
||||
if (request instanceof HttpServletRequest) {
|
||||
HttpServletRequest requestWrapper = new ContentCachingRequestWrapper((HttpServletRequest) request);
|
||||
if (contentType != null && contentType.contains(FORM_CONTENT_TYPE)) {
|
||||
chain.doFilter(request, response);
|
||||
}else if(METHOD_GET.equalsIgnoreCase(((HttpServletRequest) request).getMethod())){
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
else {
|
||||
chain.doFilter(requestWrapper, response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package net.educoder.quality.common.filter;
|
||||
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/10/18
|
||||
* @Description:
|
||||
*/
|
||||
@WebFilter(urlPatterns = "/*", filterName = "logbackFilter")
|
||||
public class LogbackFilter implements Filter {
|
||||
|
||||
private static final String UNIQUE_ID = "traceId";
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
boolean bInsertMDC = insertMDC();
|
||||
try {
|
||||
chain.doFilter(request, response);
|
||||
} finally {
|
||||
if(bInsertMDC) {
|
||||
MDC.remove(UNIQUE_ID);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean insertMDC() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
String uniqueId = uuid.toString().replace("-", "");
|
||||
MDC.put(UNIQUE_ID, uniqueId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package net.educoder.quality.common.filter;
|
||||
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.core.task.TaskDecorator;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description
|
||||
* @Author youys
|
||||
* @Since 1.0
|
||||
* @Date 2021/7/7
|
||||
*/
|
||||
public class MdcTaskDecorator implements TaskDecorator {
|
||||
@Override
|
||||
public Runnable decorate(Runnable runnable) {
|
||||
Map<String,String> map = MDC.getCopyOfContextMap();
|
||||
|
||||
return () -> {
|
||||
try{
|
||||
MDC.setContextMap(map);
|
||||
runnable.run();
|
||||
} finally {
|
||||
MDC.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
package net.educoder.quality.common.util;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Cron表达式工具类(quartz类)
|
||||
* 符号表示的值:
|
||||
* * 表示所有值;
|
||||
* ? 表示未说明的值,即不关心它为何值;
|
||||
* - 表示一个指定的范围;
|
||||
* , 表示附加一个可能值;
|
||||
* / 符号前表示开始时间,符号后表示每次递增的值;
|
||||
* L("last") ("last") "L" 用在day-of-month字段意思是 "这个月最后一天";
|
||||
* W("weekday") 只能用在day-of-month字段。用来描叙最接近指定天的工作日(周一到周五)
|
||||
* @author jshixiong
|
||||
*/
|
||||
public class CronUtil {
|
||||
private static final SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
|
||||
|
||||
/**
|
||||
* 年 (可选) 留空
|
||||
* 允许的特殊字符:留空, 1970-2099 , - * /
|
||||
*/
|
||||
private String year;
|
||||
/**
|
||||
* 星期 可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
|
||||
* 允许的特殊字符:1-7 或者 SUN-SAT , - * ? / L C #
|
||||
*/
|
||||
private String week;
|
||||
/**
|
||||
* 月 可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
|
||||
* 允许的特殊字符:1-12 或者 JAN-DEC , - * /
|
||||
*/
|
||||
private String month;
|
||||
/**
|
||||
* 日 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
|
||||
* 允许的特殊字符:1-31 , - * ? / L W C
|
||||
*/
|
||||
private String day;
|
||||
/**
|
||||
* 时 可以用数字0-23表示
|
||||
* 允许的特殊字符:0-23, - * /
|
||||
*/
|
||||
private String hour;
|
||||
/**
|
||||
* 分 可以用数字0-59 表示
|
||||
* 允许的特殊字符:0-59,- * /
|
||||
*/
|
||||
private String minutes;
|
||||
/**
|
||||
* 秒 可以用数字0-59 表示
|
||||
* 允许的特殊字符:0-59,- * /
|
||||
*/
|
||||
private String seconds ;
|
||||
|
||||
/***
|
||||
* 日期转换cron表达式 例如 "0 07 10 15 1 ? 2016"
|
||||
* @param date 时间点
|
||||
* @return
|
||||
*/
|
||||
public static String getCron(Date date) {
|
||||
String formatTimeStr = null;
|
||||
if (Objects.nonNull(date)) {
|
||||
formatTimeStr = sdf.format(date);
|
||||
}
|
||||
return formatTimeStr;
|
||||
}
|
||||
|
||||
/***
|
||||
* 日期转换cron表达式 例如 "0 07 10 15 1 ? 2016"
|
||||
* @param date 时间点
|
||||
* @return
|
||||
*/
|
||||
public static String getCron(LocalDateTime date) {
|
||||
String formatTimeStr = null;
|
||||
if (Objects.nonNull(date)) {
|
||||
formatTimeStr = DateUtil.format(date,"ss mm HH dd MM ? yyyy");
|
||||
}
|
||||
return formatTimeStr;
|
||||
}
|
||||
|
||||
/***
|
||||
* 忽略年份
|
||||
* 日期转换cron表达式 例如 "0 07 10 15 1 ?"
|
||||
* @param date 时间点
|
||||
* @return
|
||||
*/
|
||||
public static String getCronIgnoreYear(LocalDateTime date) {
|
||||
String formatTimeStr = null;
|
||||
if (Objects.nonNull(date)) {
|
||||
formatTimeStr = DateUtil.format(date,"ss mm HH dd MM ?");
|
||||
}
|
||||
return formatTimeStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定日期的cron表达式
|
||||
* @param year 年
|
||||
* @param week 星期 可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
|
||||
* @param month 月 可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
|
||||
* @param day 日 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
|
||||
* @param hour 时 可以用数字0-23表示
|
||||
* @param minutes 分 可以用数字0-59 表示
|
||||
* @param seconds 秒 可以用数字0-59 表示
|
||||
* @return
|
||||
*/
|
||||
public static String getCron(String year,String week,String month,String day,String hour,String minutes,String seconds) {
|
||||
return seconds+" "+minutes+" "+hour+" "+day+" "+month+" "+week+" "+year;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定日期的cron表达式
|
||||
* @param week 星期 可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
|
||||
* @param month 月 可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
|
||||
* @param day 日 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
|
||||
* @param hour 时 可以用数字0-23表示
|
||||
* @param minutes 分 可以用数字0-59 表示
|
||||
* @param seconds 秒 可以用数字0-59 表示
|
||||
* @return
|
||||
*/
|
||||
public static String getCron(String week,String month,String day,String hour,String minutes,String seconds) {
|
||||
return getCron("*",week,month,day,hour,minutes,seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定日期的cron表达式
|
||||
* @param month 月 可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
|
||||
* @param day 日 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
|
||||
* @param hour 时 可以用数字0-23表示
|
||||
* @param minutes 分 可以用数字0-59 表示
|
||||
* @param seconds 秒 可以用数字0-59 表示
|
||||
* @return
|
||||
*/
|
||||
static String getCron(String month,String day,String hour,String minutes,String seconds) {
|
||||
return getCron("?",month,day,hour,minutes,seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定范围的Cron表达式 例如 13-14 30-31 11-12 20-21 04-05 1-2 2021-2022
|
||||
* @param year 年 使用(year1-year2) year1<=year2
|
||||
* @param week 星期 使用(week1-week2) 可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
|
||||
* @param month 月 使用(month1-month2) 可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
|
||||
* @param day 日 使用(day1-day2) 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
|
||||
* @param hour 时 使用(hour1-hour2) 可以用数字0-23表示
|
||||
* @param minutes 分 使用(minutes1-minutes2) 可以用数字0-59 表示
|
||||
* @param seconds 秒 使用(seconds1-seconds2) 可以用数字0-59 表示
|
||||
* @return
|
||||
*/
|
||||
public static String getCronByRange(String year,String week,String month,String day,String hour,String minutes,String seconds) {
|
||||
return seconds+" "+minutes+" "+hour+" "+day+" "+month+" "+week+" "+year;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定范围的Cron表达式 例如 13-14 30-31 11-12 20-21 04-05 1-2
|
||||
* @param week 星期 使用(week1-week2) 可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
|
||||
* @param month 月 使用(month1-month2) 可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
|
||||
* @param day 日 使用(day1-day2) 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
|
||||
* @param hour 时 使用(hour1-hour2) 可以用数字0-23表示
|
||||
* @param minutes 分 使用(minutes1-minutes2) 可以用数字0-59 表示
|
||||
* @param seconds 秒 使用(seconds1-seconds2) 可以用数字0-59 表示
|
||||
* @return
|
||||
*/
|
||||
public static String getCronByRange(String week,String month,String day,String hour,String minutes,String seconds) {
|
||||
return getCron("*",week,month,day,hour,minutes,seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定范围的Cron表达式 例如 13-14 30-31 11-12 20-21 04-05
|
||||
* @param month 月 使用(month1-month2) 可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
|
||||
* @param day 日 使用(day1-day2) 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
|
||||
* @param hour 时 使用(hour1-hour2) 可以用数字0-23表示
|
||||
* @param minutes 分 使用(minutes1-minutes2) 可以用数字0-59 表示
|
||||
* @param seconds 秒 使用(seconds1-seconds2) 可以用数字0-59 表示
|
||||
* @return
|
||||
*/
|
||||
static String getCronByRange(String month,String day,String hour,String minutes,String seconds) {
|
||||
return getCron("?",month,day,hour,minutes,seconds);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package net.educoder.quality.common.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.educoder.quality.common.bean.ShellResult;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/10/14
|
||||
* @Description:
|
||||
*/
|
||||
@Slf4j
|
||||
public class GitUtil {
|
||||
|
||||
/**
|
||||
* 克隆代码到指定目录
|
||||
*/
|
||||
public static ShellResult gitClone(String gitUrl, String branch, String username, String password, String fullWorkspace) {
|
||||
File file = new File(fullWorkspace);
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
|
||||
int index = gitUrl.lastIndexOf("//");
|
||||
String command;
|
||||
if (StringUtils.isNotBlank(username)) {
|
||||
command = StringUtils.join("cd ", fullWorkspace, " && git clone -b ", branch, " ", gitUrl.substring(0, index + 2), username, ":",
|
||||
password, "@", gitUrl.substring(index + 2));
|
||||
} else {
|
||||
command = StringUtils.join("cd ", fullWorkspace, " && git clone -b ", branch, " ", gitUrl.substring(0, index + 2), gitUrl.substring(index + 2));
|
||||
}
|
||||
|
||||
return ShellUtil.executeAndGetExitStatus(command);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -94,7 +94,6 @@ public final class ShellUtil {
|
|||
continue;
|
||||
}
|
||||
|
||||
logger.debug("executeAndGetExitStatus line: {}", line); // TODO 此处稳定后去除
|
||||
out.append(line);
|
||||
out.append(System.getProperty("line.separator"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,220 @@
|
|||
package net.educoder.quality.common.util;
|
||||
|
||||
import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
|
||||
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.xwpf.usermodel.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/23
|
||||
* @Description:
|
||||
*/
|
||||
public class WordUtil {
|
||||
|
||||
public static void changeText(XWPFDocument document, Map<String, String> textMap) {
|
||||
//获取段落集合
|
||||
List<XWPFParagraph> paragraphs = document.getParagraphs();
|
||||
for (XWPFParagraph paragraph : paragraphs) {
|
||||
//判断此段落时候需要进行替换
|
||||
String text = paragraph.getText();
|
||||
if (StringUtils.isNotBlank(text) && text.contains("${")) {
|
||||
List<XWPFRun> runs = paragraph.getRuns();
|
||||
for (XWPFRun run : runs) {
|
||||
//替换模板原来位置
|
||||
String textValue = changeValue(run.toString(), textMap);
|
||||
run.setText(textValue, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配传入信息集合与模板
|
||||
*
|
||||
* @param value 模板需要替换的区域
|
||||
* @param textMap 传入信息集合
|
||||
* @return 模板需要替换区域信息集合对应值
|
||||
*/
|
||||
public static String changeValue(String value, Map<String, String> textMap) {
|
||||
Set<Map.Entry<String, String>> textSets = textMap.entrySet();
|
||||
for (Map.Entry<String, String> textSet : textSets) {
|
||||
//匹配模板与替换值 格式${key}
|
||||
String key = "${" + textSet.getKey() + "}";
|
||||
if (value.indexOf(key) != -1) {
|
||||
value = value.replace(key, textSet.getValue());
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得某个表格多行的段落
|
||||
* @param table XWPFTable
|
||||
*/
|
||||
public static List<XWPFParagraph> getTableRowsParagraphs(XWPFTable table,int begain,int end) {
|
||||
List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
|
||||
// 列表内段落
|
||||
for (int i = begain;i<=end;i++){
|
||||
XWPFTableRow row = table.getRow(i);
|
||||
List<XWPFTableCell> cells = row.getTableCells();
|
||||
for (XWPFTableCell cell : cells) {
|
||||
paragraphs.addAll(cell.getParagraphs());
|
||||
}
|
||||
}
|
||||
return paragraphs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得一行的段落
|
||||
* @param row 一行
|
||||
*/
|
||||
public static List<XWPFParagraph> getRowParagraphs(XWPFTableRow row) {
|
||||
List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
|
||||
List<XWPFTableCell> cells = row.getTableCells();
|
||||
for (XWPFTableCell cell : cells) {
|
||||
paragraphs.addAll(cell.getParagraphs());
|
||||
}
|
||||
return paragraphs;
|
||||
}
|
||||
|
||||
/**
|
||||
* insertRow 在word表格中指定位置插入一行,并将某一行的样式及内容复制到新增行
|
||||
* */
|
||||
public static XWPFTableRow insertRow(XWPFTable table, XWPFTableRow copyRow, int newrowIndex) {
|
||||
// 在表格中指定的位置新增一行
|
||||
XWPFTableRow targetRow = table.insertNewTableRow(newrowIndex);
|
||||
//复制行对象
|
||||
targetRow.getCtRow().setTrPr(copyRow.getCtRow().getTrPr());
|
||||
//或许需要复制的行的列
|
||||
List<XWPFTableCell> copyCells = copyRow.getTableCells();
|
||||
//复制列对象
|
||||
XWPFTableCell targetCell = null;
|
||||
for (int i = 0; i < copyCells.size(); i++) {
|
||||
XWPFTableCell copyCell = copyCells.get(i);
|
||||
targetCell = targetRow.addNewTableCell();
|
||||
targetCell.getCTTc().setTcPr(copyCell.getCTTc().getTcPr());
|
||||
if (copyCell.getParagraphs() != null && copyCell.getParagraphs().size() > 0) {
|
||||
targetCell.getParagraphs().get(0).getCTP().setPPr(copyCell.getParagraphs().get(0).getCTP().getPPr());
|
||||
if (copyCell.getParagraphs().get(0).getRuns() != null
|
||||
&& copyCell.getParagraphs().get(0).getRuns().size() > 0) {
|
||||
XWPFRun cellRun = targetCell.getParagraphs().get(0).createRun();
|
||||
XWPFRun copyRun = copyCell.getParagraphs().get(0).getRuns().get(0);
|
||||
//字体名称
|
||||
cellRun.setFontFamily(copyRun.getFontFamily());
|
||||
//字体颜色
|
||||
cellRun.setColor(copyRun.getColor());
|
||||
//字体加粗
|
||||
cellRun.setBold(copyRun.isBold());
|
||||
//字体倾斜
|
||||
cellRun.setItalic(copyRun.isItalic());
|
||||
|
||||
cellRun.setText(copyCell.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
return targetRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换全部文本
|
||||
* @param textMap 替换信息
|
||||
* @param paragraphs 段落
|
||||
*/
|
||||
public static void replaceAllTexts(Map<String, String> textMap, List<XWPFParagraph> paragraphs) {
|
||||
Set<Map.Entry<String, String>> textEntrySet = textMap.entrySet();
|
||||
for (Map.Entry<String, String> entry : textEntrySet) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
// 替换全部文本
|
||||
replaceAllTexts(key, value, paragraphs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换全部文本
|
||||
* @param key 替换键
|
||||
* @param value 替换值
|
||||
* @param paragraphs 段落
|
||||
*/
|
||||
public static void replaceAllTexts(String key, String value, List<XWPFParagraph> paragraphs) {
|
||||
for (XWPFParagraph paragraph : paragraphs) {
|
||||
// 待替换文本
|
||||
String text = paragraph.getText();
|
||||
if (StringUtils.isNotEmpty(text) && text.indexOf(key) != -1) {
|
||||
List<XWPFRun> runs = paragraph.getRuns();
|
||||
// 只保留第一个Run
|
||||
for (int i = (runs.size() - 1); i > 0; i--) {
|
||||
paragraph.removeRun(i);
|
||||
}
|
||||
runs.get(0).setText(text.replace(key, value), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存Word
|
||||
* @param document Word文档
|
||||
* @param filePath 保存路径
|
||||
*/
|
||||
public static void save(XWPFDocument document, String filePath) throws Exception {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
System.out.println("POI生成Word文件:" + filePath);
|
||||
File file = new File(filePath);
|
||||
// FileUtil.makeDir(file.getParentFile());
|
||||
fos = new FileOutputStream(file);
|
||||
document.write(fos);
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
fos.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开Word
|
||||
* @param filePath 文件全路径
|
||||
*/
|
||||
public static XWPFDocument open(String filePath) throws Exception {
|
||||
InputStream is = null;
|
||||
try {
|
||||
System.out.println("POI打开Word文件:" + filePath);
|
||||
is = new FileInputStream(filePath);
|
||||
return new XWPFDocument(is);
|
||||
} finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* word转pdf
|
||||
* 功能依赖于poi 3.17
|
||||
* linux或win环境下需要相应的中文字体支持(宋体,微软雅黑...),否则中文不显示
|
||||
* @param document
|
||||
*/
|
||||
public static void docToPdf(XWPFDocument document,OutputStream outPDF ){
|
||||
PdfOptions options = PdfOptions.create();
|
||||
try {
|
||||
PdfConverter.getInstance().convert(document, outPDF, options);
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
try {
|
||||
if (outPDF!=null){
|
||||
outPDF.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* SonarQube
|
||||
* Copyright (C) 2009-2019 SonarSource SA
|
||||
* mailto:info AT sonarsource DOT com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package net.educoder.quality.common.util.html;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
class CharactersReader {
|
||||
|
||||
static final int END_OF_STREAM = -1;
|
||||
|
||||
private final BufferedReader stringBuffer;
|
||||
private final Deque<String> openTags;
|
||||
|
||||
private int currentValue;
|
||||
private int previousValue;
|
||||
private int currentIndex = -1;
|
||||
|
||||
public CharactersReader(BufferedReader stringBuffer) {
|
||||
this.stringBuffer = stringBuffer;
|
||||
this.openTags = new ArrayDeque<>();
|
||||
}
|
||||
|
||||
boolean readNextChar() throws IOException {
|
||||
previousValue = currentValue;
|
||||
currentValue = stringBuffer.read();
|
||||
currentIndex++;
|
||||
return currentValue != END_OF_STREAM;
|
||||
}
|
||||
|
||||
int getCurrentValue() {
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
int getPreviousValue() {
|
||||
return previousValue;
|
||||
}
|
||||
|
||||
int getCurrentIndex() {
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
void registerOpenTag(String textType) {
|
||||
openTags.push(textType);
|
||||
}
|
||||
|
||||
void removeLastOpenTag() {
|
||||
openTags.remove();
|
||||
}
|
||||
|
||||
Deque<String> getOpenTags() {
|
||||
return openTags;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* SonarQube
|
||||
* Copyright (C) 2009-2019 SonarSource SA
|
||||
* mailto:info AT sonarsource DOT com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package net.educoder.quality.common.util.html;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
class DecorationDataHolder {
|
||||
|
||||
private static final String ENTITY_SEPARATOR = ";";
|
||||
private static final String FIELD_SEPARATOR = ",";
|
||||
private static final String SYMBOL_PREFIX = "sym-";
|
||||
private static final String HIGHLIGHTABLE = "sym";
|
||||
|
||||
private List<OpeningHtmlTag> openingTagsEntries;
|
||||
private int openingTagsIndex;
|
||||
private List<Integer> closingTagsOffsets;
|
||||
private int closingTagsIndex;
|
||||
|
||||
DecorationDataHolder() {
|
||||
openingTagsEntries = Lists.newArrayList();
|
||||
closingTagsOffsets = Lists.newArrayList();
|
||||
}
|
||||
|
||||
void loadSymbolReferences(String symbolsReferences) {
|
||||
String[] symbols = symbolsReferences.split(ENTITY_SEPARATOR);
|
||||
for (String symbol : symbols) {
|
||||
String[] symbolFields = symbol.split(FIELD_SEPARATOR);
|
||||
int declarationStartOffset = Integer.parseInt(symbolFields[0]);
|
||||
int declarationEndOffset = Integer.parseInt(symbolFields[1]);
|
||||
int symbolLength = declarationEndOffset - declarationStartOffset;
|
||||
String[] symbolOccurrences = Arrays.copyOfRange(symbolFields, 2, symbolFields.length);
|
||||
loadSymbolOccurrences(declarationStartOffset, symbolLength, symbolOccurrences);
|
||||
}
|
||||
}
|
||||
|
||||
void loadLineSymbolReferences(String symbolsReferences) {
|
||||
String[] symbols = symbolsReferences.split(ENTITY_SEPARATOR);
|
||||
for (String symbol : symbols) {
|
||||
String[] symbolFields = symbol.split(FIELD_SEPARATOR);
|
||||
int startOffset = Integer.parseInt(symbolFields[0]);
|
||||
int endOffset = Integer.parseInt(symbolFields[1]);
|
||||
int symbolLength = endOffset - startOffset;
|
||||
int symbolId = Integer.parseInt(symbolFields[2]);
|
||||
loadSymbolOccurrences(symbolId, symbolLength, new String[] { Integer.toString(startOffset) });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loadSyntaxHighlightingData(String syntaxHighlightingRules) {
|
||||
String[] rules = syntaxHighlightingRules.split(ENTITY_SEPARATOR);
|
||||
for (String rule : rules) {
|
||||
String[] ruleFields = rule.split(FIELD_SEPARATOR);
|
||||
int startOffset = Integer.parseInt(ruleFields[0]);
|
||||
int endOffset = Integer.parseInt(ruleFields[1]);
|
||||
if (startOffset < endOffset) {
|
||||
insertAndPreserveOrder(new OpeningHtmlTag(startOffset, ruleFields[2]), openingTagsEntries);
|
||||
insertAndPreserveOrder(endOffset, closingTagsOffsets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<OpeningHtmlTag> getOpeningTagsEntries() {
|
||||
return openingTagsEntries;
|
||||
}
|
||||
|
||||
OpeningHtmlTag getCurrentOpeningTagEntry() {
|
||||
return openingTagsIndex < openingTagsEntries.size() ? openingTagsEntries.get(openingTagsIndex) : null;
|
||||
}
|
||||
|
||||
void nextOpeningTagEntry() {
|
||||
openingTagsIndex++;
|
||||
}
|
||||
|
||||
List<Integer> getClosingTagsOffsets() {
|
||||
return closingTagsOffsets;
|
||||
}
|
||||
|
||||
int getCurrentClosingTagOffset() {
|
||||
return closingTagsIndex < closingTagsOffsets.size() ? closingTagsOffsets.get(closingTagsIndex) : -1;
|
||||
}
|
||||
|
||||
void nextClosingTagOffset() {
|
||||
closingTagsIndex++;
|
||||
}
|
||||
|
||||
private void loadSymbolOccurrences(int declarationStartOffset, int symbolLength, String[] symbolOccurrences) {
|
||||
for (String symbolOccurrence : symbolOccurrences) {
|
||||
int occurrenceStartOffset = Integer.parseInt(symbolOccurrence);
|
||||
int occurrenceEndOffset = occurrenceStartOffset + symbolLength;
|
||||
insertAndPreserveOrder(new OpeningHtmlTag(occurrenceStartOffset, SYMBOL_PREFIX + declarationStartOffset + " " + HIGHLIGHTABLE), openingTagsEntries);
|
||||
insertAndPreserveOrder(occurrenceEndOffset, closingTagsOffsets);
|
||||
}
|
||||
}
|
||||
|
||||
private void insertAndPreserveOrder(OpeningHtmlTag newEntry, List<OpeningHtmlTag> openingHtmlTags) {
|
||||
int insertionIndex = 0;
|
||||
Iterator<OpeningHtmlTag> tagIterator = openingHtmlTags.iterator();
|
||||
while (tagIterator.hasNext() && tagIterator.next().getStartOffset() <= newEntry.getStartOffset()) {
|
||||
insertionIndex++;
|
||||
}
|
||||
openingHtmlTags.add(insertionIndex, newEntry);
|
||||
}
|
||||
|
||||
private void insertAndPreserveOrder(int newOffset, List<Integer> orderedOffsets) {
|
||||
int insertionIndex = 0;
|
||||
Iterator<Integer> entriesIterator = orderedOffsets.iterator();
|
||||
while (entriesIterator.hasNext() && entriesIterator.next() <= newOffset) {
|
||||
insertionIndex++;
|
||||
}
|
||||
orderedOffsets.add(insertionIndex, newOffset);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* SonarQube
|
||||
* Copyright (C) 2009-2019 SonarSource SA
|
||||
* mailto:info AT sonarsource DOT com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package net.educoder.quality.common.util.html;
|
||||
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 给代码增加样式
|
||||
*/
|
||||
public final class HtmlSourceDecorator {
|
||||
|
||||
private static volatile HtmlSourceDecorator htmlSourceDecorator = null;
|
||||
|
||||
private HtmlSourceDecorator() {
|
||||
}
|
||||
|
||||
public static HtmlSourceDecorator getInstance() {
|
||||
if (htmlSourceDecorator == null) {
|
||||
synchronized (HtmlSourceDecorator.class) {
|
||||
if (htmlSourceDecorator == null) {
|
||||
htmlSourceDecorator = new HtmlSourceDecorator();
|
||||
}
|
||||
}
|
||||
}
|
||||
return htmlSourceDecorator;
|
||||
}
|
||||
|
||||
public String getDecoratedSourceAsHtml(@NotNull String sourceLine, @NotNull String highlighting, @NotNull String symbols) {
|
||||
if (sourceLine == null) {
|
||||
return null;
|
||||
}
|
||||
DecorationDataHolder decorationDataHolder = new DecorationDataHolder();
|
||||
if (StringUtils.isNotBlank(highlighting)) {
|
||||
decorationDataHolder.loadSyntaxHighlightingData(highlighting);
|
||||
}
|
||||
if (StringUtils.isNotBlank(symbols)) {
|
||||
decorationDataHolder.loadLineSymbolReferences(symbols);
|
||||
}
|
||||
HtmlTextDecorator textDecorator = new HtmlTextDecorator();
|
||||
List<String> decoratedSource = textDecorator.decorateTextWithHtml(sourceLine, decorationDataHolder, 1, 1);
|
||||
if (decoratedSource == null) {
|
||||
return null;
|
||||
} else {
|
||||
if (decoratedSource.isEmpty()) {
|
||||
return "";
|
||||
} else {
|
||||
return decoratedSource.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* SonarQube
|
||||
* Copyright (C) 2009-2019 SonarSource SA
|
||||
* mailto:info AT sonarsource DOT com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package net.educoder.quality.common.util.html;
|
||||
|
||||
import com.google.common.io.Closeables;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
|
||||
@Slf4j
|
||||
public class HtmlTextDecorator {
|
||||
|
||||
static final char CR_END_OF_LINE = '\r';
|
||||
static final char LF_END_OF_LINE = '\n';
|
||||
static final char HTML_OPENING = '<';
|
||||
static final char HTML_CLOSING = '>';
|
||||
static final char AMPERSAND = '&';
|
||||
static final String ENCODED_HTML_OPENING = "<";
|
||||
static final String ENCODED_HTML_CLOSING = ">";
|
||||
static final String ENCODED_AMPERSAND = "&";
|
||||
|
||||
List<String> decorateTextWithHtml(String text, DecorationDataHolder decorationDataHolder) {
|
||||
return decorateTextWithHtml(text, decorationDataHolder, null, null);
|
||||
}
|
||||
|
||||
List<String> decorateTextWithHtml(String text, DecorationDataHolder decorationDataHolder, @Nullable Integer from, @Nullable Integer to) {
|
||||
|
||||
StringBuilder currentHtmlLine = new StringBuilder();
|
||||
List<String> decoratedHtmlLines = newArrayList();
|
||||
int currentLine = 1;
|
||||
|
||||
BufferedReader stringBuffer = null;
|
||||
try {
|
||||
stringBuffer = new BufferedReader(new StringReader(text));
|
||||
|
||||
CharactersReader charsReader = new CharactersReader(stringBuffer);
|
||||
|
||||
while (charsReader.readNextChar()) {
|
||||
if (shouldStop(currentLine, to)) {
|
||||
break;
|
||||
}
|
||||
if (shouldStartNewLine(charsReader)) {
|
||||
if (canAddLine(currentLine, from)) {
|
||||
decoratedHtmlLines.add(currentHtmlLine.toString());
|
||||
}
|
||||
currentLine++;
|
||||
currentHtmlLine = new StringBuilder();
|
||||
}
|
||||
addCharToCurrentLine(charsReader, currentHtmlLine, decorationDataHolder);
|
||||
}
|
||||
|
||||
closeCurrentSyntaxTags(charsReader, currentHtmlLine);
|
||||
|
||||
if (shouldStartNewLine(charsReader)) {
|
||||
addLine(decoratedHtmlLines, currentHtmlLine.toString(), currentLine, from, to);
|
||||
currentLine++;
|
||||
addLine(decoratedHtmlLines, "", currentLine, from, to);
|
||||
} else if (currentHtmlLine.length() > 0) {
|
||||
addLine(decoratedHtmlLines, currentHtmlLine.toString(), currentLine, from, to);
|
||||
}
|
||||
|
||||
} catch (IOException exception) {
|
||||
String errorMsg = "An exception occurred while highlighting the syntax of one of the project's files";
|
||||
log.error(errorMsg);
|
||||
throw new IllegalStateException(errorMsg, exception);
|
||||
} finally {
|
||||
Closeables.closeQuietly(stringBuffer);
|
||||
}
|
||||
|
||||
return decoratedHtmlLines;
|
||||
}
|
||||
|
||||
private void addCharToCurrentLine(CharactersReader charsReader, StringBuilder currentHtmlLine, DecorationDataHolder decorationDataHolder) {
|
||||
if (shouldStartNewLine(charsReader)) {
|
||||
if (shouldReopenPendingTags(charsReader)) {
|
||||
reopenCurrentSyntaxTags(charsReader, currentHtmlLine);
|
||||
}
|
||||
}
|
||||
|
||||
int numberOfTagsToClose = getNumberOfTagsToClose(charsReader.getCurrentIndex(), decorationDataHolder);
|
||||
closeCompletedTags(charsReader, numberOfTagsToClose, currentHtmlLine);
|
||||
|
||||
if (shouldClosePendingTags(charsReader)) {
|
||||
closeCurrentSyntaxTags(charsReader, currentHtmlLine);
|
||||
}
|
||||
|
||||
Collection<String> tagsToOpen = getTagsToOpen(charsReader.getCurrentIndex(), decorationDataHolder);
|
||||
openNewTags(charsReader, tagsToOpen, currentHtmlLine);
|
||||
|
||||
if (shouldAppendCharToHtmlOutput(charsReader)) {
|
||||
char currentChar = (char) charsReader.getCurrentValue();
|
||||
currentHtmlLine.append(normalize(currentChar));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addLine(List<String> decoratedHtmlLines, String line, int currentLine, @Nullable Integer from, @Nullable Integer to) {
|
||||
if (canAddLine(currentLine, from) && !shouldStop(currentLine, to)) {
|
||||
decoratedHtmlLines.add(line);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean canAddLine(int currentLine, @Nullable Integer from) {
|
||||
return from == null || currentLine >= from;
|
||||
}
|
||||
|
||||
private static boolean shouldStop(int currentLine, @Nullable Integer to) {
|
||||
return to != null && to < currentLine;
|
||||
}
|
||||
|
||||
private char[] normalize(char currentChar) {
|
||||
char[] normalizedChars;
|
||||
if (currentChar == HTML_OPENING) {
|
||||
normalizedChars = ENCODED_HTML_OPENING.toCharArray();
|
||||
} else if (currentChar == HTML_CLOSING) {
|
||||
normalizedChars = ENCODED_HTML_CLOSING.toCharArray();
|
||||
} else if (currentChar == AMPERSAND) {
|
||||
normalizedChars = ENCODED_AMPERSAND.toCharArray();
|
||||
} else {
|
||||
normalizedChars = new char[] {currentChar};
|
||||
}
|
||||
return normalizedChars;
|
||||
}
|
||||
|
||||
private boolean shouldAppendCharToHtmlOutput(CharactersReader charsReader) {
|
||||
return charsReader.getCurrentValue() != CR_END_OF_LINE && charsReader.getCurrentValue() != LF_END_OF_LINE;
|
||||
}
|
||||
|
||||
private int getNumberOfTagsToClose(int currentIndex, DecorationDataHolder dataHolder) {
|
||||
int numberOfTagsToClose = 0;
|
||||
|
||||
while (currentIndex == dataHolder.getCurrentClosingTagOffset()) {
|
||||
numberOfTagsToClose++;
|
||||
dataHolder.nextClosingTagOffset();
|
||||
}
|
||||
return numberOfTagsToClose;
|
||||
}
|
||||
|
||||
private Collection<String> getTagsToOpen(int currentIndex, DecorationDataHolder dataHolder) {
|
||||
Collection<String> tagsToOpen = newArrayList();
|
||||
while (dataHolder.getCurrentOpeningTagEntry() != null && currentIndex == dataHolder.getCurrentOpeningTagEntry().getStartOffset()) {
|
||||
tagsToOpen.add(dataHolder.getCurrentOpeningTagEntry().getCssClass());
|
||||
dataHolder.nextOpeningTagEntry();
|
||||
}
|
||||
return tagsToOpen;
|
||||
}
|
||||
|
||||
private boolean shouldClosePendingTags(CharactersReader charactersReader) {
|
||||
return charactersReader.getCurrentValue() == CR_END_OF_LINE
|
||||
|| (charactersReader.getCurrentValue() == LF_END_OF_LINE && charactersReader.getPreviousValue() != CR_END_OF_LINE)
|
||||
|| (charactersReader.getCurrentValue() == CharactersReader.END_OF_STREAM && charactersReader.getPreviousValue() != LF_END_OF_LINE);
|
||||
}
|
||||
|
||||
private boolean shouldReopenPendingTags(CharactersReader charactersReader) {
|
||||
return (charactersReader.getPreviousValue() == LF_END_OF_LINE && charactersReader.getCurrentValue() != LF_END_OF_LINE)
|
||||
|| (charactersReader.getPreviousValue() == CR_END_OF_LINE && charactersReader.getCurrentValue() != CR_END_OF_LINE
|
||||
&& charactersReader.getCurrentValue() != LF_END_OF_LINE);
|
||||
}
|
||||
|
||||
private boolean shouldStartNewLine(CharactersReader charactersReader) {
|
||||
return charactersReader.getPreviousValue() == LF_END_OF_LINE
|
||||
|| (charactersReader.getPreviousValue() == CR_END_OF_LINE && charactersReader.getCurrentValue() != LF_END_OF_LINE);
|
||||
}
|
||||
|
||||
private void closeCompletedTags(CharactersReader charactersReader, int numberOfTagsToClose,
|
||||
StringBuilder decoratedText) {
|
||||
for (int i = 0; i < numberOfTagsToClose; i++) {
|
||||
injectClosingHtml(decoratedText);
|
||||
charactersReader.removeLastOpenTag();
|
||||
}
|
||||
}
|
||||
|
||||
private void openNewTags(CharactersReader charactersReader, Collection<String> tagsToOpen,
|
||||
StringBuilder decoratedText) {
|
||||
for (String tagToOpen : tagsToOpen) {
|
||||
injectOpeningHtmlForRule(tagToOpen, decoratedText);
|
||||
charactersReader.registerOpenTag(tagToOpen);
|
||||
}
|
||||
}
|
||||
|
||||
private void closeCurrentSyntaxTags(CharactersReader charactersReader, StringBuilder decoratedText) {
|
||||
for (int i = 0; i < charactersReader.getOpenTags().size(); i++) {
|
||||
injectClosingHtml(decoratedText);
|
||||
}
|
||||
}
|
||||
|
||||
private void reopenCurrentSyntaxTags(CharactersReader charactersReader, StringBuilder decoratedText) {
|
||||
for (String tags : charactersReader.getOpenTags()) {
|
||||
injectOpeningHtmlForRule(tags, decoratedText);
|
||||
}
|
||||
}
|
||||
|
||||
private void injectOpeningHtmlForRule(String textType, StringBuilder decoratedText) {
|
||||
decoratedText.append("<span class=\"").append(textType).append("\">");
|
||||
}
|
||||
|
||||
private void injectClosingHtml(StringBuilder decoratedText) {
|
||||
decoratedText.append("</span>");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* SonarQube
|
||||
* Copyright (C) 2009-2019 SonarSource SA
|
||||
* mailto:info AT sonarsource DOT com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package net.educoder.quality.common.util.html;
|
||||
|
||||
class OpeningHtmlTag {
|
||||
|
||||
private final int startOffset;
|
||||
private final String cssClass;
|
||||
|
||||
OpeningHtmlTag(int startOffset, String cssClass) {
|
||||
this.startOffset = startOffset;
|
||||
this.cssClass = cssClass;
|
||||
}
|
||||
|
||||
int getStartOffset() {
|
||||
return startOffset;
|
||||
}
|
||||
|
||||
String getCssClass() {
|
||||
return cssClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
return compareTo((OpeningHtmlTag) o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = startOffset;
|
||||
result = 31 * result + (cssClass != null ? cssClass.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean compareTo(OpeningHtmlTag otherTag) {
|
||||
if (startOffset != otherTag.startOffset) {
|
||||
return false;
|
||||
}
|
||||
return (cssClass != null) ? cssClass.equals(otherTag.cssClass) : (otherTag.cssClass == null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package net.educoder.quality.common.util.mdc;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2023/2/27
|
||||
* @Description:
|
||||
*/
|
||||
public class MdcTaskDecorator {
|
||||
|
||||
public static Runnable decorate(Runnable runnable) {
|
||||
Map<String, String> contextMap = MDC.getCopyOfContextMap();
|
||||
return () -> {
|
||||
try {
|
||||
if (contextMap != null) {
|
||||
MDC.setContextMap(contextMap);
|
||||
}
|
||||
MDC.put("traceId", IdUtil.fastSimpleUUID());
|
||||
runnable.run();
|
||||
} finally {
|
||||
MDC.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.educoder.quality.common.util.mdc;
|
||||
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2023/2/27
|
||||
* @Description:
|
||||
*/
|
||||
public class MdcThreadPoolTaskScheduler extends ThreadPoolTaskScheduler {
|
||||
|
||||
@Override
|
||||
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
|
||||
return super.scheduleWithFixedDelay(MdcTaskDecorator.decorate(task), startTime, delay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture<?> schedule(Runnable task, Date startTime) {
|
||||
return super.schedule(MdcTaskDecorator.decorate(task), startTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -163,7 +163,12 @@
|
|||
<version>${pagehelper.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- word to pdf -->
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>fr.opensagres.poi.xwpf.converter.pdf-gae</artifactId>
|
||||
<version>2.0.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
|
|
@ -196,6 +201,18 @@
|
|||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
<version>3.21.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.jpountz.lz4</groupId>
|
||||
<artifactId>lz4</artifactId>
|
||||
<version>1.3.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
|
@ -257,7 +274,7 @@
|
|||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.py</include>
|
||||
<include>**/*.docx</include>
|
||||
<include>**/*.sh</include>
|
||||
<include>**/*.xml</include>
|
||||
<include>**/*.yml</include>
|
||||
|
|
|
|||
57
web/pom.xml
57
web/pom.xml
|
|
@ -4,7 +4,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>net.educoder.quality</groupId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
|
|
@ -16,6 +16,14 @@
|
|||
<description>web</description>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<targetJavaProject>${basedir}/src/main/java</targetJavaProject>
|
||||
<targetMapperPackage>net.educoder.quality.mapper</targetMapperPackage>
|
||||
<targetModelPackage>net.educoder.quality.entity.mysql</targetModelPackage>
|
||||
<!-- XML生成路径 -->
|
||||
<targetResourcesProject>${basedir}/src/main/resources</targetResourcesProject>
|
||||
<targetXMLPackage>mysql.mapper</targetXMLPackage>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
|
@ -23,8 +31,55 @@
|
|||
<artifactId>common</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>1.15.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher -->
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-launcher</artifactId>
|
||||
<version>1.9.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.mybatis.generator</groupId>
|
||||
<artifactId>mybatis-generator-maven-plugin</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<configuration>
|
||||
<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
|
||||
<overwrite>true</overwrite>
|
||||
<verbose>true</verbose>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>tk.mybatis</groupId>
|
||||
<artifactId>mapper</artifactId>
|
||||
<version>4.1.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,13 @@ package net.educoder.quality;
|
|||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
|
||||
@EnableScheduling
|
||||
@SpringBootApplication
|
||||
@ServletComponentScan
|
||||
@EnableAspectJAutoProxy(exposeProxy = true)
|
||||
public class WebApplication {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package net.educoder.quality.aspect;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import net.educoder.quality.common.annotations.OperateLogAnnotation;
|
||||
import net.educoder.quality.common.util.IpUtil;
|
||||
import net.educoder.quality.entity.mysql.OperateLog;
|
||||
import net.educoder.quality.service.OperateLogService;
|
||||
import net.educoder.quality.vo.CommonVO;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
|
|
@ -13,6 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.util.ContentCachingRequestWrapper;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
|
@ -39,6 +42,25 @@ public class OperateLogAop {
|
|||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
|
||||
|
||||
// 获取请求参数
|
||||
CommonVO commonVO;
|
||||
if(request instanceof ContentCachingRequestWrapper){
|
||||
ContentCachingRequestWrapper requestWrapper = (ContentCachingRequestWrapper)request;
|
||||
commonVO = JSONObject.parseObject(new String(requestWrapper.getContentAsByteArray()), CommonVO.class);
|
||||
}else{
|
||||
commonVO = new CommonVO();
|
||||
commonVO.setCurrentUser(request.getParameter("currentUser"));
|
||||
commonVO.setRepoOwner(request.getParameter("repoOwner"));
|
||||
commonVO.setRepository(request.getParameter("repository"));
|
||||
}
|
||||
|
||||
if (commonVO == null){
|
||||
commonVO = new CommonVO();
|
||||
commonVO.setCurrentUser(request.getParameter("currentUser"));
|
||||
commonVO.setRepoOwner(request.getParameter("repoOwner"));
|
||||
commonVO.setRepository(request.getParameter("repository"));
|
||||
}
|
||||
// 获取IP地址
|
||||
String ipAddress = IpUtil.getIpAddress(request);
|
||||
|
||||
|
|
@ -46,17 +68,13 @@ public class OperateLogAop {
|
|||
MethodSignature signature = (MethodSignature) pjp.getSignature();
|
||||
OperateLogAnnotation annotation = signature.getMethod().getAnnotation(OperateLogAnnotation.class);
|
||||
|
||||
// 获取请求参数
|
||||
String currentUser = request.getHeader("currentUser");
|
||||
String repoOwner = request.getHeader("repoOwner");
|
||||
String repository = request.getHeader("repository");
|
||||
|
||||
OperateLog operateLog = new OperateLog();
|
||||
operateLog.setDescription(annotation.description());
|
||||
operateLog.setClientIp(ipAddress);
|
||||
operateLog.setOperator(currentUser);
|
||||
operateLog.setRepoOwner(repoOwner);
|
||||
operateLog.setRepository(repository);
|
||||
operateLog.setOperator(commonVO.getCurrentUser());
|
||||
operateLog.setRepoOwner(commonVO.getRepoOwner());
|
||||
operateLog.setRepository(commonVO.getRepository());
|
||||
try {
|
||||
Object result = pjp.proceed();
|
||||
operateLog.setResult("成功");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
package net.educoder.quality.controller;
|
||||
|
||||
import net.educoder.quality.common.util.R;
|
||||
import net.educoder.quality.dto.CloneDetectionStatisticsDTO;
|
||||
import net.educoder.quality.service.CloneDetectionService;
|
||||
import net.educoder.quality.vo.AddCloneDetectionVO;
|
||||
import net.educoder.quality.vo.PageVO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 克隆检测控制器
|
||||
*/
|
||||
@RestController
|
||||
public class CloneDetectionController {
|
||||
@Autowired
|
||||
private CloneDetectionService cloneDetectionService;
|
||||
|
||||
/**
|
||||
* 添加一个项目的对比
|
||||
*/
|
||||
@PostMapping("/clone/detection/{projectId}/add")
|
||||
public R add(@PathVariable Long projectId, @RequestBody @Valid AddCloneDetectionVO addCloneDetectionVO) {
|
||||
cloneDetectionService.add(projectId, addCloneDetectionVO);
|
||||
return R.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 克隆检测统计
|
||||
*/
|
||||
@GetMapping("/clone/detection/{projectId}/statistics")
|
||||
public R<CloneDetectionStatisticsDTO> statistics(@PathVariable Long projectId) {
|
||||
CloneDetectionStatisticsDTO cloneDetectionStatisticsDTO = cloneDetectionService.cloneDetectionStatistics(projectId);
|
||||
return R.success(cloneDetectionStatisticsDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 克隆检测列表
|
||||
*/
|
||||
@GetMapping("/clone/detection/{projectId}/list/{type}")
|
||||
public R list(@PathVariable Long projectId, @PathVariable String type, @Valid PageVO pageVO) {
|
||||
if ("file".equals(type) || "code".equals(type)) {
|
||||
return R.success(cloneDetectionService.cloneDetectionResultFileCodeLevelList(projectId, pageVO));
|
||||
} else {
|
||||
return R.success(cloneDetectionService.cloneDetectionResultProjectLevelList(projectId, pageVO));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package net.educoder.quality.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import net.educoder.quality.common.util.R;
|
||||
import net.educoder.quality.dto.*;
|
||||
import net.educoder.quality.entity.mysql.ComponentParseRecordDetail;
|
||||
import net.educoder.quality.service.ComponentService;
|
||||
import net.educoder.quality.vo.PageVO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/10/13
|
||||
* @Description: 组件控制器
|
||||
*/
|
||||
@RestController
|
||||
public class ComponentController {
|
||||
|
||||
@Autowired
|
||||
private ComponentService componentService;
|
||||
|
||||
|
||||
/**
|
||||
* 组件解析
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/component/{projectId}/parse")
|
||||
public R parse(@PathVariable Long projectId) {
|
||||
componentService.parseComponent(projectId);
|
||||
return R.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件统计
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/component/{projectId}/statistics")
|
||||
public R<ComponentStatisticsDTO> statistics(@PathVariable Long projectId) {
|
||||
ComponentStatisticsDTO componentStatisticsDTO = componentService.componentStatistics(projectId);
|
||||
return R.success(componentStatisticsDTO);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/component/{projectId}/list")
|
||||
public R list(@PathVariable Long projectId, @Valid PageVO pageVO) {
|
||||
PageInfo<ComponentParseRecordDetailDTO> componentListDTOPageInfo = componentService.componentList(projectId, pageVO);
|
||||
|
||||
List<ComponentListDTO> resultList = new ArrayList<>(componentListDTOPageInfo.getList().size());
|
||||
for (ComponentParseRecordDetail componentParseRecordDetail : componentListDTOPageInfo.getList()) {
|
||||
ComponentListDTO componentListDTO = new ComponentListDTO();
|
||||
BeanUtils.copyProperties(componentParseRecordDetail, componentListDTO);
|
||||
componentListDTO.setVulnerabilities(StringUtils.isNotEmpty(componentParseRecordDetail.getVulnerabilities()) ? JSON.parseArray(componentParseRecordDetail.getVulnerabilities()) : new JSONArray());
|
||||
resultList.add(componentListDTO);
|
||||
}
|
||||
PageInfo<ComponentListDTO> pageInfo = new PageInfo<>();
|
||||
BeanUtils.copyProperties(componentListDTOPageInfo, pageInfo);
|
||||
|
||||
pageInfo.setList(resultList);
|
||||
return R.success(pageInfo);
|
||||
}
|
||||
|
||||
@GetMapping("/component/detail/{id}")
|
||||
public R<ComponentDetailDTO> getComponentDetail(@PathVariable Long id) {
|
||||
ComponentDetailDTO detailDTO = componentService.getComponentDetail(id);
|
||||
return R.success(detailDTO);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/component/depend/{id}")
|
||||
public R<DependComponentDTO> getDependComponent(@PathVariable Long id) {
|
||||
List<DependComponentDTO> dependComponentList = componentService.getDependComponent(id);
|
||||
return R.success(dependComponentList);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package net.educoder.quality.controller;
|
||||
|
||||
|
||||
import net.educoder.quality.common.annotations.OperateLogAnnotation;
|
||||
import net.educoder.quality.common.util.R;
|
||||
import net.educoder.quality.entity.mysql.DetectionConfig;
|
||||
import net.educoder.quality.service.DetectionConfigService;
|
||||
import net.educoder.quality.vo.DetectionConfigVO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 项目检测配置 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author jshixiong
|
||||
* @since 2022-09-20
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/detectionConfig")
|
||||
public class DetectionConfigController {
|
||||
|
||||
@Autowired
|
||||
private DetectionConfigService detectionConfigService;
|
||||
|
||||
@OperateLogAnnotation(description = "修改或新增检测配置")
|
||||
@PostMapping("/editOrAdd")
|
||||
public R editOrAdd(@Valid @RequestBody DetectionConfigVO config){
|
||||
int i = detectionConfigService.editOrAdd(config);
|
||||
if (i<0){
|
||||
return R.failed("400","失败");
|
||||
}
|
||||
return R.success("成功");
|
||||
}
|
||||
|
||||
@GetMapping("/getById/{id}")
|
||||
public R getById(@PathVariable("id") Long id){
|
||||
return R.success(detectionConfigService.getById(id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,13 +54,12 @@ public class OperateLogController {
|
|||
@OperateLogAnnotation(description = "操作日志导出Excel")
|
||||
public void exportExcel(@Valid OperateListVO operateListVO, HttpServletResponse response) throws IOException {
|
||||
|
||||
PageInfo<OperateLog> operateList = operateLogService.getOperateList(operateListVO);
|
||||
List<OperateLog> operateList = operateLogService.exportExcel(operateListVO);
|
||||
|
||||
List<OperateLog> list = operateList.getList();
|
||||
|
||||
List<OperateLogExcelDTO> writeDataList = new ArrayList<>(list.size());
|
||||
List<OperateLogExcelDTO> writeDataList = new ArrayList<>(operateList.size());
|
||||
|
||||
for (OperateLog operateLog : list) {
|
||||
for (OperateLog operateLog : operateList) {
|
||||
OperateLogExcelDTO excelDTO = new OperateLogExcelDTO();
|
||||
BeanUtils.copyProperties(operateLog, excelDTO);
|
||||
writeDataList.add(excelDTO);
|
||||
|
|
|
|||
|
|
@ -1,18 +1,23 @@
|
|||
package net.educoder.quality.controller;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import net.educoder.quality.common.annotations.OperateLogAnnotation;
|
||||
import net.educoder.quality.common.util.R;
|
||||
import net.educoder.quality.dto.CompareResultDTO;
|
||||
import net.educoder.quality.dto.ProjectsDTO;
|
||||
import net.educoder.quality.dto.*;
|
||||
import net.educoder.quality.entity.mysql.ComponentParseRecordDetail;
|
||||
import net.educoder.quality.entity.mysql.Projects;
|
||||
import net.educoder.quality.service.ProjectService;
|
||||
import net.educoder.quality.vo.*;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -33,21 +38,11 @@ public class ProjectController {
|
|||
/**
|
||||
* 项目列表
|
||||
*
|
||||
* @param pageNum
|
||||
* @param pageSize
|
||||
* @param projectsVO
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/projects")
|
||||
public R<List<Projects>> getProjectList(@RequestParam(defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize,
|
||||
@RequestParam String repoOwner,
|
||||
@RequestParam String repository) {
|
||||
ProjectsVO projectsVO = new ProjectsVO();
|
||||
projectsVO.setPageNum(pageNum);
|
||||
projectsVO.setPageSize(pageSize);
|
||||
projectsVO.setUsername(repoOwner);
|
||||
projectsVO.setRepository(repository);
|
||||
|
||||
public R<List<Projects>> getProjectList(@Valid ProjectsVO projectsVO) {
|
||||
PageInfo<ProjectsDTO> page = projectService.getProjectList(projectsVO);
|
||||
return R.success(page);
|
||||
}
|
||||
|
|
@ -60,8 +55,8 @@ public class ProjectController {
|
|||
*/
|
||||
@PostMapping("/projects")
|
||||
@OperateLogAnnotation(description = "添加项目")
|
||||
public R addProject(AddProjectVO addProjectVO, @RequestParam("file") MultipartFile multipartFile) {
|
||||
projectService.addProject(addProjectVO, multipartFile);
|
||||
public R addProject(@RequestBody @Valid AddProjectVO addProjectVO) {
|
||||
projectService.addProject(addProjectVO);
|
||||
return R.success();
|
||||
}
|
||||
|
||||
|
|
@ -79,18 +74,6 @@ public class ProjectController {
|
|||
return R.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目详情
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/projects/{projectId}")
|
||||
public R<Projects> getProjectDetail(@PathVariable Long projectId) {
|
||||
Projects projects = projectService.getProjectDetail(projectId);
|
||||
return R.success(projects);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 项目检测
|
||||
|
|
@ -115,7 +98,7 @@ public class ProjectController {
|
|||
@OperateLogAnnotation(description = "重新检测")
|
||||
public R<String> reDetect(@RequestBody @Valid ReDetectVO reDetectVO) {
|
||||
String taskId = projectService.reDetect(reDetectVO);
|
||||
Map<String,Object> result = new HashMap<>(2);
|
||||
Map<String, Object> result = new HashMap<>(2);
|
||||
result.put("taskId", taskId);
|
||||
return R.success(result);
|
||||
}
|
||||
|
|
@ -129,13 +112,12 @@ public class ProjectController {
|
|||
*/
|
||||
@PostMapping("/projects/detectResultCompare")
|
||||
@OperateLogAnnotation(description = "检测结果对比")
|
||||
public R detectResultCompare(@Valid DetectResultCompareVO detectResultCompareVO) {
|
||||
public R detectResultCompare(@RequestBody @Valid DetectResultCompareVO detectResultCompareVO) {
|
||||
CompareResultDTO<?> compareResultDTO = projectService.detectResultCompare(detectResultCompareVO);
|
||||
return R.success(compareResultDTO);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 检测结果对比详情
|
||||
*
|
||||
|
|
@ -143,11 +125,106 @@ public class ProjectController {
|
|||
* @return
|
||||
*/
|
||||
@PostMapping("/projects/detectResultCompareDetail")
|
||||
public R detectResultCompareDetail(@Valid DetectResultCompareDetailVO detectResultCompareDetailVO) {
|
||||
CompareResultDTO<?> compareResultDTO = projectService.detectResultCompareDetail(detectResultCompareDetailVO);
|
||||
return R.success(compareResultDTO);
|
||||
public R detectResultCompareDetail(@RequestBody @Valid DetectResultCompareDetailVO detectResultCompareDetailVO) {
|
||||
List<DetectResultCompareDetailDTO> detectResultCompareDetailDTOS = projectService.detectResultCompareDetail(detectResultCompareDetailVO);
|
||||
return R.success(detectResultCompareDetailDTOS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 项目概览
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/projects/{projectId}/overview")
|
||||
public R<ProjectOverviewDTO> projectOverview(@PathVariable Long projectId) {
|
||||
ProjectOverviewDTO projectOverview = projectService.getProjectOverview(projectId);
|
||||
return R.success(projectOverview);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 缺陷
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/projects/{projectId}/bug")
|
||||
public R<ProjectBugDTO> projectBug(@PathVariable Long projectId) {
|
||||
ProjectBugDTO projectBugDTO = projectService.projectBug(projectId);
|
||||
return R.success(projectBugDTO);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 缺陷详情
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/projects/{projectId}/bug/detail")
|
||||
public R<ProjectBugDetailDTO> projectBugDetail(@PathVariable Long projectId) {
|
||||
ProjectBugDetailDTO projectBugDetailDTO = projectService.projectBugDetail(projectId);
|
||||
return R.success(projectBugDetailDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缺陷中心
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/projects/{projectId}/bug/center")
|
||||
public R<PageInfo> projectBugCenter(@PathVariable Long projectId, @Valid ProjectBugCenterVO projectBugCenterVO) {
|
||||
PageInfo<ProjectBugCenterDTO> projectBugCenterDTOPageInfo = projectService.projectBugCenter(projectId, projectBugCenterVO);
|
||||
return R.success(projectBugCenterDTOPageInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 缺陷列表导出
|
||||
*
|
||||
* @param projectId
|
||||
*/
|
||||
@GetMapping("/projects/{projectId}/bug/export")
|
||||
public void projectBugExport(@PathVariable Long projectId, @Valid ProjectBugCenterVO projectBugCenterVO, HttpServletResponse response) throws Exception {
|
||||
List<ProjectBugCenterDTO> projectBugCenterDTOList = projectService.projectBugList(projectId, projectBugCenterVO);
|
||||
|
||||
Projects projects = projectService.getProjectById(projectId);
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = new String(projects.getProjectName().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + fileName + "_bug.xlsx");
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
|
||||
EasyExcel.write(response.getOutputStream(), ProjectBugCenterDTO.class).sheet().doWrite(projectBugCenterDTOList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缺陷中心> 代码详情
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/projects/{projectId}/bug/center/codeDetail")
|
||||
public R<ProjectBugCenterCodeDetailDTO> projectBugCenterCodeDetail(@PathVariable Long projectId, @Valid ProjectBugCenterCodeDetailVO centerCodeDetailVO) {
|
||||
ProjectBugCenterCodeDetailDTO projectBugCenterCodeDetailDTO = projectService.projectBugCenterCodeDetail(projectId, centerCodeDetailVO);
|
||||
return R.success(projectBugCenterCodeDetailDTO);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 缺陷中心> 代码详情
|
||||
* V2版本
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/projects/v2/{projectId}/bug/center/codeDetail")
|
||||
public R<ProjectBugCenterCodeDetailV2DTO> projectBugCenterCodeDetailV2(@PathVariable Long projectId, @RequestParam("ruleId") Integer id) {
|
||||
ProjectBugCenterCodeDetailV2DTO codeDetailV2DTO = projectService.projectBugCenterCodeDetailV2(projectId, id);
|
||||
return R.success(codeDetailV2DTO);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,205 @@
|
|||
package net.educoder.quality.controller;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import net.educoder.quality.common.util.R;
|
||||
import net.educoder.quality.common.util.WordUtil;
|
||||
import net.educoder.quality.dto.ReportDetailDTO;
|
||||
import net.educoder.quality.entity.mysql.Projects;
|
||||
import net.educoder.quality.entity.mysql.ReportCenter;
|
||||
import net.educoder.quality.service.ProjectService;
|
||||
import net.educoder.quality.service.ReportCenterService;
|
||||
import net.educoder.quality.service.postgres.PgProjectsService;
|
||||
import net.educoder.quality.vo.ExportReportVO;
|
||||
import net.educoder.quality.vo.ReportListVO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/23
|
||||
* @Description: 报告中心控制器
|
||||
*/
|
||||
@RestController
|
||||
public class ReportCenterController {
|
||||
|
||||
|
||||
@Autowired
|
||||
private ReportCenterService reportCenterService;
|
||||
|
||||
@Autowired
|
||||
private ProjectService projectService;
|
||||
|
||||
@Autowired
|
||||
private PgProjectsService pgProjectsService;
|
||||
|
||||
@Value("${download.tempDir}")
|
||||
private String downloadTempDir;
|
||||
|
||||
/**
|
||||
* 导出报告
|
||||
*
|
||||
* @param exportReportVO
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/report/export")
|
||||
public R exportReport(@RequestBody @Valid ExportReportVO exportReportVO) {
|
||||
Long id = reportCenterService.exportReport(exportReportVO);
|
||||
Map<String, Object> result = new HashMap<>(2);
|
||||
result.put("id", id);
|
||||
return R.success(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 报告中心列表
|
||||
*
|
||||
* @param reportListVO
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/report/list")
|
||||
public R<PageInfo<ReportCenter>> reportList(@Valid ReportListVO reportListVO) {
|
||||
PageInfo<ReportCenter> reportCenterPageInfo = reportCenterService.reportList(reportListVO);
|
||||
return R.success(reportCenterPageInfo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 报告下载
|
||||
*
|
||||
* @param reportId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/report/download/{reportId}")
|
||||
public void downloadReport(@PathVariable Long reportId, HttpServletResponse response) throws IOException {
|
||||
ReportCenter reportCenter = reportCenterService.reportCenterDetail(reportId);
|
||||
|
||||
Projects projects = projectService.getProjectById(reportCenter.getProjectId());
|
||||
// 设置文件下载参数
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = new String(reportCenter.getReportName().getBytes("utf-8"), "ISO8859-1");
|
||||
|
||||
// 获取模板,填充数据
|
||||
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("template/report-center-template.docx");
|
||||
|
||||
ServletOutputStream outputStream = response.getOutputStream();
|
||||
|
||||
ReportDetailDTO reportDetail = pgProjectsService.getReportDetail(projects.getProjectName());
|
||||
|
||||
Map<String, String> param = new HashMap<>(13);
|
||||
param.put("projectName", projects.getProjectName());
|
||||
param.put("createTime", DateUtil.formatDateTime(new Date()));
|
||||
param.put("issueCount",String.valueOf(reportDetail.getBugCount().getTotal()));
|
||||
param.put("seriousIssueCount",String.valueOf(reportDetail.getBugCount().getCritical()));
|
||||
param.put("highRiskIssueCount",String.valueOf(reportDetail.getBugCount().getHigh()));
|
||||
param.put("midRiskIssueCount",String.valueOf(reportDetail.getBugCount().getMiddle()));
|
||||
param.put("lowRiskIssueCount",String.valueOf(reportDetail.getBugCount().getLow()));
|
||||
param.put("componentCount",String.valueOf(reportDetail.getComponents()));
|
||||
param.put("componentBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getTotal()));
|
||||
param.put("seriousBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getCritical()));
|
||||
param.put("highRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getHigh()));
|
||||
param.put("midRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getMiddle()));
|
||||
param.put("lowRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getLow()));
|
||||
|
||||
XWPFDocument doc = new XWPFDocument(resourceAsStream);
|
||||
WordUtil.changeText(doc, param);
|
||||
pgProjectsService.fillReportTable(doc,reportDetail);
|
||||
|
||||
String format = reportCenter.getFormat();
|
||||
if ("pdf".equals(format)){
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".pdf");
|
||||
response.setContentType("application/pdf");
|
||||
WordUtil.docToPdf(doc,outputStream);
|
||||
}else {
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".docx");
|
||||
response.setContentType("application/octet-stream");
|
||||
doc.write(outputStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 报告下载
|
||||
*
|
||||
* @param reportIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/report/batchDownload")
|
||||
public void batchDownloadReport(@RequestParam("reportIds") List<Long> reportIds, HttpServletResponse response) throws IOException {
|
||||
|
||||
// 设置文件下载参数
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = new String("报告中心".getBytes("utf-8"), "ISO8859-1");
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".zip");
|
||||
response.setContentType("application/octet-stream");
|
||||
|
||||
|
||||
ServletOutputStream outputStream = response.getOutputStream();
|
||||
|
||||
String[] filePaths = new String[reportIds.size()];
|
||||
InputStream[] ins = new InputStream[reportIds.size()];
|
||||
|
||||
int i = 0;
|
||||
for (Long reportId : reportIds) {
|
||||
ReportCenter reportCenter = reportCenterService.reportCenterDetail(reportId);
|
||||
Projects projects = projectService.getProjectById(reportCenter.getProjectId());
|
||||
|
||||
// 获取模板,填充数据
|
||||
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("template/report-center-template.docx");
|
||||
|
||||
|
||||
ReportDetailDTO reportDetail = pgProjectsService.getReportDetail(projects.getProjectName());
|
||||
|
||||
Map<String, String> param = new HashMap<>(13);
|
||||
param.put("projectName", projects.getProjectName());
|
||||
param.put("createTime", DateUtil.formatDateTime(new Date()));
|
||||
param.put("issueCount",String.valueOf(reportDetail.getBugCount().getTotal()));
|
||||
param.put("seriousIssueCount",String.valueOf(reportDetail.getBugCount().getCritical()));
|
||||
param.put("highRiskIssueCount",String.valueOf(reportDetail.getBugCount().getHigh()));
|
||||
param.put("midRiskIssueCount",String.valueOf(reportDetail.getBugCount().getMiddle()));
|
||||
param.put("lowRiskIssueCount",String.valueOf(reportDetail.getBugCount().getLow()));
|
||||
param.put("componentCount",String.valueOf(reportDetail.getComponents()));
|
||||
param.put("componentBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getTotal()));
|
||||
param.put("seriousBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getCritical()));
|
||||
param.put("highRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getHigh()));
|
||||
param.put("midRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getMiddle()));
|
||||
param.put("lowRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getLow()));
|
||||
|
||||
XWPFDocument doc = new XWPFDocument(resourceAsStream);
|
||||
WordUtil.changeText(doc, param);
|
||||
pgProjectsService.fillReportTable(doc,reportDetail);
|
||||
|
||||
String filePath = filePath(reportCenter.getReportName());
|
||||
doc.write(new FileOutputStream(new File(filePath)));
|
||||
doc.close();
|
||||
|
||||
ins[i] = new FileInputStream(new File(filePath));
|
||||
filePaths[i] = filePath;
|
||||
i++;
|
||||
}
|
||||
|
||||
ZipUtil.zip(outputStream, filePaths, ins);
|
||||
}
|
||||
|
||||
private String filePath(String reportName){
|
||||
String path = StringUtils.join(downloadTempDir, "/", IdUtil.fastSimpleUUID(), "/");
|
||||
String name = reportName + ".docx";
|
||||
File file = new File(path);
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
return path + name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package net.educoder.quality.controller;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import net.educoder.quality.common.util.R;
|
||||
import net.educoder.quality.dto.ProjectVulnerabilityDTO;
|
||||
import net.educoder.quality.dto.ProjectVulnerabilityDetailDTO;
|
||||
import net.educoder.quality.service.VulnerabilityService;
|
||||
import net.educoder.quality.vo.PageVO;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 克隆检测控制器
|
||||
*/
|
||||
@RestController
|
||||
public class VulnerabilityController {
|
||||
|
||||
@Resource
|
||||
private VulnerabilityService vulnerabilityService;
|
||||
|
||||
/**
|
||||
* 漏洞统计信息
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/projects/{projectId}/vulnerability")
|
||||
public R<ProjectVulnerabilityDTO> projectVulnerability(@PathVariable Long projectId) {
|
||||
ProjectVulnerabilityDTO projectVulnerabilityDTO = vulnerabilityService.vulnerabilityStatistics(projectId);
|
||||
return R.success(projectVulnerabilityDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 漏洞列表
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/projects/{projectId}/vulnerability/list")
|
||||
public R<PageInfo> projectVulnerabilityList(@PathVariable Long projectId, @Valid PageVO pageVO) {
|
||||
PageInfo<ProjectVulnerabilityDetailDTO> vulnerabilityList = vulnerabilityService.vulnerabilityList(projectId, pageVO);
|
||||
return R.success(vulnerabilityList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 漏洞详情
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/projects/{projectId}/vulnerability/detail")
|
||||
public R<ProjectVulnerabilityDetailDTO> projectVulnerabilityDetail(@PathVariable Long projectId, @RequestParam("uuid") String uuid) {
|
||||
ProjectVulnerabilityDetailDTO detailDTO = vulnerabilityService.vulnerabilityDetail(projectId, uuid);
|
||||
return R.success(detailDTO);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,29 +5,9 @@ import lombok.Data;
|
|||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/19
|
||||
* @Description:
|
||||
* @Description: bug比较结果
|
||||
*/
|
||||
@Data
|
||||
public class BugResultDTO {
|
||||
|
||||
private Long total;
|
||||
|
||||
/**
|
||||
* 严重的 对应 critical
|
||||
*/
|
||||
private Long critical;
|
||||
/**
|
||||
* 高危 对应 blocker
|
||||
*/
|
||||
private Long high;
|
||||
|
||||
/**
|
||||
* 中 对应 major
|
||||
*/
|
||||
private Long middle;
|
||||
/**
|
||||
* 低 对应 minor
|
||||
*/
|
||||
private Long low;
|
||||
public class BugResultDTO extends CompareBaseResultDTO {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CloneDetectionResultFileCodeLevelDTO {
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 源文件路径
|
||||
*/
|
||||
private String sourceFilePath;
|
||||
/**
|
||||
* 源文件开始行
|
||||
*/
|
||||
private Integer sourceFileStartLine;
|
||||
/**
|
||||
* 源文件结束行
|
||||
*/
|
||||
private Integer sourceFileEndLine;
|
||||
/**
|
||||
* 源文件代码
|
||||
*/
|
||||
private String sourceFileCode;
|
||||
/**
|
||||
* 对比文件路径
|
||||
*/
|
||||
private String targetFilePath;
|
||||
/**
|
||||
* 对比文件开始行
|
||||
*/
|
||||
private Integer targetFileStartLine;
|
||||
/**
|
||||
* 对比文件结束行
|
||||
*/
|
||||
private Integer targetFileEndLine;
|
||||
/**
|
||||
* 对比文件代码
|
||||
*/
|
||||
private String targetFileCode;
|
||||
/**
|
||||
* 对比工程名称
|
||||
*/
|
||||
private String targetProjectName;
|
||||
/**
|
||||
* 对比工程路径
|
||||
*/
|
||||
private String targetProjectUrl;
|
||||
/**
|
||||
* 相似比
|
||||
*/
|
||||
private double commonSourcePercent;
|
||||
/**
|
||||
* 相似行数
|
||||
*/
|
||||
private double commonSourceLine;
|
||||
/**
|
||||
* 原创比
|
||||
*/
|
||||
private double originalSourcePercent;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CloneDetectionResultProjectLevelDTO {
|
||||
/**
|
||||
* 克隆检测ID
|
||||
*/
|
||||
private Long cloneDetectionId;
|
||||
|
||||
/**
|
||||
* 相似文件比
|
||||
*/
|
||||
private Integer similarityFilePercent;
|
||||
|
||||
/**
|
||||
* 相似文件数
|
||||
*/
|
||||
private Integer similarityFile;
|
||||
|
||||
/**
|
||||
* 源项目名
|
||||
*/
|
||||
private String sourceProjectName;
|
||||
|
||||
/**
|
||||
* 对比项目名
|
||||
*/
|
||||
private String targetProjectName;
|
||||
|
||||
/**
|
||||
* 对比项目地址
|
||||
*/
|
||||
private String targetProjectUrl;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CloneDetectionStatisticsDTO {
|
||||
/**
|
||||
* 溯源相似比-文件
|
||||
*/
|
||||
private double fileCodeSimilarityPercent;
|
||||
|
||||
/**
|
||||
* 自主代码比-文件
|
||||
*/
|
||||
private double fileOriginalPercent;
|
||||
|
||||
/**
|
||||
* 溯源相似比-代码行
|
||||
*/
|
||||
private double codeLineSimilarityPercent;
|
||||
|
||||
/**
|
||||
* 自主代码比-代码行
|
||||
*/
|
||||
private double codeLineOriginalPercent;
|
||||
|
||||
/**
|
||||
* 溯源相似比-容量
|
||||
*/
|
||||
private double capacitySimilarityPercent;
|
||||
|
||||
/**
|
||||
* 自主代码比-容量
|
||||
*/
|
||||
private double capacityOriginalPercent;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class ClonePairDTO {
|
||||
private String sourceFile;
|
||||
private int sourceFileStartLine;
|
||||
private int sourceFileEndLine;
|
||||
private String targetFile;
|
||||
private int targetFileStartLine;
|
||||
private int targetFileEndLine;
|
||||
private double similarity;
|
||||
private int similarLines;
|
||||
|
||||
public ClonePairDTO(String sourceFile, int sourceFileStartLine, int sourceFileEndLine, String targetFile, int targetFileStartLine, int targetFileEndLine, double similarity) {
|
||||
this.sourceFile = sourceFile;
|
||||
this.sourceFileStartLine = sourceFileStartLine;
|
||||
this.sourceFileEndLine = sourceFileEndLine;
|
||||
this.targetFile = targetFile;
|
||||
this.targetFileStartLine = targetFileStartLine;
|
||||
this.targetFileEndLine = targetFileEndLine;
|
||||
this.similarity = similarity;
|
||||
this.similarLines = Math.max(Math.min(sourceFileEndLine - sourceFileStartLine, targetFileEndLine - targetFileStartLine), 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/26
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class CompareBaseResultDTO {
|
||||
|
||||
private Long total = 0L;
|
||||
|
||||
/**
|
||||
* 严重的 对应 critical
|
||||
*/
|
||||
private Long critical = 0L;
|
||||
/**
|
||||
* 高危 对应 blocker
|
||||
*/
|
||||
private Long high = 0L;
|
||||
|
||||
/**
|
||||
* 中 对应 major
|
||||
*/
|
||||
private Long middle = 0L;
|
||||
/**
|
||||
* 低 对应 minor
|
||||
*/
|
||||
private Long low = 0L;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/12/27
|
||||
* @Description: 组件-查看详情
|
||||
*/
|
||||
@Data
|
||||
public class ComponentDetailDTO {
|
||||
|
||||
/**
|
||||
* 组件名称
|
||||
*/
|
||||
private String componentName;
|
||||
/**
|
||||
* 许可证
|
||||
*/
|
||||
private String permit;
|
||||
|
||||
/**
|
||||
* 主业
|
||||
*/
|
||||
private String homeUrl;
|
||||
/**
|
||||
* 发布日期
|
||||
*/
|
||||
private String publishDate;
|
||||
|
||||
/**
|
||||
* 更新日期
|
||||
*/
|
||||
private String updateDate;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 关键词
|
||||
*/
|
||||
private String keysWord;
|
||||
|
||||
/**
|
||||
* 使用版本
|
||||
*/
|
||||
private List<String> useVersion;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/10/13
|
||||
* @Description: 组件列表
|
||||
*/
|
||||
@Data
|
||||
public class ComponentListDTO {
|
||||
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 组件名称
|
||||
*/
|
||||
private String componentName;
|
||||
/**
|
||||
* 语言
|
||||
*/
|
||||
private String language;
|
||||
/**
|
||||
* 风险等级
|
||||
*/
|
||||
private String riskLevel;
|
||||
/**
|
||||
* 漏洞
|
||||
*/
|
||||
private String vulnerability;
|
||||
/**
|
||||
* 漏洞详情
|
||||
*/
|
||||
private JSONArray vulnerabilities;
|
||||
/**
|
||||
* 依赖方式
|
||||
*/
|
||||
private String dependWay;
|
||||
|
||||
/**
|
||||
* 依赖路径
|
||||
*/
|
||||
private String dependPath;
|
||||
/**
|
||||
* 依赖数量
|
||||
*/
|
||||
private Integer dependNum;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import net.educoder.quality.entity.mysql.ComponentParseRecordDetail;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/12/27
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class ComponentParseRecordDetailDTO extends ComponentParseRecordDetail {
|
||||
|
||||
/**
|
||||
* 依赖数量
|
||||
*/
|
||||
private Integer dependNum;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/26
|
||||
* @Description: 对比组件结果
|
||||
*/
|
||||
@Data
|
||||
public class ComponentResultDTO extends CompareBaseResultDTO {
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/10/13
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class ComponentStatisticsDTO {
|
||||
|
||||
private ComponentStatistics componentStatistics;
|
||||
|
||||
private ComponentRisk componentRisk;
|
||||
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class ComponentStatistics {
|
||||
/**
|
||||
* 组件总数
|
||||
*/
|
||||
private Long componentTotal = 0L;
|
||||
|
||||
/**
|
||||
* 间接依赖
|
||||
*/
|
||||
private Long indirectDependencies = 0L;
|
||||
|
||||
/**
|
||||
* 直接依赖
|
||||
*/
|
||||
private Long directlyDependencies = 0L;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class ComponentRisk extends CompareBaseResultDTO {
|
||||
|
||||
/**
|
||||
* 风险总计
|
||||
*/
|
||||
private Long riskTotal = 0L;
|
||||
|
||||
/**
|
||||
* 未知
|
||||
*/
|
||||
private Long unKnow = 0L;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/12/27
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class DependComponentDTO {
|
||||
|
||||
private String componentName;
|
||||
private String version;
|
||||
private String dependPath;
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/23
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class DetectConfigDTO {
|
||||
|
||||
private LocalDateTime jobTime;
|
||||
private Long templateId;
|
||||
private Long id;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/10/18
|
||||
* @Description: 比对详情
|
||||
*/
|
||||
@Data
|
||||
public class DetectResultCompareDetailDTO extends CompareResultDTO<Boolean> {
|
||||
|
||||
private String name;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/27
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class FileSourceDTO {
|
||||
|
||||
private Integer rowNumber;
|
||||
private String code;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/21
|
||||
* @Description: 键值对
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class KeyValuePair {
|
||||
|
||||
private String name;
|
||||
private String value;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 许可证兼容分析
|
||||
* @author jshixiong
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LicenceCompatibleDTO {
|
||||
|
||||
/**
|
||||
* 许可证1 ID
|
||||
*/
|
||||
private Long licenceId1;
|
||||
|
||||
/**
|
||||
* 许可证1 名称
|
||||
*/
|
||||
private String licenceName1;
|
||||
|
||||
/**
|
||||
* 许可证2 ID
|
||||
*/
|
||||
private Long licenceId2;
|
||||
|
||||
/**
|
||||
* 许可证2 名称
|
||||
*/
|
||||
private String licenceName2;
|
||||
|
||||
/**
|
||||
* 兼容结果描述
|
||||
*/
|
||||
private String result;
|
||||
|
||||
/**
|
||||
* 兼容分析
|
||||
*/
|
||||
private String analysis;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 许可证版权信息
|
||||
* @author jshixiong
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LicenceCopyrightDTO {
|
||||
|
||||
private String info;
|
||||
|
||||
private Long fileCount;
|
||||
|
||||
private String distortInfo;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 许可证篡改分析
|
||||
* @author jshixiong
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LicenceDistortDTO {
|
||||
|
||||
private Long licenceId;
|
||||
|
||||
private String licenceName;
|
||||
|
||||
private String referencePath;
|
||||
|
||||
private String sourcePath;
|
||||
|
||||
private String riskLevel;
|
||||
|
||||
private String beforeDistort;
|
||||
|
||||
private String afterDistort;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jshixiong
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LicenceFileDTO {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
||||
private String version;
|
||||
|
||||
private String url;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 许可证分页列表DTO
|
||||
* @author jshixiong
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LicenceListDTO {
|
||||
/**
|
||||
* 许可证ID
|
||||
*/
|
||||
private Long licenceId;
|
||||
|
||||
/**
|
||||
* 许可证名称
|
||||
*/
|
||||
private String licenceName;
|
||||
|
||||
/**
|
||||
* 风险等级
|
||||
*/
|
||||
private String riskLevel;
|
||||
|
||||
/**
|
||||
* 文件数
|
||||
*/
|
||||
private Long fileCount;
|
||||
|
||||
/**
|
||||
* 组件数
|
||||
*/
|
||||
private Long moduleCount;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 许可证总计
|
||||
* @author jshixiong
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LicenceOverviewDTO {
|
||||
|
||||
/**
|
||||
* 许可证数
|
||||
*/
|
||||
private Long licenceCount;
|
||||
|
||||
/**
|
||||
* 版权数
|
||||
*/
|
||||
private Long copyrightCount;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 许可证兼容风险总计
|
||||
* @author jshixiong
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LicenceRiskDTO {
|
||||
/**
|
||||
* 兼容风险数
|
||||
*/
|
||||
private Long riskCount;
|
||||
|
||||
/**
|
||||
* 条件兼容数
|
||||
*/
|
||||
private Long compatible;
|
||||
|
||||
/**
|
||||
* 条件不兼容数
|
||||
*/
|
||||
private Long notCompatible;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/26
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class LicenseResultDTO extends CompareBaseResultDTO {
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/10/17
|
||||
* @Description: 缺陷中心返回结果
|
||||
*/
|
||||
@Data
|
||||
public class ProjectBugCenterCodeDetailDTO {
|
||||
|
||||
/**
|
||||
* 代码
|
||||
*/
|
||||
private List<FileSourceDTO> codes;
|
||||
/**
|
||||
* 示例代码
|
||||
*/
|
||||
private String example;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2023/3/9
|
||||
* @Description: 缺陷中心>查看详情 v2版本
|
||||
*/
|
||||
@Data
|
||||
public class ProjectBugCenterCodeDetailV2DTO {
|
||||
|
||||
private String filePath;
|
||||
/**
|
||||
* 代码行号
|
||||
*/
|
||||
private Integer line;
|
||||
/**
|
||||
* 缺陷名称
|
||||
*/
|
||||
private String bugName;
|
||||
/**
|
||||
* 缺陷描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 正确代码示例
|
||||
*/
|
||||
private String example;
|
||||
/**
|
||||
* 错误代码示例
|
||||
*/
|
||||
private String errorExample;
|
||||
/**
|
||||
* 代码所属错误分类
|
||||
*/
|
||||
private String parentBugCatalog;
|
||||
/**
|
||||
* 代码
|
||||
*/
|
||||
private List<FileSourceDTO> codes;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/27
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class ProjectBugCenterDTO {
|
||||
|
||||
/**
|
||||
* 缺陷名称
|
||||
*/
|
||||
@ExcelProperty("缺陷名称")
|
||||
private String bugName;
|
||||
/**
|
||||
* 缺陷描述
|
||||
*/
|
||||
@ExcelProperty("缺陷描述")
|
||||
private String bugDescription;
|
||||
/**
|
||||
* 文件路径
|
||||
*/
|
||||
@ExcelProperty("文件路径")
|
||||
private String filePath;
|
||||
/**
|
||||
* 行号
|
||||
*/
|
||||
@ExcelProperty("行号")
|
||||
private String rowNumber;
|
||||
/**
|
||||
* 缺陷级别
|
||||
*/
|
||||
@ExcelProperty("缺陷级别")
|
||||
private String bugLevel;
|
||||
/**
|
||||
* 检测时间
|
||||
*/
|
||||
@ExcelProperty("检测时间")
|
||||
private Date detectTime;
|
||||
|
||||
/**
|
||||
* 找文件唯一标识
|
||||
*/
|
||||
private String uuid;
|
||||
|
||||
private Integer ruleId;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/21
|
||||
* @Description: 项目缺陷展示数据
|
||||
*/
|
||||
@Data
|
||||
public class ProjectBugDTO {
|
||||
|
||||
/**
|
||||
* 代码行数
|
||||
*/
|
||||
private Integer codeNumber;
|
||||
|
||||
/**
|
||||
* 👈🏻展示数据
|
||||
*/
|
||||
private List<KeyValuePair> left;
|
||||
|
||||
/**
|
||||
* 缺陷数
|
||||
*/
|
||||
private Integer bugNumber;
|
||||
|
||||
/**
|
||||
* 👉🏻展示数据
|
||||
*/
|
||||
private List<KeyValuePair> right;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/26
|
||||
* @Description: 缺陷检测详情
|
||||
*/
|
||||
@Data
|
||||
public class ProjectBugDetailDTO {
|
||||
|
||||
/**
|
||||
* 检测基本信息
|
||||
*/
|
||||
private DetectInfo detectInfo;
|
||||
|
||||
/**
|
||||
* 检测结果
|
||||
*/
|
||||
private DetectResult detectResult;
|
||||
|
||||
|
||||
@Data
|
||||
public static class DetectInfo {
|
||||
/**
|
||||
* 语言
|
||||
*/
|
||||
private String language;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String creator;
|
||||
|
||||
/**
|
||||
* git仓库地址
|
||||
*/
|
||||
private String gitUrl;
|
||||
|
||||
/**
|
||||
* 检测模板
|
||||
*/
|
||||
private Long templateId;
|
||||
|
||||
/**
|
||||
* 开始检测时间
|
||||
*/
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 结束检测时间
|
||||
*/
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 检测时长
|
||||
*/
|
||||
private Integer detectTime;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class DetectResult {
|
||||
|
||||
private Integer fileNumber;
|
||||
private Integer codeNumber;
|
||||
private Long bugTotalNumber;
|
||||
|
||||
/**
|
||||
* 严重的 对应 critical
|
||||
*/
|
||||
private Long critical;
|
||||
/**
|
||||
* 高危 对应 blocker
|
||||
*/
|
||||
private Long high;
|
||||
|
||||
/**
|
||||
* 中 对应 major
|
||||
*/
|
||||
private Long middle;
|
||||
/**
|
||||
* 低 对应 minor
|
||||
*/
|
||||
private Long low;
|
||||
|
||||
/**
|
||||
* 未知
|
||||
*/
|
||||
private Long unKnow = 0L;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/20
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class ProjectMetricsDTO {
|
||||
|
||||
private Integer bugNumber;
|
||||
private Integer vulnerabilityNumber;
|
||||
|
||||
/**
|
||||
* 代码行数
|
||||
*/
|
||||
private Integer codeNumber;
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/20
|
||||
* @Description: 项目概览展示数据
|
||||
*/
|
||||
@Data
|
||||
public class ProjectOverviewDTO {
|
||||
|
||||
/**
|
||||
* 漏洞
|
||||
*/
|
||||
private Metres vulnerability;
|
||||
/**
|
||||
* 缺陷
|
||||
*/
|
||||
private Metres bug;
|
||||
/**
|
||||
* 组件
|
||||
*/
|
||||
private Metres component;
|
||||
/**
|
||||
* 许可证
|
||||
*/
|
||||
private Metres license;
|
||||
|
||||
/**
|
||||
* 检测内容
|
||||
*/
|
||||
private DetectContent detectContent;
|
||||
|
||||
|
||||
/**
|
||||
* 缺陷 & 漏洞
|
||||
*/
|
||||
private BugResultDTO bugDetail;
|
||||
private VulnerabilityResultDTO vulnerabilityDetail;
|
||||
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Metres {
|
||||
/**
|
||||
* 原始数量
|
||||
*/
|
||||
private Integer originNumber = 0;
|
||||
/**
|
||||
* 新增数量
|
||||
*/
|
||||
private Integer newNumber = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测内容
|
||||
*/
|
||||
@Data
|
||||
public static class DetectContent {
|
||||
/**
|
||||
* 代码行数
|
||||
*/
|
||||
private Integer codeNumber = 0;
|
||||
/**
|
||||
* 文件数
|
||||
*/
|
||||
private Integer fileNumber = 0;
|
||||
/**
|
||||
* 文件大小
|
||||
*/
|
||||
private String size = "0k";
|
||||
}
|
||||
|
||||
/**
|
||||
* 溯源信息
|
||||
*/
|
||||
@Data
|
||||
public static class RootsInfo {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 许可证
|
||||
*/
|
||||
@Data
|
||||
public static class LicenseInfo {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/28
|
||||
* @Description: 项目漏洞统计信息
|
||||
*/
|
||||
@Data
|
||||
public class ProjectVulnerabilityDTO extends CompareBaseResultDTO {
|
||||
|
||||
/**
|
||||
* 未知
|
||||
*/
|
||||
private Long unKnow = 0L;
|
||||
|
||||
|
||||
private Long newUnKnow = 0L;
|
||||
|
||||
|
||||
/**
|
||||
* 严重的 对应 critical
|
||||
*/
|
||||
private Long newCritical = 0L;
|
||||
/**
|
||||
* 高危 对应 blocker
|
||||
*/
|
||||
private Long newHigh = 0L;
|
||||
|
||||
/**
|
||||
* 中 对应 major
|
||||
*/
|
||||
private Long newMiddle = 0L;
|
||||
/**
|
||||
* 低 对应 minor
|
||||
*/
|
||||
private Long newLow = 0L;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/28
|
||||
* @Description: 项目漏洞详情
|
||||
*/
|
||||
@Data
|
||||
public class ProjectVulnerabilityDetailDTO {
|
||||
private String uuid;
|
||||
|
||||
/**
|
||||
* 漏洞编号
|
||||
*/
|
||||
private String vulnerabilityNumber;
|
||||
/**
|
||||
* 漏洞名称
|
||||
*/
|
||||
private String vulnerabilityName;
|
||||
|
||||
/**
|
||||
* 风险等级
|
||||
*/
|
||||
private String riskLevel;
|
||||
|
||||
/**
|
||||
* 发布日期
|
||||
*/
|
||||
private String publishDate;
|
||||
|
||||
/**
|
||||
* 利用难度:困难
|
||||
*/
|
||||
private String difficulty;
|
||||
|
||||
/**
|
||||
* 攻击类型:远程
|
||||
*/
|
||||
private String attackType;
|
||||
|
||||
/**
|
||||
* 漏洞描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 修复建议
|
||||
*/
|
||||
private String repairSuggestions;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnore;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/28
|
||||
* @Description: 项目漏洞列表
|
||||
*/
|
||||
@Data
|
||||
public class ProjectVulnerabilityListDTO {
|
||||
|
||||
/**
|
||||
* 漏洞编号
|
||||
*/
|
||||
@ExcelProperty("漏洞编号")
|
||||
private String vulnerabilityNumber;
|
||||
/**
|
||||
* 漏洞名称
|
||||
*/
|
||||
@ExcelProperty("漏洞名称")
|
||||
private String vulnerabilityName;
|
||||
|
||||
/**
|
||||
* 风险等级
|
||||
*/
|
||||
@ExcelProperty("风险等级")
|
||||
private String riskLevel;
|
||||
/**
|
||||
* 修复方案
|
||||
*/
|
||||
@ExcelProperty("修复方案")
|
||||
private Boolean fixPlan;
|
||||
|
||||
/**
|
||||
* uuid
|
||||
*/
|
||||
@ExcelIgnore
|
||||
private String uuid;
|
||||
|
||||
}
|
||||
|
|
@ -15,4 +15,9 @@ public class ProjectsDTO extends Projects {
|
|||
* 检测次数
|
||||
*/
|
||||
private Integer detectNum;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private DetectConfigDTO detectConfig;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.educoder.quality.entity.postgres.PgIssues;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Date: 2023/01/19
|
||||
* @author jshixiong
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ReportDetailDTO {
|
||||
|
||||
private CompareBaseResultDTO vulnerabilityCount;
|
||||
|
||||
private CompareBaseResultDTO bugCount;
|
||||
|
||||
private Integer components;
|
||||
|
||||
private List<PgIssues> bugIssues;
|
||||
|
||||
private List<ComponentParseRecordDetailDTO> parseRecordDetails;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class SastBugDTO {
|
||||
private Long bugId;
|
||||
private String bugType;
|
||||
private int line;
|
||||
private String filePath;
|
||||
private String message;
|
||||
private String methodName;
|
||||
private String variable;
|
||||
}
|
||||
|
|
@ -4,12 +4,13 @@ import lombok.Data;
|
|||
import net.educoder.quality.entity.mysql.ProjectDetectionTaskInfo;
|
||||
import net.educoder.quality.entity.mysql.ProjectFileUpload;
|
||||
import net.educoder.quality.entity.mysql.ProjectSecretKey;
|
||||
import net.educoder.quality.entity.mysql.Projects;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/1/18
|
||||
* @Description:
|
||||
* @Description: sonar扫描参数
|
||||
*/
|
||||
@Data
|
||||
public class SonarScannerParam {
|
||||
|
|
@ -31,19 +32,33 @@ public class SonarScannerParam {
|
|||
|
||||
|
||||
private String taskId;
|
||||
private String source;
|
||||
private String language;
|
||||
/**
|
||||
* 工作目录
|
||||
*/
|
||||
private String workspace;
|
||||
|
||||
private ProjectFileUpload fileUpload;
|
||||
private ProjectSecretKey projectSecretKey;
|
||||
private ProjectDetectionTaskInfo taskInfo;
|
||||
private Projects projects;
|
||||
|
||||
/**
|
||||
* 查询结果线程池
|
||||
*/
|
||||
private ThreadPoolTaskExecutor sonarQueryResultThreadPool;
|
||||
|
||||
/**
|
||||
* git用户名
|
||||
*/
|
||||
private String gitUsername;
|
||||
/**
|
||||
* git密码
|
||||
*/
|
||||
private String gitPassword;
|
||||
|
||||
/**
|
||||
* .net代码sonar扫描服务
|
||||
*/
|
||||
private String donetSonarServer;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package net.educoder.quality.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
|
|
@ -8,26 +10,5 @@ import lombok.Data;
|
|||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class VulnerabilityResultDTO {
|
||||
|
||||
private Long total;
|
||||
|
||||
/**
|
||||
* 严重的 对应 critical
|
||||
*/
|
||||
private Long critical;
|
||||
/**
|
||||
* 高危 对应 blocker
|
||||
*/
|
||||
private Long high;
|
||||
|
||||
/**
|
||||
* 中 对应 major
|
||||
*/
|
||||
private Long middle;
|
||||
/**
|
||||
* 低 对应 minor
|
||||
*/
|
||||
private Long low;
|
||||
|
||||
public class VulnerabilityResultDTO extends CompareBaseResultDTO{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
package net.educoder.quality.entity.gitea;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2023/1/17
|
||||
* @Description: 许可证
|
||||
*/
|
||||
@Data
|
||||
public class PgCodeLicense {
|
||||
|
||||
private Long id;
|
||||
private String name;
|
||||
private String riskLevel;
|
||||
private String version;
|
||||
private Date createTime;
|
||||
private String content;
|
||||
private String description;
|
||||
private String publicUrl;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package net.educoder.quality.entity.mysql;
|
||||
|
||||
import lombok.Data;
|
||||
import net.educoder.quality.common.util.AbstractDO;
|
||||
|
||||
import java.util.Date;
|
||||
import javax.persistence.*;
|
||||
|
||||
@Data
|
||||
@Table(name = "clone_detection")
|
||||
public class CloneDetection extends AbstractDO {
|
||||
|
||||
/**
|
||||
* 源工程ID
|
||||
*/
|
||||
@Column(name = "project_id")
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 目标工程名
|
||||
*/
|
||||
@Column(name = "target_project_name")
|
||||
private String targetProjectName;
|
||||
|
||||
/**
|
||||
* 目标工程URL
|
||||
*/
|
||||
@Column(name = "target_project_url")
|
||||
private String targetProjectUrl;
|
||||
|
||||
/**
|
||||
* 目标工程用户名
|
||||
*/
|
||||
@Column(name = "target_project_username")
|
||||
private String targetProjectUsername;
|
||||
|
||||
/**
|
||||
* 目标工程密码
|
||||
*/
|
||||
@Column(name = "target_project_password")
|
||||
private String targetProjectPassword;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
package net.educoder.quality.entity.mysql;
|
||||
|
||||
import lombok.Data;
|
||||
import net.educoder.quality.common.util.AbstractDO;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Table;
|
||||
|
||||
|
||||
@Data
|
||||
@Table(name = "clone_detection_result_file_code_level")
|
||||
public class CloneDetectionResultFileCodeLevel extends AbstractDO {
|
||||
|
||||
/**
|
||||
* 源工程ID
|
||||
*/
|
||||
@Column(name = "project_id")
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 源文件路径
|
||||
*/
|
||||
@Column(name = "source_file_path")
|
||||
private String sourceFilePath;
|
||||
|
||||
/**
|
||||
* 源文件开始行
|
||||
*/
|
||||
@Column(name = "source_file_start_line")
|
||||
private Integer sourceFileStartLine;
|
||||
|
||||
/**
|
||||
* 源文件结束行
|
||||
*/
|
||||
@Column(name = "source_file_end_line")
|
||||
private Integer sourceFileEndLine;
|
||||
|
||||
/**
|
||||
* 目标文件路径
|
||||
*/
|
||||
@Column(name = "target_file_path")
|
||||
private String targetFilePath;
|
||||
|
||||
/**
|
||||
* 目标文件开始行
|
||||
*/
|
||||
@Column(name = "target_file_start_line")
|
||||
private Integer targetFileStartLine;
|
||||
|
||||
/**
|
||||
* 目标文件结束行
|
||||
*/
|
||||
@Column(name = "target_file_end_line")
|
||||
private Integer targetFileEndLine;
|
||||
|
||||
/**
|
||||
* 相似比
|
||||
*/
|
||||
@Column(name = "common_source_percent")
|
||||
private Double commonSourcePercent;
|
||||
|
||||
/**
|
||||
* 相似行数
|
||||
*/
|
||||
@Column(name = "common_source_line")
|
||||
private Integer commonSourceLine;
|
||||
|
||||
/**
|
||||
* 克隆检测ID
|
||||
*/
|
||||
@Column(name = "clone_detection_id")
|
||||
private Long cloneDetectionId;
|
||||
|
||||
/**
|
||||
* 目标项目名称
|
||||
*/
|
||||
@Column(name = "target_project_name")
|
||||
private String targetProjectName;
|
||||
|
||||
/**
|
||||
* 目标项目URL
|
||||
*/
|
||||
@Column(name = "target_project_url")
|
||||
private String targetProjectUrl;
|
||||
|
||||
/**
|
||||
* 源文件代码
|
||||
*/
|
||||
@Column(name = "source_file_code")
|
||||
private String sourceFileCode;
|
||||
|
||||
/**
|
||||
* 目标文件代码
|
||||
*/
|
||||
@Column(name = "target_file_code")
|
||||
private String targetFileCode;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
package net.educoder.quality.entity.mysql;
|
||||
|
||||
import lombok.Data;
|
||||
import net.educoder.quality.common.util.AbstractDO;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Data
|
||||
@Table(name = "clone_detection_result_project_level")
|
||||
public class CloneDetectionResultProjectLevel extends AbstractDO {
|
||||
|
||||
/**
|
||||
* 克隆检测ID
|
||||
*/
|
||||
@Column(name = "clone_detection_id")
|
||||
private Long cloneDetectionId;
|
||||
|
||||
/**
|
||||
* 相似文件比
|
||||
*/
|
||||
@Column(name = "similarity_file_percent")
|
||||
private Double similarityFilePercent;
|
||||
|
||||
/**
|
||||
* 相似文件数
|
||||
*/
|
||||
@Column(name = "similarity_file")
|
||||
private Integer similarityFile;
|
||||
|
||||
/**
|
||||
* 总文件数
|
||||
*/
|
||||
@Column(name = "total_file")
|
||||
private Long totalFile;
|
||||
|
||||
/**
|
||||
* 相似行数
|
||||
*/
|
||||
@Column(name = "similarity_line")
|
||||
private Long similarityLine;
|
||||
|
||||
/**
|
||||
* 相似行数比
|
||||
*/
|
||||
@Column(name = "similarity_line_percent")
|
||||
private Double similarityLinePercent;
|
||||
|
||||
/**
|
||||
* 总行数
|
||||
*/
|
||||
@Column(name = "total_line")
|
||||
private Long totalLine;
|
||||
|
||||
/**
|
||||
* 相似容量
|
||||
*/
|
||||
@Column(name = "similarity_capacity")
|
||||
private Long similarityCapacity;
|
||||
|
||||
/**
|
||||
* 相似容量比
|
||||
*/
|
||||
@Column(name = "similarity_capacity_percent")
|
||||
private Double similarityCapacityPercent;
|
||||
|
||||
/**
|
||||
* 总容量
|
||||
*/
|
||||
@Column(name = "total_capacity")
|
||||
private Long totalCapacity;
|
||||
|
||||
/**
|
||||
* 源工程ID
|
||||
*/
|
||||
@Column(name = "project_id")
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 目标项目名称
|
||||
*/
|
||||
@Column(name = "target_project_name")
|
||||
private String targetProjectName;
|
||||
|
||||
/**
|
||||
* 目标项目URL
|
||||
*/
|
||||
@Column(name = "target_project_url")
|
||||
private String targetProjectUrl;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package net.educoder.quality.entity.mysql;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2023/1/17
|
||||
* @Description: 组件库
|
||||
*/
|
||||
@Data
|
||||
public class ComponentLibrary {
|
||||
|
||||
private Long id;
|
||||
private String language;
|
||||
private String componentName;
|
||||
private String shortName;
|
||||
private String license;
|
||||
private Date createTime;
|
||||
private String homeUrl;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package net.educoder.quality.entity.mysql;
|
||||
|
||||
import lombok.Data;
|
||||
import net.educoder.quality.common.util.AbstractDO;
|
||||
|
||||
|
||||
@Data
|
||||
public class ComponentParseRecord extends AbstractDO {
|
||||
|
||||
private Long projectId;
|
||||
|
||||
private String result;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package net.educoder.quality.entity.mysql;
|
||||
|
||||
import lombok.Data;
|
||||
import net.educoder.quality.common.util.AbstractDO;
|
||||
|
||||
|
||||
@Data
|
||||
public class ComponentParseRecordDetail extends AbstractDO {
|
||||
|
||||
private Long componentId;
|
||||
|
||||
/**
|
||||
* 组件名称
|
||||
*/
|
||||
private String componentName;
|
||||
|
||||
/**
|
||||
* 语言
|
||||
*/
|
||||
private String language;
|
||||
|
||||
/**
|
||||
* 风险等级
|
||||
*/
|
||||
private String riskLevel;
|
||||
|
||||
/**
|
||||
* 漏洞
|
||||
*/
|
||||
private String vulnerability;
|
||||
|
||||
/**
|
||||
* 版本
|
||||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* 依赖方式,直接 or 间接
|
||||
*/
|
||||
private String dependWay;
|
||||
|
||||
/**
|
||||
* 依赖路径
|
||||
*/
|
||||
private String dependPath;
|
||||
|
||||
/**
|
||||
* 父组件
|
||||
*/
|
||||
private String parentUuid;
|
||||
|
||||
/**
|
||||
* 唯一标识
|
||||
*/
|
||||
private String uuid;
|
||||
|
||||
private String vulnerabilities;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package net.educoder.quality.entity.mysql;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.educoder.quality.common.util.AbstractDO;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 项目检测配置
|
||||
* </p>
|
||||
*
|
||||
* @author jshixiong
|
||||
* @since 2022-09-20
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Table(name = "detection_config")
|
||||
public class DetectionConfig extends AbstractDO {
|
||||
|
||||
@NotNull(message = "执行时间不能为空")
|
||||
@Column(name = "job_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||
private LocalDateTime jobTime;
|
||||
|
||||
@NotNull(message = "项目id不能为空")
|
||||
@Column(name = "project_id")
|
||||
private Long projectId;
|
||||
|
||||
@NotNull(message = "模板id不能为空")
|
||||
@Column(name = "template_id")
|
||||
private Long templateId;
|
||||
|
||||
}
|
||||
|
|
@ -22,6 +22,11 @@ public class DetectionTemplate extends AbstractDO {
|
|||
|
||||
private String securityDetection;
|
||||
|
||||
/**
|
||||
* 依赖函数库
|
||||
*/
|
||||
private String dependFunction;
|
||||
|
||||
/**
|
||||
* 仓库所属用户
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
package net.educoder.quality.entity.mysql;
|
||||
|
||||
import lombok.Data;
|
||||
import net.educoder.quality.common.util.AbstractDO;
|
||||
|
||||
import javax.persistence.Table;
|
||||
import java.util.Objects;
|
||||
|
||||
@Data
|
||||
@Table(name = "project_vulnerability_detail")
|
||||
public class ProjectVulnerabilityDetail extends AbstractDO {
|
||||
/**
|
||||
* 漏洞编号
|
||||
*/
|
||||
private String vulnerabilityNumber;
|
||||
/**
|
||||
* 漏洞名称
|
||||
*/
|
||||
private String vulnerabilityName;
|
||||
|
||||
/**
|
||||
* 风险等级
|
||||
*/
|
||||
private Integer riskLevel;
|
||||
|
||||
/**
|
||||
* 发布日期
|
||||
*/
|
||||
private String publishDate;
|
||||
|
||||
/**
|
||||
* 利用难度
|
||||
*/
|
||||
private Integer difficulty;
|
||||
|
||||
/**
|
||||
* 攻击类型:远程
|
||||
*/
|
||||
private String attackType;
|
||||
|
||||
/**
|
||||
* 漏洞描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 修复建议
|
||||
*/
|
||||
private String repairSuggestions;
|
||||
|
||||
/**
|
||||
* 组件ID
|
||||
*/
|
||||
private Long componentId;
|
||||
|
||||
/**
|
||||
* 工程ID
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o){
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ProjectVulnerabilityDetail that = (ProjectVulnerabilityDetail) o;
|
||||
return strEquals(vulnerabilityNumber,that.vulnerabilityNumber) && strEquals(vulnerabilityName,that.vulnerabilityName) && intEquals(riskLevel, that.riskLevel) && strEquals(publishDate, that.publishDate) && intEquals(difficulty, that.difficulty) && strEquals(attackType, that.attackType) && strEquals(description, that.description) && strEquals(repairSuggestions, that.repairSuggestions);
|
||||
}
|
||||
|
||||
private boolean strEquals(String a,String b){
|
||||
if (a==null || "".equals(a)){
|
||||
return b == null || "".equals(b);
|
||||
}
|
||||
return a.equals(b);
|
||||
}
|
||||
|
||||
private boolean intEquals(Integer a,Integer b){
|
||||
if (a==null){
|
||||
return b == null;
|
||||
}
|
||||
return a.equals(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), vulnerabilityNumber, vulnerabilityName, riskLevel, publishDate, difficulty, attackType, description, repairSuggestions);
|
||||
}
|
||||
}
|
||||
|
|
@ -13,23 +13,58 @@ import java.util.Date;
|
|||
@Data
|
||||
public class Projects extends AbstractDO {
|
||||
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
private String projectName;
|
||||
|
||||
private String source;
|
||||
/**
|
||||
* 分支
|
||||
*/
|
||||
private String branch;
|
||||
|
||||
/**
|
||||
* git地址
|
||||
*/
|
||||
private String gitUrl;
|
||||
|
||||
/**
|
||||
* 检测时长
|
||||
*/
|
||||
private Integer duration;
|
||||
|
||||
/**
|
||||
* 目标文件数量
|
||||
*/
|
||||
private Integer targetFileNum;
|
||||
/**
|
||||
* 文件大小
|
||||
*/
|
||||
private String targetFileSize;
|
||||
|
||||
/**
|
||||
* 检测状态 0:待检测 1:检测中 2:检测成功 -1 检测失败
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String creator;
|
||||
|
||||
/**
|
||||
* 仓库
|
||||
*/
|
||||
private String repository;
|
||||
|
||||
/**
|
||||
* 检测时间
|
||||
*/
|
||||
private Date testingTime;
|
||||
|
||||
/**
|
||||
* 项目语言
|
||||
*/
|
||||
private String language;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
package net.educoder.quality.entity.mysql;
|
||||
|
||||
import lombok.Data;
|
||||
import net.educoder.quality.common.util.AbstractDO;
|
||||
|
||||
|
||||
@Data
|
||||
public class ReportCenter extends AbstractDO {
|
||||
|
||||
/**
|
||||
* 报告类型
|
||||
*/
|
||||
private Integer reportType;
|
||||
|
||||
/**
|
||||
* 报告名称
|
||||
*/
|
||||
private String reportName;
|
||||
|
||||
/**
|
||||
* 所属项目
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 报告格式 word , pdf
|
||||
*/
|
||||
private String format;
|
||||
|
||||
/**
|
||||
* 缺陷级别
|
||||
*/
|
||||
private String bugLevel;
|
||||
|
||||
/**
|
||||
* 项目名称,下载内容中的标题
|
||||
*/
|
||||
private String projectName;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String creator;
|
||||
|
||||
private String repoOwner;
|
||||
|
||||
private String repository;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
package net.educoder.quality.entity.mysql;
|
||||
|
||||
import java.util.Date;
|
||||
import javax.persistence.*;
|
||||
import lombok.Data;
|
||||
import net.educoder.quality.common.util.AbstractDO;
|
||||
|
||||
@Data
|
||||
@Table(name = "sast_analysis_detail")
|
||||
public class SastAnalysisDetail extends AbstractDO {
|
||||
|
||||
/**
|
||||
* bug分类
|
||||
*/
|
||||
@Column(name = "bug_catalog")
|
||||
private String bugCatalog;
|
||||
|
||||
/**
|
||||
* bug大分类
|
||||
*/
|
||||
@Column(name = "parent_bug_catalog")
|
||||
private String parentBugCatalog;
|
||||
|
||||
/**
|
||||
* bug类型编号
|
||||
*/
|
||||
@Column(name = "bug_no")
|
||||
private String bugNo;
|
||||
|
||||
/**
|
||||
* bug名称
|
||||
*/
|
||||
@Column(name = "bug_name")
|
||||
private String bugName;
|
||||
|
||||
/**
|
||||
* bug类型父级编号
|
||||
*/
|
||||
@Column(name = "parent_bug_no")
|
||||
private String parentBugNo;
|
||||
|
||||
/**
|
||||
* bug类型号
|
||||
*/
|
||||
@Column(name = "bug_type")
|
||||
private String bugType;
|
||||
|
||||
/**
|
||||
* bug类型名
|
||||
*/
|
||||
@Column(name = "bug_type_name")
|
||||
private String bugTypeName;
|
||||
|
||||
/**
|
||||
* bug级别
|
||||
*/
|
||||
@Column(name = "bug_level")
|
||||
private String bugLevel;
|
||||
|
||||
/**
|
||||
* 常见后果关键词
|
||||
*/
|
||||
@Column(name = "frequent_result_keyword")
|
||||
private String frequentResultKeyword;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Column(name = "update_time")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 工程id
|
||||
*/
|
||||
@Column(name = "project_id")
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
@Column(name = "task_id")
|
||||
private String taskId;
|
||||
|
||||
/**
|
||||
* 简介
|
||||
*/
|
||||
private String synopsis;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 常见后果
|
||||
*/
|
||||
@Column(name = "frequent_result")
|
||||
private String frequentResult;
|
||||
|
||||
/**
|
||||
* 修复意见
|
||||
*/
|
||||
@Column(name = "repair_opinion")
|
||||
private String repairOpinion;
|
||||
|
||||
/**
|
||||
* 示例
|
||||
*/
|
||||
private String example;
|
||||
|
||||
/**
|
||||
* 错误示例
|
||||
*/
|
||||
@Column(name = "error_example")
|
||||
private String errorExample;
|
||||
|
||||
@Column(name = "method_name")
|
||||
private String methodName;
|
||||
|
||||
private String variable;
|
||||
|
||||
private Integer line;
|
||||
|
||||
@Column(name = "file_path")
|
||||
private String filePath;
|
||||
|
||||
public static final String ID = "id";
|
||||
|
||||
public static final String DB_ID = "id";
|
||||
|
||||
public static final String BUG_CATALOG = "bugCatalog";
|
||||
|
||||
public static final String DB_BUG_CATALOG = "bug_catalog";
|
||||
|
||||
public static final String BUG_NO = "bugNo";
|
||||
|
||||
public static final String DB_BUG_NO = "bug_no";
|
||||
|
||||
public static final String BUG_NAME = "bugName";
|
||||
|
||||
public static final String DB_BUG_NAME = "bug_name";
|
||||
|
||||
public static final String PARENT_BUG_NO = "parentBugNo";
|
||||
|
||||
public static final String DB_PARENT_BUG_NO = "parent_bug_no";
|
||||
|
||||
public static final String BUG_TYPE = "bugType";
|
||||
|
||||
public static final String DB_BUG_TYPE = "bug_type";
|
||||
|
||||
public static final String BUG_TYPE_NAME = "bugTypeName";
|
||||
|
||||
public static final String DB_BUG_TYPE_NAME = "bug_type_name";
|
||||
|
||||
public static final String BUG_LEVEL = "bugLevel";
|
||||
|
||||
public static final String DB_BUG_LEVEL = "bug_level";
|
||||
|
||||
public static final String FREQUENT_RESULT_KEYWORD = "frequentResultKeyword";
|
||||
|
||||
public static final String DB_FREQUENT_RESULT_KEYWORD = "frequent_result_keyword";
|
||||
|
||||
public static final String CREATE_TIME = "createTime";
|
||||
|
||||
public static final String DB_CREATE_TIME = "create_time";
|
||||
|
||||
public static final String UPDATE_TIME = "updateTime";
|
||||
|
||||
public static final String DB_UPDATE_TIME = "update_time";
|
||||
|
||||
public static final String PROJECT_ID = "projectId";
|
||||
|
||||
public static final String DB_PROJECT_ID = "project_id";
|
||||
|
||||
public static final String TASK_ID = "taskId";
|
||||
|
||||
public static final String DB_TASK_ID = "task_id";
|
||||
|
||||
public static final String SYNOPSIS = "synopsis";
|
||||
|
||||
public static final String DB_SYNOPSIS = "synopsis";
|
||||
|
||||
public static final String DESCRIPTION = "description";
|
||||
|
||||
public static final String DB_DESCRIPTION = "description";
|
||||
|
||||
public static final String FREQUENT_RESULT = "frequentResult";
|
||||
|
||||
public static final String DB_FREQUENT_RESULT = "frequent_result";
|
||||
|
||||
public static final String REPAIR_OPINION = "repairOpinion";
|
||||
|
||||
public static final String DB_REPAIR_OPINION = "repair_opinion";
|
||||
|
||||
public static final String EXAMPLE = "example";
|
||||
|
||||
public static final String DB_EXAMPLE = "example";
|
||||
|
||||
public static final String ERROR_EXAMPLE = "errorExample";
|
||||
|
||||
public static final String DB_ERROR_EXAMPLE = "error_example";
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package net.educoder.quality.entity.postgres;
|
||||
|
||||
import com.google.protobuf.CodedInputStream;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import lombok.Data;
|
||||
import net.educoder.quality.protobuf.DbFileSources;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/27
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class PgFileSource {
|
||||
|
||||
private static final String SIZE_LIMIT_EXCEEDED_EXCEPTION_MESSAGE = "Protocol message was too large. May be malicious. " +
|
||||
"Use CodedInputStream.setSizeLimit() to increase the size limit.";
|
||||
|
||||
private Long id;
|
||||
private String projectUuid;
|
||||
private String fileUuid;
|
||||
private String lineHashes;
|
||||
|
||||
private String srcHash;
|
||||
private byte[] binaryData = new byte[0];
|
||||
private String dataHash;
|
||||
|
||||
public DbFileSources.Data decodeSourceData(byte[] binaryData) {
|
||||
try {
|
||||
return decodeRegularSourceData(binaryData);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(
|
||||
format("Fail to decompress and deserialize source data [id=%s,fileUuid=%s,projectUuid=%s]", id, fileUuid, projectUuid),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
private static DbFileSources.Data decodeRegularSourceData(byte[] binaryData) throws IOException {
|
||||
try (LZ4BlockInputStream lz4Input = new LZ4BlockInputStream(new ByteArrayInputStream(binaryData))) {
|
||||
return DbFileSources.Data.parseFrom(lz4Input);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
if (SIZE_LIMIT_EXCEEDED_EXCEPTION_MESSAGE.equals(e.getMessage())) {
|
||||
return decodeHugeSourceData(binaryData);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private static DbFileSources.Data decodeHugeSourceData(byte[] binaryData) throws IOException {
|
||||
try (LZ4BlockInputStream lz4Input = new LZ4BlockInputStream(new ByteArrayInputStream(binaryData))) {
|
||||
CodedInputStream input = CodedInputStream.newInstance(lz4Input);
|
||||
input.setSizeLimit(Integer.MAX_VALUE);
|
||||
return DbFileSources.Data.parseFrom(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,28 @@ public class PgIssues {
|
|||
private String kee;
|
||||
private Integer ruleId;
|
||||
private String severity;
|
||||
private String message;
|
||||
private String status;
|
||||
private String projectUuid;
|
||||
private Integer issueType;
|
||||
private byte[] locations = new byte[0];
|
||||
|
||||
/**
|
||||
* bug名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* bug描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 文件路径
|
||||
*/
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 对应file_sources表的file_uuid
|
||||
* 对应issue表的component_uuid
|
||||
*/
|
||||
private String uuid;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
package net.educoder.quality.entity.postgres;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/9/22
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class PgProjectMeasures {
|
||||
|
||||
private Long id;
|
||||
private BigDecimal value;
|
||||
private String textValue;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package net.educoder.quality.entity.postgres;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2022/10/17
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class PgRule {
|
||||
|
||||
private Long id;
|
||||
private String name;
|
||||
private String description;
|
||||
}
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
package net.educoder.quality.entity.sast;
|
||||
|
||||
import java.util.Date;
|
||||
import javax.persistence.*;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Table(name = "biz_knowledge_bug")
|
||||
public class BizKnowledgeBug {
|
||||
/**
|
||||
* 知识库BUG类型ID
|
||||
*/
|
||||
@Id
|
||||
@Column(name = "OID_KNOWLEDGE_BUG_ID")
|
||||
private String oidKnowledgeBugId;
|
||||
|
||||
/**
|
||||
* 知识库目录ID
|
||||
*/
|
||||
@Column(name = "OID_KNOWLEDGE_CATALOG_ID")
|
||||
private String oidKnowledgeCatalogId;
|
||||
|
||||
/**
|
||||
* BUG类型编号
|
||||
*/
|
||||
@Column(name = "BUG_NO")
|
||||
private String bugNo;
|
||||
|
||||
/**
|
||||
* BUG名称
|
||||
*/
|
||||
@Column(name = "BUG_NAME")
|
||||
private String bugName;
|
||||
|
||||
/**
|
||||
* BUG类型父级编号
|
||||
*/
|
||||
@Column(name = "PARENT_BUG_NO")
|
||||
private String parentBugNo;
|
||||
|
||||
/**
|
||||
* BUG类型号
|
||||
*/
|
||||
@Column(name = "BUG_TYPE")
|
||||
private String bugType;
|
||||
|
||||
/**
|
||||
* BUG类型名
|
||||
*/
|
||||
@Column(name = "BUG_TYPE_NAME")
|
||||
private String bugTypeName;
|
||||
|
||||
/**
|
||||
* BUG级别
|
||||
*/
|
||||
@Column(name = "BUG_LEVEL")
|
||||
private String bugLevel;
|
||||
|
||||
/**
|
||||
* 常见后果关键词
|
||||
*/
|
||||
@Column(name = "FREQUENT_RESULT_KEYWORD")
|
||||
private String frequentResultKeyword;
|
||||
|
||||
/**
|
||||
* 删除FLG
|
||||
*/
|
||||
@Column(name = "DEL_FLG")
|
||||
private String delFlg;
|
||||
|
||||
/**
|
||||
* 作成者ID
|
||||
*/
|
||||
@Column(name = "INS_USER_ID")
|
||||
private String insUserId;
|
||||
|
||||
/**
|
||||
* 作成日
|
||||
*/
|
||||
@Column(name = "INS_DATE")
|
||||
private Date insDate;
|
||||
|
||||
/**
|
||||
* 更新者ID
|
||||
*/
|
||||
@Column(name = "UPD_USER_ID")
|
||||
private String updUserId;
|
||||
|
||||
/**
|
||||
* 更新日
|
||||
*/
|
||||
@Column(name = "UPD_DATE")
|
||||
private Date updDate;
|
||||
|
||||
/**
|
||||
* 简介
|
||||
*/
|
||||
@Column(name = "SYNOPSIS")
|
||||
private String synopsis;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@Column(name = "DESCRIPTION")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 常见后果
|
||||
*/
|
||||
@Column(name = "FREQUENT_RESULT")
|
||||
private String frequentResult;
|
||||
|
||||
/**
|
||||
* 修复意见
|
||||
*/
|
||||
@Column(name = "REPAIR_OPINION")
|
||||
private String repairOpinion;
|
||||
|
||||
/**
|
||||
* 示例
|
||||
*/
|
||||
@Column(name = "EXAMPLE")
|
||||
private String example;
|
||||
|
||||
/**
|
||||
* 错误示例
|
||||
*/
|
||||
@Column(name = "ERROR_EXAMPLE")
|
||||
private String errorExample;
|
||||
|
||||
@Transient
|
||||
private String bugCatalog;
|
||||
|
||||
@Transient
|
||||
private String parentBugCatalog;
|
||||
|
||||
public static final String OID_KNOWLEDGE_BUG_ID = "oidKnowledgeBugId";
|
||||
|
||||
public static final String DB_OID_KNOWLEDGE_BUG_ID = "OID_KNOWLEDGE_BUG_ID";
|
||||
|
||||
public static final String OID_KNOWLEDGE_CATALOG_ID = "oidKnowledgeCatalogId";
|
||||
|
||||
public static final String DB_OID_KNOWLEDGE_CATALOG_ID = "OID_KNOWLEDGE_CATALOG_ID";
|
||||
|
||||
public static final String BUG_NO = "bugNo";
|
||||
|
||||
public static final String DB_BUG_NO = "BUG_NO";
|
||||
|
||||
public static final String BUG_NAME = "bugName";
|
||||
|
||||
public static final String DB_BUG_NAME = "BUG_NAME";
|
||||
|
||||
public static final String PARENT_BUG_NO = "parentBugNo";
|
||||
|
||||
public static final String DB_PARENT_BUG_NO = "PARENT_BUG_NO";
|
||||
|
||||
public static final String BUG_TYPE = "bugType";
|
||||
|
||||
public static final String DB_BUG_TYPE = "BUG_TYPE";
|
||||
|
||||
public static final String BUG_TYPE_NAME = "bugTypeName";
|
||||
|
||||
public static final String DB_BUG_TYPE_NAME = "BUG_TYPE_NAME";
|
||||
|
||||
public static final String BUG_LEVEL = "bugLevel";
|
||||
|
||||
public static final String DB_BUG_LEVEL = "BUG_LEVEL";
|
||||
|
||||
public static final String FREQUENT_RESULT_KEYWORD = "frequentResultKeyword";
|
||||
|
||||
public static final String DB_FREQUENT_RESULT_KEYWORD = "FREQUENT_RESULT_KEYWORD";
|
||||
|
||||
public static final String DEL_FLG = "delFlg";
|
||||
|
||||
public static final String DB_DEL_FLG = "DEL_FLG";
|
||||
|
||||
public static final String INS_USER_ID = "insUserId";
|
||||
|
||||
public static final String DB_INS_USER_ID = "INS_USER_ID";
|
||||
|
||||
public static final String INS_DATE = "insDate";
|
||||
|
||||
public static final String DB_INS_DATE = "INS_DATE";
|
||||
|
||||
public static final String UPD_USER_ID = "updUserId";
|
||||
|
||||
public static final String DB_UPD_USER_ID = "UPD_USER_ID";
|
||||
|
||||
public static final String UPD_DATE = "updDate";
|
||||
|
||||
public static final String DB_UPD_DATE = "UPD_DATE";
|
||||
|
||||
public static final String SYNOPSIS = "synopsis";
|
||||
|
||||
public static final String DB_SYNOPSIS = "SYNOPSIS";
|
||||
|
||||
public static final String DESCRIPTION = "description";
|
||||
|
||||
public static final String DB_DESCRIPTION = "DESCRIPTION";
|
||||
|
||||
public static final String FREQUENT_RESULT = "frequentResult";
|
||||
|
||||
public static final String DB_FREQUENT_RESULT = "FREQUENT_RESULT";
|
||||
|
||||
public static final String REPAIR_OPINION = "repairOpinion";
|
||||
|
||||
public static final String DB_REPAIR_OPINION = "REPAIR_OPINION";
|
||||
|
||||
public static final String EXAMPLE = "example";
|
||||
|
||||
public static final String DB_EXAMPLE = "EXAMPLE";
|
||||
|
||||
public static final String ERROR_EXAMPLE = "errorExample";
|
||||
|
||||
public static final String DB_ERROR_EXAMPLE = "ERROR_EXAMPLE";
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package net.educoder.quality.init;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.educoder.quality.service.DetectionConfigService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* 启动未过时的定时检测配置
|
||||
* @author jshixiong
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DetectionConfigInit {
|
||||
|
||||
@Autowired
|
||||
private DetectionConfigService detectionConfigService;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
log.info("******检测配置-启动定时检测任务******");
|
||||
try {
|
||||
detectionConfigService.detectionConfigInit();
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
log.error("******检测配置-启动定时检测任务失败******");
|
||||
}
|
||||
log.info("******检测配置-启动定时检测任务完成******");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package net.educoder.quality.mapper.gitea;
|
||||
|
||||
import net.educoder.quality.entity.gitea.PgCodeLicense;
|
||||
|
||||
/**
|
||||
* @Author: youys
|
||||
* @Date: 2023/1/17
|
||||
* @Description:
|
||||
*/
|
||||
public interface PgCodeLicenseMapper {
|
||||
|
||||
/**
|
||||
* 根据许可证名称查询
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
PgCodeLicense selectByName(String name);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package net.educoder.quality.mapper.mysql;
|
||||
|
||||
import net.educoder.quality.entity.mysql.CloneDetection;
|
||||
import tk.mybatis.mapper.common.Mapper;
|
||||
|
||||
public interface CloneDetectionMapper extends Mapper<CloneDetection> {
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package net.educoder.quality.mapper.mysql;
|
||||
|
||||
import net.educoder.quality.entity.mysql.CloneDetectionResultFileCodeLevel;
|
||||
import tk.mybatis.mapper.common.Mapper;
|
||||
|
||||
public interface CloneDetectionResultFileCodeLevelMapper extends Mapper<CloneDetectionResultFileCodeLevel> {
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue