View Javadoc

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