2018-01-13 19:08:46 +01:00
|
|
|
package filter
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2019-01-17 13:26:16 +01:00
|
|
|
"github.com/bdlm/log"
|
2018-01-13 19:08:46 +01:00
|
|
|
"github.com/pkg/errors"
|
2019-01-17 13:26:16 +01:00
|
|
|
|
|
|
|
"github.com/FreifunkBremen/yanic/runtime"
|
2018-01-13 19:08:46 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// factory function for building a filter
|
|
|
|
// may return nil if the filter never applies
|
|
|
|
type factory func(interface{}) (Filter, error)
|
|
|
|
|
|
|
|
// Filter is a filter instance
|
|
|
|
type Filter interface {
|
|
|
|
Apply(*runtime.Node) *runtime.Node
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set is a list of configured filters
|
|
|
|
type Set []Filter
|
|
|
|
|
|
|
|
var filters = make(map[string]factory)
|
|
|
|
|
|
|
|
// Register registers a new filter
|
|
|
|
func Register(name string, f factory) {
|
|
|
|
if _, ok := filters[name]; ok {
|
2019-01-17 13:26:16 +01:00
|
|
|
log.WithField("filter", name).Panic("filter already registered")
|
2018-01-13 19:08:46 +01:00
|
|
|
}
|
|
|
|
filters[name] = f
|
|
|
|
}
|
|
|
|
|
|
|
|
// New returns and initializes a set of filters
|
|
|
|
func New(configs map[string]interface{}) (set Set, errs []error) {
|
|
|
|
for name, config := range configs {
|
|
|
|
if config == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-03-28 03:56:00 +02:00
|
|
|
f := filters[name]
|
2018-01-13 19:08:46 +01:00
|
|
|
if f == nil {
|
|
|
|
errs = append(errs, fmt.Errorf("unknown filter: %s", name))
|
|
|
|
} else if filter, err := f(config); err != nil {
|
|
|
|
errs = append(errs, errors.Wrapf(err, "unable to initialize filter %s", name))
|
|
|
|
} else if filter != nil {
|
|
|
|
set = append(set, filter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Apply applies the filter set to the given node list and returns a new node list
|
|
|
|
func (set Set) Apply(nodesOrigin *runtime.Nodes) *runtime.Nodes {
|
|
|
|
nodes := runtime.NewNodes(&runtime.NodesConfig{})
|
|
|
|
|
|
|
|
nodesOrigin.Lock()
|
|
|
|
defer nodesOrigin.Unlock()
|
|
|
|
|
|
|
|
for _, nodeOrigin := range nodesOrigin.List {
|
|
|
|
//maybe cloning of this object is better?
|
|
|
|
node := nodeOrigin
|
|
|
|
for _, filter := range set {
|
|
|
|
node = filter.Apply(node)
|
|
|
|
if node == nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if node != nil {
|
|
|
|
nodes.AddNode(node)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nodes
|
|
|
|
}
|