001    // SECTION-START[License Header]
002    // <editor-fold defaultstate="collapsed" desc=" Generated License ">
003    /*
004     *   Copyright (c) 2010 The JOMC Project
005     *   Copyright (c) 2005 Christian Schulte <schulte2005@users.sourceforge.net>
006     *   All rights reserved.
007     *
008     *   Redistribution and use in source and binary forms, with or without
009     *   modification, are permitted provided that the following conditions
010     *   are met:
011     *
012     *     o Redistributions of source code must retain the above copyright
013     *       notice, this list of conditions and the following disclaimer.
014     *
015     *     o Redistributions in binary form must reproduce the above copyright
016     *       notice, this list of conditions and the following disclaimer in
017     *       the documentation and/or other materials provided with the
018     *       distribution.
019     *
020     *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
021     *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022     *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023     *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
024     *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025     *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026     *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027     *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028     *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
029     *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
030     *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031     *
032     *   $Id: StandaloneContext.java 2242 2010-06-29 07:54:56Z schulte2005 $
033     *
034     */
035    // </editor-fold>
036    // SECTION-END
037    package org.jomc.standalone.ri.naming;
038    
039    import java.util.Collections;
040    import java.util.HashMap;
041    import java.util.Hashtable;
042    import java.util.Map;
043    import javax.naming.Binding;
044    import javax.naming.CompositeName;
045    import javax.naming.Context;
046    import javax.naming.ContextNotEmptyException;
047    import javax.naming.Name;
048    import javax.naming.NameAlreadyBoundException;
049    import javax.naming.NameClassPair;
050    import javax.naming.NameNotFoundException;
051    import javax.naming.NameParser;
052    import javax.naming.NamingEnumeration;
053    import javax.naming.NamingException;
054    import javax.naming.NotContextException;
055    import javax.naming.OperationNotSupportedException;
056    import javax.naming.spi.NamingManager;
057    
058    // SECTION-START[Documentation]
059    // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
060    /**
061     * Standalone {@code Context} implementation.
062     * <p><b>Specifications</b><ul>
063     * <li>{@code 'javax.naming.Context'} {@code (javax.naming.Context)} {@code Multiton}</li>
064     * </ul></p>
065     *
066     * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.0
067     * @version $Id: StandaloneContext.java 2242 2010-06-29 07:54:56Z schulte2005 $
068     */
069    // </editor-fold>
070    // SECTION-END
071    // SECTION-START[Annotations]
072    // <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
073    @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
074    // </editor-fold>
075    // SECTION-END
076    public class StandaloneContext implements Context
077    {
078        // SECTION-START[Context]
079    
080        public Object lookup( final Name name ) throws NamingException
081        {
082            if ( name.isEmpty() )
083            {
084                final StandaloneContext shared = new StandaloneContext( this.getObjectMap() );
085                shared.getEnvironment().putAll( this.getEnvironment() );
086                return shared;
087            }
088    
089            try
090            {
091                return NamingManager.getObjectInstance( this.getObjectMap().get( name ), name, this, this.getEnvironment() );
092            }
093            catch ( final Exception e )
094            {
095                final NamingException n = new NamingException( e.getMessage() );
096                n.setRootCause( e );
097                throw n;
098            }
099        }
100    
101        public Object lookup( final String name ) throws NamingException
102        {
103            return this.lookup( new CompositeName( name ) );
104        }
105    
106        public void bind( final Name name, final Object obj ) throws NamingException
107        {
108            if ( this.getObjectMap().containsKey( name ) )
109            {
110                throw new NameAlreadyBoundException( name.toString() );
111            }
112    
113            this.getObjectMap().put( name, NamingManager.getStateToBind( obj, name, this, this.getEnvironment() ) );
114        }
115    
116        public void bind( final String name, final Object obj ) throws NamingException
117        {
118            this.bind( new CompositeName( name ), obj );
119        }
120    
121        public void rebind( final Name name, final Object obj ) throws NamingException
122        {
123            if ( name.isEmpty() )
124            {
125                throw new NamingException( name.toString() );
126            }
127    
128            this.getObjectMap().put( name, NamingManager.getStateToBind( obj, name, this, this.getEnvironment() ) );
129        }
130    
131        public void rebind( final String name, final Object obj ) throws NamingException
132        {
133            this.rebind( new CompositeName( name ), obj );
134        }
135    
136        public void unbind( final Name name ) throws NamingException
137        {
138            this.getObjectMap().remove( name );
139        }
140    
141        public void unbind( final String name ) throws NamingException
142        {
143            this.unbind( new CompositeName( name ) );
144        }
145    
146        public synchronized void rename( final Name oldName, final Name newName ) throws NamingException
147        {
148            if ( oldName.isEmpty() )
149            {
150                throw new NamingException( oldName.toString() );
151            }
152            if ( newName.isEmpty() )
153            {
154                throw new NamingException( newName.toString() );
155            }
156    
157            this.bind( newName, this.lookup( oldName ) );
158            this.unbind( oldName );
159        }
160    
161        public void rename( final String oldName, final String newName ) throws NamingException
162        {
163            this.rename( new CompositeName( oldName ), new CompositeName( newName ) );
164        }
165    
166        public NamingEnumeration<NameClassPair> list( final Name name ) throws NamingException
167        {
168            return new NamingEnumeration<NameClassPair>()
169            {
170    
171                private Object next = lookup( name );
172    
173                public NameClassPair next() throws NamingException
174                {
175                    if ( this.next == null )
176                    {
177                        throw new NamingException();
178                    }
179    
180                    final NameClassPair nameClassPair =
181                        new NameClassPair( name.toString(), this.next.getClass().getName() );
182    
183                    this.next = null;
184                    return nameClassPair;
185                }
186    
187                public boolean hasMore() throws NamingException
188                {
189                    return this.next != null;
190                }
191    
192                public void close() throws NamingException
193                {
194                    this.next = null;
195                }
196    
197                public boolean hasMoreElements()
198                {
199                    try
200                    {
201                        return this.hasMore();
202                    }
203                    catch ( final NamingException e )
204                    {
205                        throw new AssertionError( e );
206                    }
207                }
208    
209                public NameClassPair nextElement()
210                {
211                    try
212                    {
213                        return this.next();
214                    }
215                    catch ( final NamingException e )
216                    {
217                        throw new AssertionError( e );
218                    }
219                }
220    
221            };
222        }
223    
224        public NamingEnumeration<NameClassPair> list( final String name ) throws NamingException
225        {
226            return this.list( new CompositeName( name ) );
227        }
228    
229        public NamingEnumeration<Binding> listBindings( final Name name ) throws NamingException
230        {
231            return new NamingEnumeration<Binding>()
232            {
233    
234                private Object next = lookup( name );
235    
236                public Binding next() throws NamingException
237                {
238                    if ( this.next == null )
239                    {
240                        throw new NamingException();
241                    }
242    
243                    final Binding binding = new Binding( name.toString(), this.next );
244                    this.next = null;
245                    return binding;
246                }
247    
248                public boolean hasMore() throws NamingException
249                {
250                    return this.next != null;
251                }
252    
253                public void close() throws NamingException
254                {
255                    this.next = null;
256                }
257    
258                public boolean hasMoreElements()
259                {
260                    try
261                    {
262                        return this.hasMore();
263                    }
264                    catch ( final NamingException e )
265                    {
266                        throw new AssertionError( e );
267                    }
268                }
269    
270                public Binding nextElement()
271                {
272                    try
273                    {
274                        return this.next();
275                    }
276                    catch ( final NamingException e )
277                    {
278                        throw new AssertionError( e );
279                    }
280                }
281    
282            };
283        }
284    
285        public NamingEnumeration<Binding> listBindings( final String name ) throws NamingException
286        {
287            return this.listBindings( new CompositeName( name ) );
288        }
289    
290        public synchronized void destroySubcontext( final Name name ) throws NamingException
291        {
292            if ( name.isEmpty() )
293            {
294                throw new NamingException( name.toString() );
295            }
296    
297            final Object o = this.getContextMap().get( name );
298            if ( o == null )
299            {
300                throw new NameNotFoundException( name.toString() );
301            }
302            if ( !( o instanceof StandaloneContext ) )
303            {
304                throw new NotContextException( o.toString() );
305            }
306            if ( !( (StandaloneContext) o ).getObjectMap().isEmpty() )
307            {
308                throw new ContextNotEmptyException( name.toString() );
309            }
310    
311            this.getContextMap().remove( name );
312        }
313    
314        public void destroySubcontext( final String name ) throws NamingException
315        {
316            this.destroySubcontext( new CompositeName( name ) );
317        }
318    
319        public synchronized Context createSubcontext( final Name name ) throws NamingException
320        {
321            if ( name.isEmpty() )
322            {
323                throw new NamingException( name.toString() );
324            }
325            if ( this.getObjectMap().containsKey( name ) )
326            {
327                throw new NameAlreadyBoundException( name.toString() );
328            }
329    
330            final StandaloneContext subcontext = new StandaloneContext();
331            subcontext.getEnvironment().putAll( this.getEnvironment() );
332            this.getContextMap().put( name, subcontext );
333            return subcontext;
334        }
335    
336        public Context createSubcontext( final String name ) throws NamingException
337        {
338            return this.createSubcontext( new CompositeName( name ) );
339        }
340    
341        public Object lookupLink( final Name name ) throws NamingException
342        {
343            return this.lookup( name );
344        }
345    
346        public Object lookupLink( final String name ) throws NamingException
347        {
348            return this.lookupLink( new CompositeName( name ) );
349        }
350    
351        public NameParser getNameParser( final Name name ) throws NamingException
352        {
353            return new NameParser()
354            {
355    
356                public Name parse( final String name ) throws NamingException
357                {
358                    return new CompositeName( name );
359                }
360    
361            };
362        }
363    
364        public NameParser getNameParser( final String name ) throws NamingException
365        {
366            return this.getNameParser( new CompositeName( name ) );
367        }
368    
369        public Name composeName( final Name name, final Name prefix ) throws NamingException
370        {
371            return new CompositeName( prefix.toString() ).add( name.toString() );
372        }
373    
374        public String composeName( final String name, final String prefix ) throws NamingException
375        {
376            return this.composeName( new CompositeName( name ), new CompositeName( prefix ) ).toString();
377        }
378    
379        public Object addToEnvironment( final String propName, final Object propVal ) throws NamingException
380        {
381            if ( propName == null )
382            {
383                throw new NamingException();
384            }
385            if ( propVal == null )
386            {
387                throw new NamingException();
388            }
389    
390            return this.getEnvironment().put( propName, propVal );
391        }
392    
393        public Object removeFromEnvironment( final String propName ) throws NamingException
394        {
395            if ( propName == null )
396            {
397                throw new NamingException();
398            }
399            return this.getEnvironment().remove( propName );
400        }
401    
402        public Hashtable getEnvironment() throws NamingException
403        {
404            if ( this.environment == null )
405            {
406                this.environment = new Hashtable();
407            }
408    
409            return this.environment;
410        }
411    
412        public void close() throws NamingException
413        {
414        }
415    
416        public String getNameInNamespace() throws NamingException
417        {
418            throw new OperationNotSupportedException();
419        }
420    
421        // SECTION-END
422        // SECTION-START[StandaloneContext]
423        /** Sub-contexts of the instance. */
424        private Map<Name, Context> contextMap;
425    
426        /** Objects of the instance. */
427        private Map<Name, Object> objectMap;
428    
429        /** Environment of the instance. */
430        private Hashtable<?, ?> environment;
431    
432        /**
433         * Creates a new {@code StandaloneContext} taking a map backing the instance.
434         *
435         * @param objectMap The map backing the instance.
436         */
437        public StandaloneContext( final Map<Name, Object> objectMap )
438        {
439            super();
440            this.objectMap = objectMap;
441        }
442    
443        /**
444         * Gets the object map backing the instance.
445         *
446         * @return The object map backing the instance.
447         */
448        protected Map<Name, Object> getObjectMap()
449        {
450            if ( this.objectMap == null )
451            {
452                this.objectMap = Collections.synchronizedMap( new HashMap<Name, Object>() );
453            }
454    
455            return this.objectMap;
456        }
457    
458        /**
459         * Gets the context map backing the instance.
460         *
461         * @return The context map backing the instance.
462         */
463        protected Map<Name, Context> getContextMap()
464        {
465            if ( this.contextMap == null )
466            {
467                this.contextMap = Collections.synchronizedMap( new HashMap<Name, Context>() );
468            }
469    
470            return this.contextMap;
471        }
472    
473        // SECTION-END
474        // SECTION-START[Constructors]
475        // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
476    
477        /** Creates a new {@code StandaloneContext} instance. */
478        @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
479        public StandaloneContext()
480        {
481            // SECTION-START[Default Constructor]
482            this( null );
483            // SECTION-END
484        }
485        // </editor-fold>
486        // SECTION-END
487        // SECTION-START[Dependencies]
488        // SECTION-END
489        // SECTION-START[Properties]
490        // SECTION-END
491        // SECTION-START[Messages]
492        // SECTION-END
493    }