| // 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() {} |