View Javadoc
1   /*
2    * Copyright 2013 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty5.channel.group;
17  
18  import io.netty5.channel.Channel;
19  import io.netty5.channel.ServerChannel;
20  
21  /**
22   * Helper class which provides often used {@link ChannelMatcher} implementations.
23   */
24  public final class ChannelMatchers {
25  
26      private static final ChannelMatcher ALL_MATCHER = channel -> true;
27  
28      private static final ChannelMatcher SERVER_CHANNEL_MATCHER = isInstanceOf(ServerChannel.class);
29      private static final ChannelMatcher NON_SERVER_CHANNEL_MATCHER = isNotInstanceOf(ServerChannel.class);
30  
31      private ChannelMatchers() {
32          // static methods only
33      }
34  
35      /**
36       * Returns a {@link ChannelMatcher} that matches all {@link Channel}s.
37       */
38      public static ChannelMatcher all() {
39          return ALL_MATCHER;
40      }
41  
42      /**
43       * Returns a {@link ChannelMatcher} that matches all {@link Channel}s except the given.
44       */
45      public static ChannelMatcher isNot(Channel channel) {
46          return invert(is(channel));
47      }
48  
49      /**
50       * Returns a {@link ChannelMatcher} that matches the given {@link Channel}.
51       */
52      public static ChannelMatcher is(Channel channel) {
53          return new InstanceMatcher(channel);
54      }
55  
56      /**
57       * Returns a {@link ChannelMatcher} that matches all {@link Channel}s that are an instance of sub-type of
58       * the given class.
59       */
60      public static ChannelMatcher isInstanceOf(Class<? extends Channel> clazz) {
61          return new ClassMatcher(clazz);
62      }
63  
64      /**
65       * Returns a {@link ChannelMatcher} that matches all {@link Channel}s that are <strong>not</strong> an
66       * instance of sub-type of the given class.
67       */
68      public static ChannelMatcher isNotInstanceOf(Class<? extends Channel> clazz) {
69          return invert(isInstanceOf(clazz));
70      }
71  
72      /**
73       * Returns a {@link ChannelMatcher} that matches all {@link Channel}s that are of type {@link ServerChannel}.
74       */
75      public static ChannelMatcher isServerChannel() {
76           return SERVER_CHANNEL_MATCHER;
77      }
78  
79      /**
80       * Returns a {@link ChannelMatcher} that matches all {@link Channel}s that are <strong>not</strong> of type
81       * {@link ServerChannel}.
82       */
83      public static ChannelMatcher isNonServerChannel() {
84          return NON_SERVER_CHANNEL_MATCHER;
85      }
86  
87      /**
88       * Invert the given {@link ChannelMatcher}.
89       */
90      public static ChannelMatcher invert(ChannelMatcher matcher) {
91          return new InvertMatcher(matcher);
92      }
93  
94      /**
95       * Return a composite of the given {@link ChannelMatcher}s. This means all {@link ChannelMatcher} must
96       * return {@code true} to match.
97       */
98      public static ChannelMatcher compose(ChannelMatcher... matchers) {
99          if (matchers.length < 1) {
100             throw new IllegalArgumentException("matchers must at least contain one element");
101         }
102         if (matchers.length == 1) {
103             return matchers[0];
104         }
105         return new CompositeMatcher(matchers);
106     }
107 
108     private static final class CompositeMatcher implements ChannelMatcher {
109         private final ChannelMatcher[] matchers;
110 
111         CompositeMatcher(ChannelMatcher... matchers) {
112             this.matchers = matchers;
113         }
114 
115         @Override
116         public boolean matches(Channel channel) {
117             for (ChannelMatcher m: matchers) {
118                 if (!m.matches(channel)) {
119                     return false;
120                 }
121             }
122             return true;
123         }
124     }
125 
126     private static final class InvertMatcher implements ChannelMatcher {
127         private final ChannelMatcher matcher;
128 
129         InvertMatcher(ChannelMatcher matcher) {
130             this.matcher = matcher;
131         }
132 
133         @Override
134         public boolean matches(Channel channel) {
135             return !matcher.matches(channel);
136         }
137     }
138 
139     private static final class InstanceMatcher implements ChannelMatcher {
140         private final Channel channel;
141 
142         InstanceMatcher(Channel channel) {
143             this.channel = channel;
144         }
145 
146         @Override
147         public boolean matches(Channel ch) {
148             return channel == ch;
149         }
150     }
151 
152     private static final class ClassMatcher implements ChannelMatcher {
153         private final Class<? extends Channel> clazz;
154 
155         ClassMatcher(Class<? extends Channel> clazz) {
156             this.clazz = clazz;
157         }
158 
159         @Override
160         public boolean matches(Channel ch) {
161             return clazz.isInstance(ch);
162         }
163     }
164 }