Perfect theme configuration resolve

pull/146/head
johnniang 2019-04-10 12:48:21 +08:00
parent 901a6a0456
commit 4b486ae099
5 changed files with 94 additions and 19 deletions

View File

@ -0,0 +1,71 @@
package run.halo.app.handler.theme;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import run.halo.app.handler.theme.impl.YamlThemeConfigResolverImpl;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Theme configuration resolver manager.
*
* @author johnniang
* @date 4/10/19
*/
@Component
public class ThemeConfigResolvers {
private final Map<ConfigType, ThemeConfigResolver> resolverMap = new ConcurrentHashMap<>(2);
public ThemeConfigResolvers() {
resolverMap.put(ConfigType.YAML, new YamlThemeConfigResolverImpl());
// TODO Add another theme config resolver
}
/**
* Config type enum.
*/
public enum ConfigType {
YAML,
PROPERTY
}
/**
* Resolves the content.
*
* @param content content must not be blank
* @param type config type
* @return a list of group
* @throws IOException throws when content conversion fails
*/
public List<Group> resolve(@NonNull String content, @Nullable ConfigType type) throws IOException {
ThemeConfigResolver resolver = getResolver(type);
if (resolver == null) {
throw new UnsupportedOperationException("Unsupported theme config type: " + type);
}
return resolver.resolve(content);
}
/**
* Resolves the content.
*
* @param content content must not be blank
* @return a list of group
* @throws IOException throws when content conversion fails
*/
public List<Group> resolve(String content) throws IOException {
return resolve(content, ConfigType.YAML);
}
private ThemeConfigResolver getResolver(@Nullable ConfigType type) {
return type == null ? null : resolverMap.get(type);
}
}

View File

@ -3,7 +3,6 @@ package run.halo.app.handler.theme.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import run.halo.app.handler.theme.Group;
import run.halo.app.handler.theme.Item;
import run.halo.app.handler.theme.Option;
@ -23,7 +22,6 @@ import java.util.Map;
* @author johnniang
* @date 4/10/19
*/
@Component
public class YamlThemeConfigResolverImpl implements ThemeConfigResolver {
private final ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());

View File

@ -2,6 +2,7 @@ package run.halo.app.service;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import run.halo.app.handler.theme.Group;
import run.halo.app.model.support.ThemeFile;
import run.halo.app.model.support.ThemeProperty;
@ -164,10 +165,10 @@ public interface ThemeService {
* Fetches theme configuration.
*
* @param themeId must not be blank
* @return theme configuration or null if not found
* @return theme configuration
*/
@Nullable
Object fetchConfig(@NonNull String themeId);
@NonNull
List<Group> fetchConfig(@NonNull String themeId);
/**
* Renders a theme page.

View File

@ -21,6 +21,8 @@ import run.halo.app.exception.BadRequestException;
import run.halo.app.exception.ForbiddenException;
import run.halo.app.exception.NotFoundException;
import run.halo.app.exception.ServiceException;
import run.halo.app.handler.theme.Group;
import run.halo.app.handler.theme.ThemeConfigResolvers;
import run.halo.app.model.properties.PrimaryProperties;
import run.halo.app.model.support.HaloConst;
import run.halo.app.model.support.ThemeFile;
@ -60,22 +62,23 @@ public class ThemeServiceImpl implements ThemeService {
*/
private String activatedThemeId;
private final ObjectMapper yamlMapper;
private final OptionService optionService;
private final StringCacheStore cacheStore;
private final Configuration configuration;
private final ThemeConfigResolvers resolvers;
public ThemeServiceImpl(HaloProperties haloProperties,
OptionService optionService,
StringCacheStore cacheStore,
Configuration configuration) {
Configuration configuration,
ThemeConfigResolvers resolvers) {
this.optionService = optionService;
this.cacheStore = cacheStore;
this.configuration = configuration;
yamlMapper = new ObjectMapper(new YAMLFactory());
this.resolvers = resolvers;
workDir = Paths.get(haloProperties.getWorkDir(), THEME_FOLDER);
}
@ -224,15 +227,15 @@ public class ThemeServiceImpl implements ThemeService {
}
@Override
public Object fetchConfig(String themeId) {
public List<Group> fetchConfig(String themeId) {
Assert.hasText(themeId, "Theme name must not be blank");
// Get theme property
ThemeProperty themeProperty = getThemeOfNonNullBy(themeId);
if (!themeProperty.isHasOptions()) {
// If this theme dose not has an option, then return null
return null;
// If this theme dose not has an option, then return empty list
return Collections.emptyList();
}
try {
@ -247,14 +250,15 @@ public class ThemeServiceImpl implements ThemeService {
continue;
}
// Read the yaml file and return the object value
return yamlMapper.readValue(optionsPath.toFile(), Object.class);
// Read the yaml file
String optionContent = new String(Files.readAllBytes(optionsPath));
// Resolve it
return resolvers.resolve(optionContent);
}
return null;
return Collections.emptyList();
} catch (IOException e) {
log.error("Failed to read options.yaml", e);
return null;
throw new ServiceException("Failed to read options file", e);
}
}

View File

@ -2,6 +2,7 @@ package run.halo.app.web.controller.admin.api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import run.halo.app.handler.theme.Group;
import run.halo.app.model.support.BaseResponse;
import run.halo.app.model.support.ThemeFile;
import run.halo.app.model.support.ThemeProperty;
@ -97,8 +98,8 @@ public class ThemeController {
@GetMapping("{themeId}/configurations")
@ApiOperation("Fetches theme configuration by theme id")
public BaseResponse<Object> fetchConfig(@PathVariable("themeId") String themeId) {
return BaseResponse.ok(themeService.fetchConfig(themeId));
public List<Group> fetchConfig(@PathVariable("themeId") String themeId) {
return themeService.fetchConfig(themeId);
}
@PostMapping("{themeId}/settings")