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.connector.path;
25  
26  import java.io.ByteArrayInputStream;
27  import java.io.IOException;
28  import java.io.ObjectInputStream;
29  import java.util.Enumeration;
30  import java.util.HashMap;
31  import java.util.Map;
32  import java.util.UUID;
33  import javax.naming.BinaryRefAddr;
34  import javax.naming.RefAddr;
35  import javax.naming.Reference;
36  import javax.naming.StringRefAddr;
37  import net.jcip.annotations.ThreadSafe;
38  import org.modeshape.common.util.CheckArg;
39  import org.modeshape.graph.connector.RepositoryContext;
40  import org.modeshape.graph.connector.RepositorySourceException;
41  import org.modeshape.graph.connector.path.cache.NoCachePolicy;
42  import org.modeshape.graph.connector.path.cache.PathCachePolicy;
43  import org.modeshape.graph.connector.path.cache.PathRepositoryCache;
44  
45  /**
46   * Basic implementation of the trivial {@link PathRepositorySource} methods and the {@link org.modeshape.graph.connector.path path
47   * repository cache life cycle}.
48   */
49  @ThreadSafe
50  public abstract class AbstractPathRepositorySource implements PathRepositorySource {
51  
52      private static final long serialVersionUID = 1L;
53  
54      /**
55       * The default UUID that is used for root nodes in a store.
56       */
57      public static final String DEFAULT_ROOT_NODE_UUID = "cafebabe-cafe-babe-cafe-babecafebabe";
58  
59      /**
60       * The default number of times that a request that failed due to system error should be retried
61       */
62      public static final int DEFAULT_RETRY_LIMIT = 0;
63  
64      /**
65       * The default cache policy for this repository source (no caching)
66       */
67      public static final PathCachePolicy DEFAULT_CACHE_POLICY = new NoCachePolicy();
68  
69      protected int retryLimit = DEFAULT_RETRY_LIMIT;
70      protected String name;
71  
72      protected transient RepositoryContext repositoryContext;
73      protected transient UUID rootNodeUuid = UUID.fromString(DEFAULT_ROOT_NODE_UUID);
74      protected transient PathCachePolicy cachePolicy = DEFAULT_CACHE_POLICY;
75  
76      private transient PathRepositoryCache repositoryCache = new PathRepositoryCache(cachePolicy);
77  
78      /**
79       * {@inheritDoc}
80       * 
81       * @see org.modeshape.graph.connector.path.PathRepositorySource#areUpdatesAllowed()
82       */
83      public boolean areUpdatesAllowed() {
84          return false;
85      }
86  
87      /**
88       * {@inheritDoc}
89       * 
90       * @see org.modeshape.graph.connector.path.PathRepositorySource#getRepositoryContext()
91       */
92      public RepositoryContext getRepositoryContext() {
93          return repositoryContext;
94      }
95  
96      /**
97       * {@inheritDoc}
98       * 
99       * @see org.modeshape.graph.connector.RepositorySource#initialize(RepositoryContext)
100      */
101     public void initialize( RepositoryContext context ) throws RepositorySourceException {
102         CheckArg.isNotNull(context, "context");
103         this.repositoryContext = context;
104     }
105 
106     /**
107      * {@inheritDoc}
108      * 
109      * @see org.modeshape.graph.connector.path.PathRepositorySource#getCachePolicy()
110      */
111     public PathCachePolicy getCachePolicy() {
112         return this.cachePolicy;
113     }
114 
115     /**
116      * Sets the cache policy for the repository and replaces the path repository cache with a new path repository cache tied to
117      * the new cache policy
118      * 
119      * @param cachePolicy the new cache policy; may not be null
120      */
121     public void setCachePolicy( PathCachePolicy cachePolicy ) {
122         CheckArg.isNotNull(cachePolicy, "cachePolicy");
123 
124         PathRepositoryCache oldCache = repositoryCache;
125         this.cachePolicy = cachePolicy;
126         this.repositoryCache = new PathRepositoryCache(cachePolicy);
127 
128         oldCache.close();
129     }
130 
131     /**
132      * @return rootNodeUuid
133      */
134     public UUID getRootNodeUuid() {
135         return rootNodeUuid;
136     }
137 
138     /**
139      * @param rootNodeUuid Sets rootNodeUuid to the specified value.
140      * @throws IllegalArgumentException if the string value cannot be converted to UUID
141      */
142     public void setRootNodeUuid( String rootNodeUuid ) {
143         if (rootNodeUuid != null && rootNodeUuid.trim().length() == 0) rootNodeUuid = DEFAULT_ROOT_NODE_UUID;
144         this.rootNodeUuid = UUID.fromString(rootNodeUuid);
145     }
146 
147     /**
148      * {@inheritDoc}
149      * 
150      * @see org.modeshape.graph.connector.RepositorySource#close()
151      */
152     public void close() {
153     }
154 
155     /**
156      * {@inheritDoc}
157      * 
158      * @see org.modeshape.graph.connector.RepositorySource#getName()
159      */
160     public String getName() {
161         return name;
162     }
163 
164     /**
165      * Sets the name of the repository source. The name should be unique among loaded repository sources.
166      * 
167      * @param name the new name for the repository source; may not be empty
168      */
169     public void setName( String name ) {
170         if (name != null) {
171             name = name.trim();
172             if (name.length() == 0) name = null;
173         }
174 
175         this.name = name;
176     }
177 
178     /**
179      * {@inheritDoc}
180      * 
181      * @see org.modeshape.graph.connector.RepositorySource#getRetryLimit()
182      */
183     public int getRetryLimit() {
184         return retryLimit;
185     }
186 
187     /**
188      * {@inheritDoc}
189      * 
190      * @see org.modeshape.graph.connector.RepositorySource#setRetryLimit(int limit)
191      */
192     public void setRetryLimit( int limit ) {
193         this.retryLimit = limit < 0 ? 0 : limit;
194     }
195 
196     /**
197      * Extracts the values from the given reference, automatically translating {@link BinaryRefAddr} instances into the
198      * deserialized classes that they represent.
199      * 
200      * @param ref the reference from which the values should be extracted
201      * @return a map of value names to values from the reference
202      * @throws IOException if there is an error deserializing a {@code BinaryRefAddr}
203      * @throws ClassNotFoundException if a serialized class cannot be deserialized because its class is not in the classpath
204      */
205     protected Map<String, Object> valuesFrom( Reference ref ) throws IOException, ClassNotFoundException {
206         Map<String, Object> values = new HashMap<String, Object>();
207 
208         Enumeration<?> en = ref.getAll();
209         while (en.hasMoreElements()) {
210             RefAddr subref = (RefAddr)en.nextElement();
211             if (subref instanceof StringRefAddr) {
212                 String key = subref.getType();
213                 Object value = subref.getContent();
214                 if (value != null) values.put(key, value.toString());
215             } else if (subref instanceof BinaryRefAddr) {
216                 String key = subref.getType();
217                 Object value = subref.getContent();
218                 if (value instanceof byte[]) {
219                     // Deserialize ...
220                     ByteArrayInputStream bais = new ByteArrayInputStream((byte[])value);
221                     ObjectInputStream ois = new ObjectInputStream(bais);
222                     value = ois.readObject();
223                     values.put(key, value);
224                 }
225             }
226         }
227 
228         return values;
229     }
230 
231     /**
232      * @return the active path repository cache; never null
233      */
234     public PathRepositoryCache getPathRepositoryCache() {
235         return repositoryCache;
236     }
237 }