mirror of https://github.com/halo-dev/halo
Enable code style check available (#590)
* Add check style plugin and remove halo code style * Reformat codes for whole project * Resolve conflicts due to provided checkstyle.xmlpull/593/head
parent
c224b68fbc
commit
e8db12a93d
|
@ -1,7 +1,7 @@
|
||||||
plugins {
|
plugins {
|
||||||
id 'org.springframework.boot' version '2.2.2.RELEASE'
|
id 'org.springframework.boot' version '2.2.2.RELEASE'
|
||||||
id "io.freefair.lombok" version "3.6.6"
|
id "io.freefair.lombok" version "3.6.6"
|
||||||
// id 'war'
|
id 'checkstyle'
|
||||||
id 'java'
|
id 'java'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!DOCTYPE module PUBLIC
|
||||||
|
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||||
|
"http://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||||
|
<!--Refer http://checkstyle.sourceforge.net/reports/google-java-style.html#s2.2-file-encoding -->
|
||||||
|
<module name="Checker">
|
||||||
|
|
||||||
|
<property name="localeLanguage" value="en"/>
|
||||||
|
|
||||||
|
<!--To configure the check to report on the first instance in each file-->
|
||||||
|
<module name="FileTabCharacter"/>
|
||||||
|
|
||||||
|
<module name="RegexpSingleline">
|
||||||
|
<property name="format" value="System\.out"/>
|
||||||
|
<property name="message" value="Prohibit invoking System.out in source code !"/>
|
||||||
|
</module>
|
||||||
|
|
||||||
|
<module name="FileLength">
|
||||||
|
<property name="max" value="3000"/>
|
||||||
|
</module>
|
||||||
|
|
||||||
|
<module name="TreeWalker">
|
||||||
|
|
||||||
|
<module name="UnusedImports">
|
||||||
|
<property name="processJavadoc" value="true"/>
|
||||||
|
</module>
|
||||||
|
|
||||||
|
<module name="RedundantImport"/>
|
||||||
|
|
||||||
|
<!--Checks that classes that override equals() also override hashCode()-->
|
||||||
|
<module name="EqualsHashCode"/>
|
||||||
|
<!--Checks for over-complicated boolean expressions. Currently finds code like if (topic == true), topic || true, !false, etc.-->
|
||||||
|
<module name="SimplifyBooleanExpression"/>
|
||||||
|
<module name="OneStatementPerLine"/>
|
||||||
|
<module name="UnnecessaryParentheses"/>
|
||||||
|
<!--Checks for over-complicated boolean return statements. For example the following code-->
|
||||||
|
<module name="SimplifyBooleanReturn"/>
|
||||||
|
|
||||||
|
<!--Check that the default is after all the cases in producerGroup switch statement-->
|
||||||
|
<module name="DefaultComesLast"/>
|
||||||
|
<!--Detects empty statements (standalone ";" semicolon)-->
|
||||||
|
<module name="EmptyStatement"/>
|
||||||
|
<!--Checks that long constants are defined with an upper ell-->
|
||||||
|
<module name="UpperEll"/>
|
||||||
|
<module name="ConstantName">
|
||||||
|
<property name="format" value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)|(^logger)"/>
|
||||||
|
</module>
|
||||||
|
<!--Checks that local, non-final variable names conform to producerGroup format specified by the format property-->
|
||||||
|
<module name="LocalVariableName"/>
|
||||||
|
<!--Validates identifiers for local, final variables, including catch parameters-->
|
||||||
|
<module name="LocalFinalVariableName"/>
|
||||||
|
<!--Validates identifiers for non-static fields-->
|
||||||
|
<module name="MemberName"/>
|
||||||
|
<!--Validates identifiers for class type parameters-->
|
||||||
|
<module name="ClassTypeParameterName">
|
||||||
|
<property name="format" value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)"/>
|
||||||
|
</module>
|
||||||
|
<!--Validates identifiers for method type parameters-->
|
||||||
|
<module name="MethodTypeParameterName">
|
||||||
|
<property name="format" value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)"/>
|
||||||
|
</module>
|
||||||
|
<module name="PackageName">
|
||||||
|
<property name="format" value="^run\.halo(\.[a-zA-Z][a-zA-Z0-9]*)+$"/>
|
||||||
|
</module>
|
||||||
|
<module name="ParameterName"/>
|
||||||
|
<module name="StaticVariableName">
|
||||||
|
<property name="format" value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)"/>
|
||||||
|
</module>
|
||||||
|
<module name="TypeName">
|
||||||
|
<property name="format" value="(^[A-Z][a-zA-Z0-9]*$)|(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)"/>
|
||||||
|
</module>
|
||||||
|
|
||||||
|
<!--whitespace-->
|
||||||
|
<module name="GenericWhitespace"/>
|
||||||
|
<module name="NoWhitespaceBefore"/>
|
||||||
|
<module name="NoWhitespaceAfter"/>
|
||||||
|
<module name="WhitespaceAround">
|
||||||
|
<property name="allowEmptyConstructors" value="true"/>
|
||||||
|
<property name="allowEmptyMethods" value="true"/>
|
||||||
|
</module>
|
||||||
|
<module name="Indentation"/>
|
||||||
|
<module name="MethodParamPad"/>
|
||||||
|
<module name="ParenPad"/>
|
||||||
|
<module name="TypecastParenPad"/>
|
||||||
|
<module name="TypecastParenPad"/>
|
||||||
|
|
||||||
|
</module>
|
||||||
|
|
||||||
|
</module>
|
|
@ -1,26 +0,0 @@
|
||||||
<code_scheme name="halo" version="173">
|
|
||||||
<DBN-PSQL>
|
|
||||||
<case-options enabled="true">
|
|
||||||
<option name="KEYWORD_CASE" value="lower" />
|
|
||||||
<option name="FUNCTION_CASE" value="lower" />
|
|
||||||
<option name="PARAMETER_CASE" value="lower" />
|
|
||||||
<option name="DATATYPE_CASE" value="lower" />
|
|
||||||
<option name="OBJECT_CASE" value="preserve" />
|
|
||||||
</case-options>
|
|
||||||
<formatting-settings enabled="false" />
|
|
||||||
</DBN-PSQL>
|
|
||||||
<DBN-SQL>
|
|
||||||
<case-options enabled="true">
|
|
||||||
<option name="KEYWORD_CASE" value="lower" />
|
|
||||||
<option name="FUNCTION_CASE" value="lower" />
|
|
||||||
<option name="PARAMETER_CASE" value="lower" />
|
|
||||||
<option name="DATATYPE_CASE" value="lower" />
|
|
||||||
<option name="OBJECT_CASE" value="preserve" />
|
|
||||||
</case-options>
|
|
||||||
<formatting-settings enabled="false">
|
|
||||||
<option name="STATEMENT_SPACING" value="one_line" />
|
|
||||||
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
|
|
||||||
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
|
|
||||||
</formatting-settings>
|
|
||||||
</DBN-SQL>
|
|
||||||
</code_scheme>
|
|
|
@ -25,14 +25,14 @@ import run.halo.app.repository.base.BaseRepositoryImpl;
|
||||||
@EnableJpaRepositories(basePackages = "run.halo.app.repository", repositoryBaseClass = BaseRepositoryImpl.class)
|
@EnableJpaRepositories(basePackages = "run.halo.app.repository", repositoryBaseClass = BaseRepositoryImpl.class)
|
||||||
public class Application extends SpringBootServletInitializer {
|
public class Application extends SpringBootServletInitializer {
|
||||||
|
|
||||||
private static ConfigurableApplicationContext context;
|
private static ConfigurableApplicationContext CONTEXT;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Customize the spring config location
|
// Customize the spring config location
|
||||||
System.setProperty("spring.config.additional-location", "file:${user.home}/.halo/,file:${user.home}/halo-dev/");
|
System.setProperty("spring.config.additional-location", "file:${user.home}/.halo/,file:${user.home}/halo-dev/");
|
||||||
|
|
||||||
// Run application
|
// Run application
|
||||||
context = SpringApplication.run(Application.class, args);
|
CONTEXT = SpringApplication.run(Application.class, args);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,11 +40,11 @@ public class Application extends SpringBootServletInitializer {
|
||||||
* Restart Application.
|
* Restart Application.
|
||||||
*/
|
*/
|
||||||
public static void restart() {
|
public static void restart() {
|
||||||
ApplicationArguments args = context.getBean(ApplicationArguments.class);
|
ApplicationArguments args = CONTEXT.getBean(ApplicationArguments.class);
|
||||||
|
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
context.close();
|
CONTEXT.close();
|
||||||
context = SpringApplication.run(Application.class, args.getSourceArgs());
|
CONTEXT = SpringApplication.run(Application.class, args.getSourceArgs());
|
||||||
});
|
});
|
||||||
|
|
||||||
thread.setDaemon(false);
|
thread.setDaemon(false);
|
||||||
|
|
|
@ -28,8 +28,7 @@ public class LevelCacheStore extends StringCacheStore {
|
||||||
*/
|
*/
|
||||||
private final static long PERIOD = 60 * 1000;
|
private final static long PERIOD = 60 * 1000;
|
||||||
|
|
||||||
private static DB leveldb;
|
private static DB LEVEL_DB;
|
||||||
|
|
||||||
|
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
|
|
||||||
|
@ -38,7 +37,7 @@ public class LevelCacheStore extends StringCacheStore {
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
if (leveldb != null) return;
|
if (LEVEL_DB != null) return;
|
||||||
try {
|
try {
|
||||||
//work path
|
//work path
|
||||||
File folder = new File(haloProperties.getWorkDir() + ".leveldb");
|
File folder = new File(haloProperties.getWorkDir() + ".leveldb");
|
||||||
|
@ -46,7 +45,7 @@ public class LevelCacheStore extends StringCacheStore {
|
||||||
Options options = new Options();
|
Options options = new Options();
|
||||||
options.createIfMissing(true);
|
options.createIfMissing(true);
|
||||||
//open leveldb store folder
|
//open leveldb store folder
|
||||||
leveldb = factory.open(folder, options);
|
LEVEL_DB = factory.open(folder, options);
|
||||||
timer = new Timer();
|
timer = new Timer();
|
||||||
timer.scheduleAtFixedRate(new CacheExpiryCleaner(), 0, PERIOD);
|
timer.scheduleAtFixedRate(new CacheExpiryCleaner(), 0, PERIOD);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
@ -60,7 +59,7 @@ public class LevelCacheStore extends StringCacheStore {
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
public void preDestroy() {
|
public void preDestroy() {
|
||||||
try {
|
try {
|
||||||
leveldb.close();
|
LEVEL_DB.close();
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("close leveldb error ", e);
|
log.error("close leveldb error ", e);
|
||||||
|
@ -70,7 +69,7 @@ public class LevelCacheStore extends StringCacheStore {
|
||||||
@Override
|
@Override
|
||||||
Optional<CacheWrapper<String>> getInternal(String key) {
|
Optional<CacheWrapper<String>> getInternal(String key) {
|
||||||
Assert.hasText(key, "Cache key must not be blank");
|
Assert.hasText(key, "Cache key must not be blank");
|
||||||
byte[] bytes = leveldb.get(stringToBytes(key));
|
byte[] bytes = LEVEL_DB.get(stringToBytes(key));
|
||||||
if (bytes != null) {
|
if (bytes != null) {
|
||||||
String valueJson = bytesToString(bytes);
|
String valueJson = bytesToString(bytes);
|
||||||
return StringUtils.isEmpty(valueJson) ? Optional.empty() : jsonToCacheWrapper(valueJson);
|
return StringUtils.isEmpty(valueJson) ? Optional.empty() : jsonToCacheWrapper(valueJson);
|
||||||
|
@ -88,9 +87,9 @@ public class LevelCacheStore extends StringCacheStore {
|
||||||
Assert.hasText(key, "Cache key must not be blank");
|
Assert.hasText(key, "Cache key must not be blank");
|
||||||
Assert.notNull(cacheWrapper, "Cache wrapper must not be null");
|
Assert.notNull(cacheWrapper, "Cache wrapper must not be null");
|
||||||
try {
|
try {
|
||||||
leveldb.put(
|
LEVEL_DB.put(
|
||||||
stringToBytes(key),
|
stringToBytes(key),
|
||||||
stringToBytes(JsonUtils.objectToJson(cacheWrapper))
|
stringToBytes(JsonUtils.objectToJson(cacheWrapper))
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
|
@ -102,7 +101,7 @@ public class LevelCacheStore extends StringCacheStore {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete(String key) {
|
public void delete(String key) {
|
||||||
leveldb.delete(stringToBytes(key));
|
LEVEL_DB.delete(stringToBytes(key));
|
||||||
log.debug("cache remove key: [{}]", key);
|
log.debug("cache remove key: [{}]", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,9 +131,9 @@ public class LevelCacheStore extends StringCacheStore {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
//batch
|
//batch
|
||||||
WriteBatch writeBatch = leveldb.createWriteBatch();
|
WriteBatch writeBatch = LEVEL_DB.createWriteBatch();
|
||||||
|
|
||||||
DBIterator iterator = leveldb.iterator();
|
DBIterator iterator = LEVEL_DB.iterator();
|
||||||
long currentTimeMillis = System.currentTimeMillis();
|
long currentTimeMillis = System.currentTimeMillis();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
Map.Entry<byte[], byte[]> next = iterator.next();
|
Map.Entry<byte[], byte[]> next = iterator.next();
|
||||||
|
@ -147,8 +146,8 @@ public class LevelCacheStore extends StringCacheStore {
|
||||||
if (stringCacheWrapper.isPresent()) {
|
if (stringCacheWrapper.isPresent()) {
|
||||||
//get expireat time
|
//get expireat time
|
||||||
long expireAtTime = stringCacheWrapper.map(CacheWrapper::getExpireAt)
|
long expireAtTime = stringCacheWrapper.map(CacheWrapper::getExpireAt)
|
||||||
.map(Date::getTime)
|
.map(Date::getTime)
|
||||||
.orElse(0L);
|
.orElse(0L);
|
||||||
//if expire
|
//if expire
|
||||||
if (expireAtTime != 0 && currentTimeMillis > expireAtTime) {
|
if (expireAtTime != 0 && currentTimeMillis > expireAtTime) {
|
||||||
writeBatch.delete(next.getKey());
|
writeBatch.delete(next.getKey());
|
||||||
|
@ -156,7 +155,7 @@ public class LevelCacheStore extends StringCacheStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leveldb.write(writeBatch);
|
LEVEL_DB.write(writeBatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,10 +55,10 @@ public class HaloConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public RestTemplate httpsRestTemplate(RestTemplateBuilder builder)
|
public RestTemplate httpsRestTemplate(RestTemplateBuilder builder)
|
||||||
throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
|
throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
|
||||||
RestTemplate httpsRestTemplate = builder.build();
|
RestTemplate httpsRestTemplate = builder.build();
|
||||||
httpsRestTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(HttpClientUtils.createHttpsClient(
|
httpsRestTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(HttpClientUtils.createHttpsClient(
|
||||||
(int) haloProperties.getDownloadTimeout().toMillis())));
|
(int) haloProperties.getDownloadTimeout().toMillis())));
|
||||||
return httpsRestTemplate;
|
return httpsRestTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,12 +125,12 @@ public class HaloConfiguration {
|
||||||
String adminPattern = HaloUtils.ensureBoth(haloProperties.getAdminPath(), "/") + "**";
|
String adminPattern = HaloUtils.ensureBoth(haloProperties.getAdminPath(), "/") + "**";
|
||||||
|
|
||||||
contentFilter.addExcludeUrlPatterns(
|
contentFilter.addExcludeUrlPatterns(
|
||||||
adminPattern,
|
adminPattern,
|
||||||
"/api/**",
|
"/api/**",
|
||||||
"/install",
|
"/install",
|
||||||
"/version",
|
"/version",
|
||||||
"/js/**",
|
"/js/**",
|
||||||
"/css/**");
|
"/css/**");
|
||||||
|
|
||||||
FilterRegistrationBean<ContentFilter> contentFrb = new FilterRegistrationBean<>();
|
FilterRegistrationBean<ContentFilter> contentFrb = new FilterRegistrationBean<>();
|
||||||
contentFrb.addUrlPatterns("/*");
|
contentFrb.addUrlPatterns("/*");
|
||||||
|
@ -148,9 +148,9 @@ public class HaloConfiguration {
|
||||||
OneTimeTokenService oneTimeTokenService) {
|
OneTimeTokenService oneTimeTokenService) {
|
||||||
ApiAuthenticationFilter apiFilter = new ApiAuthenticationFilter(haloProperties, optionService, cacheStore, oneTimeTokenService);
|
ApiAuthenticationFilter apiFilter = new ApiAuthenticationFilter(haloProperties, optionService, cacheStore, oneTimeTokenService);
|
||||||
apiFilter.addExcludeUrlPatterns(
|
apiFilter.addExcludeUrlPatterns(
|
||||||
"/api/content/*/comments",
|
"/api/content/*/comments",
|
||||||
"/api/content/**/comments/**",
|
"/api/content/**/comments/**",
|
||||||
"/api/content/options/comment"
|
"/api/content/options/comment"
|
||||||
);
|
);
|
||||||
|
|
||||||
DefaultAuthenticationFailureHandler failureHandler = new DefaultAuthenticationFailureHandler();
|
DefaultAuthenticationFailureHandler failureHandler = new DefaultAuthenticationFailureHandler();
|
||||||
|
@ -176,7 +176,7 @@ public class HaloConfiguration {
|
||||||
OptionService optionService,
|
OptionService optionService,
|
||||||
OneTimeTokenService oneTimeTokenService) {
|
OneTimeTokenService oneTimeTokenService) {
|
||||||
AdminAuthenticationFilter adminAuthenticationFilter = new AdminAuthenticationFilter(cacheStore, userService,
|
AdminAuthenticationFilter adminAuthenticationFilter = new AdminAuthenticationFilter(cacheStore, userService,
|
||||||
haloProperties, optionService, oneTimeTokenService);
|
haloProperties, optionService, oneTimeTokenService);
|
||||||
|
|
||||||
DefaultAuthenticationFailureHandler failureHandler = new DefaultAuthenticationFailureHandler();
|
DefaultAuthenticationFailureHandler failureHandler = new DefaultAuthenticationFailureHandler();
|
||||||
failureHandler.setProductionEnv(haloProperties.isProductionEnv());
|
failureHandler.setProductionEnv(haloProperties.isProductionEnv());
|
||||||
|
@ -184,14 +184,14 @@ public class HaloConfiguration {
|
||||||
|
|
||||||
// Config the admin filter
|
// Config the admin filter
|
||||||
adminAuthenticationFilter.addExcludeUrlPatterns(
|
adminAuthenticationFilter.addExcludeUrlPatterns(
|
||||||
"/api/admin/login",
|
"/api/admin/login",
|
||||||
"/api/admin/refresh/*",
|
"/api/admin/refresh/*",
|
||||||
"/api/admin/installations",
|
"/api/admin/installations",
|
||||||
"/api/admin/recoveries/migrations/*",
|
"/api/admin/recoveries/migrations/*",
|
||||||
"/api/admin/migrations/*",
|
"/api/admin/migrations/*",
|
||||||
"/api/admin/is_installed",
|
"/api/admin/is_installed",
|
||||||
"/api/admin/password/code",
|
"/api/admin/password/code",
|
||||||
"/api/admin/password/reset"
|
"/api/admin/password/reset"
|
||||||
);
|
);
|
||||||
adminAuthenticationFilter.setFailureHandler(failureHandler);
|
adminAuthenticationFilter.setFailureHandler(failureHandler);
|
||||||
|
|
||||||
|
|
|
@ -47,12 +47,12 @@ public class SwaggerConfiguration {
|
||||||
private final HaloProperties haloProperties;
|
private final HaloProperties haloProperties;
|
||||||
|
|
||||||
private final List<ResponseMessage> globalResponses = Arrays.asList(
|
private final List<ResponseMessage> globalResponses = Arrays.asList(
|
||||||
new ResponseMessageBuilder().code(200).message("Success").build(),
|
new ResponseMessageBuilder().code(200).message("Success").build(),
|
||||||
new ResponseMessageBuilder().code(400).message("Bad request").build(),
|
new ResponseMessageBuilder().code(400).message("Bad request").build(),
|
||||||
new ResponseMessageBuilder().code(401).message("Unauthorized").build(),
|
new ResponseMessageBuilder().code(401).message("Unauthorized").build(),
|
||||||
new ResponseMessageBuilder().code(403).message("Forbidden").build(),
|
new ResponseMessageBuilder().code(403).message("Forbidden").build(),
|
||||||
new ResponseMessageBuilder().code(404).message("Not found").build(),
|
new ResponseMessageBuilder().code(404).message("Not found").build(),
|
||||||
new ResponseMessageBuilder().code(500).message("Internal server error").build());
|
new ResponseMessageBuilder().code(500).message("Internal server error").build());
|
||||||
|
|
||||||
public SwaggerConfiguration(HaloProperties haloProperties) {
|
public SwaggerConfiguration(HaloProperties haloProperties) {
|
||||||
this.haloProperties = haloProperties;
|
this.haloProperties = haloProperties;
|
||||||
|
@ -65,11 +65,11 @@ public class SwaggerConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildApiDocket("run.halo.app.content.api",
|
return buildApiDocket("run.halo.app.content.api",
|
||||||
"run.halo.app.controller.content.api",
|
"run.halo.app.controller.content.api",
|
||||||
"/api/content/**")
|
"/api/content/**")
|
||||||
.securitySchemes(contentApiKeys())
|
.securitySchemes(contentApiKeys())
|
||||||
.securityContexts(contentSecurityContext())
|
.securityContexts(contentSecurityContext())
|
||||||
.enable(!haloProperties.isDocDisabled());
|
.enable(!haloProperties.isDocDisabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -79,24 +79,24 @@ public class SwaggerConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildApiDocket("run.halo.app.admin.api",
|
return buildApiDocket("run.halo.app.admin.api",
|
||||||
"run.halo.app.controller.admin",
|
"run.halo.app.controller.admin",
|
||||||
"/api/admin/**")
|
"/api/admin/**")
|
||||||
.securitySchemes(adminApiKeys())
|
.securitySchemes(adminApiKeys())
|
||||||
.securityContexts(adminSecurityContext())
|
.securityContexts(adminSecurityContext())
|
||||||
.enable(!haloProperties.isDocDisabled());
|
.enable(!haloProperties.isDocDisabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
SecurityConfiguration security() {
|
SecurityConfiguration security() {
|
||||||
return SecurityConfigurationBuilder.builder()
|
return SecurityConfigurationBuilder.builder()
|
||||||
.clientId("halo-app-client-id")
|
.clientId("halo-app-client-id")
|
||||||
.clientSecret("halo-app-client-secret")
|
.clientSecret("halo-app-client-secret")
|
||||||
.realm("halo-app-realm")
|
.realm("halo-app-realm")
|
||||||
.appName("halo-app")
|
.appName("halo-app")
|
||||||
.scopeSeparator(",")
|
.scopeSeparator(",")
|
||||||
.additionalQueryStringParams(null)
|
.additionalQueryStringParams(null)
|
||||||
.useBasicAuthenticationWithAccessCodeGrant(false)
|
.useBasicAuthenticationWithAccessCodeGrant(false)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Docket buildApiDocket(@NonNull String groupName, @NonNull String basePackage, @NonNull String antPattern) {
|
private Docket buildApiDocket(@NonNull String groupName, @NonNull String basePackage, @NonNull String antPattern) {
|
||||||
|
@ -105,74 +105,74 @@ public class SwaggerConfiguration {
|
||||||
Assert.hasText(antPattern, "Ant pattern must not be blank");
|
Assert.hasText(antPattern, "Ant pattern must not be blank");
|
||||||
|
|
||||||
return new Docket(DocumentationType.SWAGGER_2)
|
return new Docket(DocumentationType.SWAGGER_2)
|
||||||
.groupName(groupName)
|
.groupName(groupName)
|
||||||
.select()
|
.select()
|
||||||
.apis(RequestHandlerSelectors.basePackage(basePackage))
|
.apis(RequestHandlerSelectors.basePackage(basePackage))
|
||||||
.paths(PathSelectors.ant(antPattern))
|
.paths(PathSelectors.ant(antPattern))
|
||||||
.build()
|
.build()
|
||||||
.apiInfo(apiInfo())
|
.apiInfo(apiInfo())
|
||||||
.useDefaultResponseMessages(false)
|
.useDefaultResponseMessages(false)
|
||||||
.globalResponseMessage(RequestMethod.GET, globalResponses)
|
.globalResponseMessage(RequestMethod.GET, globalResponses)
|
||||||
.globalResponseMessage(RequestMethod.POST, globalResponses)
|
.globalResponseMessage(RequestMethod.POST, globalResponses)
|
||||||
.globalResponseMessage(RequestMethod.DELETE, globalResponses)
|
.globalResponseMessage(RequestMethod.DELETE, globalResponses)
|
||||||
.globalResponseMessage(RequestMethod.PUT, globalResponses)
|
.globalResponseMessage(RequestMethod.PUT, globalResponses)
|
||||||
.directModelSubstitute(Temporal.class, String.class);
|
.directModelSubstitute(Temporal.class, String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ApiKey> adminApiKeys() {
|
private List<ApiKey> adminApiKeys() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
new ApiKey("Token from header", ADMIN_TOKEN_HEADER_NAME, In.HEADER.name()),
|
new ApiKey("Token from header", ADMIN_TOKEN_HEADER_NAME, In.HEADER.name()),
|
||||||
new ApiKey("Token from query", ADMIN_TOKEN_QUERY_NAME, In.QUERY.name())
|
new ApiKey("Token from query", ADMIN_TOKEN_QUERY_NAME, In.QUERY.name())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SecurityContext> adminSecurityContext() {
|
private List<SecurityContext> adminSecurityContext() {
|
||||||
return Collections.singletonList(
|
return Collections.singletonList(
|
||||||
SecurityContext.builder()
|
SecurityContext.builder()
|
||||||
.securityReferences(defaultAuth())
|
.securityReferences(defaultAuth())
|
||||||
.forPaths(PathSelectors.regex("/api/admin/.*"))
|
.forPaths(PathSelectors.regex("/api/admin/.*"))
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ApiKey> contentApiKeys() {
|
private List<ApiKey> contentApiKeys() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
new ApiKey("Access key from header", API_ACCESS_KEY_HEADER_NAME, In.HEADER.name()),
|
new ApiKey("Access key from header", API_ACCESS_KEY_HEADER_NAME, In.HEADER.name()),
|
||||||
new ApiKey("Access key from query", API_ACCESS_KEY_QUERY_NAME, In.QUERY.name())
|
new ApiKey("Access key from query", API_ACCESS_KEY_QUERY_NAME, In.QUERY.name())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SecurityContext> contentSecurityContext() {
|
private List<SecurityContext> contentSecurityContext() {
|
||||||
return Collections.singletonList(
|
return Collections.singletonList(
|
||||||
SecurityContext.builder()
|
SecurityContext.builder()
|
||||||
.securityReferences(contentApiAuth())
|
.securityReferences(contentApiAuth())
|
||||||
.forPaths(PathSelectors.regex("/api/content/.*"))
|
.forPaths(PathSelectors.regex("/api/content/.*"))
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SecurityReference> defaultAuth() {
|
private List<SecurityReference> defaultAuth() {
|
||||||
AuthorizationScope[] authorizationScopes = {new AuthorizationScope("Admin api", "Access admin api")};
|
AuthorizationScope[] authorizationScopes = {new AuthorizationScope("Admin api", "Access admin api")};
|
||||||
return Arrays.asList(new SecurityReference("Token from header", authorizationScopes),
|
return Arrays.asList(new SecurityReference("Token from header", authorizationScopes),
|
||||||
new SecurityReference("Token from query", authorizationScopes));
|
new SecurityReference("Token from query", authorizationScopes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SecurityReference> contentApiAuth() {
|
private List<SecurityReference> contentApiAuth() {
|
||||||
AuthorizationScope[] authorizationScopes = {new AuthorizationScope("content api", "Access content api")};
|
AuthorizationScope[] authorizationScopes = {new AuthorizationScope("content api", "Access content api")};
|
||||||
return Arrays.asList(new SecurityReference("Access key from header", authorizationScopes),
|
return Arrays.asList(new SecurityReference("Access key from header", authorizationScopes),
|
||||||
new SecurityReference("Access key from query", authorizationScopes));
|
new SecurityReference("Access key from query", authorizationScopes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApiInfo apiInfo() {
|
private ApiInfo apiInfo() {
|
||||||
return new ApiInfoBuilder()
|
return new ApiInfoBuilder()
|
||||||
.title("Halo API Documentation")
|
.title("Halo API Documentation")
|
||||||
.description("Documentation for Halo API")
|
.description("Documentation for Halo API")
|
||||||
.version(HALO_VERSION)
|
.version(HALO_VERSION)
|
||||||
.termsOfServiceUrl("https://github.com/halo-dev")
|
.termsOfServiceUrl("https://github.com/halo-dev")
|
||||||
.contact(new Contact("halo-dev", "https://github.com/halo-dev/halo/issues", "i#ryanc.cc"))
|
.contact(new Contact("halo-dev", "https://github.com/halo-dev/halo/issues", "i#ryanc.cc"))
|
||||||
.license("GNU General Public License v3.0")
|
.license("GNU General Public License v3.0")
|
||||||
.licenseUrl("https://github.com/halo-dev/halo/blob/master/LICENSE")
|
.licenseUrl("https://github.com/halo-dev/halo/blob/master/LICENSE")
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -186,10 +186,10 @@ public class SwaggerConfiguration {
|
||||||
@Override
|
@Override
|
||||||
public List<AlternateTypeRule> rules() {
|
public List<AlternateTypeRule> rules() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
newRule(User.class, emptyMixin(User.class)),
|
newRule(User.class, emptyMixin(User.class)),
|
||||||
newRule(UserDetail.class, emptyMixin(UserDetail.class)),
|
newRule(UserDetail.class, emptyMixin(UserDetail.class)),
|
||||||
newRule(resolver.resolve(Pageable.class), resolver.resolve(pageableMixin())),
|
newRule(resolver.resolve(Pageable.class), resolver.resolve(pageableMixin())),
|
||||||
newRule(resolver.resolve(Sort.class), resolver.resolve(sortMixin())));
|
newRule(resolver.resolve(Sort.class), resolver.resolve(sortMixin())));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -204,31 +204,31 @@ public class SwaggerConfiguration {
|
||||||
Assert.notNull(clazz, "class type must not be null");
|
Assert.notNull(clazz, "class type must not be null");
|
||||||
|
|
||||||
return new AlternateTypeBuilder()
|
return new AlternateTypeBuilder()
|
||||||
.fullyQualifiedClassName(String.format("%s.generated.%s", clazz.getPackage().getName(), clazz.getSimpleName()))
|
.fullyQualifiedClassName(String.format("%s.generated.%s", clazz.getPackage().getName(), clazz.getSimpleName()))
|
||||||
.withProperties(Collections.emptyList())
|
.withProperties(Collections.emptyList())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type sortMixin() {
|
private Type sortMixin() {
|
||||||
return new AlternateTypeBuilder()
|
return new AlternateTypeBuilder()
|
||||||
.fullyQualifiedClassName(String.format("%s.generated.%s", Sort.class.getPackage().getName(), Sort.class.getSimpleName()))
|
.fullyQualifiedClassName(String.format("%s.generated.%s", Sort.class.getPackage().getName(), Sort.class.getSimpleName()))
|
||||||
.withProperties(Collections.singletonList(property(String[].class, "sort")))
|
.withProperties(Collections.singletonList(property(String[].class, "sort")))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type pageableMixin() {
|
private Type pageableMixin() {
|
||||||
return new AlternateTypeBuilder()
|
return new AlternateTypeBuilder()
|
||||||
.fullyQualifiedClassName(String.format("%s.generated.%s", Pageable.class.getPackage().getName(), Pageable.class.getSimpleName()))
|
.fullyQualifiedClassName(String.format("%s.generated.%s", Pageable.class.getPackage().getName(), Pageable.class.getSimpleName()))
|
||||||
.withProperties(Arrays.asList(property(Integer.class, "page"), property(Integer.class, "size"), property(String[].class, "sort")))
|
.withProperties(Arrays.asList(property(Integer.class, "page"), property(Integer.class, "size"), property(String[].class, "sort")))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private AlternateTypePropertyBuilder property(Class<?> type, String name) {
|
private AlternateTypePropertyBuilder property(Class<?> type, String name) {
|
||||||
return new AlternateTypePropertyBuilder()
|
return new AlternateTypePropertyBuilder()
|
||||||
.withName(name)
|
.withName(name)
|
||||||
.withType(type)
|
.withType(type)
|
||||||
.withCanRead(true)
|
.withCanRead(true)
|
||||||
.withCanWrite(true);
|
.withCanWrite(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,15 +76,16 @@ public class WebMvcAutoConfiguration extends WebMvcConfigurationSupport {
|
||||||
@Override
|
@Override
|
||||||
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
|
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
converters.stream()
|
converters.stream()
|
||||||
.filter(c -> c instanceof MappingJackson2HttpMessageConverter)
|
.filter(c -> c instanceof MappingJackson2HttpMessageConverter)
|
||||||
.findFirst().ifPresent(converter -> {
|
.findFirst()
|
||||||
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = (MappingJackson2HttpMessageConverter) converter;
|
.ifPresent(converter -> {
|
||||||
Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json();
|
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = (MappingJackson2HttpMessageConverter) converter;
|
||||||
JsonComponentModule module = new JsonComponentModule();
|
Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json();
|
||||||
module.addSerializer(PageImpl.class, new PageJacksonSerializer());
|
JsonComponentModule module = new JsonComponentModule();
|
||||||
ObjectMapper objectMapper = builder.modules(module).build();
|
module.addSerializer(PageImpl.class, new PageJacksonSerializer());
|
||||||
mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
|
ObjectMapper objectMapper = builder.modules(module).build();
|
||||||
});
|
mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -105,29 +106,29 @@ public class WebMvcAutoConfiguration extends WebMvcConfigurationSupport {
|
||||||
|
|
||||||
// register /** resource handler.
|
// register /** resource handler.
|
||||||
registry.addResourceHandler("/**")
|
registry.addResourceHandler("/**")
|
||||||
.addResourceLocations(workDir + "templates/admin/")
|
.addResourceLocations(workDir + "templates/admin/")
|
||||||
.addResourceLocations("classpath:/admin/")
|
.addResourceLocations("classpath:/admin/")
|
||||||
.addResourceLocations(workDir + "static/");
|
.addResourceLocations(workDir + "static/");
|
||||||
|
|
||||||
// register /themes/** resource handler.
|
// register /themes/** resource handler.
|
||||||
registry.addResourceHandler("/themes/**")
|
registry.addResourceHandler("/themes/**")
|
||||||
.addResourceLocations(workDir + "templates/themes/");
|
.addResourceLocations(workDir + "templates/themes/");
|
||||||
|
|
||||||
String uploadUrlPattern = ensureBoth(haloProperties.getUploadUrlPrefix(), URL_SEPARATOR) + "**";
|
String uploadUrlPattern = ensureBoth(haloProperties.getUploadUrlPrefix(), URL_SEPARATOR) + "**";
|
||||||
String adminPathPattern = ensureSuffix(haloProperties.getAdminPath(), URL_SEPARATOR) + "**";
|
String adminPathPattern = ensureSuffix(haloProperties.getAdminPath(), URL_SEPARATOR) + "**";
|
||||||
|
|
||||||
registry.addResourceHandler(uploadUrlPattern)
|
registry.addResourceHandler(uploadUrlPattern)
|
||||||
.addResourceLocations(workDir + "upload/");
|
.addResourceLocations(workDir + "upload/");
|
||||||
registry.addResourceHandler(adminPathPattern)
|
registry.addResourceHandler(adminPathPattern)
|
||||||
.addResourceLocations(workDir + HALO_ADMIN_RELATIVE_PATH)
|
.addResourceLocations(workDir + HALO_ADMIN_RELATIVE_PATH)
|
||||||
.addResourceLocations("classpath:/admin/");
|
.addResourceLocations("classpath:/admin/");
|
||||||
|
|
||||||
if (!haloProperties.isDocDisabled()) {
|
if (!haloProperties.isDocDisabled()) {
|
||||||
// If doc is enable
|
// If doc is enable
|
||||||
registry.addResourceHandler("swagger-ui.html")
|
registry.addResourceHandler("swagger-ui.html")
|
||||||
.addResourceLocations("classpath:/META-INF/resources/");
|
.addResourceLocations("classpath:/META-INF/resources/");
|
||||||
registry.addResourceHandler("/webjars/**")
|
registry.addResourceHandler("/webjars/**")
|
||||||
.addResourceLocations("classpath:/META-INF/resources/webjars/");
|
.addResourceLocations("classpath:/META-INF/resources/webjars/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,9 +72,9 @@ public class BackupController {
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResponseEntity.ok()
|
return ResponseEntity.ok()
|
||||||
.contentType(MediaType.parseMediaType(contentType))
|
.contentType(MediaType.parseMediaType(contentType))
|
||||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + backupResource.getFilename() + "\"")
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + backupResource.getFilename() + "\"")
|
||||||
.body(backupResource);
|
.body(backupResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("halo")
|
@DeleteMapping("halo")
|
||||||
|
|
|
@ -46,8 +46,8 @@ public class CategoryController {
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@ApiOperation("Lists all categories")
|
@ApiOperation("Lists all categories")
|
||||||
public List<? extends CategoryDTO> listAll(
|
public List<? extends CategoryDTO> listAll(
|
||||||
@SortDefault(sort = "updateTime", direction = DESC) Sort sort,
|
@SortDefault(sort = "updateTime", direction = DESC) Sort sort,
|
||||||
@RequestParam(name = "more", required = false, defaultValue = "false") boolean more) {
|
@RequestParam(name = "more", required = false, defaultValue = "false") boolean more) {
|
||||||
if (more) {
|
if (more) {
|
||||||
return postCategoryService.listCategoryWithPostCountDto(sort);
|
return postCategoryService.listCategoryWithPostCountDto(sort);
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class InstallController {
|
||||||
createDefaultMenu();
|
createDefaultMenu();
|
||||||
|
|
||||||
eventPublisher.publishEvent(
|
eventPublisher.publishEvent(
|
||||||
new LogEvent(this, user.getId().toString(), LogType.BLOG_INITIALIZED, "博客已成功初始化")
|
new LogEvent(this, user.getId().toString(), LogType.BLOG_INITIALIZED, "博客已成功初始化")
|
||||||
);
|
);
|
||||||
|
|
||||||
return BaseResponse.ok("安装完成!");
|
return BaseResponse.ok("安装完成!");
|
||||||
|
@ -167,8 +167,8 @@ public class InstallController {
|
||||||
postParam.setTitle("Hello Halo");
|
postParam.setTitle("Hello Halo");
|
||||||
postParam.setStatus(PostStatus.PUBLISHED);
|
postParam.setStatus(PostStatus.PUBLISHED);
|
||||||
postParam.setOriginalContent("## Hello Halo!\n" +
|
postParam.setOriginalContent("## Hello Halo!\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"感谢使用 [Halo](https://github.com/halo-dev/halo) 进行创作,请删除该文章开始吧!");
|
"感谢使用 [Halo](https://github.com/halo-dev/halo) 进行创作,请删除该文章开始吧!");
|
||||||
|
|
||||||
if (category != null) {
|
if (category != null) {
|
||||||
Set<Integer> categoryIds = new HashSet<>();
|
Set<Integer> categoryIds = new HashSet<>();
|
||||||
|
@ -218,7 +218,7 @@ public class InstallController {
|
||||||
properties.put(BlogProperties.BLOG_LOCALE, installParam.getLocale());
|
properties.put(BlogProperties.BLOG_LOCALE, installParam.getLocale());
|
||||||
properties.put(BlogProperties.BLOG_TITLE, installParam.getTitle());
|
properties.put(BlogProperties.BLOG_TITLE, installParam.getTitle());
|
||||||
properties.put(BlogProperties.BLOG_URL, StringUtils.isBlank(installParam.getUrl()) ?
|
properties.put(BlogProperties.BLOG_URL, StringUtils.isBlank(installParam.getUrl()) ?
|
||||||
optionService.getBlogBaseUrl() : installParam.getUrl());
|
optionService.getBlogBaseUrl() : installParam.getUrl());
|
||||||
properties.put(PrimaryProperties.BIRTHDAY, String.valueOf(System.currentTimeMillis()));
|
properties.put(PrimaryProperties.BIRTHDAY, String.valueOf(System.currentTimeMillis()));
|
||||||
|
|
||||||
// Create properties
|
// Create properties
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class LinkController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("teams")
|
@GetMapping("teams")
|
||||||
@ApiOperation(("Lists all link teams"))
|
@ApiOperation("Lists all link teams")
|
||||||
public List<String> teams() {
|
public List<String> teams() {
|
||||||
return linkService.listAllTeams();
|
return linkService.listAllTeams();
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class MenuController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("teams")
|
@GetMapping("teams")
|
||||||
@ApiOperation(("Lists all menu teams"))
|
@ApiOperation("Lists all menu teams")
|
||||||
public List<String> teams() {
|
public List<String> teams() {
|
||||||
return menuService.listAllTeams();
|
return menuService.listAllTeams();
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,8 +125,8 @@ public class PostController {
|
||||||
@PutMapping("{postId:\\d+}/status/{status}")
|
@PutMapping("{postId:\\d+}/status/{status}")
|
||||||
@ApiOperation("Updates post status")
|
@ApiOperation("Updates post status")
|
||||||
public BasePostMinimalDTO updateStatusBy(
|
public BasePostMinimalDTO updateStatusBy(
|
||||||
@PathVariable("postId") Integer postId,
|
@PathVariable("postId") Integer postId,
|
||||||
@PathVariable("status") PostStatus status) {
|
@PathVariable("status") PostStatus status) {
|
||||||
Post post = postService.updateStatus(status, postId);
|
Post post = postService.updateStatus(status, postId);
|
||||||
|
|
||||||
return new BasePostMinimalDTO().convertFrom(post);
|
return new BasePostMinimalDTO().convertFrom(post);
|
||||||
|
@ -142,8 +142,8 @@ public class PostController {
|
||||||
@PutMapping("{postId:\\d+}/status/draft/content")
|
@PutMapping("{postId:\\d+}/status/draft/content")
|
||||||
@ApiOperation("Updates draft")
|
@ApiOperation("Updates draft")
|
||||||
public BasePostDetailDTO updateDraftBy(
|
public BasePostDetailDTO updateDraftBy(
|
||||||
@PathVariable("postId") Integer postId,
|
@PathVariable("postId") Integer postId,
|
||||||
@RequestBody PostContentParam contentParam) {
|
@RequestBody PostContentParam contentParam) {
|
||||||
// Update draft content
|
// Update draft content
|
||||||
Post post = postService.updateDraftContent(contentParam.getContent(), postId);
|
Post post = postService.updateDraftContent(contentParam.getContent(), postId);
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,8 @@ public class RecoveryController {
|
||||||
@ApiOperation("Migrates from halo v0.4.3")
|
@ApiOperation("Migrates from halo v0.4.3")
|
||||||
@CacheLock
|
@CacheLock
|
||||||
public void migrateFromVersion_0_4_3(
|
public void migrateFromVersion_0_4_3(
|
||||||
@ApiParam("This file content type should be json")
|
@ApiParam("This file content type should be json")
|
||||||
@RequestPart("file") MultipartFile file) {
|
@RequestPart("file") MultipartFile file) {
|
||||||
if (optionService.getByPropertyOrDefault(PrimaryProperties.IS_INSTALLED, Boolean.class, false)) {
|
if (optionService.getByPropertyOrDefault(PrimaryProperties.IS_INSTALLED, Boolean.class, false)) {
|
||||||
throw new BadRequestException("无法在博客初始化完成之后迁移数据");
|
throw new BadRequestException("无法在博客初始化完成之后迁移数据");
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,9 +82,9 @@ public class SheetController {
|
||||||
@PutMapping("{sheetId:\\d+}")
|
@PutMapping("{sheetId:\\d+}")
|
||||||
@ApiOperation("Updates a sheet")
|
@ApiOperation("Updates a sheet")
|
||||||
public SheetDetailVO updateBy(
|
public SheetDetailVO updateBy(
|
||||||
@PathVariable("sheetId") Integer sheetId,
|
@PathVariable("sheetId") Integer sheetId,
|
||||||
@RequestBody @Valid SheetParam sheetParam,
|
@RequestBody @Valid SheetParam sheetParam,
|
||||||
@RequestParam(value = "autoSave", required = false, defaultValue = "false") Boolean autoSave) {
|
@RequestParam(value = "autoSave", required = false, defaultValue = "false") Boolean autoSave) {
|
||||||
Sheet sheetToUpdate = sheetService.getById(sheetId);
|
Sheet sheetToUpdate = sheetService.getById(sheetId);
|
||||||
|
|
||||||
sheetParam.update(sheetToUpdate);
|
sheetParam.update(sheetToUpdate);
|
||||||
|
@ -97,8 +97,8 @@ public class SheetController {
|
||||||
@PutMapping("{sheetId:\\d+}/{status}")
|
@PutMapping("{sheetId:\\d+}/{status}")
|
||||||
@ApiOperation("Updates a sheet")
|
@ApiOperation("Updates a sheet")
|
||||||
public void updateStatusBy(
|
public void updateStatusBy(
|
||||||
@PathVariable("sheetId") Integer sheetId,
|
@PathVariable("sheetId") Integer sheetId,
|
||||||
@PathVariable("status") PostStatus status) {
|
@PathVariable("status") PostStatus status) {
|
||||||
Sheet sheet = sheetService.getById(sheetId);
|
Sheet sheet = sheetService.getById(sheetId);
|
||||||
|
|
||||||
// Set status
|
// Set status
|
||||||
|
|
|
@ -107,7 +107,7 @@ public class PostModel {
|
||||||
model.addAttribute("comments", Page.empty());
|
model.addAttribute("comments", Page.empty());
|
||||||
|
|
||||||
if (themeService.templateExists(
|
if (themeService.templateExists(
|
||||||
ThemeService.CUSTOM_POST_PREFIX + post.getTemplate() + HaloConst.SUFFIX_FTL)) {
|
ThemeService.CUSTOM_POST_PREFIX + post.getTemplate() + HaloConst.SUFFIX_FTL)) {
|
||||||
return themeService.render(ThemeService.CUSTOM_POST_PREFIX + post.getTemplate());
|
return themeService.render(ThemeService.CUSTOM_POST_PREFIX + post.getTemplate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ public class PostModel {
|
||||||
public String list(Integer page, Model model, String decide, String template) {
|
public String list(Integer page, Model model, String decide, String template) {
|
||||||
int pageSize = optionService.getPostPageSize();
|
int pageSize = optionService.getPostPageSize();
|
||||||
Pageable pageable = PageRequest
|
Pageable pageable = PageRequest
|
||||||
.of(page >= 1 ? page - 1 : page, pageSize, postService.getPostDefaultSort());
|
.of(page >= 1 ? page - 1 : page, pageSize, postService.getPostDefaultSort());
|
||||||
|
|
||||||
Page<Post> postPage = postService.pageBy(PostStatus.PUBLISHED, pageable);
|
Page<Post> postPage = postService.pageBy(PostStatus.PUBLISHED, pageable);
|
||||||
Page<PostListVO> posts = postService.convertToListVo(postPage);
|
Page<PostListVO> posts = postService.convertToListVo(postPage);
|
||||||
|
@ -135,15 +135,15 @@ public class PostModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
nextPageFullPath.append("/page/")
|
nextPageFullPath.append("/page/")
|
||||||
.append(posts.getNumber() + 2)
|
.append(posts.getNumber() + 2)
|
||||||
.append(optionService.getPathSuffix());
|
.append(optionService.getPathSuffix());
|
||||||
|
|
||||||
if (posts.getNumber() == 1) {
|
if (posts.getNumber() == 1) {
|
||||||
prePageFullPath.append("/");
|
prePageFullPath.append("/");
|
||||||
} else {
|
} else {
|
||||||
prePageFullPath.append("/page/")
|
prePageFullPath.append("/page/")
|
||||||
.append(posts.getNumber())
|
.append(posts.getNumber())
|
||||||
.append(optionService.getPathSuffix());
|
.append(optionService.getPathSuffix());
|
||||||
}
|
}
|
||||||
|
|
||||||
model.addAttribute(decide, true);
|
model.addAttribute(decide, true);
|
||||||
|
|
|
@ -70,10 +70,10 @@ public class CommonController extends AbstractErrorController {
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public String handleError(HttpServletRequest request, HttpServletResponse response, Model model) {
|
public String handleError(HttpServletRequest request, HttpServletResponse response, Model model) {
|
||||||
log.error("Request URL: [{}], URI: [{}], Request Method: [{}], IP: [{}]",
|
log.error("Request URL: [{}], URI: [{}], Request Method: [{}], IP: [{}]",
|
||||||
request.getRequestURL(),
|
request.getRequestURL(),
|
||||||
request.getRequestURI(),
|
request.getRequestURI(),
|
||||||
request.getMethod(),
|
request.getMethod(),
|
||||||
ServletUtil.getClientIP(request));
|
ServletUtil.getClientIP(request));
|
||||||
|
|
||||||
handleCustomException(request);
|
handleCustomException(request);
|
||||||
|
|
||||||
|
@ -138,9 +138,9 @@ public class CommonController extends AbstractErrorController {
|
||||||
|
|
||||||
StringBuilder path = new StringBuilder();
|
StringBuilder path = new StringBuilder();
|
||||||
path.append("themes/")
|
path.append("themes/")
|
||||||
.append(themeService.getActivatedTheme().getFolderName())
|
.append(themeService.getActivatedTheme().getFolderName())
|
||||||
.append('/')
|
.append('/')
|
||||||
.append(FilenameUtils.getBasename(template));
|
.append(FilenameUtils.getBasename(template));
|
||||||
|
|
||||||
return path.toString();
|
return path.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class CommonResultControllerAdvice implements ResponseBodyAdvice<Object>
|
||||||
* additional serialization instructions) or simply cast it if already wrapped.
|
* additional serialization instructions) or simply cast it if already wrapped.
|
||||||
*/
|
*/
|
||||||
private MappingJacksonValue getOrCreateContainer(Object body) {
|
private MappingJacksonValue getOrCreateContainer(Object body) {
|
||||||
return (body instanceof MappingJacksonValue ? (MappingJacksonValue) body : new MappingJacksonValue(body));
|
return body instanceof MappingJacksonValue ? (MappingJacksonValue) body : new MappingJacksonValue(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void beforeBodyWriteInternal(MappingJacksonValue bodyContainer,
|
private void beforeBodyWriteInternal(MappingJacksonValue bodyContainer,
|
||||||
|
|
|
@ -27,7 +27,7 @@ import java.util.Map;
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
*/
|
*/
|
||||||
@RestControllerAdvice({"run.halo.app.controller.admin.api", "run.halo.app.controller.content.api"})
|
@RestControllerAdvice(value = {"run.halo.app.controller.admin.api", "run.halo.app.controller.content.api"})
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ControllerExceptionHandler {
|
public class ControllerExceptionHandler {
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,10 @@ public class ControllerLogAop {
|
||||||
|
|
||||||
private void printRequestLog(HttpServletRequest request, String clazzName, String methodName, Object[] args) throws JsonProcessingException {
|
private void printRequestLog(HttpServletRequest request, String clazzName, String methodName, Object[] args) throws JsonProcessingException {
|
||||||
log.debug("Request URL: [{}], URI: [{}], Request Method: [{}], IP: [{}]",
|
log.debug("Request URL: [{}], URI: [{}], Request Method: [{}], IP: [{}]",
|
||||||
request.getRequestURL(),
|
request.getRequestURL(),
|
||||||
request.getRequestURI(),
|
request.getRequestURI(),
|
||||||
request.getMethod(),
|
request.getMethod(),
|
||||||
ServletUtil.getClientIP(request));
|
ServletUtil.getClientIP(request));
|
||||||
|
|
||||||
if (args == null || !log.isDebugEnabled()) {
|
if (args == null || !log.isDebugEnabled()) {
|
||||||
return;
|
return;
|
||||||
|
@ -65,10 +65,10 @@ public class ControllerLogAop {
|
||||||
boolean shouldNotLog = false;
|
boolean shouldNotLog = false;
|
||||||
for (Object arg : args) {
|
for (Object arg : args) {
|
||||||
if (arg == null ||
|
if (arg == null ||
|
||||||
arg instanceof HttpServletRequest ||
|
arg instanceof HttpServletRequest ||
|
||||||
arg instanceof HttpServletResponse ||
|
arg instanceof HttpServletResponse ||
|
||||||
arg instanceof MultipartFile ||
|
arg instanceof MultipartFile ||
|
||||||
arg.getClass().isAssignableFrom(MultipartFile[].class)) {
|
arg.getClass().isAssignableFrom(MultipartFile[].class)) {
|
||||||
shouldNotLog = true;
|
shouldNotLog = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ public class StringToEnumConverterFactory implements ConverterFactory<String, En
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class StringToEnumConverter<T extends Enum>
|
private static class StringToEnumConverter<T extends Enum>
|
||||||
implements Converter<String, T> {
|
implements Converter<String, T> {
|
||||||
|
|
||||||
private Class<T> enumType;
|
private Class<T> enumType;
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class LogFilter extends OncePerRequestFilter {
|
||||||
// Do filter
|
// Do filter
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
|
|
||||||
log.debug("Ending url: [{}], method: [{}], ip: [{}], status: [{}], usage: [{}] ms", request.getRequestURL(), request.getMethod(), remoteAddr, response.getStatus(), (System.currentTimeMillis() - startTime));
|
log.debug("Ending url: [{}], method: [{}], ip: [{}], status: [{}], usage: [{}] ms", request.getRequestURL(), request.getMethod(), remoteAddr, response.getStatus(), System.currentTimeMillis() - startTime);
|
||||||
log.debug("");
|
log.debug("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,12 +60,12 @@ public class AliOssFileHandler implements FileHandler {
|
||||||
|
|
||||||
if (StringUtils.isNotEmpty(domain)) {
|
if (StringUtils.isNotEmpty(domain)) {
|
||||||
basePath.append(domain)
|
basePath.append(domain)
|
||||||
.append("/");
|
.append("/");
|
||||||
} else {
|
} else {
|
||||||
basePath.append(bucketName)
|
basePath.append(bucketName)
|
||||||
.append(".")
|
.append(".")
|
||||||
.append(endPoint)
|
.append(endPoint)
|
||||||
.append("/");
|
.append("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -76,14 +76,14 @@ public class AliOssFileHandler implements FileHandler {
|
||||||
|
|
||||||
if (StringUtils.isNotEmpty(source)) {
|
if (StringUtils.isNotEmpty(source)) {
|
||||||
upFilePath.append(source)
|
upFilePath.append(source)
|
||||||
.append("/");
|
.append("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
upFilePath.append(basename)
|
upFilePath.append(basename)
|
||||||
.append("_")
|
.append("_")
|
||||||
.append(timestamp)
|
.append(timestamp)
|
||||||
.append(".")
|
.append(".")
|
||||||
.append(extension);
|
.append(extension);
|
||||||
|
|
||||||
String filePath = StringUtils.join(basePath.toString(), upFilePath.toString());
|
String filePath = StringUtils.join(basePath.toString(), upFilePath.toString());
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import run.halo.app.exception.FileOperationException;
|
import run.halo.app.exception.FileOperationException;
|
||||||
import run.halo.app.model.enums.AttachmentType;
|
|
||||||
import run.halo.app.model.support.UploadResult;
|
import run.halo.app.model.support.UploadResult;
|
||||||
|
|
||||||
import static run.halo.app.model.support.HaloConst.FILE_SEPARATOR;
|
import static run.halo.app.model.support.HaloConst.FILE_SEPARATOR;
|
||||||
|
|
|
@ -72,10 +72,10 @@ public class QiniuOssFileHandler implements FileHandler {
|
||||||
// Build put plicy
|
// Build put plicy
|
||||||
StringMap putPolicy = new StringMap();
|
StringMap putPolicy = new StringMap();
|
||||||
putPolicy.put("returnBody", "{\"size\":$(fsize), " +
|
putPolicy.put("returnBody", "{\"size\":$(fsize), " +
|
||||||
"\"width\":$(imageInfo.width), " +
|
"\"width\":$(imageInfo.width), " +
|
||||||
"\"height\":$(imageInfo.height)," +
|
"\"height\":$(imageInfo.height)," +
|
||||||
" \"key\":\"$(key)\", " +
|
" \"key\":\"$(key)\", " +
|
||||||
"\"hash\":\"$(etag)\"}");
|
"\"hash\":\"$(etag)\"}");
|
||||||
// Get upload token
|
// Get upload token
|
||||||
String uploadToken = auth.uploadToken(bucket, null, 3600, putPolicy);
|
String uploadToken = auth.uploadToken(bucket, null, 3600, putPolicy);
|
||||||
|
|
||||||
|
@ -83,8 +83,8 @@ public class QiniuOssFileHandler implements FileHandler {
|
||||||
Path tmpPath = Paths.get(System.getProperty("java.io.tmpdir"), bucket);
|
Path tmpPath = Paths.get(System.getProperty("java.io.tmpdir"), bucket);
|
||||||
|
|
||||||
StringBuilder basePath = new StringBuilder(protocol)
|
StringBuilder basePath = new StringBuilder(protocol)
|
||||||
.append(domain)
|
.append(domain)
|
||||||
.append("/");
|
.append("/");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String basename = FilenameUtils.getBasename(Objects.requireNonNull(file.getOriginalFilename()));
|
String basename = FilenameUtils.getBasename(Objects.requireNonNull(file.getOriginalFilename()));
|
||||||
|
@ -93,13 +93,13 @@ public class QiniuOssFileHandler implements FileHandler {
|
||||||
StringBuilder upFilePath = new StringBuilder();
|
StringBuilder upFilePath = new StringBuilder();
|
||||||
if (StringUtils.isNotEmpty(source)) {
|
if (StringUtils.isNotEmpty(source)) {
|
||||||
upFilePath.append(source)
|
upFilePath.append(source)
|
||||||
.append("/");
|
.append("/");
|
||||||
}
|
}
|
||||||
upFilePath.append(basename)
|
upFilePath.append(basename)
|
||||||
.append("_")
|
.append("_")
|
||||||
.append(timestamp)
|
.append(timestamp)
|
||||||
.append(".")
|
.append(".")
|
||||||
.append(extension);
|
.append(extension);
|
||||||
|
|
||||||
// Get file recorder for temp directory
|
// Get file recorder for temp directory
|
||||||
FileRecorder fileRecorder = new FileRecorder(tmpPath.toFile());
|
FileRecorder fileRecorder = new FileRecorder(tmpPath.toFile());
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package run.halo.app.handler.file;
|
package run.halo.app.handler.file;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -189,7 +190,8 @@ public class SmmsFileHandler implements FileHandler {
|
||||||
|
|
||||||
private SmmsResponseData data;
|
private SmmsResponseData data;
|
||||||
|
|
||||||
private String RequestId;
|
@JsonProperty("RequestId")
|
||||||
|
private String requestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|
|
@ -68,13 +68,13 @@ public class TencentCosFileHandler implements FileHandler {
|
||||||
|
|
||||||
if (StringUtils.isNotEmpty(domain)) {
|
if (StringUtils.isNotEmpty(domain)) {
|
||||||
basePath.append(domain)
|
basePath.append(domain)
|
||||||
.append("/");
|
.append("/");
|
||||||
} else {
|
} else {
|
||||||
basePath.append(bucketName)
|
basePath.append(bucketName)
|
||||||
.append(".cos.")
|
.append(".cos.")
|
||||||
.append(region)
|
.append(region)
|
||||||
.append(".myqcloud.com")
|
.append(".myqcloud.com")
|
||||||
.append("/");
|
.append("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -85,14 +85,14 @@ public class TencentCosFileHandler implements FileHandler {
|
||||||
|
|
||||||
if (StringUtils.isNotEmpty(source)) {
|
if (StringUtils.isNotEmpty(source)) {
|
||||||
upFilePath.append(source)
|
upFilePath.append(source)
|
||||||
.append("/");
|
.append("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
upFilePath.append(basename)
|
upFilePath.append(basename)
|
||||||
.append("_")
|
.append("_")
|
||||||
.append(timestamp)
|
.append(timestamp)
|
||||||
.append(".")
|
.append(".")
|
||||||
.append(extension);
|
.append(extension);
|
||||||
|
|
||||||
String filePath = StringUtils.join(basePath.toString(), upFilePath.toString());
|
String filePath = StringUtils.join(basePath.toString(), upFilePath.toString());
|
||||||
|
|
||||||
|
|
|
@ -230,8 +230,8 @@ public class OldVersionMigrateHandler implements MigrateHandler {
|
||||||
log.debug("Migrated tags of post [{}]: [{}]", tags, createdPost.getId());
|
log.debug("Migrated tags of post [{}]: [{}]", tags, createdPost.getId());
|
||||||
|
|
||||||
List<PostComment> postComments = baseComments.stream()
|
List<PostComment> postComments = baseComments.stream()
|
||||||
.map(baseComment -> BeanUtils.transformFrom(baseComment, PostComment.class))
|
.map(baseComment -> BeanUtils.transformFrom(baseComment, PostComment.class))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Build virtual comment
|
// Build virtual comment
|
||||||
|
@ -259,8 +259,8 @@ public class OldVersionMigrateHandler implements MigrateHandler {
|
||||||
List<BaseComment> baseComments = handleComment(commentsObject, createdSheet.getId());
|
List<BaseComment> baseComments = handleComment(commentsObject, createdSheet.getId());
|
||||||
|
|
||||||
List<SheetComment> sheetComments = baseComments.stream()
|
List<SheetComment> sheetComments = baseComments.stream()
|
||||||
.map(baseComment -> BeanUtils.transformFrom(baseComment, SheetComment.class))
|
.map(baseComment -> BeanUtils.transformFrom(baseComment, SheetComment.class))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// Create comments
|
// Create comments
|
||||||
try {
|
try {
|
||||||
|
@ -293,8 +293,8 @@ public class OldVersionMigrateHandler implements MigrateHandler {
|
||||||
}
|
}
|
||||||
// Get all children
|
// Get all children
|
||||||
List<PostComment> children = postComments.stream()
|
List<PostComment> children = postComments.stream()
|
||||||
.filter(postComment -> Objects.equals(oldParentId, postComment.getParentId()))
|
.filter(postComment -> Objects.equals(oldParentId, postComment.getParentId()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
|
||||||
// Set parent id again
|
// Set parent id again
|
||||||
|
@ -320,8 +320,8 @@ public class OldVersionMigrateHandler implements MigrateHandler {
|
||||||
}
|
}
|
||||||
// Get all children
|
// Get all children
|
||||||
List<SheetComment> children = sheetComments.stream()
|
List<SheetComment> children = sheetComments.stream()
|
||||||
.filter(sheetComment -> Objects.equals(oldParentId, sheetComment.getParentId()))
|
.filter(sheetComment -> Objects.equals(oldParentId, sheetComment.getParentId()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// Set parent id again
|
// Set parent id again
|
||||||
children.forEach(postComment -> postComment.setParentId(parentComment.getId()));
|
children.forEach(postComment -> postComment.setParentId(parentComment.getId()));
|
||||||
|
|
|
@ -8,7 +8,7 @@ import java.lang.annotation.*;
|
||||||
* @author guqing
|
* @author guqing
|
||||||
* @date 2020-1-19 13:51
|
* @date 2020-1-19 13:51
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.FIELD, ElementType.TYPE})
|
@Target(value = {ElementType.FIELD, ElementType.TYPE})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
public @interface PropertyMappingTo {
|
public @interface PropertyMappingTo {
|
||||||
|
|
|
@ -114,7 +114,7 @@ public class RelationMapperUtils {
|
||||||
|
|
||||||
// Common situation
|
// Common situation
|
||||||
fieldName = methodType + fieldName.substring(0, 1).toUpperCase() +
|
fieldName = methodType + fieldName.substring(0, 1).toUpperCase() +
|
||||||
fieldName.substring(1);
|
fieldName.substring(1);
|
||||||
return fieldName;
|
return fieldName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class YamlThemeConfigResolverImpl implements ThemeConfigResolver {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map tabMap = ((Map) tabYaml);
|
Map tabMap = (Map) tabYaml;
|
||||||
|
|
||||||
Group group = new Group();
|
Group group = new Group();
|
||||||
|
|
||||||
|
|
|
@ -78,12 +78,12 @@ public class StartedListener implements ApplicationListener<ApplicationStartedEv
|
||||||
private void migrate() {
|
private void migrate() {
|
||||||
log.info("Starting migrate database...");
|
log.info("Starting migrate database...");
|
||||||
Flyway flyway = Flyway
|
Flyway flyway = Flyway
|
||||||
.configure()
|
.configure()
|
||||||
.locations("classpath:/migration")
|
.locations("classpath:/migration")
|
||||||
.baselineVersion("1")
|
.baselineVersion("1")
|
||||||
.baselineOnMigrate(true)
|
.baselineOnMigrate(true)
|
||||||
.dataSource(url, username, password)
|
.dataSource(url, username, password)
|
||||||
.load();
|
.load();
|
||||||
flyway.migrate();
|
flyway.migrate();
|
||||||
log.info("Migrate database succeed.");
|
log.info("Migrate database succeed.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,8 +96,8 @@ public class CommentEventListener {
|
||||||
data.put("content", postComment.getContent());
|
data.put("content", postComment.getContent());
|
||||||
|
|
||||||
subject.append("您的博客文章《")
|
subject.append("您的博客文章《")
|
||||||
.append(post.getTitle())
|
.append(post.getTitle())
|
||||||
.append("》有了新的评论。");
|
.append("》有了新的评论。");
|
||||||
|
|
||||||
} else if (newEvent.getSource() instanceof SheetCommentService) {
|
} else if (newEvent.getSource() instanceof SheetCommentService) {
|
||||||
SheetComment sheetComment = sheetCommentService.getById(newEvent.getCommentId());
|
SheetComment sheetComment = sheetCommentService.getById(newEvent.getCommentId());
|
||||||
|
@ -112,8 +112,8 @@ public class CommentEventListener {
|
||||||
data.put("content", sheetComment.getContent());
|
data.put("content", sheetComment.getContent());
|
||||||
|
|
||||||
subject.append("您的博客页面《")
|
subject.append("您的博客页面《")
|
||||||
.append(sheet.getTitle())
|
.append(sheet.getTitle())
|
||||||
.append("》有了新的评论。");
|
.append("》有了新的评论。");
|
||||||
} else if (newEvent.getSource() instanceof JournalCommentService) {
|
} else if (newEvent.getSource() instanceof JournalCommentService) {
|
||||||
JournalComment journalComment = journalCommentService.getById(newEvent.getCommentId());
|
JournalComment journalComment = journalCommentService.getById(newEvent.getCommentId());
|
||||||
|
|
||||||
|
@ -186,10 +186,10 @@ public class CommentEventListener {
|
||||||
data.put("replyContent", postComment.getContent());
|
data.put("replyContent", postComment.getContent());
|
||||||
|
|
||||||
subject.append("您在【")
|
subject.append("您在【")
|
||||||
.append(blogTitle)
|
.append(blogTitle)
|
||||||
.append("】评论的文章《")
|
.append("】评论的文章《")
|
||||||
.append(post.getTitle())
|
.append(post.getTitle())
|
||||||
.append("》有了新的评论。");
|
.append("》有了新的评论。");
|
||||||
} else if (replyEvent.getSource() instanceof SheetCommentService) {
|
} else if (replyEvent.getSource() instanceof SheetCommentService) {
|
||||||
|
|
||||||
SheetComment sheetComment = sheetCommentService.getById(replyEvent.getCommentId());
|
SheetComment sheetComment = sheetCommentService.getById(replyEvent.getCommentId());
|
||||||
|
@ -216,10 +216,10 @@ public class CommentEventListener {
|
||||||
data.put("replyContent", sheetComment.getContent());
|
data.put("replyContent", sheetComment.getContent());
|
||||||
|
|
||||||
subject.append("您在【")
|
subject.append("您在【")
|
||||||
.append(blogTitle)
|
.append(blogTitle)
|
||||||
.append("】评论的页面《")
|
.append("】评论的页面《")
|
||||||
.append(sheet.getTitle())
|
.append(sheet.getTitle())
|
||||||
.append("》有了新的评论。");
|
.append("》有了新的评论。");
|
||||||
} else if (replyEvent.getSource() instanceof JournalCommentService) {
|
} else if (replyEvent.getSource() instanceof JournalCommentService) {
|
||||||
JournalComment journalComment = journalCommentService.getById(replyEvent.getCommentId());
|
JournalComment journalComment = journalCommentService.getById(replyEvent.getCommentId());
|
||||||
|
|
||||||
|
@ -248,9 +248,9 @@ public class CommentEventListener {
|
||||||
data.put("replyContent", journalComment.getContent());
|
data.put("replyContent", journalComment.getContent());
|
||||||
|
|
||||||
subject.append("您在【")
|
subject.append("您在【")
|
||||||
.append(blogTitle)
|
.append(blogTitle)
|
||||||
.append("】评论的日志")
|
.append("】评论的日志")
|
||||||
.append("有了新的评论。");
|
.append("有了新的评论。");
|
||||||
}
|
}
|
||||||
|
|
||||||
mailService.sendTemplateMail(baseAuthorEmail, subject.toString(), data, "common/mail_template/mail_reply.ftl");
|
mailService.sendTemplateMail(baseAuthorEmail, subject.toString(), data, "common/mail_template/mail_reply.ftl");
|
||||||
|
|
|
@ -29,15 +29,10 @@ import java.util.concurrent.Executors;
|
||||||
public abstract class AbstractMailService implements MailService {
|
public abstract class AbstractMailService implements MailService {
|
||||||
|
|
||||||
private static final int DEFAULT_POOL_SIZE = 5;
|
private static final int DEFAULT_POOL_SIZE = 5;
|
||||||
|
|
||||||
private JavaMailSender cachedMailSender;
|
|
||||||
|
|
||||||
private MailProperties cachedMailProperties;
|
|
||||||
|
|
||||||
private String cachedFromName;
|
|
||||||
|
|
||||||
protected final OptionService optionService;
|
protected final OptionService optionService;
|
||||||
|
private JavaMailSender cachedMailSender;
|
||||||
|
private MailProperties cachedMailProperties;
|
||||||
|
private String cachedFromName;
|
||||||
@Nullable
|
@Nullable
|
||||||
private ExecutorService executorService;
|
private ExecutorService executorService;
|
||||||
|
|
||||||
|
@ -45,10 +40,6 @@ public abstract class AbstractMailService implements MailService {
|
||||||
this.optionService = optionService;
|
this.optionService = optionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExecutorService(ExecutorService executorService) {
|
|
||||||
this.executorService = executorService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public ExecutorService getExecutorService() {
|
public ExecutorService getExecutorService() {
|
||||||
if (this.executorService == null) {
|
if (this.executorService == null) {
|
||||||
|
@ -57,6 +48,10 @@ public abstract class AbstractMailService implements MailService {
|
||||||
return executorService;
|
return executorService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setExecutorService(ExecutorService executorService) {
|
||||||
|
this.executorService = executorService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test connection with email server.
|
* Test connection with email server.
|
||||||
*/
|
*/
|
||||||
|
@ -111,9 +106,9 @@ public abstract class AbstractMailService implements MailService {
|
||||||
mailSender.send(mimeMessage);
|
mailSender.send(mimeMessage);
|
||||||
|
|
||||||
log.info("Sent an email to [{}] successfully, subject: [{}], sent date: [{}]",
|
log.info("Sent an email to [{}] successfully, subject: [{}], sent date: [{}]",
|
||||||
Arrays.toString(mimeMessage.getAllRecipients()),
|
Arrays.toString(mimeMessage.getAllRecipients()),
|
||||||
mimeMessage.getSubject(),
|
mimeMessage.getSubject(),
|
||||||
mimeMessage.getSentDate());
|
mimeMessage.getSentDate());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new EmailException("邮件发送失败,请检查 SMTP 服务配置是否正确", e);
|
throw new EmailException("邮件发送失败,请检查 SMTP 服务配置是否正确", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,15 +34,15 @@ public class MailProperties extends org.springframework.boot.autoconfigure.mail.
|
||||||
properties.put(key, value);
|
properties.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProperties(Map<String, String> properties) {
|
|
||||||
this.properties = properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getProperties() {
|
public Map<String, String> getProperties() {
|
||||||
return this.properties;
|
return this.properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProperties(Map<String, String> properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final String lineSuffix = ",\n";
|
final String lineSuffix = ",\n";
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class MailServiceImpl extends AbstractMailService implements ApplicationL
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendAttachMail(String to, String subject, Map<String, Object> content, String templateName, String attachFilePath) {
|
public void sendAttachMail(String to, String subject, Map<String, Object> content, String templateName, String attachFilePath) {
|
||||||
sendMailTemplate(true, (messageHelper) -> {
|
sendMailTemplate(true, messageHelper -> {
|
||||||
messageHelper.setSubject(subject);
|
messageHelper.setSubject(subject);
|
||||||
messageHelper.setTo(to);
|
messageHelper.setTo(to);
|
||||||
Path attachmentPath = Paths.get(attachFilePath);
|
Path attachmentPath = Paths.get(attachFilePath);
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class PostCategory extends BaseEntity {
|
||||||
}
|
}
|
||||||
PostCategory that = (PostCategory) o;
|
PostCategory that = (PostCategory) o;
|
||||||
return categoryId.equals(that.categoryId) &&
|
return categoryId.equals(that.categoryId) &&
|
||||||
postId.equals(that.postId);
|
postId.equals(that.postId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class PostTag extends BaseEntity {
|
||||||
}
|
}
|
||||||
PostTag postTag = (PostTag) o;
|
PostTag postTag = (PostTag) o;
|
||||||
return Objects.equals(postId, postTag.postId) &&
|
return Objects.equals(postId, postTag.postId) &&
|
||||||
Objects.equals(tagId, postTag.tagId);
|
Objects.equals(tagId, postTag.tagId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,8 +13,7 @@ public enum BanStatusEnum {
|
||||||
/**
|
/**
|
||||||
* 封禁状态
|
* 封禁状态
|
||||||
*/
|
*/
|
||||||
NORMAL(0),
|
NORMAL(0);
|
||||||
;
|
|
||||||
|
|
||||||
private int status;
|
private int status;
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,7 @@ public enum CommentViolationTypeEnum {
|
||||||
/**
|
/**
|
||||||
* 频繁
|
* 频繁
|
||||||
*/
|
*/
|
||||||
FREQUENTLY(1),
|
FREQUENTLY(1);
|
||||||
;
|
|
||||||
|
|
||||||
private int type;
|
private int type;
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,9 @@ public interface ValueEnum<T> {
|
||||||
Assert.isTrue(enumType.isEnum(), "type must be an enum type");
|
Assert.isTrue(enumType.isEnum(), "type must be an enum type");
|
||||||
|
|
||||||
return Stream.of(enumType.getEnumConstants())
|
return Stream.of(enumType.getEnumConstants())
|
||||||
.filter(item -> item.getValue().equals(value))
|
.filter(item -> item.getValue().equals(value))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseThrow(() -> new IllegalArgumentException("unknown database value: " + value));
|
.orElseThrow(() -> new IllegalArgumentException("unknown database value: " + value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,40 +20,6 @@ import java.util.Map;
|
||||||
public interface PropertyEnum extends ValueEnum<String> {
|
public interface PropertyEnum extends ValueEnum<String> {
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get property type.
|
|
||||||
*
|
|
||||||
* @return property type
|
|
||||||
*/
|
|
||||||
Class<?> getType();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default value.
|
|
||||||
*
|
|
||||||
* @return default value
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
String defaultValue();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default value with given type.
|
|
||||||
*
|
|
||||||
* @param propertyType property type must not be null
|
|
||||||
* @param <T> property type
|
|
||||||
* @return default value with given type
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default <T> T defaultValue(Class<T> propertyType) {
|
|
||||||
// Get default value
|
|
||||||
String defaultValue = defaultValue();
|
|
||||||
if (defaultValue == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert to the given type
|
|
||||||
return PropertyEnum.convertTo(defaultValue, propertyType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts to value with corresponding type
|
* Converts to value with corresponding type
|
||||||
*
|
*
|
||||||
|
@ -160,19 +126,20 @@ public interface PropertyEnum extends ValueEnum<String> {
|
||||||
* @return true if supports; false else
|
* @return true if supports; false else
|
||||||
*/
|
*/
|
||||||
static boolean isSupportedType(Class<?> type) {
|
static boolean isSupportedType(Class<?> type) {
|
||||||
return type != null && (
|
if (type == null) {
|
||||||
type.isAssignableFrom(String.class)
|
return false;
|
||||||
|| type.isAssignableFrom(Number.class)
|
}
|
||||||
|| type.isAssignableFrom(Integer.class)
|
return type.isAssignableFrom(String.class)
|
||||||
|| type.isAssignableFrom(Long.class)
|
|| type.isAssignableFrom(Number.class)
|
||||||
|| type.isAssignableFrom(Boolean.class)
|
|| type.isAssignableFrom(Integer.class)
|
||||||
|| type.isAssignableFrom(Short.class)
|
|| type.isAssignableFrom(Long.class)
|
||||||
|| type.isAssignableFrom(Byte.class)
|
|| type.isAssignableFrom(Boolean.class)
|
||||||
|| type.isAssignableFrom(Double.class)
|
|| type.isAssignableFrom(Short.class)
|
||||||
|| type.isAssignableFrom(Float.class)
|
|| type.isAssignableFrom(Byte.class)
|
||||||
|| type.isAssignableFrom(Enum.class)
|
|| type.isAssignableFrom(Double.class)
|
||||||
|| type.isAssignableFrom(ValueEnum.class)
|
|| type.isAssignableFrom(Float.class)
|
||||||
);
|
|| type.isAssignableFrom(Enum.class)
|
||||||
|
|| type.isAssignableFrom(ValueEnum.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, PropertyEnum> getValuePropertyEnumMap() {
|
static Map<String, PropertyEnum> getValuePropertyEnumMap() {
|
||||||
|
@ -209,4 +176,38 @@ public interface PropertyEnum extends ValueEnum<String> {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get property type.
|
||||||
|
*
|
||||||
|
* @return property type
|
||||||
|
*/
|
||||||
|
Class<?> getType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default value.
|
||||||
|
*
|
||||||
|
* @return default value
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String defaultValue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default value with given type.
|
||||||
|
*
|
||||||
|
* @param propertyType property type must not be null
|
||||||
|
* @param <T> property type
|
||||||
|
* @return default value with given type
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default <T> T defaultValue(Class<T> propertyType) {
|
||||||
|
// Get default value
|
||||||
|
String defaultValue = defaultValue();
|
||||||
|
if (defaultValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to the given type
|
||||||
|
return PropertyEnum.convertTo(defaultValue, propertyType);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package run.halo.app.model.support;
|
|
||||||
|
|
||||||
import javax.validation.GroupSequence;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All check for hibernate validation.
|
|
||||||
*
|
|
||||||
* @author johnniang
|
|
||||||
* @date 19-4-28
|
|
||||||
*/
|
|
||||||
@GroupSequence({CreateCheck.class, UpdateCheck.class})
|
|
||||||
public interface AllCheck {
|
|
||||||
}
|
|
|
@ -26,8 +26,8 @@ public interface JournalCommentRepository extends BaseCommentRepository<JournalC
|
||||||
* @return a list of CommentCountProjection
|
* @return a list of CommentCountProjection
|
||||||
*/
|
*/
|
||||||
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) " +
|
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) " +
|
||||||
"from JournalComment comment " +
|
"from JournalComment comment " +
|
||||||
"where comment.postId in ?1 group by comment.postId")
|
"where comment.postId in ?1 group by comment.postId")
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
List<CommentCountProjection> countByPostIds(@NonNull Collection<Integer> postIds);
|
List<CommentCountProjection> countByPostIds(@NonNull Collection<Integer> postIds);
|
||||||
|
@ -39,9 +39,9 @@ public interface JournalCommentRepository extends BaseCommentRepository<JournalC
|
||||||
* @return a list of CommentChildrenCountProjection
|
* @return a list of CommentChildrenCountProjection
|
||||||
*/
|
*/
|
||||||
@Query("select new run.halo.app.model.projection.CommentChildrenCountProjection(count(comment.id), comment.parentId) " +
|
@Query("select new run.halo.app.model.projection.CommentChildrenCountProjection(count(comment.id), comment.parentId) " +
|
||||||
"from JournalComment comment " +
|
"from JournalComment comment " +
|
||||||
"where comment.parentId in ?1 " +
|
"where comment.parentId in ?1 " +
|
||||||
"group by comment.parentId")
|
"group by comment.parentId")
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
List<CommentChildrenCountProjection> findDirectChildrenCount(@NonNull Collection<Long> commentIds);
|
List<CommentChildrenCountProjection> findDirectChildrenCount(@NonNull Collection<Long> commentIds);
|
||||||
|
|
|
@ -27,8 +27,8 @@ public interface PostCommentRepository extends BaseCommentRepository<PostComment
|
||||||
* @return a list of CommentCountProjection
|
* @return a list of CommentCountProjection
|
||||||
*/
|
*/
|
||||||
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) " +
|
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) " +
|
||||||
"from PostComment comment " +
|
"from PostComment comment " +
|
||||||
"where comment.postId in ?1 group by comment.postId")
|
"where comment.postId in ?1 group by comment.postId")
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
List<CommentCountProjection> countByPostIds(@NonNull Collection<Integer> postIds);
|
List<CommentCountProjection> countByPostIds(@NonNull Collection<Integer> postIds);
|
||||||
|
@ -40,9 +40,9 @@ public interface PostCommentRepository extends BaseCommentRepository<PostComment
|
||||||
* @return a list of CommentChildrenCountProjection
|
* @return a list of CommentChildrenCountProjection
|
||||||
*/
|
*/
|
||||||
@Query("select new run.halo.app.model.projection.CommentChildrenCountProjection(count(comment.id), comment.parentId) " +
|
@Query("select new run.halo.app.model.projection.CommentChildrenCountProjection(count(comment.id), comment.parentId) " +
|
||||||
"from PostComment comment " +
|
"from PostComment comment " +
|
||||||
"where comment.parentId in ?1 " +
|
"where comment.parentId in ?1 " +
|
||||||
"group by comment.parentId")
|
"group by comment.parentId")
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
List<CommentChildrenCountProjection> findDirectChildrenCount(@NonNull Collection<Long> commentIds);
|
List<CommentChildrenCountProjection> findDirectChildrenCount(@NonNull Collection<Long> commentIds);
|
||||||
|
|
|
@ -26,8 +26,8 @@ public interface SheetCommentRepository extends BaseCommentRepository<SheetComme
|
||||||
* @return a list of CommentCountProjection
|
* @return a list of CommentCountProjection
|
||||||
*/
|
*/
|
||||||
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) " +
|
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) " +
|
||||||
"from SheetComment comment " +
|
"from SheetComment comment " +
|
||||||
"where comment.postId in ?1 group by comment.postId")
|
"where comment.postId in ?1 group by comment.postId")
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
List<CommentCountProjection> countByPostIds(@NonNull Collection<Integer> sheetIds);
|
List<CommentCountProjection> countByPostIds(@NonNull Collection<Integer> sheetIds);
|
||||||
|
@ -39,9 +39,9 @@ public interface SheetCommentRepository extends BaseCommentRepository<SheetComme
|
||||||
* @return a list of CommentChildrenCountProjection
|
* @return a list of CommentChildrenCountProjection
|
||||||
*/
|
*/
|
||||||
@Query("select new run.halo.app.model.projection.CommentChildrenCountProjection(count(comment.id), comment.parentId) " +
|
@Query("select new run.halo.app.model.projection.CommentChildrenCountProjection(count(comment.id), comment.parentId) " +
|
||||||
"from SheetComment comment " +
|
"from SheetComment comment " +
|
||||||
"where comment.parentId in ?1 " +
|
"where comment.parentId in ?1 " +
|
||||||
"group by comment.parentId")
|
"group by comment.parentId")
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
List<CommentChildrenCountProjection> findDirectChildrenCount(@NonNull Collection<Long> commentIds);
|
List<CommentChildrenCountProjection> findDirectChildrenCount(@NonNull Collection<Long> commentIds);
|
||||||
|
|
|
@ -61,9 +61,9 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
|
||||||
* @return a list of comment count
|
* @return a list of comment count
|
||||||
*/
|
*/
|
||||||
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) " +
|
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) " +
|
||||||
"from BaseComment comment " +
|
"from BaseComment comment " +
|
||||||
"where comment.postId in ?1 " +
|
"where comment.postId in ?1 " +
|
||||||
"group by comment.postId")
|
"group by comment.postId")
|
||||||
@NonNull
|
@NonNull
|
||||||
List<CommentCountProjection> countByPostIds(@NonNull Collection<Integer> postIds);
|
List<CommentCountProjection> countByPostIds(@NonNull Collection<Integer> postIds);
|
||||||
|
|
||||||
|
@ -181,9 +181,9 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
|
||||||
* @return a list of CommentChildrenCountProjection
|
* @return a list of CommentChildrenCountProjection
|
||||||
*/
|
*/
|
||||||
@Query("select new run.halo.app.model.projection.CommentChildrenCountProjection(count(comment.id), comment.parentId) " +
|
@Query("select new run.halo.app.model.projection.CommentChildrenCountProjection(count(comment.id), comment.parentId) " +
|
||||||
"from BaseComment comment " +
|
"from BaseComment comment " +
|
||||||
"where comment.parentId in ?1 " +
|
"where comment.parentId in ?1 " +
|
||||||
"group by comment.parentId")
|
"group by comment.parentId")
|
||||||
@NonNull
|
@NonNull
|
||||||
List<CommentChildrenCountProjection> findDirectChildrenCount(@NonNull Collection<Long> commentIds);
|
List<CommentChildrenCountProjection> findDirectChildrenCount(@NonNull Collection<Long> commentIds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,8 +110,8 @@ public class BaseRepositoryImpl<DOMAIN, ID> extends SimpleJpaRepository<DOMAIN,
|
||||||
TypedQuery<Long> countQuery = getCountQuery(specification, getDomainClass()).setParameter(specification.parameter, ids);
|
TypedQuery<Long> countQuery = getCountQuery(specification, getDomainClass()).setParameter(specification.parameter, ids);
|
||||||
|
|
||||||
return pageable.isUnpaged() ?
|
return pageable.isUnpaged() ?
|
||||||
new PageImpl<>(query.getResultList())
|
new PageImpl<>(query.getResultList())
|
||||||
: readPage(query, getDomainClass(), pageable, countQuery);
|
: readPage(query, getDomainClass(), pageable, countQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,7 +143,7 @@ public class BaseRepositoryImpl<DOMAIN, ID> extends SimpleJpaRepository<DOMAIN,
|
||||||
}
|
}
|
||||||
|
|
||||||
return PageableExecutionUtils.getPage(query.getResultList(), pageable,
|
return PageableExecutionUtils.getPage(query.getResultList(), pageable,
|
||||||
() -> executeCountQuery(countQuery));
|
() -> executeCountQuery(countQuery));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class ByIdsSpecification<T> implements Specification<T> {
|
private static final class ByIdsSpecification<T> implements Specification<T> {
|
||||||
|
|
|
@ -197,7 +197,7 @@ public abstract class AbstractAuthenticationFilter extends OncePerRequestFilter
|
||||||
|
|
||||||
// Get allowed uri
|
// Get allowed uri
|
||||||
String allowedUri = oneTimeTokenService.get(oneTimeToken)
|
String allowedUri = oneTimeTokenService.get(oneTimeToken)
|
||||||
.orElseThrow(() -> new BadRequestException("The one-time token does not exist").setErrorData(oneTimeToken));
|
.orElseThrow(() -> new BadRequestException("The one-time token does not exist").setErrorData(oneTimeToken));
|
||||||
|
|
||||||
// Get request uri
|
// Get request uri
|
||||||
String requestUri = request.getRequestURI();
|
String requestUri = request.getRequestURI();
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class AdminAuthenticationFilter extends AbstractAuthenticationFilter {
|
||||||
if (!haloProperties.isAuthEnabled()) {
|
if (!haloProperties.isAuthEnabled()) {
|
||||||
// Set security
|
// Set security
|
||||||
userService.getCurrentUser().ifPresent(user ->
|
userService.getCurrentUser().ifPresent(user ->
|
||||||
SecurityContextHolder.setContext(new SecurityContextImpl(new AuthenticationImpl(new UserDetail(user)))));
|
SecurityContextHolder.setContext(new SecurityContextImpl(new AuthenticationImpl(new UserDetail(user)))));
|
||||||
|
|
||||||
// Do filter
|
// Do filter
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
|
|
|
@ -31,9 +31,9 @@ public class AuthenticationArgumentResolver implements HandlerMethodArgumentReso
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsParameter(MethodParameter parameter) {
|
public boolean supportsParameter(MethodParameter parameter) {
|
||||||
Class<?> parameterType = parameter.getParameterType();
|
Class<?> parameterType = parameter.getParameterType();
|
||||||
return (Authentication.class.isAssignableFrom(parameterType) ||
|
return Authentication.class.isAssignableFrom(parameterType)
|
||||||
UserDetail.class.isAssignableFrom(parameterType) ||
|
|| UserDetail.class.isAssignableFrom(parameterType)
|
||||||
User.class.isAssignableFrom(parameterType));
|
|| User.class.isAssignableFrom(parameterType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -44,7 +44,7 @@ public class AuthenticationArgumentResolver implements HandlerMethodArgumentReso
|
||||||
Class<?> parameterType = parameter.getParameterType();
|
Class<?> parameterType = parameter.getParameterType();
|
||||||
|
|
||||||
Authentication authentication = Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
|
Authentication authentication = Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
|
||||||
.orElseThrow(() -> new AuthenticationException("You haven't signed in yet"));
|
.orElseThrow(() -> new AuthenticationException("You haven't signed in yet"));
|
||||||
|
|
||||||
if (Authentication.class.isAssignableFrom(parameterType)) {
|
if (Authentication.class.isAssignableFrom(parameterType)) {
|
||||||
return authentication;
|
return authentication;
|
||||||
|
|
|
@ -89,7 +89,6 @@ public interface BaseCommentService<COMMENT extends BaseComment> extends CrudSer
|
||||||
*
|
*
|
||||||
* @param postId post id must not be null
|
* @param postId post id must not be null
|
||||||
* @param pageable page info must not be null
|
* @param pageable page info must not be null
|
||||||
* @param status status must not be null
|
|
||||||
* @return a page of comment vo
|
* @return a page of comment vo
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@ -153,12 +152,12 @@ public interface BaseCommentService<COMMENT extends BaseComment> extends CrudSer
|
||||||
/**
|
/**
|
||||||
* Creates a comment by comment.
|
* Creates a comment by comment.
|
||||||
*
|
*
|
||||||
* @param COMMENT comment must not be null
|
* @param comment comment must not be null
|
||||||
* @return created comment
|
* @return created comment
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
COMMENT create(@NonNull COMMENT COMMENT);
|
COMMENT create(@NonNull COMMENT comment);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a comment by comment param.
|
* Creates a comment by comment param.
|
||||||
|
|
|
@ -145,7 +145,7 @@ public class AdminServiceImpl implements AdminService {
|
||||||
try {
|
try {
|
||||||
// Get user by username or email
|
// Get user by username or email
|
||||||
user = Validator.isEmail(username) ?
|
user = Validator.isEmail(username) ?
|
||||||
userService.getByEmailOfNonNull(username) : userService.getByUsernameOfNonNull(username);
|
userService.getByEmailOfNonNull(username) : userService.getByUsernameOfNonNull(username);
|
||||||
} catch (NotFoundException e) {
|
} catch (NotFoundException e) {
|
||||||
log.error("Failed to find user by name: " + username, e);
|
log.error("Failed to find user by name: " + username, e);
|
||||||
eventPublisher.publishEvent(new LogEvent(this, loginParam.getUsername(), LogType.LOGIN_FAILED, loginParam.getUsername()));
|
eventPublisher.publishEvent(new LogEvent(this, loginParam.getUsername(), LogType.LOGIN_FAILED, loginParam.getUsername()));
|
||||||
|
@ -311,14 +311,14 @@ public class AdminServiceImpl implements AdminService {
|
||||||
Assert.hasText(refreshToken, "Refresh token must not be blank");
|
Assert.hasText(refreshToken, "Refresh token must not be blank");
|
||||||
|
|
||||||
Integer userId = cacheStore.getAny(SecurityUtils.buildTokenRefreshKey(refreshToken), Integer.class)
|
Integer userId = cacheStore.getAny(SecurityUtils.buildTokenRefreshKey(refreshToken), Integer.class)
|
||||||
.orElseThrow(() -> new BadRequestException("登录状态已失效,请重新登录").setErrorData(refreshToken));
|
.orElseThrow(() -> new BadRequestException("登录状态已失效,请重新登录").setErrorData(refreshToken));
|
||||||
|
|
||||||
// Get user info
|
// Get user info
|
||||||
User user = userService.getById(userId);
|
User user = userService.getById(userId);
|
||||||
|
|
||||||
// Remove all token
|
// Remove all token
|
||||||
cacheStore.getAny(SecurityUtils.buildAccessTokenKey(user), String.class)
|
cacheStore.getAny(SecurityUtils.buildAccessTokenKey(user), String.class)
|
||||||
.ifPresent(accessToken -> cacheStore.delete(SecurityUtils.buildTokenAccessKey(accessToken)));
|
.ifPresent(accessToken -> cacheStore.delete(SecurityUtils.buildTokenAccessKey(accessToken)));
|
||||||
cacheStore.delete(SecurityUtils.buildTokenRefreshKey(refreshToken));
|
cacheStore.delete(SecurityUtils.buildTokenRefreshKey(refreshToken));
|
||||||
cacheStore.delete(SecurityUtils.buildAccessTokenKey(user));
|
cacheStore.delete(SecurityUtils.buildAccessTokenKey(user));
|
||||||
cacheStore.delete(SecurityUtils.buildRefreshTokenKey(user));
|
cacheStore.delete(SecurityUtils.buildRefreshTokenKey(user));
|
||||||
|
@ -333,8 +333,8 @@ public class AdminServiceImpl implements AdminService {
|
||||||
ResponseEntity<Map> responseEntity = restTemplate.getForEntity(HaloConst.HALO_ADMIN_RELEASES_LATEST, Map.class);
|
ResponseEntity<Map> responseEntity = restTemplate.getForEntity(HaloConst.HALO_ADMIN_RELEASES_LATEST, Map.class);
|
||||||
|
|
||||||
if (responseEntity == null ||
|
if (responseEntity == null ||
|
||||||
responseEntity.getStatusCode().isError() ||
|
responseEntity.getStatusCode().isError() ||
|
||||||
responseEntity.getBody() == null) {
|
responseEntity.getBody() == null) {
|
||||||
log.debug("Failed to request remote url: [{}]", HALO_ADMIN_RELEASES_LATEST);
|
log.debug("Failed to request remote url: [{}]", HALO_ADMIN_RELEASES_LATEST);
|
||||||
throw new ServiceException("系统无法访问到 Github 的 API").setErrorData(HALO_ADMIN_RELEASES_LATEST);
|
throw new ServiceException("系统无法访问到 Github 的 API").setErrorData(HALO_ADMIN_RELEASES_LATEST);
|
||||||
}
|
}
|
||||||
|
@ -348,17 +348,17 @@ public class AdminServiceImpl implements AdminService {
|
||||||
try {
|
try {
|
||||||
List assets = (List) assetsObject;
|
List assets = (List) assetsObject;
|
||||||
Map assetMap = (Map) assets.stream()
|
Map assetMap = (Map) assets.stream()
|
||||||
.filter(assetPredicate())
|
.filter(assetPredicate())
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseThrow(() -> new ServiceException("Halo admin 最新版暂无资源文件,请稍后再试"));
|
.orElseThrow(() -> new ServiceException("Halo admin 最新版暂无资源文件,请稍后再试"));
|
||||||
|
|
||||||
Object browserDownloadUrl = assetMap.getOrDefault("browser_download_url", "");
|
Object browserDownloadUrl = assetMap.getOrDefault("browser_download_url", "");
|
||||||
// Download the assets
|
// Download the assets
|
||||||
ResponseEntity<byte[]> downloadResponseEntity = restTemplate.getForEntity(browserDownloadUrl.toString(), byte[].class);
|
ResponseEntity<byte[]> downloadResponseEntity = restTemplate.getForEntity(browserDownloadUrl.toString(), byte[].class);
|
||||||
|
|
||||||
if (downloadResponseEntity == null ||
|
if (downloadResponseEntity == null ||
|
||||||
downloadResponseEntity.getStatusCode().isError() ||
|
downloadResponseEntity.getStatusCode().isError() ||
|
||||||
downloadResponseEntity.getBody() == null) {
|
downloadResponseEntity.getBody() == null) {
|
||||||
throw new ServiceException("Failed to request remote url: " + browserDownloadUrl.toString()).setErrorData(browserDownloadUrl.toString());
|
throw new ServiceException("Failed to request remote url: " + browserDownloadUrl.toString()).setErrorData(browserDownloadUrl.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ public class AdminServiceImpl implements AdminService {
|
||||||
|
|
||||||
// Create temp folder
|
// Create temp folder
|
||||||
Path assetTempPath = FileUtils.createTempDirectory()
|
Path assetTempPath = FileUtils.createTempDirectory()
|
||||||
.resolve(assetMap.getOrDefault("name", "halo-admin-latest.zip").toString());
|
.resolve(assetMap.getOrDefault("name", "halo-admin-latest.zip").toString());
|
||||||
|
|
||||||
// Unzip
|
// Unzip
|
||||||
FileUtils.unzip(downloadResponseEntity.getBody(), assetTempPath);
|
FileUtils.unzip(downloadResponseEntity.getBody(), assetTempPath);
|
||||||
|
@ -526,7 +526,7 @@ public class AdminServiceImpl implements AdminService {
|
||||||
|
|
||||||
linesArray.forEach(line -> {
|
linesArray.forEach(line -> {
|
||||||
result.append(line)
|
result.append(line)
|
||||||
.append(StringUtils.LF);
|
.append(StringUtils.LF);
|
||||||
});
|
});
|
||||||
|
|
||||||
return result.toString();
|
return result.toString();
|
||||||
|
|
|
@ -88,9 +88,9 @@ public class BackupServiceImpl implements BackupService {
|
||||||
*/
|
*/
|
||||||
public static String sanitizeFilename(final String unSanitized) {
|
public static String sanitizeFilename(final String unSanitized) {
|
||||||
return unSanitized.
|
return unSanitized.
|
||||||
replaceAll("[^(a-zA-Z0-9\\u4e00-\\u9fa5\\.)]", "").
|
replaceAll("[^(a-zA-Z0-9\\u4e00-\\u9fa5\\.)]", "").
|
||||||
replaceAll("[\\?\\\\/:|<>\\*\\[\\]\\(\\)\\$%\\{\\}@~\\.]", "").
|
replaceAll("[\\?\\\\/:|<>\\*\\[\\]\\(\\)\\$%\\{\\}@~\\.]", "").
|
||||||
replaceAll("\\s", "");
|
replaceAll("\\s", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -170,8 +170,8 @@ public class BackupServiceImpl implements BackupService {
|
||||||
try {
|
try {
|
||||||
// Create zip path for halo zip
|
// Create zip path for halo zip
|
||||||
String haloZipFileName = HaloConst.HALO_BACKUP_PREFIX +
|
String haloZipFileName = HaloConst.HALO_BACKUP_PREFIX +
|
||||||
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss-")) +
|
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss-")) +
|
||||||
IdUtil.simpleUUID().hashCode() + ".zip";
|
IdUtil.simpleUUID().hashCode() + ".zip";
|
||||||
// Create halo zip file
|
// Create halo zip file
|
||||||
Path haloZipPath = Files.createFile(Paths.get(haloProperties.getBackupDir(), haloZipFileName));
|
Path haloZipPath = Files.createFile(Paths.get(haloProperties.getBackupDir(), haloZipFileName));
|
||||||
|
|
||||||
|
@ -196,17 +196,17 @@ public class BackupServiceImpl implements BackupService {
|
||||||
// Build backup dto
|
// Build backup dto
|
||||||
try (Stream<Path> subPathStream = Files.list(backupParentPath)) {
|
try (Stream<Path> subPathStream = Files.list(backupParentPath)) {
|
||||||
return subPathStream
|
return subPathStream
|
||||||
.filter(backupPath -> StringUtils.startsWithIgnoreCase(backupPath.getFileName().toString(), HaloConst.HALO_BACKUP_PREFIX))
|
.filter(backupPath -> StringUtils.startsWithIgnoreCase(backupPath.getFileName().toString(), HaloConst.HALO_BACKUP_PREFIX))
|
||||||
.map(this::buildBackupDto)
|
.map(this::buildBackupDto)
|
||||||
.sorted((leftBackup, rightBackup) -> {
|
.sorted((leftBackup, rightBackup) -> {
|
||||||
// Sort the result
|
// Sort the result
|
||||||
if (leftBackup.getUpdateTime() < rightBackup.getUpdateTime()) {
|
if (leftBackup.getUpdateTime() < rightBackup.getUpdateTime()) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (leftBackup.getUpdateTime() > rightBackup.getUpdateTime()) {
|
} else if (leftBackup.getUpdateTime() > rightBackup.getUpdateTime()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ServiceException("Failed to fetch backups", e);
|
throw new ServiceException("Failed to fetch backups", e);
|
||||||
}
|
}
|
||||||
|
@ -309,9 +309,9 @@ public class BackupServiceImpl implements BackupService {
|
||||||
|
|
||||||
// Build full url
|
// Build full url
|
||||||
return HaloUtils.compositeHttpUrl(optionService.getBlogBaseUrl(), backupUri)
|
return HaloUtils.compositeHttpUrl(optionService.getBlogBaseUrl(), backupUri)
|
||||||
+ "?"
|
+ "?"
|
||||||
+ HaloConst.ONE_TIME_TOKEN_QUERY_NAME
|
+ HaloConst.ONE_TIME_TOKEN_QUERY_NAME
|
||||||
+ "=" + oneTimeToken;
|
+ "=" + oneTimeToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -397,8 +397,8 @@ public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extend
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
return comments.stream()
|
return comments.stream()
|
||||||
.map(this::convertTo)
|
.map(this::convertTo)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -454,9 +454,9 @@ public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extend
|
||||||
|
|
||||||
// Get sort order
|
// Get sort order
|
||||||
Sort.Order order = sort.filter(anOrder -> "id".equals(anOrder.getProperty()))
|
Sort.Order order = sort.filter(anOrder -> "id".equals(anOrder.getProperty()))
|
||||||
.get()
|
.get()
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseGet(() -> Sort.Order.desc("id"));
|
.orElseGet(() -> Sort.Order.desc("id"));
|
||||||
|
|
||||||
// Init sign
|
// Init sign
|
||||||
int sign = order.getDirection().isAscending() ? 1 : -1;
|
int sign = order.getDirection().isAscending() ? 1 : -1;
|
||||||
|
@ -696,8 +696,8 @@ public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extend
|
||||||
|
|
||||||
// Get children
|
// Get children
|
||||||
List<COMMENT> children = comments.stream()
|
List<COMMENT> children = comments.stream()
|
||||||
.filter(comment -> Objects.equals(parentComment.getId(), comment.getParentId()))
|
.filter(comment -> Objects.equals(parentComment.getId(), comment.getParentId()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// Add children
|
// Add children
|
||||||
children.forEach(comment -> {
|
children.forEach(comment -> {
|
||||||
|
|
|
@ -80,7 +80,7 @@ public abstract class BaseMetaServiceImpl<META extends BaseMeta> extends Abstrac
|
||||||
|
|
||||||
// Foreach and collect
|
// Foreach and collect
|
||||||
postMetas.forEach(postMeta -> postMetaListMap.computeIfAbsent(postMeta.getPostId(), postId -> new LinkedList<>())
|
postMetas.forEach(postMeta -> postMetaListMap.computeIfAbsent(postMeta.getPostId(), postId -> new LinkedList<>())
|
||||||
.add(postMetaMap.get(postMeta.getId())));
|
.add(postMetaMap.get(postMeta.getId())));
|
||||||
|
|
||||||
return postMetaListMap;
|
return postMetaListMap;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ public abstract class BaseMetaServiceImpl<META extends BaseMeta> extends Abstrac
|
||||||
}
|
}
|
||||||
|
|
||||||
return postMetaList.stream()
|
return postMetaList.stream()
|
||||||
.map(this::convertTo)
|
.map(this::convertTo)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
|
||||||
|
|
||||||
private final OptionService optionService;
|
private final OptionService optionService;
|
||||||
|
|
||||||
private final Pattern SUMMARY_PATTERN = Pattern.compile("\\s*|\t|\r|\n");
|
private final Pattern summaryPattern = Pattern.compile("\\s*|\t|\r|\n");
|
||||||
|
|
||||||
public BasePostServiceImpl(BasePostRepository<POST> basePostRepository,
|
public BasePostServiceImpl(BasePostRepository<POST> basePostRepository,
|
||||||
OptionService optionService) {
|
OptionService optionService) {
|
||||||
|
@ -117,9 +117,9 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
|
||||||
Assert.notNull(date, "Date must not be null");
|
Assert.notNull(date, "Date must not be null");
|
||||||
|
|
||||||
return basePostRepository.findAllByStatusAndCreateTimeAfter(PostStatus.PUBLISHED,
|
return basePostRepository.findAllByStatusAndCreateTimeAfter(PostStatus.PUBLISHED,
|
||||||
date,
|
date,
|
||||||
PageRequest.of(0, size, Sort.by(ASC, "createTime")))
|
PageRequest.of(0, size, Sort.by(ASC, "createTime")))
|
||||||
.getContent();
|
.getContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -127,9 +127,9 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
|
||||||
Assert.notNull(date, "Date must not be null");
|
Assert.notNull(date, "Date must not be null");
|
||||||
|
|
||||||
return basePostRepository.findAllByStatusAndCreateTimeBefore(PostStatus.PUBLISHED,
|
return basePostRepository.findAllByStatusAndCreateTimeBefore(PostStatus.PUBLISHED,
|
||||||
date,
|
date,
|
||||||
PageRequest.of(0, size, Sort.by(DESC, "createTime")))
|
PageRequest.of(0, size, Sort.by(DESC, "createTime")))
|
||||||
.getContent();
|
.getContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -282,8 +282,8 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
|
||||||
}
|
}
|
||||||
|
|
||||||
return posts.stream()
|
return posts.stream()
|
||||||
.map(this::convertToMinimal)
|
.map(this::convertToMinimal)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -314,8 +314,8 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
|
||||||
}
|
}
|
||||||
|
|
||||||
return posts.stream()
|
return posts.stream()
|
||||||
.map(this::convertToSimple)
|
.map(this::convertToSimple)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -468,7 +468,7 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
|
||||||
|
|
||||||
String text = HaloUtils.cleanHtmlTag(htmlContent);
|
String text = HaloUtils.cleanHtmlTag(htmlContent);
|
||||||
|
|
||||||
Matcher matcher = SUMMARY_PATTERN.matcher(text);
|
Matcher matcher = summaryPattern.matcher(text);
|
||||||
text = matcher.replaceAll("");
|
text = matcher.replaceAll("");
|
||||||
|
|
||||||
// Get summary length
|
// Get summary length
|
||||||
|
|
|
@ -113,8 +113,8 @@ public class CategoryServiceImpl extends AbstractCrudService<Category, Integer>
|
||||||
|
|
||||||
// Get children for removing after
|
// Get children for removing after
|
||||||
List<Category> children = categories.stream()
|
List<Category> children = categories.stream()
|
||||||
.filter(category -> Objects.equal(parentCategory.getId(), category.getParentId()))
|
.filter(category -> Objects.equal(parentCategory.getId(), category.getParentId()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
children.forEach(category -> {
|
children.forEach(category -> {
|
||||||
// Convert to child category vo
|
// Convert to child category vo
|
||||||
|
@ -219,7 +219,7 @@ public class CategoryServiceImpl extends AbstractCrudService<Category, Integer>
|
||||||
}
|
}
|
||||||
|
|
||||||
return categories.stream()
|
return categories.stream()
|
||||||
.map(this::convertTo)
|
.map(this::convertTo)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import java.util.Optional;
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class CommentBlackListServiceImpl extends AbstractCrudService<CommentBlackList, Long> implements CommentBlackListService {
|
public class CommentBlackListServiceImpl extends AbstractCrudService<CommentBlackList, Long> implements CommentBlackListService {
|
||||||
private static ZoneId zoneId = ZoneId.of("Asia/Shanghai");
|
private static final ZoneId ZONE_ID = ZoneId.of("Asia/Shanghai");
|
||||||
private final CommentBlackListRepository commentBlackListRepository;
|
private final CommentBlackListRepository commentBlackListRepository;
|
||||||
private final PostCommentRepository postCommentRepository;
|
private final PostCommentRepository postCommentRepository;
|
||||||
private final OptionService optionService;
|
private final OptionService optionService;
|
||||||
|
@ -50,10 +50,10 @@ public class CommentBlackListServiceImpl extends AbstractCrudService<CommentBlac
|
||||||
*/
|
*/
|
||||||
Optional<CommentBlackList> blackList = commentBlackListRepository.findByIpAddress(ipAddress);
|
Optional<CommentBlackList> blackList = commentBlackListRepository.findByIpAddress(ipAddress);
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
Date endTime = new Date(now.atZone(zoneId).toInstant().toEpochMilli());
|
Date endTime = new Date(now.atZone(ZONE_ID).toInstant().toEpochMilli());
|
||||||
Integer banTime = optionService.getByPropertyOrDefault(CommentProperties.COMMENT_BAN_TIME, Integer.class, 10);
|
Integer banTime = optionService.getByPropertyOrDefault(CommentProperties.COMMENT_BAN_TIME, Integer.class, 10);
|
||||||
Date startTime = new Date(now.minusMinutes(banTime)
|
Date startTime = new Date(now.minusMinutes(banTime)
|
||||||
.atZone(zoneId).toInstant().toEpochMilli());
|
.atZone(ZONE_ID).toInstant().toEpochMilli());
|
||||||
Integer range = optionService.getByPropertyOrDefault(CommentProperties.COMMENT_RANGE, Integer.class, 30);
|
Integer range = optionService.getByPropertyOrDefault(CommentProperties.COMMENT_RANGE, Integer.class, 30);
|
||||||
boolean isPresent = postCommentRepository.countByIpAndTime(ipAddress, startTime, endTime) >= range;
|
boolean isPresent = postCommentRepository.countByIpAndTime(ipAddress, startTime, endTime) >= range;
|
||||||
if (isPresent && blackList.isPresent()) {
|
if (isPresent && blackList.isPresent()) {
|
||||||
|
@ -61,10 +61,10 @@ public class CommentBlackListServiceImpl extends AbstractCrudService<CommentBlac
|
||||||
return CommentViolationTypeEnum.FREQUENTLY;
|
return CommentViolationTypeEnum.FREQUENTLY;
|
||||||
} else if (isPresent) {
|
} else if (isPresent) {
|
||||||
CommentBlackList commentBlackList = CommentBlackList
|
CommentBlackList commentBlackList = CommentBlackList
|
||||||
.builder()
|
.builder()
|
||||||
.banTime(getBanTime(now, banTime))
|
.banTime(getBanTime(now, banTime))
|
||||||
.ipAddress(ipAddress)
|
.ipAddress(ipAddress)
|
||||||
.build();
|
.build();
|
||||||
super.create(commentBlackList);
|
super.create(commentBlackList);
|
||||||
return CommentViolationTypeEnum.FREQUENTLY;
|
return CommentViolationTypeEnum.FREQUENTLY;
|
||||||
}
|
}
|
||||||
|
@ -75,10 +75,10 @@ public class CommentBlackListServiceImpl extends AbstractCrudService<CommentBlac
|
||||||
blackList.setBanTime(getBanTime(localDateTime, banTime));
|
blackList.setBanTime(getBanTime(localDateTime, banTime));
|
||||||
int updateResult = commentBlackListRepository.updateByIpAddress(blackList);
|
int updateResult = commentBlackListRepository.updateByIpAddress(blackList);
|
||||||
Optional.of(updateResult)
|
Optional.of(updateResult)
|
||||||
.filter(result -> result <= 0).ifPresent(result -> log.error("更新评论封禁时间失败"));
|
.filter(result -> result <= 0).ifPresent(result -> log.error("更新评论封禁时间失败"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date getBanTime(LocalDateTime localDateTime, Integer banTime) {
|
private Date getBanTime(LocalDateTime localDateTime, Integer banTime) {
|
||||||
return new Date(localDateTime.plusMinutes(banTime).atZone(zoneId).toInstant().toEpochMilli());
|
return new Date(localDateTime.plusMinutes(banTime).atZone(ZONE_ID).toInstant().toEpochMilli());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,13 +68,13 @@ public class JournalCommentServiceImpl extends BaseCommentServiceImpl<JournalCom
|
||||||
Map<Integer, Journal> journalMap = ServiceUtils.convertToMap(journals, Journal::getId);
|
Map<Integer, Journal> journalMap = ServiceUtils.convertToMap(journals, Journal::getId);
|
||||||
|
|
||||||
return journalComments.stream()
|
return journalComments.stream()
|
||||||
.filter(journalComment -> journalMap.containsKey(journalComment.getPostId()))
|
.filter(journalComment -> journalMap.containsKey(journalComment.getPostId()))
|
||||||
.map(journalComment -> {
|
.map(journalComment -> {
|
||||||
JournalCommentWithJournalVO journalCmtWithJournalVo = new JournalCommentWithJournalVO().convertFrom(journalComment);
|
JournalCommentWithJournalVO journalCmtWithJournalVo = new JournalCommentWithJournalVO().convertFrom(journalComment);
|
||||||
journalCmtWithJournalVo.setJournal(new JournalDTO().convertFrom(journalMap.get(journalComment.getPostId())));
|
journalCmtWithJournalVo.setJournal(new JournalDTO().convertFrom(journalMap.get(journalComment.getPostId())));
|
||||||
return journalCmtWithJournalVo;
|
return journalCmtWithJournalVo;
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -119,13 +119,13 @@ public class JournalServiceImpl extends AbstractCrudService<Journal, Integer> im
|
||||||
Map<Integer, Long> journalCommentCountMap = journalCommentService.countByPostIds(journalIds);
|
Map<Integer, Long> journalCommentCountMap = journalCommentService.countByPostIds(journalIds);
|
||||||
|
|
||||||
return journals.stream()
|
return journals.stream()
|
||||||
.map(journal -> {
|
.map(journal -> {
|
||||||
JournalWithCmtCountDTO journalWithCmtCountDTO = new JournalWithCmtCountDTO().convertFrom(journal);
|
JournalWithCmtCountDTO journalWithCmtCountDTO = new JournalWithCmtCountDTO().convertFrom(journal);
|
||||||
// Set comment count
|
// Set comment count
|
||||||
journalWithCmtCountDTO.setCommentCount(journalCommentCountMap.getOrDefault(journal.getId(), 0L));
|
journalWithCmtCountDTO.setCommentCount(journalCommentCountMap.getOrDefault(journal.getId(), 0L));
|
||||||
return journalWithCmtCountDTO;
|
return journalWithCmtCountDTO;
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -136,6 +136,6 @@ public class LinkServiceImpl extends AbstractCrudService<Link, Integer> implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
return links.stream().map(link -> (LinkDTO) new LinkDTO().convertFrom(link))
|
return links.stream().map(link -> (LinkDTO) new LinkDTO().convertFrom(link))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,8 +211,8 @@ public class MenuServiceImpl extends AbstractCrudService<Menu, Integer> implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
return menus.stream()
|
return menus.stream()
|
||||||
.map(menu -> (MenuDTO) new MenuDTO().convertFrom(menu))
|
.map(menu -> (MenuDTO) new MenuDTO().convertFrom(menu))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void nameMustNotExist(@NonNull Menu menu) {
|
private void nameMustNotExist(@NonNull Menu menu) {
|
||||||
|
|
|
@ -192,17 +192,17 @@ public class OptionServiceImpl extends AbstractCrudService<Option, Integer> impl
|
||||||
|
|
||||||
// Add default property
|
// Add default property
|
||||||
propertyEnumMap.keySet()
|
propertyEnumMap.keySet()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(key -> !keys.contains(key))
|
.filter(key -> !keys.contains(key))
|
||||||
.forEach(key -> {
|
.forEach(key -> {
|
||||||
PropertyEnum propertyEnum = propertyEnumMap.get(key);
|
PropertyEnum propertyEnum = propertyEnumMap.get(key);
|
||||||
|
|
||||||
if (StringUtils.isBlank(propertyEnum.defaultValue())) {
|
if (StringUtils.isBlank(propertyEnum.defaultValue())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.put(key, PropertyEnum.convertTo(propertyEnum.defaultValue(), propertyEnum));
|
result.put(key, PropertyEnum.convertTo(propertyEnum.defaultValue(), propertyEnum));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cache the result
|
// Cache the result
|
||||||
cacheStore.putAny(OPTIONS_KEY, result);
|
cacheStore.putAny(OPTIONS_KEY, result);
|
||||||
|
@ -222,8 +222,8 @@ public class OptionServiceImpl extends AbstractCrudService<Option, Integer> impl
|
||||||
Map<String, Object> result = new HashMap<>(keys.size());
|
Map<String, Object> result = new HashMap<>(keys.size());
|
||||||
|
|
||||||
keys.stream()
|
keys.stream()
|
||||||
.filter(optionMap::containsKey)
|
.filter(optionMap::containsKey)
|
||||||
.forEach(key -> result.put(key, optionMap.get(key)));
|
.forEach(key -> result.put(key, optionMap.get(key)));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class PostCategoryServiceImpl extends AbstractCrudService<PostCategory, I
|
||||||
|
|
||||||
// Foreach and collect
|
// Foreach and collect
|
||||||
postCategories.forEach(postCategory -> categoryListMap.computeIfAbsent(postCategory.getPostId(), postId -> new LinkedList<>())
|
postCategories.forEach(postCategory -> categoryListMap.computeIfAbsent(postCategory.getPostId(), postId -> new LinkedList<>())
|
||||||
.add(categoryMap.get(postCategory.getCategoryId())));
|
.add(categoryMap.get(postCategory.getCategoryId())));
|
||||||
|
|
||||||
return categoryListMap;
|
return categoryListMap;
|
||||||
}
|
}
|
||||||
|
@ -241,28 +241,28 @@ public class PostCategoryServiceImpl extends AbstractCrudService<PostCategory, I
|
||||||
|
|
||||||
// Convert and return
|
// Convert and return
|
||||||
return categories.stream()
|
return categories.stream()
|
||||||
.map(category -> {
|
.map(category -> {
|
||||||
// Create category post count dto
|
// Create category post count dto
|
||||||
CategoryWithPostCountDTO categoryWithPostCountDTO = new CategoryWithPostCountDTO().convertFrom(category);
|
CategoryWithPostCountDTO categoryWithPostCountDTO = new CategoryWithPostCountDTO().convertFrom(category);
|
||||||
// Set post count
|
// Set post count
|
||||||
categoryWithPostCountDTO.setPostCount(categoryPostCountMap.getOrDefault(category.getId(), 0L));
|
categoryWithPostCountDTO.setPostCount(categoryPostCountMap.getOrDefault(category.getId(), 0L));
|
||||||
|
|
||||||
StringBuilder fullPath = new StringBuilder();
|
StringBuilder fullPath = new StringBuilder();
|
||||||
|
|
||||||
if (optionService.isEnabledAbsolutePath()) {
|
if (optionService.isEnabledAbsolutePath()) {
|
||||||
fullPath.append(optionService.getBlogBaseUrl());
|
fullPath.append(optionService.getBlogBaseUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
fullPath.append("/")
|
fullPath.append("/")
|
||||||
.append(optionService.getCategoriesPrefix())
|
.append(optionService.getCategoriesPrefix())
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(category.getSlugName())
|
.append(category.getSlugName())
|
||||||
.append(optionService.getPathSuffix());
|
.append(optionService.getPathSuffix());
|
||||||
|
|
||||||
categoryWithPostCountDTO.setFullPath(fullPath.toString());
|
categoryWithPostCountDTO.setFullPath(fullPath.toString());
|
||||||
|
|
||||||
return categoryWithPostCountDTO;
|
return categoryWithPostCountDTO;
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,17 +91,17 @@ public class PostCommentServiceImpl extends BaseCommentServiceImpl<PostComment>
|
||||||
Map<Integer, Post> postMap = ServiceUtils.convertToMap(postRepository.findAllById(postIds), Post::getId);
|
Map<Integer, Post> postMap = ServiceUtils.convertToMap(postRepository.findAllById(postIds), Post::getId);
|
||||||
|
|
||||||
return postComments.stream()
|
return postComments.stream()
|
||||||
.filter(comment -> postMap.containsKey(comment.getPostId()))
|
.filter(comment -> postMap.containsKey(comment.getPostId()))
|
||||||
.map(comment -> {
|
.map(comment -> {
|
||||||
// Convert to vo
|
// Convert to vo
|
||||||
PostCommentWithPostVO postCommentWithPostVO = new PostCommentWithPostVO().convertFrom(comment);
|
PostCommentWithPostVO postCommentWithPostVO = new PostCommentWithPostVO().convertFrom(comment);
|
||||||
|
|
||||||
BasePostMinimalDTO basePostMinimalDTO = new BasePostMinimalDTO().convertFrom(postMap.get(comment.getPostId()));
|
BasePostMinimalDTO basePostMinimalDTO = new BasePostMinimalDTO().convertFrom(postMap.get(comment.getPostId()));
|
||||||
|
|
||||||
postCommentWithPostVO.setPost(buildPostFullPath(basePostMinimalDTO));
|
postCommentWithPostVO.setPost(buildPostFullPath(basePostMinimalDTO));
|
||||||
|
|
||||||
return postCommentWithPostVO;
|
return postCommentWithPostVO;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private BasePostMinimalDTO buildPostFullPath(BasePostMinimalDTO basePostMinimalDTO) {
|
private BasePostMinimalDTO buildPostFullPath(BasePostMinimalDTO basePostMinimalDTO) {
|
||||||
|
@ -121,28 +121,28 @@ public class PostCommentServiceImpl extends BaseCommentServiceImpl<PostComment>
|
||||||
|
|
||||||
if (permalinkType.equals(PostPermalinkType.DEFAULT)) {
|
if (permalinkType.equals(PostPermalinkType.DEFAULT)) {
|
||||||
fullPath.append(archivesPrefix)
|
fullPath.append(archivesPrefix)
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(basePostMinimalDTO.getUrl())
|
.append(basePostMinimalDTO.getUrl())
|
||||||
.append(pathSuffix);
|
.append(pathSuffix);
|
||||||
} else if (permalinkType.equals(PostPermalinkType.ID)) {
|
} else if (permalinkType.equals(PostPermalinkType.ID)) {
|
||||||
fullPath.append("?p=")
|
fullPath.append("?p=")
|
||||||
.append(basePostMinimalDTO.getId());
|
.append(basePostMinimalDTO.getId());
|
||||||
} else if (permalinkType.equals(PostPermalinkType.DATE)) {
|
} else if (permalinkType.equals(PostPermalinkType.DATE)) {
|
||||||
fullPath.append(DateUtil.year(basePostMinimalDTO.getCreateTime()))
|
fullPath.append(DateUtil.year(basePostMinimalDTO.getCreateTime()))
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(DateUtil.month(basePostMinimalDTO.getCreateTime()) + 1)
|
.append(DateUtil.month(basePostMinimalDTO.getCreateTime()) + 1)
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(basePostMinimalDTO.getUrl())
|
.append(basePostMinimalDTO.getUrl())
|
||||||
.append(pathSuffix);
|
.append(pathSuffix);
|
||||||
} else if (permalinkType.equals(PostPermalinkType.DAY)) {
|
} else if (permalinkType.equals(PostPermalinkType.DAY)) {
|
||||||
fullPath.append(DateUtil.year(basePostMinimalDTO.getCreateTime()))
|
fullPath.append(DateUtil.year(basePostMinimalDTO.getCreateTime()))
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(DateUtil.month(basePostMinimalDTO.getCreateTime()) + 1)
|
.append(DateUtil.month(basePostMinimalDTO.getCreateTime()) + 1)
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(DateUtil.dayOfMonth(basePostMinimalDTO.getCreateTime()))
|
.append(DateUtil.dayOfMonth(basePostMinimalDTO.getCreateTime()))
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(basePostMinimalDTO.getUrl())
|
.append(basePostMinimalDTO.getUrl())
|
||||||
.append(pathSuffix);
|
.append(pathSuffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
basePostMinimalDTO.setFullPath(fullPath.toString());
|
basePostMinimalDTO.setFullPath(fullPath.toString());
|
||||||
|
@ -153,7 +153,7 @@ public class PostCommentServiceImpl extends BaseCommentServiceImpl<PostComment>
|
||||||
@Override
|
@Override
|
||||||
public void validateTarget(Integer postId) {
|
public void validateTarget(Integer postId) {
|
||||||
Post post = postRepository.findById(postId)
|
Post post = postRepository.findById(postId)
|
||||||
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(postId));
|
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(postId));
|
||||||
|
|
||||||
if (post.getDisallowComment()) {
|
if (post.getDisallowComment()) {
|
||||||
throw new BadRequestException("该文章已经被禁止评论").setErrorData(postId);
|
throw new BadRequestException("该文章已经被禁止评论").setErrorData(postId);
|
||||||
|
|
|
@ -30,6 +30,6 @@ public class PostMetaServiceImpl extends BaseMetaServiceImpl<PostMeta> implement
|
||||||
@Override
|
@Override
|
||||||
public void validateTarget(Integer postId) {
|
public void validateTarget(Integer postId) {
|
||||||
postRepository.findById(postId)
|
postRepository.findById(postId)
|
||||||
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(postId));
|
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(postId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,8 +87,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
PostCategoryService postCategoryService,
|
PostCategoryService postCategoryService,
|
||||||
PostCommentService postCommentService,
|
PostCommentService postCommentService,
|
||||||
ApplicationEventPublisher eventPublisher,
|
ApplicationEventPublisher eventPublisher,
|
||||||
PostMetaService postMetaService,
|
PostMetaService postMetaService) {
|
||||||
OptionService optionService1) {
|
|
||||||
super(basePostRepository, optionService);
|
super(basePostRepository, optionService);
|
||||||
this.postRepository = postRepository;
|
this.postRepository = postRepository;
|
||||||
this.tagService = tagService;
|
this.tagService = tagService;
|
||||||
|
@ -98,7 +97,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
this.postCommentService = postCommentService;
|
this.postCommentService = postCommentService;
|
||||||
this.eventPublisher = eventPublisher;
|
this.eventPublisher = eventPublisher;
|
||||||
this.postMetaService = postMetaService;
|
this.postMetaService = postMetaService;
|
||||||
this.optionService = optionService1;
|
this.optionService = optionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -131,7 +130,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
if (!autoSave) {
|
if (!autoSave) {
|
||||||
// Log the creation
|
// Log the creation
|
||||||
LogEvent logEvent = new LogEvent(this, createdPost.getId().toString(),
|
LogEvent logEvent = new LogEvent(this, createdPost.getId().toString(),
|
||||||
LogType.POST_PUBLISHED, createdPost.getTitle());
|
LogType.POST_PUBLISHED, createdPost.getTitle());
|
||||||
eventPublisher.publishEvent(logEvent);
|
eventPublisher.publishEvent(logEvent);
|
||||||
}
|
}
|
||||||
return createdPost;
|
return createdPost;
|
||||||
|
@ -144,7 +143,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
if (!autoSave) {
|
if (!autoSave) {
|
||||||
// Log the creation
|
// Log the creation
|
||||||
LogEvent logEvent = new LogEvent(this, createdPost.getId().toString(),
|
LogEvent logEvent = new LogEvent(this, createdPost.getId().toString(),
|
||||||
LogType.POST_PUBLISHED, createdPost.getTitle());
|
LogType.POST_PUBLISHED, createdPost.getTitle());
|
||||||
eventPublisher.publishEvent(logEvent);
|
eventPublisher.publishEvent(logEvent);
|
||||||
}
|
}
|
||||||
return createdPost;
|
return createdPost;
|
||||||
|
@ -160,7 +159,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
if (!autoSave) {
|
if (!autoSave) {
|
||||||
// Log the creation
|
// Log the creation
|
||||||
LogEvent logEvent = new LogEvent(this, updatedPost.getId().toString(),
|
LogEvent logEvent = new LogEvent(this, updatedPost.getId().toString(),
|
||||||
LogType.POST_EDITED, updatedPost.getTitle());
|
LogType.POST_EDITED, updatedPost.getTitle());
|
||||||
eventPublisher.publishEvent(logEvent);
|
eventPublisher.publishEvent(logEvent);
|
||||||
}
|
}
|
||||||
return updatedPost;
|
return updatedPost;
|
||||||
|
@ -180,7 +179,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
Optional<Post> postOptional = postRepository.findBy(year, month, url);
|
Optional<Post> postOptional = postRepository.findBy(year, month, url);
|
||||||
|
|
||||||
return postOptional
|
return postOptional
|
||||||
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(url));
|
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -193,7 +192,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
Optional<Post> postOptional = postRepository.findBy(year, month, url, status);
|
Optional<Post> postOptional = postRepository.findBy(year, month, url, status);
|
||||||
|
|
||||||
return postOptional
|
return postOptional
|
||||||
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(url));
|
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -206,7 +205,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
Optional<Post> postOptional = postRepository.findBy(year, month, day, url);
|
Optional<Post> postOptional = postRepository.findBy(year, month, day, url);
|
||||||
|
|
||||||
return postOptional
|
return postOptional
|
||||||
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(url));
|
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -220,7 +219,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
Optional<Post> postOptional = postRepository.findBy(year, month, day, url, status);
|
Optional<Post> postOptional = postRepository.findBy(year, month, day, url, status);
|
||||||
|
|
||||||
return postOptional
|
return postOptional
|
||||||
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(url));
|
.orElseThrow(() -> new NotFoundException("查询不到该文章的信息").setErrorData(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -240,14 +239,14 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
public List<ArchiveYearVO> listYearArchives() {
|
public List<ArchiveYearVO> listYearArchives() {
|
||||||
// Get all posts
|
// Get all posts
|
||||||
List<Post> posts = postRepository
|
List<Post> posts = postRepository
|
||||||
.findAllByStatus(PostStatus.PUBLISHED, Sort.by(DESC, "createTime"));
|
.findAllByStatus(PostStatus.PUBLISHED, Sort.by(DESC, "createTime"));
|
||||||
|
|
||||||
Map<Integer, List<Post>> yearPostMap = new HashMap<>(8);
|
Map<Integer, List<Post>> yearPostMap = new HashMap<>(8);
|
||||||
|
|
||||||
posts.forEach(post -> {
|
posts.forEach(post -> {
|
||||||
Calendar calendar = DateUtils.convertTo(post.getCreateTime());
|
Calendar calendar = DateUtils.convertTo(post.getCreateTime());
|
||||||
yearPostMap.computeIfAbsent(calendar.get(Calendar.YEAR), year -> new LinkedList<>())
|
yearPostMap.computeIfAbsent(calendar.get(Calendar.YEAR), year -> new LinkedList<>())
|
||||||
.add(post);
|
.add(post);
|
||||||
});
|
});
|
||||||
|
|
||||||
List<ArchiveYearVO> archives = new LinkedList<>();
|
List<ArchiveYearVO> archives = new LinkedList<>();
|
||||||
|
@ -272,7 +271,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
public List<ArchiveMonthVO> listMonthArchives() {
|
public List<ArchiveMonthVO> listMonthArchives() {
|
||||||
// Get all posts
|
// Get all posts
|
||||||
List<Post> posts = postRepository
|
List<Post> posts = postRepository
|
||||||
.findAllByStatus(PostStatus.PUBLISHED, Sort.by(DESC, "createTime"));
|
.findAllByStatus(PostStatus.PUBLISHED, Sort.by(DESC, "createTime"));
|
||||||
|
|
||||||
Map<Integer, Map<Integer, List<Post>>> yearMonthPostMap = new HashMap<>(8);
|
Map<Integer, Map<Integer, List<Post>>> yearMonthPostMap = new HashMap<>(8);
|
||||||
|
|
||||||
|
@ -280,22 +279,22 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
Calendar calendar = DateUtils.convertTo(post.getCreateTime());
|
Calendar calendar = DateUtils.convertTo(post.getCreateTime());
|
||||||
|
|
||||||
yearMonthPostMap.computeIfAbsent(calendar.get(Calendar.YEAR), year -> new HashMap<>())
|
yearMonthPostMap.computeIfAbsent(calendar.get(Calendar.YEAR), year -> new HashMap<>())
|
||||||
.computeIfAbsent((calendar.get(Calendar.MONTH) + 1),
|
.computeIfAbsent(calendar.get(Calendar.MONTH) + 1,
|
||||||
month -> new LinkedList<>())
|
month -> new LinkedList<>())
|
||||||
.add(post);
|
.add(post);
|
||||||
});
|
});
|
||||||
|
|
||||||
List<ArchiveMonthVO> archives = new LinkedList<>();
|
List<ArchiveMonthVO> archives = new LinkedList<>();
|
||||||
|
|
||||||
yearMonthPostMap.forEach((year, monthPostMap) ->
|
yearMonthPostMap.forEach((year, monthPostMap) ->
|
||||||
monthPostMap.forEach((month, postList) -> {
|
monthPostMap.forEach((month, postList) -> {
|
||||||
ArchiveMonthVO archive = new ArchiveMonthVO();
|
ArchiveMonthVO archive = new ArchiveMonthVO();
|
||||||
archive.setYear(year);
|
archive.setYear(year);
|
||||||
archive.setMonth(month);
|
archive.setMonth(month);
|
||||||
archive.setPosts(convertToMinimal(postList));
|
archive.setPosts(convertToMinimal(postList));
|
||||||
|
|
||||||
archives.add(archive);
|
archives.add(archive);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Sort this list
|
// Sort this list
|
||||||
archives.sort(new ArchiveMonthVO.ArchiveComparator());
|
archives.sort(new ArchiveMonthVO.ArchiveComparator());
|
||||||
|
@ -435,7 +434,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
content.append("postMetas:").append("\n");
|
content.append("postMetas:").append("\n");
|
||||||
for (PostMeta postMeta : postMetas) {
|
for (PostMeta postMeta : postMetas) {
|
||||||
content.append(" - ").append(postMeta.getKey()).append(" : ")
|
content.append(" - ").append(postMeta.getKey()).append(" : ")
|
||||||
.append(postMeta.getValue()).append("\n");
|
.append(postMeta.getValue()).append("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +483,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
|
|
||||||
// Log it
|
// Log it
|
||||||
eventPublisher.publishEvent(new LogEvent(this, postId.toString(), LogType.POST_DELETED,
|
eventPublisher.publishEvent(new LogEvent(this, postId.toString(), LogType.POST_DELETED,
|
||||||
deletedPost.getTitle()));
|
deletedPost.getTitle()));
|
||||||
|
|
||||||
return deletedPost;
|
return deletedPost;
|
||||||
}
|
}
|
||||||
|
@ -502,7 +501,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
|
|
||||||
// Get category list map
|
// Get category list map
|
||||||
Map<Integer, List<Category>> categoryListMap = postCategoryService
|
Map<Integer, List<Category>> categoryListMap = postCategoryService
|
||||||
.listCategoryListMap(postIds);
|
.listCategoryListMap(postIds);
|
||||||
|
|
||||||
// Get comment count
|
// Get comment count
|
||||||
Map<Integer, Long> commentCountMap = postCommentService.countByPostIds(postIds);
|
Map<Integer, Long> commentCountMap = postCommentService.countByPostIds(postIds);
|
||||||
|
@ -521,27 +520,27 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
|
|
||||||
// Set tags
|
// Set tags
|
||||||
postListVO.setTags(Optional.ofNullable(tagListMap.get(post.getId()))
|
postListVO.setTags(Optional.ofNullable(tagListMap.get(post.getId()))
|
||||||
.orElseGet(LinkedList::new)
|
.orElseGet(LinkedList::new)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(tagService::convertTo)
|
.map(tagService::convertTo)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
// Set categories
|
// Set categories
|
||||||
postListVO.setCategories(Optional.ofNullable(categoryListMap.get(post.getId()))
|
postListVO.setCategories(Optional.ofNullable(categoryListMap.get(post.getId()))
|
||||||
.orElseGet(LinkedList::new)
|
.orElseGet(LinkedList::new)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(categoryService::convertTo)
|
.map(categoryService::convertTo)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
// Set post metas
|
// Set post metas
|
||||||
postListVO.setPostMetas(Optional.ofNullable(postMetaListMap.get(post.getId()))
|
postListVO.setPostMetas(Optional.ofNullable(postMetaListMap.get(post.getId()))
|
||||||
.orElseGet(LinkedList::new)
|
.orElseGet(LinkedList::new)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(postMeta -> (BaseMetaDTO) new BaseMetaDTO().convertFrom(postMeta))
|
.map(postMeta -> (BaseMetaDTO) new BaseMetaDTO().convertFrom(postMeta))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
// Set comment count
|
// Set comment count
|
||||||
postListVO.setCommentCount(commentCountMap.getOrDefault(post.getId(), 0L));
|
postListVO.setCommentCount(commentCountMap.getOrDefault(post.getId(), 0L));
|
||||||
|
@ -563,7 +562,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
|
|
||||||
// Get category list map
|
// Get category list map
|
||||||
Map<Integer, List<Category>> categoryListMap = postCategoryService
|
Map<Integer, List<Category>> categoryListMap = postCategoryService
|
||||||
.listCategoryListMap(postIds);
|
.listCategoryListMap(postIds);
|
||||||
|
|
||||||
// Get comment count
|
// Get comment count
|
||||||
Map<Integer, Long> commentCountMap = postCommentService.countByPostIds(postIds);
|
Map<Integer, Long> commentCountMap = postCommentService.countByPostIds(postIds);
|
||||||
|
@ -582,27 +581,27 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
|
|
||||||
// Set tags
|
// Set tags
|
||||||
postListVO.setTags(Optional.ofNullable(tagListMap.get(post.getId()))
|
postListVO.setTags(Optional.ofNullable(tagListMap.get(post.getId()))
|
||||||
.orElseGet(LinkedList::new)
|
.orElseGet(LinkedList::new)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(tagService::convertTo)
|
.map(tagService::convertTo)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
// Set categories
|
// Set categories
|
||||||
postListVO.setCategories(Optional.ofNullable(categoryListMap.get(post.getId()))
|
postListVO.setCategories(Optional.ofNullable(categoryListMap.get(post.getId()))
|
||||||
.orElseGet(LinkedList::new)
|
.orElseGet(LinkedList::new)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(categoryService::convertTo)
|
.map(categoryService::convertTo)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
// Set post metas
|
// Set post metas
|
||||||
postListVO.setPostMetas(Optional.ofNullable(postMetaListMap.get(post.getId()))
|
postListVO.setPostMetas(Optional.ofNullable(postMetaListMap.get(post.getId()))
|
||||||
.orElseGet(LinkedList::new)
|
.orElseGet(LinkedList::new)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(postMeta -> (BaseMetaDTO) new BaseMetaDTO().convertFrom(postMeta))
|
.map(postMeta -> (BaseMetaDTO) new BaseMetaDTO().convertFrom(postMeta))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
// Set comment count
|
// Set comment count
|
||||||
postListVO.setCommentCount(commentCountMap.getOrDefault(post.getId(), 0L));
|
postListVO.setCommentCount(commentCountMap.getOrDefault(post.getId(), 0L));
|
||||||
|
@ -636,8 +635,8 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
}
|
}
|
||||||
|
|
||||||
return posts.stream()
|
return posts.stream()
|
||||||
.map(this::convertToMinimal)
|
.map(this::convertToMinimal)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -723,21 +722,21 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
Root<PostCategory> postCategoryRoot = postSubquery.from(PostCategory.class);
|
Root<PostCategory> postCategoryRoot = postSubquery.from(PostCategory.class);
|
||||||
postSubquery.select(postCategoryRoot.get("postId"));
|
postSubquery.select(postCategoryRoot.get("postId"));
|
||||||
postSubquery.where(
|
postSubquery.where(
|
||||||
criteriaBuilder.equal(root.get("id"), postCategoryRoot.get("postId")),
|
criteriaBuilder.equal(root.get("id"), postCategoryRoot.get("postId")),
|
||||||
criteriaBuilder.equal(postCategoryRoot.get("categoryId"),
|
criteriaBuilder.equal(postCategoryRoot.get("categoryId"),
|
||||||
postQuery.getCategoryId()));
|
postQuery.getCategoryId()));
|
||||||
predicates.add(criteriaBuilder.exists(postSubquery));
|
predicates.add(criteriaBuilder.exists(postSubquery));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (postQuery.getKeyword() != null) {
|
if (postQuery.getKeyword() != null) {
|
||||||
// Format like condition
|
// Format like condition
|
||||||
String likeCondition = String
|
String likeCondition = String
|
||||||
.format("%%%s%%", StringUtils.strip(postQuery.getKeyword()));
|
.format("%%%s%%", StringUtils.strip(postQuery.getKeyword()));
|
||||||
|
|
||||||
// Build like predicate
|
// Build like predicate
|
||||||
Predicate titleLike = criteriaBuilder.like(root.get("title"), likeCondition);
|
Predicate titleLike = criteriaBuilder.like(root.get("title"), likeCondition);
|
||||||
Predicate originalContentLike = criteriaBuilder
|
Predicate originalContentLike = criteriaBuilder
|
||||||
.like(root.get("originalContent"), likeCondition);
|
.like(root.get("originalContent"), likeCondition);
|
||||||
|
|
||||||
predicates.add(criteriaBuilder.or(titleLike, originalContentLike));
|
predicates.add(criteriaBuilder.or(titleLike, originalContentLike));
|
||||||
}
|
}
|
||||||
|
@ -765,20 +764,20 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
|
|
||||||
// Create post tags
|
// Create post tags
|
||||||
List<PostTag> postTags = postTagService.mergeOrCreateByIfAbsent(post.getId(),
|
List<PostTag> postTags = postTagService.mergeOrCreateByIfAbsent(post.getId(),
|
||||||
ServiceUtils.fetchProperty(tags, Tag::getId));
|
ServiceUtils.fetchProperty(tags, Tag::getId));
|
||||||
|
|
||||||
log.debug("Created post tags: [{}]", postTags);
|
log.debug("Created post tags: [{}]", postTags);
|
||||||
|
|
||||||
// Create post categories
|
// Create post categories
|
||||||
List<PostCategory> postCategories = postCategoryService
|
List<PostCategory> postCategories = postCategoryService
|
||||||
.mergeOrCreateByIfAbsent(post.getId(),
|
.mergeOrCreateByIfAbsent(post.getId(),
|
||||||
ServiceUtils.fetchProperty(categories, Category::getId));
|
ServiceUtils.fetchProperty(categories, Category::getId));
|
||||||
|
|
||||||
log.debug("Created post categories: [{}]", postCategories);
|
log.debug("Created post categories: [{}]", postCategories);
|
||||||
|
|
||||||
// Create post meta data
|
// Create post meta data
|
||||||
List<PostMeta> postMetaList = postMetaService
|
List<PostMeta> postMetaList = postMetaService
|
||||||
.createOrUpdateByPostId(post.getId(), postMetas);
|
.createOrUpdateByPostId(post.getId(), postMetas);
|
||||||
log.debug("Created post postMetas: [{}]", postMetaList);
|
log.debug("Created post postMetas: [{}]", postMetaList);
|
||||||
|
|
||||||
// Convert to post detail vo
|
// Convert to post detail vo
|
||||||
|
@ -809,7 +808,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
|
|
||||||
while (needNext && totalCount > postList.size()) {
|
while (needNext && totalCount > postList.size()) {
|
||||||
pageable = PageRequest
|
pageable = PageRequest
|
||||||
.of(page >= 1 ? page - 1 : page, defaultPageSize, sort);
|
.of(page >= 1 ? page - 1 : page, defaultPageSize, sort);
|
||||||
|
|
||||||
Page<Post> postPage = pageBy(postStatus, pageable);
|
Page<Post> postPage = pageBy(postStatus, pageable);
|
||||||
List<Post> pageablePostList = postPage.getContent();
|
List<Post> pageablePostList = postPage.getContent();
|
||||||
|
@ -818,8 +817,8 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
}
|
}
|
||||||
postList.addAll(postPage.getContent());
|
postList.addAll(postPage.getContent());
|
||||||
if (postList.stream().filter(it -> it.getId().equals(currentPost.getId())).count() == 1
|
if (postList.stream().filter(it -> it.getId().equals(currentPost.getId())).count() == 1
|
||||||
&& !postList.stream().reduce((first, second) -> second).get().getId()
|
&& !postList.stream().reduce((first, second) -> second).get().getId()
|
||||||
.equals(currentPost.getId())) {
|
.equals(currentPost.getId())) {
|
||||||
// contains the post && the post is not in the end
|
// contains the post && the post is not in the end
|
||||||
needNext = false;
|
needNext = false;
|
||||||
}
|
}
|
||||||
|
@ -858,7 +857,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
@Override
|
@Override
|
||||||
public @NotNull Sort getPostDefaultSort() {
|
public @NotNull Sort getPostDefaultSort() {
|
||||||
String indexSort = optionService.getByPropertyOfNonNull(PostProperties.INDEX_SORT)
|
String indexSort = optionService.getByPropertyOfNonNull(PostProperties.INDEX_SORT)
|
||||||
.toString();
|
.toString();
|
||||||
return Sort.by(DESC, "topPriority").and(Sort.by(DESC, indexSort)).and(Sort.by(DESC, "id"));
|
return Sort.by(DESC, "topPriority").and(Sort.by(DESC, indexSort)).and(Sort.by(DESC, "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,28 +879,28 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
|
|
||||||
if (permalinkType.equals(PostPermalinkType.DEFAULT)) {
|
if (permalinkType.equals(PostPermalinkType.DEFAULT)) {
|
||||||
fullPath.append(archivesPrefix)
|
fullPath.append(archivesPrefix)
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(post.getUrl())
|
.append(post.getUrl())
|
||||||
.append(pathSuffix);
|
.append(pathSuffix);
|
||||||
} else if (permalinkType.equals(PostPermalinkType.ID)) {
|
} else if (permalinkType.equals(PostPermalinkType.ID)) {
|
||||||
fullPath.append("?p=")
|
fullPath.append("?p=")
|
||||||
.append(post.getId());
|
.append(post.getId());
|
||||||
} else if (permalinkType.equals(PostPermalinkType.DATE)) {
|
} else if (permalinkType.equals(PostPermalinkType.DATE)) {
|
||||||
fullPath.append(DateUtil.year(post.getCreateTime()))
|
fullPath.append(DateUtil.year(post.getCreateTime()))
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(DateUtil.month(post.getCreateTime()) + 1)
|
.append(DateUtil.month(post.getCreateTime()) + 1)
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(post.getUrl())
|
.append(post.getUrl())
|
||||||
.append(pathSuffix);
|
.append(pathSuffix);
|
||||||
} else if (permalinkType.equals(PostPermalinkType.DAY)) {
|
} else if (permalinkType.equals(PostPermalinkType.DAY)) {
|
||||||
fullPath.append(DateUtil.year(post.getCreateTime()))
|
fullPath.append(DateUtil.year(post.getCreateTime()))
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(DateUtil.month(post.getCreateTime()) + 1)
|
.append(DateUtil.month(post.getCreateTime()) + 1)
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(DateUtil.dayOfMonth(post.getCreateTime()))
|
.append(DateUtil.dayOfMonth(post.getCreateTime()))
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(post.getUrl())
|
.append(post.getUrl())
|
||||||
.append(pathSuffix);
|
.append(pathSuffix);
|
||||||
}
|
}
|
||||||
return fullPath.toString();
|
return fullPath.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,26 +75,26 @@ public class PostTagServiceImpl extends AbstractCrudService<PostTag, Integer> im
|
||||||
|
|
||||||
// Find post count
|
// Find post count
|
||||||
return tags.stream().map(
|
return tags.stream().map(
|
||||||
tag -> {
|
tag -> {
|
||||||
TagWithPostCountDTO tagWithCountOutputDTO = new TagWithPostCountDTO().convertFrom(tag);
|
TagWithPostCountDTO tagWithCountOutputDTO = new TagWithPostCountDTO().convertFrom(tag);
|
||||||
tagWithCountOutputDTO.setPostCount(tagPostCountMap.getOrDefault(tag.getId(), 0L));
|
tagWithCountOutputDTO.setPostCount(tagPostCountMap.getOrDefault(tag.getId(), 0L));
|
||||||
|
|
||||||
StringBuilder fullPath = new StringBuilder();
|
StringBuilder fullPath = new StringBuilder();
|
||||||
|
|
||||||
if (optionService.isEnabledAbsolutePath()) {
|
if (optionService.isEnabledAbsolutePath()) {
|
||||||
fullPath.append(optionService.getBlogBaseUrl());
|
fullPath.append(optionService.getBlogBaseUrl());
|
||||||
}
|
|
||||||
|
|
||||||
fullPath.append("/")
|
|
||||||
.append(optionService.getTagsPrefix())
|
|
||||||
.append("/")
|
|
||||||
.append(tag.getSlugName())
|
|
||||||
.append(optionService.getPathSuffix());
|
|
||||||
|
|
||||||
tagWithCountOutputDTO.setFullPath(fullPath.toString());
|
|
||||||
|
|
||||||
return tagWithCountOutputDTO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fullPath.append("/")
|
||||||
|
.append(optionService.getTagsPrefix())
|
||||||
|
.append("/")
|
||||||
|
.append(tag.getSlugName())
|
||||||
|
.append(optionService.getPathSuffix());
|
||||||
|
|
||||||
|
tagWithCountOutputDTO.setFullPath(fullPath.toString());
|
||||||
|
|
||||||
|
return tagWithCountOutputDTO;
|
||||||
|
}
|
||||||
).collect(Collectors.toList());
|
).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -240,8 +240,8 @@ public class RecoveryServiceImpl implements RecoveryService {
|
||||||
log.debug("Migrated tags of post [{}]: [{}]", tags, createdPost.getId());
|
log.debug("Migrated tags of post [{}]: [{}]", tags, createdPost.getId());
|
||||||
|
|
||||||
List<PostComment> postComments = baseComments.stream()
|
List<PostComment> postComments = baseComments.stream()
|
||||||
.map(baseComment -> BeanUtils.transformFrom(baseComment, PostComment.class))
|
.map(baseComment -> BeanUtils.transformFrom(baseComment, PostComment.class))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Build virtual comment
|
// Build virtual comment
|
||||||
|
@ -269,8 +269,8 @@ public class RecoveryServiceImpl implements RecoveryService {
|
||||||
List<BaseComment> baseComments = handleComment(commentsObject, createdSheet.getId());
|
List<BaseComment> baseComments = handleComment(commentsObject, createdSheet.getId());
|
||||||
|
|
||||||
List<SheetComment> sheetComments = baseComments.stream()
|
List<SheetComment> sheetComments = baseComments.stream()
|
||||||
.map(baseComment -> BeanUtils.transformFrom(baseComment, SheetComment.class))
|
.map(baseComment -> BeanUtils.transformFrom(baseComment, SheetComment.class))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// Create comments
|
// Create comments
|
||||||
try {
|
try {
|
||||||
|
@ -303,8 +303,8 @@ public class RecoveryServiceImpl implements RecoveryService {
|
||||||
}
|
}
|
||||||
// Get all children
|
// Get all children
|
||||||
List<PostComment> children = postComments.stream()
|
List<PostComment> children = postComments.stream()
|
||||||
.filter(postComment -> Objects.equals(oldParentId, postComment.getParentId()))
|
.filter(postComment -> Objects.equals(oldParentId, postComment.getParentId()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
|
||||||
// Set parent id again
|
// Set parent id again
|
||||||
|
@ -330,8 +330,8 @@ public class RecoveryServiceImpl implements RecoveryService {
|
||||||
}
|
}
|
||||||
// Get all children
|
// Get all children
|
||||||
List<SheetComment> children = sheetComments.stream()
|
List<SheetComment> children = sheetComments.stream()
|
||||||
.filter(sheetComment -> Objects.equals(oldParentId, sheetComment.getParentId()))
|
.filter(sheetComment -> Objects.equals(oldParentId, sheetComment.getParentId()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// Set parent id again
|
// Set parent id again
|
||||||
children.forEach(postComment -> postComment.setParentId(parentComment.getId()));
|
children.forEach(postComment -> postComment.setParentId(parentComment.getId()));
|
||||||
|
|
|
@ -33,6 +33,6 @@ public class SheetMetaServiceImpl extends BaseMetaServiceImpl<SheetMeta> impleme
|
||||||
@Override
|
@Override
|
||||||
public void validateTarget(Integer sheetId) {
|
public void validateTarget(Integer sheetId) {
|
||||||
sheetRepository.findById(sheetId)
|
sheetRepository.findById(sheetId)
|
||||||
.orElseThrow(() -> new NotFoundException("查询不到该页面的信息").setErrorData(sheetId));
|
.orElseThrow(() -> new NotFoundException("查询不到该页面的信息").setErrorData(sheetId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,8 +168,8 @@ public class StaticPageServiceImpl implements StaticPageService {
|
||||||
public Path zipStaticPagesDirectory() {
|
public Path zipStaticPagesDirectory() {
|
||||||
try {
|
try {
|
||||||
String staticPagePackName = HaloConst.STATIC_PAGE_PACK_PREFIX +
|
String staticPagePackName = HaloConst.STATIC_PAGE_PACK_PREFIX +
|
||||||
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss-")) +
|
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss-")) +
|
||||||
IdUtil.simpleUUID().hashCode() + ".zip";
|
IdUtil.simpleUUID().hashCode() + ".zip";
|
||||||
Path staticPageZipPath = Files.createFile(Paths.get(STATIC_PAGE_PACK_DIR, staticPagePackName));
|
Path staticPageZipPath = Files.createFile(Paths.get(STATIC_PAGE_PACK_DIR, staticPagePackName));
|
||||||
|
|
||||||
FileUtils.zip(pagesDir, staticPageZipPath);
|
FileUtils.zip(pagesDir, staticPageZipPath);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package run.halo.app.service.impl;
|
package run.halo.app.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
@ -30,6 +31,7 @@ import java.util.stream.Stream;
|
||||||
* @date 2019-12-06
|
* @date 2019-12-06
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
public class StaticStorageServiceImpl implements StaticStorageService {
|
public class StaticStorageServiceImpl implements StaticStorageService {
|
||||||
|
|
||||||
private final Path staticDir;
|
private final Path staticDir;
|
||||||
|
@ -90,7 +92,7 @@ public class StaticStorageServiceImpl implements StaticStorageService {
|
||||||
Assert.notNull(relativePath, "Relative path must not be null");
|
Assert.notNull(relativePath, "Relative path must not be null");
|
||||||
|
|
||||||
Path path = Paths.get(staticDir.toString(), relativePath);
|
Path path = Paths.get(staticDir.toString(), relativePath);
|
||||||
System.out.println(path.toString());
|
log.debug(path.toString());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (path.toFile().isDirectory()) {
|
if (path.toFile().isDirectory()) {
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class TagServiceImpl extends AbstractCrudService<Tag, Integer> implements
|
||||||
}
|
}
|
||||||
|
|
||||||
return tags.stream()
|
return tags.stream()
|
||||||
.map(this::convertTo)
|
.map(this::convertTo)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
// List and filter sub folders
|
// List and filter sub folders
|
||||||
List<Path> themePaths = pathStream.filter(path -> Files.isDirectory(path))
|
List<Path> themePaths = pathStream.filter(path -> Files.isDirectory(path))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(themePaths)) {
|
if (CollectionUtils.isEmpty(themePaths)) {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
|
@ -177,13 +177,13 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
try (Stream<Path> pathStream = Files.list(themePath)) {
|
try (Stream<Path> pathStream = Files.list(themePath)) {
|
||||||
return pathStream.filter(path -> StringUtils.startsWithIgnoreCase(path.getFileName().toString(), CUSTOM_SHEET_PREFIX))
|
return pathStream.filter(path -> StringUtils.startsWithIgnoreCase(path.getFileName().toString(), CUSTOM_SHEET_PREFIX))
|
||||||
.map(path -> {
|
.map(path -> {
|
||||||
// Remove prefix
|
// Remove prefix
|
||||||
String customTemplate = StringUtils.removeStartIgnoreCase(path.getFileName().toString(), CUSTOM_SHEET_PREFIX);
|
String customTemplate = StringUtils.removeStartIgnoreCase(path.getFileName().toString(), CUSTOM_SHEET_PREFIX);
|
||||||
// Remove suffix
|
// Remove suffix
|
||||||
return StringUtils.removeEndIgnoreCase(customTemplate, HaloConst.SUFFIX_FTL);
|
return StringUtils.removeEndIgnoreCase(customTemplate, HaloConst.SUFFIX_FTL);
|
||||||
})
|
})
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ServiceException("Failed to list files of path " + themePath.toString(), e);
|
throw new ServiceException("Failed to list files of path " + themePath.toString(), e);
|
||||||
}
|
}
|
||||||
|
@ -196,13 +196,13 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
try (Stream<Path> pathStream = Files.list(themePath)) {
|
try (Stream<Path> pathStream = Files.list(themePath)) {
|
||||||
return pathStream.filter(path -> StringUtils.startsWithIgnoreCase(path.getFileName().toString(), prefix))
|
return pathStream.filter(path -> StringUtils.startsWithIgnoreCase(path.getFileName().toString(), prefix))
|
||||||
.map(path -> {
|
.map(path -> {
|
||||||
// Remove prefix
|
// Remove prefix
|
||||||
String customTemplate = StringUtils.removeStartIgnoreCase(path.getFileName().toString(), prefix);
|
String customTemplate = StringUtils.removeStartIgnoreCase(path.getFileName().toString(), prefix);
|
||||||
// Remove suffix
|
// Remove suffix
|
||||||
return StringUtils.removeEndIgnoreCase(customTemplate, HaloConst.SUFFIX_FTL);
|
return StringUtils.removeEndIgnoreCase(customTemplate, HaloConst.SUFFIX_FTL);
|
||||||
})
|
})
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ServiceException("Failed to list files of path " + themePath.toString(), e);
|
throw new ServiceException("Failed to list files of path " + themePath.toString(), e);
|
||||||
}
|
}
|
||||||
|
@ -473,7 +473,7 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
// Check theme existence
|
// Check theme existence
|
||||||
boolean isExist = getThemes().stream()
|
boolean isExist = getThemes().stream()
|
||||||
.anyMatch(themeProperty -> themeProperty.getId().equalsIgnoreCase(tmpThemeProperty.getId()));
|
.anyMatch(themeProperty -> themeProperty.getId().equalsIgnoreCase(tmpThemeProperty.getId()));
|
||||||
|
|
||||||
if (isExist) {
|
if (isExist) {
|
||||||
throw new AlreadyExistsException("当前安装的主题已存在");
|
throw new AlreadyExistsException("当前安装的主题已存在");
|
||||||
|
@ -616,7 +616,7 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
// Get branch
|
// Get branch
|
||||||
String branch = StringUtils.isBlank(themeProperty.getBranch()) ?
|
String branch = StringUtils.isBlank(themeProperty.getBranch()) ?
|
||||||
DEFAULT_REMOTE_BRANCH : themeProperty.getBranch();
|
DEFAULT_REMOTE_BRANCH : themeProperty.getBranch();
|
||||||
|
|
||||||
Git git = null;
|
Git git = null;
|
||||||
|
|
||||||
|
@ -634,38 +634,38 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
// Force to set remote name
|
// Force to set remote name
|
||||||
git.remoteRemove().setRemoteName(THEME_PROVIDER_REMOTE_NAME).call();
|
git.remoteRemove().setRemoteName(THEME_PROVIDER_REMOTE_NAME).call();
|
||||||
RemoteConfig remoteConfig = git.remoteAdd()
|
RemoteConfig remoteConfig = git.remoteAdd()
|
||||||
.setName(THEME_PROVIDER_REMOTE_NAME)
|
.setName(THEME_PROVIDER_REMOTE_NAME)
|
||||||
.setUri(new URIish(themeProperty.getRepo()))
|
.setUri(new URIish(themeProperty.getRepo()))
|
||||||
.call();
|
.call();
|
||||||
|
|
||||||
// Add all changes
|
// Add all changes
|
||||||
git.add()
|
git.add()
|
||||||
.addFilepattern(".")
|
.addFilepattern(".")
|
||||||
.call();
|
.call();
|
||||||
// Commit the changes
|
// Commit the changes
|
||||||
git.commit().setMessage("Commit by halo automatically").call();
|
git.commit().setMessage("Commit by halo automatically").call();
|
||||||
|
|
||||||
// Check out to specified branch
|
// Check out to specified branch
|
||||||
if (!StringUtils.equalsIgnoreCase(branch, git.getRepository().getBranch())) {
|
if (!StringUtils.equalsIgnoreCase(branch, git.getRepository().getBranch())) {
|
||||||
boolean present = git.branchList()
|
boolean present = git.branchList()
|
||||||
.call()
|
.call()
|
||||||
.stream()
|
.stream()
|
||||||
.map(Ref::getName)
|
.map(Ref::getName)
|
||||||
.anyMatch(name -> StringUtils.equalsIgnoreCase(name, branch));
|
.anyMatch(name -> StringUtils.equalsIgnoreCase(name, branch));
|
||||||
|
|
||||||
git.checkout()
|
git.checkout()
|
||||||
.setCreateBranch(true)
|
.setCreateBranch(true)
|
||||||
.setForced(!present)
|
.setForced(!present)
|
||||||
.setName(branch)
|
.setName(branch)
|
||||||
.call();
|
.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull with rebasing
|
// Pull with rebasing
|
||||||
PullResult pullResult = git.pull()
|
PullResult pullResult = git.pull()
|
||||||
.setRemote(remoteConfig.getName())
|
.setRemote(remoteConfig.getName())
|
||||||
.setRemoteBranchName(branch)
|
.setRemoteBranchName(branch)
|
||||||
.setRebase(true)
|
.setRebase(true)
|
||||||
.call();
|
.call();
|
||||||
|
|
||||||
if (!pullResult.isSuccessful()) {
|
if (!pullResult.isSuccessful()) {
|
||||||
log.debug("Rebase result: [{}]", pullResult.getRebaseResult());
|
log.debug("Rebase result: [{}]", pullResult.getRebaseResult());
|
||||||
|
@ -681,9 +681,9 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
if (StringUtils.isNotEmpty(updatedThemeProperty.getRequire()) && !VersionUtil.compareVersion(HaloConst.HALO_VERSION, updatedThemeProperty.getRequire())) {
|
if (StringUtils.isNotEmpty(updatedThemeProperty.getRequire()) && !VersionUtil.compareVersion(HaloConst.HALO_VERSION, updatedThemeProperty.getRequire())) {
|
||||||
// reset theme version
|
// reset theme version
|
||||||
git.reset()
|
git.reset()
|
||||||
.setMode(ResetCommand.ResetType.HARD)
|
.setMode(ResetCommand.ResetType.HARD)
|
||||||
.setRef(lastCommit.getName())
|
.setRef(lastCommit.getName())
|
||||||
.call();
|
.call();
|
||||||
throw new ThemeNotSupportException("新版本主题仅支持 Halo " + updatedThemeProperty.getRequire() + " 以上的版本");
|
throw new ThemeNotSupportException("新版本主题仅支持 Halo " + updatedThemeProperty.getRequire() + " 以上的版本");
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -864,11 +864,11 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
// Set screenshots
|
// Set screenshots
|
||||||
getScreenshotsFileName(themePath).ifPresent(screenshotsName ->
|
getScreenshotsFileName(themePath).ifPresent(screenshotsName ->
|
||||||
themeProperty.setScreenshots(StringUtils.join(optionService.getBlogBaseUrl(),
|
themeProperty.setScreenshots(StringUtils.join(optionService.getBlogBaseUrl(),
|
||||||
"/themes/",
|
"/themes/",
|
||||||
FilenameUtils.getBasename(themeProperty.getThemePath()),
|
FilenameUtils.getBasename(themeProperty.getThemePath()),
|
||||||
"/",
|
"/",
|
||||||
screenshotsName)));
|
screenshotsName)));
|
||||||
|
|
||||||
if (StringUtils.equals(themeProperty.getId(), getActivatedThemeId())) {
|
if (StringUtils.equals(themeProperty.getId(), getActivatedThemeId())) {
|
||||||
// Set activation
|
// Set activation
|
||||||
|
@ -908,10 +908,10 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
try (Stream<Path> pathStream = Files.list(themePath)) {
|
try (Stream<Path> pathStream = Files.list(themePath)) {
|
||||||
return pathStream.filter(path -> Files.isRegularFile(path)
|
return pathStream.filter(path -> Files.isRegularFile(path)
|
||||||
&& Files.isReadable(path)
|
&& Files.isReadable(path)
|
||||||
&& FilenameUtils.getBasename(path.toString()).equalsIgnoreCase(THEME_SCREENSHOTS_NAME))
|
&& FilenameUtils.getBasename(path.toString()).equalsIgnoreCase(THEME_SCREENSHOTS_NAME))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.map(path -> path.getFileName().toString());
|
.map(path -> path.getFileName().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,11 +59,11 @@ public class ThemeSettingServiceImpl extends AbstractCrudService<ThemeSetting, I
|
||||||
if (StringUtils.isBlank(value)) {
|
if (StringUtils.isBlank(value)) {
|
||||||
// Delete it
|
// Delete it
|
||||||
return themeSettingOptional
|
return themeSettingOptional
|
||||||
.map(setting -> {
|
.map(setting -> {
|
||||||
themeSettingRepository.delete(setting);
|
themeSettingRepository.delete(setting);
|
||||||
log.debug("Removed theme setting: [{}]", setting);
|
log.debug("Removed theme setting: [{}]", setting);
|
||||||
return setting;
|
return setting;
|
||||||
}).orElse(null);
|
}).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get config item map
|
// Get config item map
|
||||||
|
@ -74,19 +74,19 @@ public class ThemeSettingServiceImpl extends AbstractCrudService<ThemeSetting, I
|
||||||
|
|
||||||
// Update or create
|
// Update or create
|
||||||
ThemeSetting themeSetting = themeSettingOptional
|
ThemeSetting themeSetting = themeSettingOptional
|
||||||
.map(setting -> {
|
.map(setting -> {
|
||||||
log.debug("Updating theme setting: [{}]", setting);
|
log.debug("Updating theme setting: [{}]", setting);
|
||||||
setting.setValue(value);
|
setting.setValue(value);
|
||||||
log.debug("Updated theme setting: [{}]", setting);
|
log.debug("Updated theme setting: [{}]", setting);
|
||||||
return setting;
|
return setting;
|
||||||
}).orElseGet(() -> {
|
}).orElseGet(() -> {
|
||||||
ThemeSetting setting = new ThemeSetting();
|
ThemeSetting setting = new ThemeSetting();
|
||||||
setting.setKey(key);
|
setting.setKey(key);
|
||||||
setting.setValue(value);
|
setting.setValue(value);
|
||||||
setting.setThemeId(themeId);
|
setting.setThemeId(themeId);
|
||||||
log.debug("Creating theme setting: [{}]", setting);
|
log.debug("Creating theme setting: [{}]", setting);
|
||||||
return setting;
|
return setting;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Save the theme setting
|
// Save the theme setting
|
||||||
return themeSettingRepository.save(themeSetting);
|
return themeSettingRepository.save(themeSetting);
|
||||||
|
|
|
@ -69,8 +69,8 @@ public class BeanUtils {
|
||||||
|
|
||||||
// Transform in batch
|
// Transform in batch
|
||||||
return sources.stream()
|
return sources.stream()
|
||||||
.map(source -> transformFrom(source, targetClass))
|
.map(source -> transformFrom(source, targetClass))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class FileUtils {
|
||||||
|
|
||||||
// Delete folder recursively
|
// Delete folder recursively
|
||||||
org.eclipse.jgit.util.FileUtils.delete(deletingPath.toFile(),
|
org.eclipse.jgit.util.FileUtils.delete(deletingPath.toFile(),
|
||||||
org.eclipse.jgit.util.FileUtils.RECURSIVE | org.eclipse.jgit.util.FileUtils.RETRY);
|
org.eclipse.jgit.util.FileUtils.RECURSIVE | org.eclipse.jgit.util.FileUtils.RETRY);
|
||||||
|
|
||||||
log.info("Deleted [{}] successfully", deletingPath);
|
log.info("Deleted [{}] successfully", deletingPath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,9 +37,9 @@ public class GitUtils {
|
||||||
Git git = null;
|
Git git = null;
|
||||||
try {
|
try {
|
||||||
git = Git.cloneRepository()
|
git = Git.cloneRepository()
|
||||||
.setURI(repoUrl)
|
.setURI(repoUrl)
|
||||||
.setDirectory(targetPath.toFile())
|
.setDirectory(targetPath.toFile())
|
||||||
.call();
|
.call();
|
||||||
log.debug("Cloned git repo [{}] successfully", repoUrl);
|
log.debug("Cloned git repo [{}] successfully", repoUrl);
|
||||||
} finally {
|
} finally {
|
||||||
closeQuietly(git);
|
closeQuietly(git);
|
||||||
|
|
|
@ -244,7 +244,7 @@ public class HaloUtils {
|
||||||
Assert.hasText(originalUrl, "Original Url must not be blank");
|
Assert.hasText(originalUrl, "Original Url must not be blank");
|
||||||
|
|
||||||
if (StringUtils.startsWithAny(originalUrl, "/", "https://", "http://")
|
if (StringUtils.startsWithAny(originalUrl, "/", "https://", "http://")
|
||||||
&& !StringUtils.startsWith(originalUrl, "//")) {
|
&& !StringUtils.startsWith(originalUrl, "//")) {
|
||||||
return originalUrl;
|
return originalUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,14 @@ public class HttpClientUtils {
|
||||||
@NonNull
|
@NonNull
|
||||||
public static CloseableHttpClient createHttpsClient(int timeout) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
|
public static CloseableHttpClient createHttpsClient(int timeout) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
|
||||||
SSLContext sslContext = new SSLContextBuilder()
|
SSLContext sslContext = new SSLContextBuilder()
|
||||||
.loadTrustMaterial(null, (certificate, authType) -> true)
|
.loadTrustMaterial(null, (certificate, authType) -> true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return HttpClients.custom()
|
return HttpClients.custom()
|
||||||
.setSSLContext(sslContext)
|
.setSSLContext(sslContext)
|
||||||
.setSSLHostnameVerifier(new NoopHostnameVerifier())
|
.setSSLHostnameVerifier(new NoopHostnameVerifier())
|
||||||
.setDefaultRequestConfig(getReqeustConfig(timeout))
|
.setDefaultRequestConfig(getReqeustConfig(timeout))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,10 +59,10 @@ public class HttpClientUtils {
|
||||||
*/
|
*/
|
||||||
private static RequestConfig getReqeustConfig(int timeout) {
|
private static RequestConfig getReqeustConfig(int timeout) {
|
||||||
return RequestConfig.custom()
|
return RequestConfig.custom()
|
||||||
.setConnectTimeout(timeout)
|
.setConnectTimeout(timeout)
|
||||||
.setConnectionRequestTimeout(timeout)
|
.setConnectionRequestTimeout(timeout)
|
||||||
.setSocketTimeout(timeout)
|
.setSocketTimeout(timeout)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,32 +37,32 @@ import java.util.Map;
|
||||||
public class MarkdownUtils {
|
public class MarkdownUtils {
|
||||||
|
|
||||||
private static final DataHolder OPTIONS = new MutableDataSet()
|
private static final DataHolder OPTIONS = new MutableDataSet()
|
||||||
.set(Parser.EXTENSIONS, Arrays.asList(
|
.set(Parser.EXTENSIONS, Arrays.asList(
|
||||||
AttributesExtension.create(),
|
AttributesExtension.create(),
|
||||||
AutolinkExtension.create(),
|
AutolinkExtension.create(),
|
||||||
EmojiExtension.create(),
|
EmojiExtension.create(),
|
||||||
EscapedCharacterExtension.create(),
|
EscapedCharacterExtension.create(),
|
||||||
StrikethroughExtension.create(),
|
StrikethroughExtension.create(),
|
||||||
TaskListExtension.create(),
|
TaskListExtension.create(),
|
||||||
InsExtension.create(),
|
InsExtension.create(),
|
||||||
MediaTagsExtension.create(),
|
MediaTagsExtension.create(),
|
||||||
TablesExtension.create(),
|
TablesExtension.create(),
|
||||||
TocExtension.create(),
|
TocExtension.create(),
|
||||||
YamlFrontMatterExtension.create(),
|
YamlFrontMatterExtension.create(),
|
||||||
GitLabExtension.create())
|
GitLabExtension.create())
|
||||||
)
|
)
|
||||||
.set(TocExtension.LEVELS, 255)
|
.set(TocExtension.LEVELS, 255)
|
||||||
.set(TablesExtension.WITH_CAPTION, false)
|
.set(TablesExtension.WITH_CAPTION, false)
|
||||||
.set(TablesExtension.COLUMN_SPANS, false)
|
.set(TablesExtension.COLUMN_SPANS, false)
|
||||||
.set(TablesExtension.MIN_SEPARATOR_DASHES, 1)
|
.set(TablesExtension.MIN_SEPARATOR_DASHES, 1)
|
||||||
.set(TablesExtension.MIN_HEADER_ROWS, 1)
|
.set(TablesExtension.MIN_HEADER_ROWS, 1)
|
||||||
.set(TablesExtension.MAX_HEADER_ROWS, 1)
|
.set(TablesExtension.MAX_HEADER_ROWS, 1)
|
||||||
.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
|
.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
|
||||||
.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
|
.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
|
||||||
.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
|
.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
|
||||||
.set(EmojiExtension.USE_SHORTCUT_TYPE, EmojiShortcutType.EMOJI_CHEAT_SHEET)
|
.set(EmojiExtension.USE_SHORTCUT_TYPE, EmojiShortcutType.EMOJI_CHEAT_SHEET)
|
||||||
.set(EmojiExtension.USE_IMAGE_TYPE, EmojiImageType.UNICODE_ONLY)
|
.set(EmojiExtension.USE_IMAGE_TYPE, EmojiImageType.UNICODE_ONLY)
|
||||||
.set(HtmlRenderer.SOFT_BREAK, "<br />\n");
|
.set(HtmlRenderer.SOFT_BREAK, "<br />\n");
|
||||||
|
|
||||||
private static final Parser PARSER = Parser.builder(OPTIONS).build();
|
private static final Parser PARSER = Parser.builder(OPTIONS).build();
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ public class ServiceUtils {
|
||||||
@NonNull
|
@NonNull
|
||||||
public static <ID, T> Set<ID> fetchProperty(final Collection<T> datas, Function<T, ID> mappingFunction) {
|
public static <ID, T> Set<ID> fetchProperty(final Collection<T> datas, Function<T, ID> mappingFunction) {
|
||||||
return CollectionUtils.isEmpty(datas) ?
|
return CollectionUtils.isEmpty(datas) ?
|
||||||
Collections.emptySet() :
|
Collections.emptySet() :
|
||||||
datas.stream().map(mappingFunction).collect(Collectors.toSet());
|
datas.stream().map(mappingFunction).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,9 +28,9 @@ public class ServletUtils {
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Optional<HttpServletRequest> getCurrentRequest() {
|
public static Optional<HttpServletRequest> getCurrentRequest() {
|
||||||
return Optional.ofNullable(RequestContextHolder.getRequestAttributes())
|
return Optional.ofNullable(RequestContextHolder.getRequestAttributes())
|
||||||
.filter(requestAttributes -> requestAttributes instanceof ServletRequestAttributes)
|
.filter(requestAttributes -> requestAttributes instanceof ServletRequestAttributes)
|
||||||
.map(requestAttributes -> ((ServletRequestAttributes) requestAttributes))
|
.map(requestAttributes -> (ServletRequestAttributes) requestAttributes)
|
||||||
.map(ServletRequestAttributes::getRequest);
|
.map(ServletRequestAttributes::getRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -47,10 +47,10 @@ public class SlugUtils {
|
||||||
public static String slug(@NonNull String input) {
|
public static String slug(@NonNull String input) {
|
||||||
Assert.hasText(input, "Input string must not be blank");
|
Assert.hasText(input, "Input string must not be blank");
|
||||||
String slug = input.
|
String slug = input.
|
||||||
replaceAll("[^(a-zA-Z0-9\\u4e00-\\u9fa5\\.\\-)]", "").
|
replaceAll("[^(a-zA-Z0-9\\u4e00-\\u9fa5\\.\\-)]", "").
|
||||||
replaceAll("[\\?\\\\/:|<>\\*\\[\\]\\(\\)\\$%\\{\\}@~\\.]", "").
|
replaceAll("[\\?\\\\/:|<>\\*\\[\\]\\(\\)\\$%\\{\\}@~\\.]", "").
|
||||||
replaceAll("\\s", "")
|
replaceAll("\\s", "")
|
||||||
.toLowerCase(Locale.ENGLISH);
|
.toLowerCase(Locale.ENGLISH);
|
||||||
return StrUtil.isNotEmpty(slug) ? slug : String.valueOf(System.currentTimeMillis());
|
return StrUtil.isNotEmpty(slug) ? slug : String.valueOf(System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,8 +77,8 @@ public class ValidationUtils {
|
||||||
Map<String, String> errMap = new HashMap<>(4);
|
Map<String, String> errMap = new HashMap<>(4);
|
||||||
// Format the error message
|
// Format the error message
|
||||||
constraintViolations.forEach(
|
constraintViolations.forEach(
|
||||||
constraintViolation ->
|
constraintViolation ->
|
||||||
errMap.put(constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage()));
|
errMap.put(constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage()));
|
||||||
return errMap;
|
return errMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ public class VersionUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] getCanonicalVersion(String version) {
|
public static int[] getCanonicalVersion(String version) {
|
||||||
int[] canonicalVersion = new int[]{1, 1, 0, 0};
|
int[] canonicalVersion = new int[] {1, 1, 0, 0};
|
||||||
StringTokenizer tokenizer = new StringTokenizer(version, ".");
|
StringTokenizer tokenizer = new StringTokenizer(version, ".");
|
||||||
String token = tokenizer.nextToken();
|
String token = tokenizer.nextToken();
|
||||||
canonicalVersion[0] = Integer.parseInt(token);
|
canonicalVersion[0] = Integer.parseInt(token);
|
||||||
|
|
|
@ -14,10 +14,10 @@ spring:
|
||||||
password: 123456
|
password: 123456
|
||||||
|
|
||||||
# MySQL database configuration.
|
# MySQL database configuration.
|
||||||
# driver-class-name: com.mysql.cj.jdbc.Driver
|
# driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
# url: jdbc:mysql://127.0.0.1:3306/halodb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
# url: jdbc:mysql://127.0.0.1:3306/halodb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||||
# username: root
|
# username: root
|
||||||
# password: 123456
|
# password: 123456
|
||||||
|
|
||||||
# H2 database console configuration.
|
# H2 database console configuration.
|
||||||
h2:
|
h2:
|
||||||
|
|
|
@ -30,14 +30,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
@AutoConfigureMockMvc
|
@AutoConfigureMockMvc
|
||||||
class DisableOnConditionAspectTest {
|
class DisableOnConditionAspectTest {
|
||||||
|
|
||||||
|
static final String REQUEST_URI = "/api/admin/test/disableOnCondition";
|
||||||
@Autowired
|
@Autowired
|
||||||
MockMvc mvc;
|
MockMvc mvc;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
OptionService optionService;
|
OptionService optionService;
|
||||||
|
|
||||||
static final String REQUEST_URI = "/api/admin/test/disableOnCondition";
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
optionService.saveProperty(PrimaryProperties.IS_INSTALLED, "true");
|
optionService.saveProperty(PrimaryProperties.IS_INSTALLED, "true");
|
||||||
|
@ -48,8 +46,8 @@ class DisableOnConditionAspectTest {
|
||||||
Throwable t = null;
|
Throwable t = null;
|
||||||
try {
|
try {
|
||||||
mvc.perform(get(REQUEST_URI + "/no"))
|
mvc.perform(get(REQUEST_URI + "/no"))
|
||||||
.andDo(print())
|
.andDo(print())
|
||||||
.andReturn();
|
.andReturn();
|
||||||
} catch (NestedServletException nse) {
|
} catch (NestedServletException nse) {
|
||||||
t = nse;
|
t = nse;
|
||||||
}
|
}
|
||||||
|
@ -63,8 +61,8 @@ class DisableOnConditionAspectTest {
|
||||||
@Test
|
@Test
|
||||||
void ableAccessTest() throws Exception {
|
void ableAccessTest() throws Exception {
|
||||||
mvc.perform(get(REQUEST_URI + "/yes"))
|
mvc.perform(get(REQUEST_URI + "/yes"))
|
||||||
.andDo(print())
|
.andDo(print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.status", is(HttpStatus.OK.value())));
|
.andExpect(jsonPath("$.status", is(HttpStatus.OK.value())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package run.halo.app.handler.theme;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import run.halo.app.handler.theme.config.support.ThemeProperty;
|
import run.halo.app.handler.theme.config.support.ThemeProperty;
|
||||||
|
|
||||||
|
@ -11,6 +12,7 @@ import java.io.IOException;
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 4/11/19
|
* @date 4/11/19
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class YamlThemePropertyResolverTest {
|
public class YamlThemePropertyResolverTest {
|
||||||
|
|
||||||
private final ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());
|
private final ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());
|
||||||
|
@ -18,17 +20,17 @@ public class YamlThemePropertyResolverTest {
|
||||||
@Test
|
@Test
|
||||||
public void directResolveTest() throws IOException {
|
public void directResolveTest() throws IOException {
|
||||||
String yaml = "id: viosey_material\n" +
|
String yaml = "id: viosey_material\n" +
|
||||||
"name: Material\n" +
|
"name: Material\n" +
|
||||||
"author:\n" +
|
"author:\n" +
|
||||||
" name: Viosey\n" +
|
" name: Viosey\n" +
|
||||||
" website: https://viosey.com\n" +
|
" website: https://viosey.com\n" +
|
||||||
"description: Nature, Pure | 原质,纯粹\n" +
|
"description: Nature, Pure | 原质,纯粹\n" +
|
||||||
"logo: https://avatars0.githubusercontent.com/u/8141232?s=460&v=4\n" +
|
"logo: https://avatars0.githubusercontent.com/u/8141232?s=460&v=4\n" +
|
||||||
"website: https://github.com/viosey/hexo-theme-material\n" +
|
"website: https://github.com/viosey/hexo-theme-material\n" +
|
||||||
"version: 1.0";
|
"version: 1.0";
|
||||||
|
|
||||||
ThemeProperty themeProperty = yamlMapper.readValue(yaml, ThemeProperty.class);
|
ThemeProperty themeProperty = yamlMapper.readValue(yaml, ThemeProperty.class);
|
||||||
|
|
||||||
System.out.println(themeProperty);
|
log.debug("[{}]", themeProperty);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,6 @@ package run.halo.app.model;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import run.halo.app.service.support.HaloMediaType;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package run.halo.app.model.enums;
|
package run.halo.app.model.enums;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data type test.
|
* Data type test.
|
||||||
|
@ -11,12 +12,13 @@ import static org.junit.Assert.*;
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-4-21
|
* @date 19-4-21
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class DataTypeTest {
|
public class DataTypeTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typeOf() {
|
public void typeOf() {
|
||||||
DataType type = DataType.typeOf("bool");
|
DataType type = DataType.typeOf("bool");
|
||||||
System.out.println(type);
|
log.debug("[{}]", type);
|
||||||
assertThat(type, equalTo(DataType.BOOL));
|
assertThat(type, equalTo(DataType.BOOL));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,6 @@ package run.halo.app.model.params;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import run.halo.app.model.support.AllCheck;
|
|
||||||
import run.halo.app.model.support.CreateCheck;
|
import run.halo.app.model.support.CreateCheck;
|
||||||
|
|
||||||
import javax.validation.ConstraintViolation;
|
import javax.validation.ConstraintViolation;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package run.halo.app.repository;
|
package run.halo.app.repository;
|
||||||
|
|
||||||
import run.halo.app.model.entity.Sheet;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import run.halo.app.model.entity.Sheet;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ import java.util.List;
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@ActiveProfiles("test")
|
@ActiveProfiles("test")
|
||||||
|
@Slf4j
|
||||||
public class SheetRepositoryTest {
|
public class SheetRepositoryTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -27,6 +29,6 @@ public class SheetRepositoryTest {
|
||||||
@Test
|
@Test
|
||||||
public void listAllTest() {
|
public void listAllTest() {
|
||||||
List<Sheet> allSheets = sheetRepository.findAll();
|
List<Sheet> allSheets = sheetRepository.findAll();
|
||||||
System.out.println(allSheets);
|
log.debug("{}", allSheets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,21 +21,19 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
@AutoConfigureMockMvc
|
@AutoConfigureMockMvc
|
||||||
class OneTimeTokenTest {
|
class OneTimeTokenTest {
|
||||||
|
|
||||||
|
static final String REQUEST_URI = "/api/admin/counts";
|
||||||
@Autowired
|
@Autowired
|
||||||
MockMvc mvc;
|
MockMvc mvc;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
OneTimeTokenService oneTimeTokenService;
|
OneTimeTokenService oneTimeTokenService;
|
||||||
|
|
||||||
static final String REQUEST_URI = "/api/admin/counts";
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void provideNonExistOneTimeTokenTest() throws Exception {
|
void provideNonExistOneTimeTokenTest() throws Exception {
|
||||||
mvc.perform(get(REQUEST_URI + "?ott={ott}", "one-time-token-value"))
|
mvc.perform(get(REQUEST_URI + "?ott={ott}", "one-time-token-value"))
|
||||||
.andDo(print())
|
.andDo(print())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
|
||||||
.andExpect(status().isBadRequest())
|
.andExpect(status().isBadRequest())
|
||||||
.andExpect(jsonPath("$.status", is(HttpStatus.BAD_REQUEST.value())));
|
.andExpect(jsonPath("$.status", is(HttpStatus.BAD_REQUEST.value())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -44,8 +42,8 @@ class OneTimeTokenTest {
|
||||||
String ott = oneTimeTokenService.create(REQUEST_URI);
|
String ott = oneTimeTokenService.create(REQUEST_URI);
|
||||||
|
|
||||||
mvc.perform(get(REQUEST_URI + "?ott={ott}", ott))
|
mvc.perform(get(REQUEST_URI + "?ott={ott}", ott))
|
||||||
.andDo(print())
|
.andDo(print())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package run.halo.app.service.impl;
|
package run.halo.app.service.impl;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
@ -12,28 +13,29 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@ActiveProfiles("test")
|
@ActiveProfiles("test")
|
||||||
|
@Slf4j
|
||||||
public class PostServiceImplTest {
|
public class PostServiceImplTest {
|
||||||
|
|
||||||
private String standardMdContent = "---\n" +
|
private String standardMdContent = "---\n" +
|
||||||
"title: springfox-swagger2配置成功但无法访问/swagger-ui.html\n" +
|
"title: springfox-swagger2配置成功但无法访问/swagger-ui.html\n" +
|
||||||
"tags:\n" +
|
"tags:\n" +
|
||||||
" - spring boot\n" +
|
" - spring boot\n" +
|
||||||
" - swagger\n" +
|
" - swagger\n" +
|
||||||
" - solution\n" +
|
" - solution\n" +
|
||||||
"date: 2018-11-23 16:11:28\n" +
|
"date: 2018-11-23 16:11:28\n" +
|
||||||
"---\n" +
|
"---\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"# Pre\n" +
|
"# Pre\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"在前后端分离项目中,通常需要用到 API 文档,springfox 开发的 **[SpringFox](https://github.com/springfox/springfox)** 可以实现自动化 json API 文档。";
|
"在前后端分离项目中,通常需要用到 API 文档,springfox 开发的 **[SpringFox](https://github.com/springfox/springfox)** 可以实现自动化 json API 文档。";
|
||||||
|
|
||||||
private String nonStandardMdContent = "---\n" +
|
private String nonStandardMdContent = "---\n" +
|
||||||
"title: Basic concepts of JPA\n" +
|
"title: Basic concepts of JPA\n" +
|
||||||
"date: 2018-08-03 11:57:00\n" +
|
"date: 2018-08-03 11:57:00\n" +
|
||||||
"tags: ['spring', 'jpa', 'database', 'concept']\n" +
|
"tags: ['spring', 'jpa', 'database', 'concept']\n" +
|
||||||
"---\n" +
|
"---\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"以下将讲解关系型数据的关系描述。仅仅是作为总结。";
|
"以下将讲解关系型数据的关系描述。仅仅是作为总结。";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PostServiceImpl postService;
|
private PostServiceImpl postService;
|
||||||
|
@ -42,7 +44,7 @@ public class PostServiceImplTest {
|
||||||
@Ignore
|
@Ignore
|
||||||
public void getContent() {
|
public void getContent() {
|
||||||
String exportMarkdown = postService.exportMarkdown(18);
|
String exportMarkdown = postService.exportMarkdown(18);
|
||||||
System.out.println(exportMarkdown);
|
log.debug(exportMarkdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package run.halo.app.utils;
|
package run.halo.app.utils;
|
||||||
|
|
||||||
import cn.hutool.crypto.digest.BCrypt;
|
import cn.hutool.crypto.digest.BCrypt;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,11 +10,12 @@ import org.junit.Test;
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 3/28/19
|
* @date 3/28/19
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class BcryptTest {
|
public class BcryptTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void cryptTest() {
|
public void cryptTest() {
|
||||||
String cryptPassword = BCrypt.hashpw("opentest", BCrypt.gensalt());
|
String cryptPassword = BCrypt.hashpw("opentest", BCrypt.gensalt());
|
||||||
System.out.println("Crypt password: " + cryptPassword);
|
log.debug("Crypt password: [{}]", cryptPassword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@ package run.halo.app.utils;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BeanUtils test.
|
* BeanUtils test.
|
||||||
|
@ -38,8 +38,8 @@ public class BeanUtilsTest {
|
||||||
@Test
|
@Test
|
||||||
public void transformFromInBatch() {
|
public void transformFromInBatch() {
|
||||||
TestA[] as = {
|
TestA[] as = {
|
||||||
new TestA(1, 2),
|
new TestA(1, 2),
|
||||||
new TestA(3, 4)
|
new TestA(3, 4)
|
||||||
};
|
};
|
||||||
|
|
||||||
List<TestA> aList = Arrays.asList(as);
|
List<TestA> aList = Arrays.asList(as);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package run.halo.app.utils;
|
package run.halo.app.utils;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import run.halo.app.exception.ForbiddenException;
|
import run.halo.app.exception.ForbiddenException;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import java.nio.file.Paths;
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 4/9/19
|
* @date 4/9/19
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class DirectoryAttackTest {
|
public class DirectoryAttackTest {
|
||||||
|
|
||||||
private String userHome = System.getProperty("user.home");
|
private String userHome = System.getProperty("user.home");
|
||||||
|
@ -25,8 +26,8 @@ public class DirectoryAttackTest {
|
||||||
|
|
||||||
Path testPath = Paths.get(userHome + "/../../etc/passwd");
|
Path testPath = Paths.get(userHome + "/../../etc/passwd");
|
||||||
|
|
||||||
System.out.println("Work directory path: " + workDirPath);
|
log.debug("Work directory path: [{}]", workDirPath);
|
||||||
System.out.println("Test path: " + testPath);
|
log.debug("Test path: [{}]", testPath);
|
||||||
|
|
||||||
Assert.assertFalse(testPath.startsWith(workDirPath));
|
Assert.assertFalse(testPath.startsWith(workDirPath));
|
||||||
Assert.assertFalse(workDirPath.startsWith(testPath));
|
Assert.assertFalse(workDirPath.startsWith(testPath));
|
||||||
|
@ -38,8 +39,8 @@ public class DirectoryAttackTest {
|
||||||
|
|
||||||
Path testPath = Paths.get(userHome + "/halo-test/test.txt");
|
Path testPath = Paths.get(userHome + "/halo-test/test.txt");
|
||||||
|
|
||||||
System.out.println("Work directory path: " + workDirPath);
|
log.debug("Work directory path: [{}]", workDirPath);
|
||||||
System.out.println("Test path: " + testPath);
|
log.debug("Test path: [{}]", testPath);
|
||||||
|
|
||||||
Assert.assertTrue(testPath.startsWith(workDirPath));
|
Assert.assertTrue(testPath.startsWith(workDirPath));
|
||||||
Assert.assertFalse(workDirPath.startsWith(testPath));
|
Assert.assertFalse(workDirPath.startsWith(testPath));
|
||||||
|
@ -52,8 +53,8 @@ public class DirectoryAttackTest {
|
||||||
|
|
||||||
Path testPath = Paths.get("/etc/passwd");
|
Path testPath = Paths.get("/etc/passwd");
|
||||||
|
|
||||||
System.out.println("Work directory path: " + workDirPath);
|
log.debug("Work directory path: [{}]", workDirPath);
|
||||||
System.out.println("Test path: " + testPath);
|
log.debug("Test path: [{}]", testPath);
|
||||||
|
|
||||||
Assert.assertTrue(testPath.startsWith(workDirPath));
|
Assert.assertTrue(testPath.startsWith(workDirPath));
|
||||||
Assert.assertFalse(workDirPath.startsWith(testPath));
|
Assert.assertFalse(workDirPath.startsWith(testPath));
|
||||||
|
@ -64,10 +65,10 @@ public class DirectoryAttackTest {
|
||||||
String pathname = "/home/test/../../etc/";
|
String pathname = "/home/test/../../etc/";
|
||||||
Path path = Paths.get(pathname);
|
Path path = Paths.get(pathname);
|
||||||
|
|
||||||
System.out.println("Path: " + path);
|
log.debug("Path: [{}]", path);
|
||||||
System.out.println("Absolute path: " + path.toAbsolutePath());
|
log.debug("Absolute path: [{}]", path.toAbsolutePath());
|
||||||
System.out.println("Name count: " + path.getNameCount());
|
log.debug("Name count: [{}]", path.getNameCount());
|
||||||
System.out.println("Normalized path: " + path.normalize());
|
log.debug("Normalized path: [{}]", path.normalize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue