1 /*
2 * Copyright (C) The Spice Group. All rights reserved.
3 *
4 * This software is published under the terms of the Spice
5 * Software License version 1.1, a copy of which has been included
6 * with this distribution in the LICENSE.txt file.
7 */
8 package org.realityforge.jndikit;
9
10 import java.io.IOException;
11 import java.io.Serializable;
12 import java.rmi.MarshalledObject;
13 import java.util.Hashtable;
14 import java.util.Iterator;
15 import javax.naming.Binding;
16 import javax.naming.CommunicationException;
17 import javax.naming.ConfigurationException;
18 import javax.naming.Context;
19 import javax.naming.InvalidNameException;
20 import javax.naming.Name;
21 import javax.naming.NameClassPair;
22 import javax.naming.NameParser;
23 import javax.naming.NamingEnumeration;
24 import javax.naming.NamingException;
25 import javax.naming.Reference;
26 import javax.naming.Referenceable;
27
28 /***
29 * Context that hooks up to a remote source.
30 *
31 * @author <a href="mailto:peter at realityforge.org">Peter Donald</a>
32 * @version $Revision: 1.2 $
33 */
34 public class RemoteContext
35 extends AbstractContext
36 implements Serializable
37 {
38 public static final String NAMESPACE_NAME = "org.realityforge.jndikit.Namespace/NAME";
39 public static final String NAMESPACE = "org.realityforge.jndikit.Namespace";
40 public static final String NAMING_PROVIDER = "org.realityforge.jndikit.NamingProvider";
41
42 private transient NamingProvider m_provider;
43 private transient NameParser m_nameParser;
44 private transient Namespace m_namespace;
45
46 private Name m_baseName;
47
48 //for deserialisation
49 public RemoteContext()
50 {
51 }
52
53 public RemoteContext( final Hashtable environment, final Name baseName )
54 throws NamingException
55 {
56 super( environment );
57 m_baseName = baseName;
58 }
59
60 /***
61 * Helper method to bind
62 */
63 protected void bind( final Name name, Object object, final boolean rebind )
64 throws NamingException
65 {
66 if( isSelf( name ) )
67 {
68 throw new InvalidNameException( "Failed to bind self" );
69 }
70
71 String className = null;
72
73 object = getNamespace().getStateToBind( object, name, this, getRawEnvironment() );
74
75 if( object instanceof Reference )
76 {
77 className = ( (Reference)object ).getClassName();
78 }
79 else if( object instanceof Referenceable )
80 {
81 object = ( (Referenceable)object ).getReference();
82 className = ( (Reference)object ).getClassName();
83 }
84 else
85 {
86 className = object.getClass().getName();
87
88 try
89 {
90 object = new MarshalledObject( object );
91 }
92 catch( final IOException ioe )
93 {
94 throw new NamingException( "Only Reference, Referenceables and " +
95 "Serializable objects can be bound " +
96 "to context" );
97 }
98 }
99
100 try
101 {
102 if( rebind )
103 {
104 getProvider().rebind( getAbsoluteName( name ), className, object );
105 }
106 else
107 {
108 getProvider().bind( getAbsoluteName( name ), className, object );
109 }
110 }
111 catch( final Exception e )
112 {
113 throw handleException( e );
114 }
115 }
116
117 /***
118 * Release resources associated with context.
119 */
120 public void close()
121 {
122 super.close();
123 m_namespace = null;
124 m_provider = null;
125 }
126
127 /***
128 * Create a Subcontext.
129 *
130 * @param name the name of subcontext
131 * @return the created context
132 * @throws NamingException if an error occurs
133 * (ie context exists, badly formated name etc)
134 */
135 public Context createSubcontext( final Name name )
136 throws NamingException
137 {
138 if( isSelf( name ) )
139 {
140 throw new InvalidNameException( "Failed to create null subcontext" );
141 }
142
143 Context result = null;
144 try
145 {
146 result = getProvider().createSubcontext( getAbsoluteName( name ) );
147 }
148 catch( final Exception e )
149 {
150 throw handleException( e );
151 }
152
153 fillInContext( result );
154
155 return result;
156 }
157
158 public void destroySubcontext( final Name name )
159 throws NamingException
160 {
161 if( isSelf( name ) )
162 {
163 throw new InvalidNameException( "Failed to destroy self" );
164 }
165
166 try
167 {
168 getProvider().destroySubcontext( getAbsoluteName( name ) );
169 }
170 catch( final Exception e )
171 {
172 throw handleException( e );
173 }
174 }
175
176 public String getNameInNamespace()
177 throws NamingException
178 {
179 return getAbsoluteName( getNameParser().parse( "" ) ).toString();
180 }
181
182 /***
183 * Enumerates the names bound in the named context.
184 *
185 * @param name the name of the context
186 * @return the enumeration
187 * @throws javax.naming.NamingException if an error occurs
188 */
189 public NamingEnumeration list( final Name name )
190 throws NamingException
191 {
192 try
193 {
194 final NameClassPair[] result = getProvider().list( getAbsoluteName( name ) );
195 return new ArrayNamingEnumeration( this, m_namespace, result );
196 }
197 catch( final Exception e )
198 {
199 throw handleException( e );
200 }
201 }
202
203 /***
204 * Enumerates the names bound in the named context, along with the objects bound to them.
205 *
206 * @param name the name of the context
207 * @return the enumeration
208 * @throws javax.naming.NamingException if an error occurs
209 */
210 public NamingEnumeration listBindings( final Name name )
211 throws NamingException
212 {
213 try
214 {
215 final Binding[] result = getProvider().listBindings( getAbsoluteName( name ) );
216
217 for( int i = 0; i < result.length; i++ )
218 {
219 final Object object = result[ i ].getObject();
220 if( object instanceof Context )
221 {
222 fillInContext( (Context)object );
223 }
224 }
225
226 return new ArrayNamingEnumeration( this, m_namespace, result );
227 }
228 catch( final Exception e )
229 {
230 throw handleException( e );
231 }
232 }
233
234 /***
235 * Get the object named.
236 *
237 * @param name the name
238 * @return the object
239 * @throws NamingException if an error occurs
240 * (ie object name is inavlid or unbound)
241 */
242 public Object lookup( final Name name )
243 throws NamingException
244 {
245 if( isSelf( name ) )
246 {
247 return new RemoteContext( getRawEnvironment(), m_baseName );
248 }
249
250 //actually do a real-lookup
251 Object object = null;
252 try
253 {
254 object = getProvider().lookup( getAbsoluteName( name ) );
255
256 if( object instanceof MarshalledObject )
257 {
258 object = ( (MarshalledObject)object ).get();
259 }
260
261 object = getNamespace().getObjectInstance( object, name, this, getRawEnvironment() );
262
263 if( object instanceof Context )
264 {
265 fillInContext( (Context)object );
266 }
267 }
268 catch( final Exception e )
269 {
270 throw handleException( e );
271 }
272
273 return object;
274 }
275
276 /***
277 * Unbind a object from a name.
278 *
279 * @param name the name
280 * @throws javax.naming.NamingException if an error occurs
281 */
282 public void unbind( final Name name )
283 throws NamingException
284 {
285 if( isSelf( name ) )
286 {
287 throw new InvalidNameException( "Failed to unbind self" );
288 }
289
290 try
291 {
292 getProvider().unbind( getAbsoluteName( name ) );
293 }
294 catch( final Exception e )
295 {
296 throw handleException( e );
297 }
298 }
299
300 protected void fillInContext( final Context object )
301 throws NamingException
302 {
303 final Hashtable environment = getRawEnvironment();
304 final Iterator keys = environment.keySet().iterator();
305
306 while( keys.hasNext() )
307 {
308 final String key = (String)keys.next();
309 final Object value = environment.get( key );
310 object.addToEnvironment( key, value );
311 }
312 }
313
314 protected Namespace getNamespace()
315 throws NamingException
316 {
317 if( null == m_namespace )
318 {
319 final Object object = getRawEnvironment().get( RemoteContext.NAMESPACE );
320
321 if( !( object instanceof Namespace ) || null == object )
322 {
323 throw new ConfigurationException( "Context does not contain Namespace" );
324 }
325 else
326 {
327 m_namespace = (Namespace)object;
328 }
329 }
330
331 return m_namespace;
332 }
333
334 protected NamingProvider getProvider()
335 throws NamingException
336 {
337 if( null == m_provider )
338 {
339 final Object object = getRawEnvironment().get( RemoteContext.NAMING_PROVIDER );
340
341 if( !( object instanceof NamingProvider ) || null == object )
342 {
343 throw new ConfigurationException( "Context does not contain provider" );
344 }
345 else
346 {
347 m_provider = (NamingProvider)object;
348 }
349 }
350
351 return m_provider;
352 }
353
354 protected NameParser getNameParser()
355 throws NamingException
356 {
357 if( null == m_nameParser )
358 {
359 //Make sure provider is valid and returns nameparser
360 try
361 {
362 m_nameParser = getProvider().getNameParser();
363 }
364 catch( final Exception e )
365 {
366 throw handleException( e );
367 }
368
369 }
370 return m_nameParser;
371 }
372
373 protected Name getAbsoluteName( final Name name )
374 throws NamingException
375 {
376 return composeName( name, m_baseName );
377 }
378
379 protected NamingException handleException( final Exception e )
380 {
381 if( e instanceof NamingException )
382 {
383 return (NamingException)e;
384 }
385 else
386 {
387 return new CommunicationException( e.toString() );
388 }
389 }
390 }
This page was automatically generated by Maven