loader.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package conf
  2. import (
  3. "encoding/json"
  4. "strings"
  5. )
  6. type ConfigCreator func() interface{}
  7. type ConfigCreatorCache map[string]ConfigCreator
  8. func (v ConfigCreatorCache) RegisterCreator(id string, creator ConfigCreator) error {
  9. if _, found := v[id]; found {
  10. return newError(id, " already registered.").AtError()
  11. }
  12. v[id] = creator
  13. return nil
  14. }
  15. func (v ConfigCreatorCache) CreateConfig(id string) (interface{}, error) {
  16. creator, found := v[id]
  17. if !found {
  18. return nil, newError("unknown config id: ", id)
  19. }
  20. return creator(), nil
  21. }
  22. type JSONConfigLoader struct {
  23. cache ConfigCreatorCache
  24. idKey string
  25. configKey string
  26. }
  27. func NewJSONConfigLoader(cache ConfigCreatorCache, idKey string, configKey string) *JSONConfigLoader {
  28. return &JSONConfigLoader{
  29. idKey: idKey,
  30. configKey: configKey,
  31. cache: cache,
  32. }
  33. }
  34. func (v *JSONConfigLoader) LoadWithID(raw []byte, id string) (interface{}, error) {
  35. id = strings.ToLower(id)
  36. config, err := v.cache.CreateConfig(id)
  37. if err != nil {
  38. return nil, err
  39. }
  40. if err := json.Unmarshal(raw, config); err != nil {
  41. return nil, err
  42. }
  43. return config, nil
  44. }
  45. func (v *JSONConfigLoader) Load(raw []byte) (interface{}, string, error) {
  46. var obj map[string]json.RawMessage
  47. if err := json.Unmarshal(raw, &obj); err != nil {
  48. return nil, "", err
  49. }
  50. rawID, found := obj[v.idKey]
  51. if !found {
  52. return nil, "", newError(v.idKey, " not found in JSON context").AtError()
  53. }
  54. var id string
  55. if err := json.Unmarshal(rawID, &id); err != nil {
  56. return nil, "", err
  57. }
  58. rawConfig := json.RawMessage(raw)
  59. if len(v.configKey) > 0 {
  60. configValue, found := obj[v.configKey]
  61. if found {
  62. rawConfig = configValue
  63. } else {
  64. // Default to empty json object.
  65. rawConfig = json.RawMessage([]byte("{}"))
  66. }
  67. }
  68. config, err := v.LoadWithID([]byte(rawConfig), id)
  69. if err != nil {
  70. return nil, id, err
  71. }
  72. return config, id, nil
  73. }