Capstan is a Golang web framework that shares some similarities with others in its segment.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
2.8KB

  1. package capstan
  2. import (
  3. "net/http"
  4. "sync"
  5. )
  6. // TODO: Extensions should be included in the server configuration so they can
  7. // be initialized with the consideration of their dependencies. At the moment,
  8. // they're initialized as they're loaded.
  9. type Extension interface {
  10. // Name for this extension; symbolic.
  11. Name() string
  12. // Provides indicates the dependency fulfilled by this extension.
  13. Provides() string
  14. // Requires indicates which dependency or dependencies must be loaded prior
  15. // to this extension.
  16. Requires() []string
  17. // Init this extension. This is called after the extension has been loaded;
  18. // for extensions that have dependencies on other extensions, this is called
  19. // after the dependency has been loaded. Circular dependencies will result
  20. // in a panic.
  21. Init(app *Application)
  22. }
  23. type MiddlewareExtension interface {
  24. Extension
  25. // Middleware should return any middleware required by this extension.
  26. Middleware() []func(http.Handler) http.Handler
  27. }
  28. type DependencyMapperExtension interface {
  29. Extension
  30. // Dependency name and value for automatically binding this extension into
  31. // the dependency mapper. Most extensions will prefer doing this manually
  32. // via calling the dependency mapper directly after SetServer passes in the
  33. // active Capstan.Server instance, but implementing this interface allows
  34. // the Capstan extension manager to perform the function automatically. The
  35. // returned interface may be the extension itself or it may be any other
  36. // value/structure used by the extension.
  37. //
  38. // Bear in mind that whatever value is exported via this method must also be
  39. // importable from the defined controllers that rely on the dependency.
  40. Dependency() (string, interface{})
  41. }
  42. type ExtensionManager struct {
  43. extensions map[string]Extension
  44. provides map[string]Extension
  45. depends map[string][]Extension
  46. app *Application
  47. sync.RWMutex
  48. }
  49. func NewExtensionManager(app *Application) *ExtensionManager {
  50. return &ExtensionManager{
  51. extensions: make(map[string]Extension),
  52. provides: make(map[string]Extension),
  53. depends: make(map[string][]Extension),
  54. app: app,
  55. }
  56. }
  57. func (m *ExtensionManager) Init() *ExtensionManager {
  58. for _, ext := range m.extensions {
  59. ext.Init(m.app)
  60. }
  61. return m
  62. }
  63. func (m *ExtensionManager) Register(extension Extension) error {
  64. m.Lock()
  65. m.extensions[extension.Name()] = extension
  66. /*m.provides[extension.Provides()] = extension
  67. failed := make([]string, 0)
  68. if len(extension.Requires()) > 0 {
  69. for _, requirement := range extension.Requires() {
  70. if _, ok := m.provides[requirement]; !ok {
  71. failed = append(failed, requirement)
  72. }
  73. }
  74. }
  75. if len(failed) > 0 {
  76. return errors.New("failed dependencies: requires (missing): " +
  77. strings.Join(failed, ", "))
  78. }*/
  79. m.Unlock()
  80. extension.Init(m.app)
  81. return nil
  82. }