1//  Copyright (c) 2014 Couchbase, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// 		http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package registry
16
17import (
18	"fmt"
19
20	"github.com/blevesearch/bleve/analysis"
21)
22
23func RegisterCharFilter(name string, constructor CharFilterConstructor) {
24	_, exists := charFilters[name]
25	if exists {
26		panic(fmt.Errorf("attempted to register duplicate char filter named '%s'", name))
27	}
28	charFilters[name] = constructor
29}
30
31type CharFilterConstructor func(config map[string]interface{}, cache *Cache) (analysis.CharFilter, error)
32type CharFilterRegistry map[string]CharFilterConstructor
33
34type CharFilterCache struct {
35	*ConcurrentCache
36}
37
38func NewCharFilterCache() *CharFilterCache {
39	return &CharFilterCache{
40		NewConcurrentCache(),
41	}
42}
43
44func CharFilterBuild(name string, config map[string]interface{}, cache *Cache) (interface{}, error) {
45	cons, registered := charFilters[name]
46	if !registered {
47		return nil, fmt.Errorf("no char filter with name or type '%s' registered", name)
48	}
49	charFilter, err := cons(config, cache)
50	if err != nil {
51		return nil, fmt.Errorf("error building char filter: %v", err)
52	}
53	return charFilter, nil
54}
55
56func (c *CharFilterCache) CharFilterNamed(name string, cache *Cache) (analysis.CharFilter, error) {
57	item, err := c.ItemNamed(name, cache, CharFilterBuild)
58	if err != nil {
59		return nil, err
60	}
61	return item.(analysis.CharFilter), nil
62}
63
64func (c *CharFilterCache) DefineCharFilter(name string, typ string, config map[string]interface{}, cache *Cache) (analysis.CharFilter, error) {
65	item, err := c.DefineItem(name, typ, config, cache, CharFilterBuild)
66	if err != nil {
67		if err == ErrAlreadyDefined {
68			return nil, fmt.Errorf("char filter named '%s' already defined", name)
69		}
70		return nil, err
71	}
72	return item.(analysis.CharFilter), nil
73}
74
75func CharFilterTypesAndInstances() ([]string, []string) {
76	emptyConfig := map[string]interface{}{}
77	emptyCache := NewCache()
78	var types []string
79	var instances []string
80	for name, cons := range charFilters {
81		_, err := cons(emptyConfig, emptyCache)
82		if err == nil {
83			instances = append(instances, name)
84		} else {
85			types = append(types, name)
86		}
87	}
88	return types, instances
89}
90