mirror of https://github.com/halo-dev/halo
Complete yaml conversion test
parent
8a8d55eae1
commit
8054b8f714
|
@ -1,5 +1,8 @@
|
|||
package run.halo.app.model.enums;
|
||||
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Data type enum.
|
||||
*
|
||||
|
@ -27,4 +30,22 @@ public enum DataType implements ValueEnum<Integer> {
|
|||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data type of string.
|
||||
*
|
||||
* @param type data type string
|
||||
* @return corresponding data type, default is `STRING` if the type is missing
|
||||
*/
|
||||
public static DataType typeOf(@Nullable Object type) {
|
||||
if (type != null) {
|
||||
for (DataType datatype : values()) {
|
||||
if (datatype.name().equalsIgnoreCase(type.toString())) {
|
||||
return datatype;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package run.halo.app.model.enums;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Input type enum.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 4/10/19
|
||||
*/
|
||||
public enum InputType {
|
||||
|
||||
TEXT,
|
||||
|
||||
NUMBER,
|
||||
|
||||
RADIO,
|
||||
|
||||
SELECT,
|
||||
|
||||
TEXTAREA;
|
||||
|
||||
/**
|
||||
* Convert type to input type.
|
||||
*
|
||||
* @param type input type
|
||||
* @return corresponding input type or TEXT if the given type is missing or mismatch
|
||||
*/
|
||||
public static InputType typeOf(@Nullable Object type) {
|
||||
if (type != null) {
|
||||
for (InputType inputType : values()) {
|
||||
if (inputType.name().equalsIgnoreCase(type.toString())) {
|
||||
return inputType;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TEXT;
|
||||
}
|
||||
|
||||
}
|
|
@ -36,7 +36,7 @@ public interface ThemeSettingService {
|
|||
* @param themeId theme id must not be blank
|
||||
*/
|
||||
@Transactional
|
||||
void save(@Nullable Map<String, String> settings, @NonNull String themeId);
|
||||
void save(@Nullable Map<String, Object> settings, @NonNull String themeId);
|
||||
|
||||
/**
|
||||
* Lists theme settings by theme id.
|
||||
|
@ -54,5 +54,5 @@ public interface ThemeSettingService {
|
|||
* @return theme setting map
|
||||
*/
|
||||
@NonNull
|
||||
Map<String, String> listAsMapBy(@NonNull String themeId);
|
||||
Map<String, Object> listAsMapBy(@NonNull String themeId);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public class ThemeSettingServiceImpl extends AbstractCrudService<ThemeSetting, I
|
|||
}
|
||||
|
||||
@Override
|
||||
public void save(Map<String, String> settings, String themeId) {
|
||||
public void save(Map<String, Object> settings, String themeId) {
|
||||
assertThemeIdHasText(themeId);
|
||||
|
||||
if (CollectionUtils.isEmpty(settings)) {
|
||||
|
@ -70,7 +70,7 @@ public class ThemeSettingServiceImpl extends AbstractCrudService<ThemeSetting, I
|
|||
}
|
||||
|
||||
// Save the settings
|
||||
settings.forEach((key, value) -> save(key, value, themeId));
|
||||
settings.forEach((key, value) -> save(key, value.toString(), themeId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -81,7 +81,9 @@ public class ThemeSettingServiceImpl extends AbstractCrudService<ThemeSetting, I
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> listAsMapBy(String themeId) {
|
||||
public Map<String, Object> listAsMapBy(String themeId) {
|
||||
|
||||
// TODO Convert to corresponding data type
|
||||
return ServiceUtils.convertToMap(listBy(themeId), ThemeSetting::getKey, ThemeSetting::getValue);
|
||||
}
|
||||
|
||||
|
|
|
@ -85,13 +85,13 @@ public class ThemeController {
|
|||
|
||||
@GetMapping("activation/settings")
|
||||
@ApiOperation("Lists activated theme settings")
|
||||
public Map<String, String> listSettingsBy() {
|
||||
public Map<String, Object> listSettingsBy() {
|
||||
return themeSettingService.listAsMapBy(themeService.getActivatedThemeId());
|
||||
}
|
||||
|
||||
@PostMapping("activation/settings")
|
||||
@ApiOperation("Saves theme settings")
|
||||
public void saveSettingsBy(@RequestBody Map<String, String> settings) {
|
||||
public void saveSettingsBy(@RequestBody Map<String, Object> settings) {
|
||||
themeSettingService.save(settings, themeService.getActivatedThemeId());
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ public class ThemeController {
|
|||
@PostMapping("{themeId}/settings")
|
||||
@ApiOperation("Saves theme settings")
|
||||
public void saveSettingsBy(@PathVariable("themeId") String themeId,
|
||||
@RequestBody Map<String, String> settings) {
|
||||
@RequestBody Map<String, Object> settings) {
|
||||
themeSettingService.save(settings, themeId);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,14 @@ package run.halo.app.utils;
|
|||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import lombok.Data;
|
||||
import org.junit.Test;
|
||||
import org.springframework.lang.Nullable;
|
||||
import run.halo.app.model.enums.DataType;
|
||||
import run.halo.app.model.enums.InputType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Yaml test.
|
||||
|
@ -21,26 +26,358 @@ public class YamlTest {
|
|||
@Test
|
||||
public void readYamlTest() throws IOException {
|
||||
|
||||
String yaml = "style:\n" +
|
||||
" name: Style settings\n" +
|
||||
String yaml = "sns:\n" +
|
||||
" label: 社交资料设置\n" +
|
||||
" items:\n" +
|
||||
" post_title_lower:\n" +
|
||||
" name: post_title_lower\n" +
|
||||
" description: Post title lower\n" +
|
||||
" rss:\n" +
|
||||
" name: rss\n" +
|
||||
" label: RSS\n" +
|
||||
" type: radio\n" +
|
||||
" defaultValue: true\n" +
|
||||
" default: true\n" +
|
||||
" options:\n" +
|
||||
" - value: true\n" +
|
||||
" label: Enabled\n" +
|
||||
" label: 开启\n" +
|
||||
" - value: false\n" +
|
||||
" label: Disabled\n" +
|
||||
" custom_style:\n" +
|
||||
" name: custom_style\n" +
|
||||
" description: Custom style\n" +
|
||||
" type: textarea\n";
|
||||
" label: 关闭\n" +
|
||||
" twitter:\n" +
|
||||
" name: twitter\n" +
|
||||
" label: Twitter\n" +
|
||||
" type: text\n" +
|
||||
" facebook:\n" +
|
||||
" name: facebook\n" +
|
||||
" label: Facebook\n" +
|
||||
" type: text\n" +
|
||||
"style:\n" +
|
||||
" label: 样式设置\n" +
|
||||
" items:\n" +
|
||||
" icon:\n" +
|
||||
" name: icon\n" +
|
||||
" label: 右上角图标\n" +
|
||||
" type: text\n" +
|
||||
" post_title_uppper:\n" +
|
||||
" name: post_title_uppper\n" +
|
||||
" label: 文章标题大写\n" +
|
||||
" type: radio\n" +
|
||||
" default: true\n" +
|
||||
" options:\n" +
|
||||
" - value: true\n" +
|
||||
" label: 开启\n" +
|
||||
" - value: false\n" +
|
||||
" label: 关闭";
|
||||
|
||||
Object config = yamlMapper.readValue(yaml, Object.class);
|
||||
LinkedHashMap config = yamlMapper.readValue(yaml, LinkedHashMap.class);
|
||||
|
||||
System.out.println(config.getClass());
|
||||
|
||||
System.out.println(jsonMapper.writeValueAsString(config));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void readAnotherYamlTest() throws IOException {
|
||||
String yaml = "sns:\n" +
|
||||
" label: 社交资料设置\n" +
|
||||
" items:\n" +
|
||||
" - name: rss\n" +
|
||||
" label: RSS\n" +
|
||||
" type: radio\n" +
|
||||
" default: true\n" +
|
||||
" options:\n" +
|
||||
" - value: true\n" +
|
||||
" label: 开启\n" +
|
||||
" - value: false\n" +
|
||||
" label: 关闭\n" +
|
||||
" - name: twitter\n" +
|
||||
" label: Twitter\n" +
|
||||
" type: text\n" +
|
||||
" - name: facebook\n" +
|
||||
" label: Facebook\n" +
|
||||
" type: text\n" +
|
||||
" - name: instagram\n" +
|
||||
" label: Instagram\n" +
|
||||
" type: text\n" +
|
||||
"style:\n" +
|
||||
" label: 样式设置\n" +
|
||||
" items:\n" +
|
||||
" - name: icon\n" +
|
||||
" label: 右上角图标\n" +
|
||||
" type: text\n" +
|
||||
" - name: post_title_uppper\n" +
|
||||
" label: 文章标题大写\n" +
|
||||
" type: radio\n" +
|
||||
" default: true\n" +
|
||||
" options:\n" +
|
||||
" - value: true\n" +
|
||||
" label: 开启\n" +
|
||||
" - value: false\n" +
|
||||
" label: 关闭\n" +
|
||||
" - name: blog_title_uppper\n" +
|
||||
" label: 博客标题大写\n" +
|
||||
" type: radio\n" +
|
||||
" default: true\n" +
|
||||
" options:\n" +
|
||||
" - value: true\n" +
|
||||
" label: 开启\n" +
|
||||
" - value: false\n" +
|
||||
" label: 关闭\n";
|
||||
|
||||
Object config = yamlMapper.readValue(yaml, Object.class);
|
||||
|
||||
List<Tab> tabs = handleTabs(config);
|
||||
|
||||
System.out.println(config.getClass());
|
||||
|
||||
System.out.println(tabs);
|
||||
|
||||
System.out.println(jsonMapper.writeValueAsString(config));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertYamlTest() throws IOException {
|
||||
String yaml = "- name: sns\n" +
|
||||
" label: 社交资料设置\n" +
|
||||
" items:\n" +
|
||||
" - name: rss\n" +
|
||||
" label: RSS\n" +
|
||||
" type: radio\n" +
|
||||
" default: true\n" +
|
||||
" options:\n" +
|
||||
" - value: true\n" +
|
||||
" label: 开启\n" +
|
||||
" - value: false\n" +
|
||||
" label: 关闭\n" +
|
||||
" - name: twitter\n" +
|
||||
" label: Twitter\n" +
|
||||
" type: text\n" +
|
||||
" - name: facebook\n" +
|
||||
" label: Facebook\n" +
|
||||
" type: text\n" +
|
||||
" - name: instagram\n" +
|
||||
" label: Instagram\n" +
|
||||
" type: text\n" +
|
||||
"- name: style\n" +
|
||||
" label: 样式设置\n" +
|
||||
" items:\n" +
|
||||
" - name: icon\n" +
|
||||
" label: 右上角图标\n" +
|
||||
" type: text\n" +
|
||||
" - name: post_title_uppper\n" +
|
||||
" label: 文章标题大写\n" +
|
||||
" type: radio\n" +
|
||||
" default: true\n" +
|
||||
" options:\n" +
|
||||
" - value: true\n" +
|
||||
" label: 开启\n" +
|
||||
" - value: false\n" +
|
||||
" label: 关闭\n" +
|
||||
" - name: blog_title_uppper\n" +
|
||||
" label: 博客标题大写\n" +
|
||||
" type: radio\n" +
|
||||
" default: true\n" +
|
||||
" options:\n" +
|
||||
" - value: true\n" +
|
||||
" label: 开启\n" +
|
||||
" - value: false\n" +
|
||||
" label: 关闭";
|
||||
|
||||
|
||||
Object config = yamlMapper.readValue(yaml, Object.class);
|
||||
|
||||
List<Tab> tabs = handleTabs(config);
|
||||
|
||||
System.out.println(config.getClass());
|
||||
|
||||
System.out.print(tabs);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Tab> handleTabs(@Nullable Object config) {
|
||||
List<Tab> tabs = new LinkedList<>();
|
||||
|
||||
if (config instanceof List) {
|
||||
List configList = (List) config;
|
||||
|
||||
// Resolve tab
|
||||
|
||||
configList.forEach(tabYaml -> {
|
||||
// tabYaml should be map
|
||||
if (!(tabYaml instanceof Map)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map tabMap = ((Map) tabYaml);
|
||||
|
||||
Tab tab = new Tab();
|
||||
|
||||
tab.setName(tabMap.get("name").toString());
|
||||
tab.setLabel(tabMap.get("label").toString());
|
||||
|
||||
// Handle items
|
||||
tab.setItems(handleItems(tabMap.get("items")));
|
||||
|
||||
tabs.add(tab);
|
||||
});
|
||||
|
||||
} else if (config instanceof Map) {
|
||||
Map configMap = (Map) config;
|
||||
configMap.forEach((key, value) -> {
|
||||
// key: tab name
|
||||
// value: tab property, should be a map
|
||||
if (!(value instanceof Map)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map tabMap = (Map) value;
|
||||
|
||||
Tab tab = new Tab();
|
||||
|
||||
tab.setName(key.toString());
|
||||
tab.setLabel(tabMap.get("label").toString());
|
||||
|
||||
// Handle items
|
||||
tab.setItems(handleItems(tabMap.get("items")));
|
||||
|
||||
tabs.add(tab);
|
||||
});
|
||||
}
|
||||
|
||||
return tabs;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Item> handleItems(@Nullable Object items) {
|
||||
|
||||
if (items == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<Item> result = new LinkedList<>();
|
||||
|
||||
if (items instanceof List) {
|
||||
((List) items).forEach(itemYaml -> {
|
||||
if (!(itemYaml instanceof Map)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Should be Map
|
||||
Map itemMap = (Map) itemYaml;
|
||||
|
||||
// Build item
|
||||
Item item = new Item();
|
||||
|
||||
item.setName(itemMap.get("name").toString());
|
||||
item.setLabel(itemMap.getOrDefault("label", item.getName()).toString());
|
||||
item.setDataType(DataType.typeOf(itemMap.get("data_type")));
|
||||
item.setType(InputType.typeOf(itemMap.get("type")));
|
||||
item.setDefaultValue(itemMap.get("default"));
|
||||
|
||||
// Handle options
|
||||
item.setOptions(handleOptions(itemMap.get("options")));
|
||||
|
||||
// Add item
|
||||
result.add(item);
|
||||
});
|
||||
} else if (items instanceof Map) {
|
||||
Map itemsMap = (Map) items;
|
||||
|
||||
itemsMap.forEach((key, value) -> {
|
||||
if (!(value instanceof Map)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map itemMap = (Map) value;
|
||||
|
||||
// key: item name
|
||||
Item item = new Item();
|
||||
item.setName(key.toString());
|
||||
item.setLabel(itemMap.getOrDefault("label", item.getName()).toString());
|
||||
item.setDataType(DataType.typeOf(itemMap.get("data_type")));
|
||||
item.setType(InputType.typeOf(itemMap.get("type")));
|
||||
item.setDefaultValue(itemMap.get("default"));
|
||||
|
||||
// Handle options
|
||||
item.setOptions(handleOptions(itemMap.get("options")));
|
||||
|
||||
// Add item
|
||||
result.add(item);
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Option> handleOptions(@Nullable Object options) {
|
||||
|
||||
if (options == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<Option> result = new LinkedList<>();
|
||||
|
||||
if (options instanceof List) {
|
||||
((List) options).forEach(optionYaml -> {
|
||||
// optionYaml should be Map
|
||||
if (!(optionYaml instanceof Map)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map optionMap = (Map) optionYaml;
|
||||
|
||||
// Build option
|
||||
Option option = new Option();
|
||||
// TODO Convert the value type
|
||||
option.setValue(optionMap.get("value"));
|
||||
option.setLabel(optionMap.get("label").toString());
|
||||
|
||||
result.add(option);
|
||||
});
|
||||
} else if (options instanceof Map) {
|
||||
Map optionsMap = (Map) options;
|
||||
optionsMap.forEach((key, value) -> {
|
||||
// key: option value
|
||||
// value: Map that contains option label
|
||||
|
||||
if (!(value instanceof Map)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map optionMap = (Map) value;
|
||||
|
||||
|
||||
Option option = new Option();
|
||||
// TODO Convert the value type
|
||||
option.setValue(key);
|
||||
option.setLabel(optionMap.get("label").toString());
|
||||
|
||||
result.add(option);
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Data
|
||||
private class Tab {
|
||||
private String name;
|
||||
private String label;
|
||||
private List<Item> items;
|
||||
}
|
||||
|
||||
@Data
|
||||
private class Item {
|
||||
private String name;
|
||||
private String label;
|
||||
private InputType type;
|
||||
private DataType dataType;
|
||||
private Object defaultValue;
|
||||
|
||||
private List<Option> options;
|
||||
}
|
||||
|
||||
@Data
|
||||
private class Option {
|
||||
private String label;
|
||||
private Object value;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue