blob: c2d2f0fd016d2db45264f94155b3bd4c4c1885c3 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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.
package storage
import (
"github.com/apache/dubbo-kubernetes/pkg/bufman/pkg/normalpath"
)
// Matcher is a path matcher.
//
// This will cause a Bucket to operate as if it only contains matching paths.
type Matcher interface {
Mapper
isMatcher()
}
// MatchPathExt returns a Matcher for the extension.
func MatchPathExt(ext string) Matcher {
return pathMatcherFunc(func(path string) bool {
return normalpath.Ext(path) == ext
})
}
// MatchPathBase returns a Matcher for the base.
func MatchPathBase(base string) Matcher {
return pathMatcherFunc(func(path string) bool {
return normalpath.Base(path) == base
})
}
// MatchPathEqual returns a Matcher for the path.
func MatchPathEqual(equalPath string) Matcher {
return pathMatcherFunc(func(path string) bool {
return path == equalPath
})
}
// MatchPathEqualOrContained returns a Matcher for the path that matches
// on paths equal or contained by equalOrContainingPath.
func MatchPathEqualOrContained(equalOrContainingPath string) Matcher {
return pathMatcherFunc(func(path string) bool {
return normalpath.EqualsOrContainsPath(equalOrContainingPath, path, normalpath.Relative)
})
}
// MatchPathContained returns a Matcher for the directory that matches
// on paths by contained by containingDir.
func MatchPathContained(containingDir string) Matcher {
return pathMatcherFunc(func(path string) bool {
return normalpath.ContainsPath(containingDir, path, normalpath.Relative)
})
}
// MatchOr returns an Or of the Matchers.
func MatchOr(matchers ...Matcher) Matcher {
return orMatcher(matchers)
}
// MatchAnd returns an And of the Matchers.
func MatchAnd(matchers ...Matcher) Matcher {
return andMatcher(matchers)
}
// MatchNot returns an Not of the Matcher.
func MatchNot(matcher Matcher) Matcher {
return notMatcher{matcher}
}
// ***** private *****
// We limit or/and/not to Matchers as composite logic must assume
// the the input path is not modified, so that we can always return it
//
// We might want to just remove Matcher implementing Mapper for simplification,
// and just have a Matches function, then handle chaining them separately.
type pathMatcherFunc func(string) bool
func (f pathMatcherFunc) MapPath(path string) (string, bool) {
matches := f(path)
return path, matches
}
func (f pathMatcherFunc) MapPrefix(prefix string) (string, bool) {
// always returns true, path matchers do not check prefixes
return prefix, true
}
func (f pathMatcherFunc) UnmapFullPath(fullPath string) (string, bool, error) {
matches := f(fullPath)
return fullPath, matches, nil
}
func (pathMatcherFunc) isMatcher() {}
func (pathMatcherFunc) isMapper() {}
type orMatcher []Matcher
func (o orMatcher) MapPath(path string) (string, bool) {
for _, matcher := range o {
if _, matches := matcher.MapPath(path); matches {
return path, true
}
}
return "", false
}
func (o orMatcher) MapPrefix(prefix string) (string, bool) {
for _, matcher := range o {
if _, matches := matcher.MapPrefix(prefix); matches {
return prefix, true
}
}
return "", false
}
func (o orMatcher) UnmapFullPath(fullPath string) (string, bool, error) {
for _, matcher := range o {
_, matches, err := matcher.UnmapFullPath(fullPath)
if err != nil {
return "", false, err
}
if matches {
return fullPath, true, nil
}
}
return fullPath, false, nil
}
func (orMatcher) isMatcher() {}
func (orMatcher) isMapper() {}
type andMatcher []Matcher
func (a andMatcher) MapPath(path string) (string, bool) {
for _, matcher := range a {
if _, matches := matcher.MapPath(path); !matches {
return path, false
}
}
return path, true
}
func (a andMatcher) MapPrefix(prefix string) (string, bool) {
for _, matcher := range a {
if _, matches := matcher.MapPrefix(prefix); !matches {
return prefix, false
}
}
return prefix, true
}
func (a andMatcher) UnmapFullPath(fullPath string) (string, bool, error) {
for _, matcher := range a {
_, matches, err := matcher.UnmapFullPath(fullPath)
if err != nil {
return "", false, err
}
if !matches {
return fullPath, false, nil
}
}
return fullPath, true, nil
}
func (andMatcher) isMatcher() {}
func (andMatcher) isMapper() {}
type notMatcher struct {
delegate Matcher
}
func (n notMatcher) MapPath(path string) (string, bool) {
_, matches := n.delegate.MapPath(path)
return path, !matches
}
func (n notMatcher) MapPrefix(prefix string) (string, bool) {
_, matches := n.delegate.MapPath(prefix)
return prefix, !matches
}
func (n notMatcher) UnmapFullPath(fullPath string) (string, bool, error) {
_, matches, err := n.delegate.UnmapFullPath(fullPath)
if err != nil {
return "", false, err
}
return fullPath, !matches, nil
}
func (notMatcher) isMatcher() {}
func (notMatcher) isMapper() {}