View Javadoc

1   /*
2      Copyright 2008 Ramon Servadei
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   
8          http://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,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15   */
16  package fulmine.event.subscription;
17  
18  import java.util.regex.Pattern;
19  
20  import fulmine.Addressable;
21  import fulmine.IAddressable;
22  import fulmine.IDomain;
23  import fulmine.IType;
24  import fulmine.util.reference.AutoCreatingStore;
25  import fulmine.util.reference.IAutoCreatingStore;
26  import fulmine.util.reference.IObjectBuilder;
27  import fulmine.util.reference.IReferenceCounter;
28  import fulmine.util.reference.ReferenceCounter;
29  
30  /**
31   * Standard implementation of the {@link ISubscriptionParameters}
32   * <p>
33   * This is thread safe.
34   * 
35   * @author Ramon Servadei
36   */
37  public final class SubscriptionParameters extends Addressable implements
38      ISubscriptionParameters
39  {
40  
41      /**
42       * Builds {@link Pattern} instances
43       * 
44       * @author Ramon Servadei
45       */
46      private static final class PatternBuilder implements
47          IObjectBuilder<String, Pattern>
48      {
49          public Pattern create(String key)
50          {
51              SubscriptionParameters.patternCount.adjustCount(key, 1);
52              return Pattern.compile(key);
53          }
54      }
55  
56      /**
57       * Cache of {@link Pattern} instances indexed by regular expression. Pattern
58       * objects are thread safe.
59       */
60      final static IAutoCreatingStore<String, Pattern> patternCache =
61          new AutoCreatingStore<String, Pattern>(new PatternBuilder());
62  
63      /** Tracks the reference count per pattern */
64      final static IReferenceCounter<String> patternCount =
65          new ReferenceCounter<String>();
66  
67      public SubscriptionParameters(IAddressable id)
68      {
69          this(id.getIdentity(), id.getType(), id.getDomain());
70      }
71  
72      public SubscriptionParameters(String identityRegularExpression, IType type,
73          IDomain domain)
74      {
75          super(identityRegularExpression, type, domain);
76      }
77  
78      public boolean matches(ISubscriptionParameters parameters)
79      {
80          if (parameters == null)
81          {
82              return false;
83          }
84          // check type
85          if (parameters.getType() == getType()
86          // check domain
87              && parameters.getDomain() == getDomain()
88              // check identity
89              && parameters.getIdentity().equals(getIdentity()))
90          {
91              return true;
92          }
93          return false;
94      }
95  
96      public boolean includes(IAddressable other)
97      {
98          if (other == null)
99          {
100             return false;
101         }
102         // check type
103         if ((other.getType().equals(getType()) || ISubscription.WILDCARD_TYPE.equals(getType()))
104             // check domain
105             && (other.getDomain().equals(getDomain()) || ISubscription.WILDCARD_DOMAIN.equals(getDomain()))
106             // check identity
107             && (other.getIdentity().equals(getIdentity()) ||
108             // this checks ".*" matches with "foo.*"
109             // but "foo.*" doesn't match with ".*"
110             patternCache.get(getIdentity()).matcher(other.getIdentity()).matches()))
111         {
112             return true;
113         }
114         return false;
115     }
116 
117     public boolean matches(IAddressable other)
118     {
119         if (other == null)
120         {
121             return false;
122         }
123         // check type
124         if ((other.getType() == getType() || ISubscription.WILDCARD_TYPE.equals(getType()))
125             // check domain
126             && (other.getDomain() == getDomain() || ISubscription.WILDCARD_DOMAIN.equals(getDomain()))
127             // check identity
128             && patternCache.get(getIdentity()).matcher(other.getIdentity()).matches())
129         {
130             return true;
131         }
132         return false;
133     }
134 
135     public void destroy()
136     {
137         synchronized (patternCache)
138         {
139             if (patternCount.adjustCount(getIdentity(), -1) == 0)
140             {
141                 patternCache.remove(getIdentity());
142             }
143         }
144     }
145 }