1   // ========================================================================
2   // Copyright 2007 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // Licensed under the Apache License, Version 2.0 (the "License");
5   // you may not use this file except in compliance with the License.
6   // You may obtain a copy of the License at 
7   // http://www.apache.org/licenses/LICENSE-2.0
8   // Unless required by applicable law or agreed to in writing, software
9   // distributed under the License is distributed on an "AS IS" BASIS,
10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  // See the License for the specific language governing permissions and
12  // limitations under the License.
13  //========================================================================
14  
15  package org.mortbay.cometd;
16  
17  
18  
19  
20  public class ChannelId
21  {
22      public final static String WILD="*";
23      public final static String WILDWILD="**";
24      
25      private static final String[] ROOT = {};
26      String _name;
27      String[] _segments;
28      int _wild;
29      
30      public ChannelId(String name)
31      {
32          _name=name;
33          if (name==null || name.length()==0 || name.charAt(0)!='/')
34              throw new IllegalArgumentException(name);
35          
36          if ("/".equals(name))
37          {
38              _segments=ROOT;
39          }
40          else
41          {
42              if (name.charAt(name.length()-1)=='/')
43                  throw new IllegalArgumentException(name);
44                  
45              _segments=name.substring(1).split("/");
46          }
47          
48          if (_segments.length==0)
49              _wild=0;
50          else if (WILD.equals(_segments[_segments.length-1]))
51              _wild=1;
52          else if (WILDWILD.equals(_segments[_segments.length-1]))
53              _wild=2;
54      }
55      
56      public boolean isWild()
57      {
58          return _wild>0;
59      }
60      
61      public boolean equals(Object obj)
62      {
63          if (this==obj)
64              return true;
65          
66          if (obj instanceof ChannelId)
67          {
68              ChannelId other=(ChannelId)obj;
69              if (isWild())
70              {
71                  if (other.isWild())
72                      return _name.equals(other._name);
73                  return matches(other);
74              }
75              else
76              {
77                  if (other.isWild())
78                      return other.matches(this);
79                  return _name.equals(other._name);
80              }
81          }
82          else if (obj instanceof String)
83          {
84              if (isWild())
85                  return matches((String)obj);
86              return _name.equals(obj);
87          }
88              
89          return false;
90      }
91  
92      public boolean matches(ChannelId name)
93      {
94          if (name.isWild())
95              return equals(name);
96          
97          switch(_wild)
98          {
99              case 0:
100                 return equals(name);
101             case 1:
102                 if (name._segments.length!=_segments.length)
103                     return false;
104                 for (int i=_segments.length-1;i-->0;)
105                     if (!_segments[i].equals(name._segments[i]))
106                         return false;
107                 return true;
108                 
109             case 2:
110                 if (name._segments.length<_segments.length)
111                     return false;
112                 for (int i=_segments.length-1;i-->0;)
113                     if (!_segments[i].equals(name._segments[i]))
114                         return false;
115                 return true;
116         }
117         return false;
118     }
119 
120     public boolean matches(String name)
121     {
122         if (_wild==0)
123             return _name.equals(name);
124         
125         // TODO more efficient?
126         return matches(new ChannelId(name));
127     }
128     
129     public int hashCode()
130     {
131         return _name.hashCode();
132     }
133 
134     public String toString()
135     {
136         return _name;
137     }
138     
139     public int depth()
140     {
141         return _segments.length;
142     }
143 
144     public boolean isParentOf(ChannelId id)
145     {
146         if (isWild() || depth()>=id.depth())
147             return false;
148 
149         for (int i=_segments.length-1;i-->0;)
150             if (!_segments[i].equals(id._segments[i]))
151                 return false;
152         
153         return true;
154     }
155 
156     public String getSegment(int i)
157     {
158         if (i>_segments.length)
159             return null;
160         return _segments[i];
161     }
162 }