View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors. 
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   *
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.graph.property.basic;
25  
26  import java.util.ArrayList;
27  import java.util.Collections;
28  import java.util.List;
29  import java.util.Set;
30  import java.util.concurrent.locks.Lock;
31  import java.util.concurrent.locks.ReadWriteLock;
32  import java.util.concurrent.locks.ReentrantReadWriteLock;
33  import net.jcip.annotations.ThreadSafe;
34  import org.modeshape.common.util.CheckArg;
35  import org.modeshape.graph.property.NamespaceRegistry;
36  
37  /**
38   * A thread-safe {@link NamespaceRegistry} that may be used as a thread-safe wrapper around another non-thread-safe
39   * implementation.
40   */
41  @ThreadSafe
42  public class ThreadSafeNamespaceRegistry implements NamespaceRegistry {
43  
44      private final ReadWriteLock registryLock = new ReentrantReadWriteLock();
45      private final NamespaceRegistry delegate;
46  
47      /**
48       */
49      public ThreadSafeNamespaceRegistry() {
50          this(new SimpleNamespaceRegistry());
51      }
52  
53      /**
54       * @param nonThreadSafeRegistry a {@link NamespaceRegistry} implementation that is not thread safe and to which this instance
55       *        will delegate; may not be null
56       */
57      public ThreadSafeNamespaceRegistry( NamespaceRegistry nonThreadSafeRegistry ) {
58          CheckArg.isNotNull(nonThreadSafeRegistry, "nonThreadSafeRegistry");
59          delegate = nonThreadSafeRegistry;
60      }
61  
62      /**
63       * {@inheritDoc}
64       */
65      public String getNamespaceForPrefix( String prefix ) {
66          CheckArg.isNotNull(prefix, "prefix");
67          Lock lock = this.registryLock.readLock();
68          try {
69              lock.lock();
70              return this.delegate.getNamespaceForPrefix(prefix);
71          } finally {
72              lock.unlock();
73          }
74      }
75  
76      /**
77       * {@inheritDoc}
78       */
79      public String getPrefixForNamespaceUri( String namespaceUri,
80                                              boolean generateIfMissing ) {
81          CheckArg.isNotNull(namespaceUri, "namespaceUri");
82          String prefix = null;
83          Lock lock = this.registryLock.readLock();
84          try {
85              lock.lock();
86              prefix = delegate.getPrefixForNamespaceUri(namespaceUri, false);
87          } finally {
88              lock.unlock();
89          }
90          if (prefix == null && generateIfMissing) {
91              // Get a write lock ...
92              lock = this.registryLock.writeLock();
93              try {
94                  lock.lock();
95                  prefix = delegate.getPrefixForNamespaceUri(namespaceUri, true);
96                  return prefix;
97              } finally {
98                  lock.unlock();
99              }
100         }
101         return prefix;
102     }
103 
104     /**
105      * {@inheritDoc}
106      */
107     public boolean isRegisteredNamespaceUri( String namespaceUri ) {
108         CheckArg.isNotNull(namespaceUri, "namespaceUri");
109         Lock lock = this.registryLock.readLock();
110         try {
111             lock.lock();
112             return delegate.isRegisteredNamespaceUri(namespaceUri);
113         } finally {
114             lock.unlock();
115         }
116     }
117 
118     /**
119      * {@inheritDoc}
120      */
121     public String getDefaultNamespaceUri() {
122         Lock lock = this.registryLock.readLock();
123         try {
124             lock.lock();
125             return delegate.getDefaultNamespaceUri();
126         } finally {
127             lock.unlock();
128         }
129     }
130 
131     /**
132      * {@inheritDoc}
133      */
134     public String register( String prefix,
135                             String namespaceUri ) {
136         CheckArg.isNotNull(namespaceUri, "namespaceUri");
137         Lock lock = this.registryLock.writeLock();
138         try {
139             lock.lock();
140             return delegate.register(prefix, namespaceUri);
141         } finally {
142             lock.unlock();
143         }
144     }
145 
146     /**
147      * {@inheritDoc}
148      * 
149      * @see org.modeshape.graph.property.NamespaceRegistry#unregister(java.lang.String)
150      */
151     public boolean unregister( String namespaceUri ) {
152         CheckArg.isNotNull(namespaceUri, "namespaceUri");
153         Lock lock = this.registryLock.writeLock();
154         try {
155             lock.lock();
156             return delegate.unregister(namespaceUri);
157         } finally {
158             lock.unlock();
159         }
160     }
161 
162     /**
163      * {@inheritDoc}
164      */
165     public Set<String> getRegisteredNamespaceUris() {
166         Lock lock = this.registryLock.readLock();
167         try {
168             lock.lock();
169             return delegate.getRegisteredNamespaceUris();
170         } finally {
171             lock.unlock();
172         }
173     }
174 
175     /**
176      * {@inheritDoc}
177      * 
178      * @see org.modeshape.graph.property.NamespaceRegistry#getNamespaces()
179      */
180     public Set<Namespace> getNamespaces() {
181         Lock lock = this.registryLock.readLock();
182         try {
183             lock.lock();
184             return delegate.getNamespaces();
185         } finally {
186             lock.unlock();
187         }
188     }
189 
190     /**
191      * {@inheritDoc}
192      * 
193      * @see java.lang.Object#toString()
194      */
195     @Override
196     public String toString() {
197         List<Namespace> namespaces = new ArrayList<Namespace>(getNamespaces());
198         Collections.sort(namespaces);
199         return namespaces.toString();
200     }
201 
202 }