mirror of
https://github.com/cs3org/reva.git
synced 2025-04-18 13:44:12 +03:00
137 lines
3.8 KiB
Go
137 lines
3.8 KiB
Go
// Copyright 2018-2024 CERN
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
// In applying this license, CERN does not waive the privileges and immunities
|
|
// granted to it by virtue of its status as an Intergovernmental Organization
|
|
// or submit itself to any jurisdiction.
|
|
|
|
package reva
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// Plugin is a type used as reva plugin.
|
|
// The type may implement something useful, depending
|
|
// on what is possible to plug in.
|
|
type Plugin interface {
|
|
// RevaPlugin returns the plugin info, like the ID
|
|
// in the form of <namespace>.<name>, and a New func
|
|
// used to create the plugin.
|
|
// The namespace can be only one defined by reva,
|
|
// depending on the scope of the plugin, while the name
|
|
// can be whatever, but unique in the namespace.
|
|
RevaPlugin() PluginInfo
|
|
}
|
|
|
|
// PluginInfo holds the information of a reva plugin.
|
|
type PluginInfo struct {
|
|
// ID is the full name of the plugin, in the form
|
|
// <namespace>.<name>. It must be unique.
|
|
ID PluginID
|
|
// New is the constructor of the plugin. We rely
|
|
// on the developer to correctly provide a valid
|
|
// construct depending on the plugin.
|
|
New any
|
|
}
|
|
|
|
// String return a string representation of the PluginInfo.
|
|
func (pi PluginInfo) String() string { return string(pi.ID) }
|
|
|
|
// PluginID is the string that uniquely identify a reva plugin.
|
|
// It consists of a dot-separated labels. The last label is the
|
|
// name of the plugin, while the labels before represents the
|
|
// namespace.
|
|
// A pluginID is in the form <namespace>.<name>
|
|
// Neither the name nor the namespace can be empty.
|
|
// The name cannot contain dots.
|
|
// ModuleIDs shuld be lowercase and use underscores (_) instead
|
|
// of spaces.
|
|
type PluginID string
|
|
|
|
var registry = map[string]Plugin{}
|
|
|
|
// Name returns the name of the Plugin ID (i.e. the last name).
|
|
func (i PluginID) Name() string {
|
|
parts := strings.Split(string(i), ".")
|
|
if len(parts) <= 1 {
|
|
panic("plugin id must be <namespace>.<name>")
|
|
}
|
|
return parts[len(parts)-1]
|
|
}
|
|
|
|
// Namespace returns the namespace of the plugin ID, which is
|
|
// all but the last label of the ID.
|
|
func (i PluginID) Namespace() string {
|
|
idx := strings.LastIndex(string(i), ".")
|
|
if idx < 0 {
|
|
panic("plugin id must be <namespace>.<name>")
|
|
}
|
|
return string(i)[:idx]
|
|
}
|
|
|
|
// RegisterPlugin registers a reva plugin. For registration
|
|
// this method should be called in the init() method.
|
|
func RegisterPlugin(p Plugin) {
|
|
if p == nil {
|
|
panic("plugin cannot be nil")
|
|
}
|
|
plug := p.RevaPlugin()
|
|
if plug.ID == "" {
|
|
panic("plugin id cannot be nil")
|
|
}
|
|
if plug.New == nil {
|
|
panic("plugin new func cannot be nil")
|
|
}
|
|
|
|
registry[string(p.RevaPlugin().ID)] = p
|
|
}
|
|
|
|
func hasPrefixSlices(s, prefix []string) bool {
|
|
if len(prefix) > len(s) {
|
|
return false
|
|
}
|
|
for i := range prefix {
|
|
if s[i] != prefix[i] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// GetPlugins returns all the plugins in the given namespace,
|
|
// and their descendants.
|
|
// For example, a namespace "foo" returns modules with id "foo",
|
|
// "foo.bar", "foo.bar.foo", but not "bar".
|
|
func GetPlugins(ns string) []PluginInfo {
|
|
prefix := strings.Split(ns, ".")
|
|
if ns == "" {
|
|
prefix = []string{}
|
|
}
|
|
|
|
var plugs []PluginInfo
|
|
for ns, p := range registry {
|
|
nsParts := strings.Split(ns, ".")
|
|
if hasPrefixSlices(nsParts, prefix) {
|
|
plugs = append(plugs, p.RevaPlugin())
|
|
}
|
|
}
|
|
|
|
sort.SliceStable(plugs, func(i, j int) bool {
|
|
return plugs[i].ID < plugs[j].ID
|
|
})
|
|
return plugs
|
|
}
|