001    // SECTION-START[License Header]
002    // <editor-fold defaultstate="collapsed" desc=" Generated License ">
003    /*
004     *   Java Object Management and Configuration
005     *   Copyright (C) Christian Schulte, 2005-206
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 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
021     *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
022     *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
023     *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
024     *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
025     *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
026     *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
027     *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
028     *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
029     *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
030     *
031     *   $JOMC: DefaultLocator.java 4381 2012-03-04 19:29:29Z schulte2005 $
032     *
033     */
034    // </editor-fold>
035    // SECTION-END
036    package org.jomc.ri;
037    
038    import java.io.IOException;
039    import java.net.URI;
040    import java.util.Locale;
041    import javax.naming.Context;
042    import javax.naming.InitialContext;
043    import javax.naming.NamingException;
044    import javax.rmi.PortableRemoteObject;
045    import org.jomc.spi.Locator;
046    
047    // SECTION-START[Documentation]
048    // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
049    /**
050     * Default {@code Locator} implementation.
051     *
052     * <dl>
053     *   <dt><b>Identifier:</b></dt><dd>org.jomc.ri.DefaultLocator</dd>
054     *   <dt><b>Name:</b></dt><dd>JOMC RI</dd>
055     *   <dt><b>Abstract:</b></dt><dd>No</dd>
056     *   <dt><b>Final:</b></dt><dd>No</dd>
057     *   <dt><b>Stateless:</b></dt><dd>No</dd>
058     * </dl>
059     *
060     * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.0
061     * @version 1.0
062     */
063    // </editor-fold>
064    // SECTION-END
065    // SECTION-START[Annotations]
066    // <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
067    @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.2.2", comments = "See http://jomc.sourceforge.net/jomc/1.2/jomc-tools-1.2.2" )
068    // </editor-fold>
069    // SECTION-END
070    public class DefaultLocator implements Locator
071    {
072        // SECTION-START[DefaultLocator]
073    
074        /** Constant for the {@code 'jndi'} URI scheme. */
075        private static final String JNDI_URI_SCHEME = "jndi";
076    
077        /** Constant for the {@code 'jndi+rmi'} URI scheme. */
078        private static final String JNDI_RMI_URI_SCHEME = "jndi+rmi";
079    
080        /** URI schemes supported by this {@code Locator} implementation. */
081        private static final String[] SUPPORTED_URI_SCHEMES =
082        {
083            JNDI_URI_SCHEME, JNDI_RMI_URI_SCHEME
084        };
085    
086        /** The JNDI context of the instance. */
087        private Context jndiContext;
088    
089        /**
090         * Gets a flag indicating support for a given location URI.
091         *
092         * @param location The location URI to test support for.
093         *
094         * @return {@code true}, if {@code location} is supported by this implementation; {@code false}, else.
095         *
096         * @throws NullPointerException if {@code location} is {@code null}.
097         */
098        public boolean isLocationSupported( final URI location )
099        {
100            if ( location == null )
101            {
102                throw new NullPointerException( "location" );
103            }
104    
105            for ( int i = SUPPORTED_URI_SCHEMES.length - 1; i >= 0; i-- )
106            {
107                if ( SUPPORTED_URI_SCHEMES[i].equals( location.getScheme() ) )
108                {
109                    return true;
110                }
111            }
112    
113            return false;
114        }
115    
116        /**
117         * Gets the JNDI context of the instance.
118         *
119         * @return The JNDI context of the instance.
120         *
121         * @throws NamingException if getting the context fails.
122         */
123        public Context getJndiContext() throws NamingException
124        {
125            if ( this.jndiContext == null )
126            {
127                this.jndiContext = new InitialContext();
128            }
129    
130            return this.jndiContext;
131        }
132    
133        /**
134         * Gets the JNDI name for a given location.
135         *
136         * @param location The location to get a JNDI name for.
137         *
138         * @return The JNDI name for {@code location}.
139         *
140         * @throws NullPointerException if {@code location} is {@code null}.
141         */
142        public String getJndiName( final URI location )
143        {
144            if ( location == null )
145            {
146                throw new NullPointerException( "location" );
147            }
148    
149            String name = location.getSchemeSpecificPart();
150            if ( name == null || name.replace( '/', ' ' ).trim().length() == 0 )
151            {
152                name = "";
153            }
154            if ( location.getFragment() != null )
155            {
156                name += '#' + location.getFragment();
157            }
158    
159            return name;
160        }
161    
162        public <T> T getObject( final Class<T> specification, final URI location ) throws IOException
163        {
164            if ( specification == null )
165            {
166                throw new NullPointerException( "specification" );
167            }
168            if ( location == null )
169            {
170                throw new NullPointerException( "location" );
171            }
172    
173            T object = null;
174    
175            try
176            {
177                final String scheme = location.getScheme();
178                if ( !this.isLocationSupported( location ) )
179                {
180                    throw new IOException( getUnsupportedUriSchemeMessage( Locale.getDefault(), location.getScheme() ) );
181                }
182    
183                final Object jndiObject = this.getJndiContext().lookup( this.getJndiName( location ) );
184    
185                if ( JNDI_URI_SCHEME.equals( scheme ) )
186                {
187                    object = (T) jndiObject;
188                }
189                else if ( JNDI_RMI_URI_SCHEME.equals( scheme ) )
190                {
191                    object = (T) PortableRemoteObject.narrow( jndiObject, specification );
192                }
193    
194                return object;
195            }
196            catch ( final NamingException e )
197            {
198                // JDK: As of JDK 6, "new IOException( message, cause )".
199                throw (IOException) new IOException( getMessage( e ) ).initCause( e );
200            }
201            catch ( final ClassCastException e )
202            {
203                // JDK: As of JDK 6, "new IOException( message, cause )".
204                throw (IOException) new IOException( getIllegalObjectMessage(
205                    Locale.getDefault(), object != null ? object.toString() : null,
206                    specification.getName() ) ).initCause( e );
207    
208            }
209        }
210    
211        private static String getMessage( final Throwable t )
212        {
213            return t != null ? t.getMessage() != null ? t.getMessage() : getMessage( t.getCause() ) : null;
214        }
215    
216        // SECTION-END
217        // SECTION-START[Constructors]
218        // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
219        /** Creates a new {@code DefaultLocator} instance. */
220        @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.2.2", comments = "See http://jomc.sourceforge.net/jomc/1.2/jomc-tools-1.2.2" )
221        public DefaultLocator()
222        {
223            // SECTION-START[Default Constructor]
224            super();
225            // SECTION-END
226        }
227        // </editor-fold>
228        // SECTION-END
229        // SECTION-START[Dependencies]
230        // SECTION-END
231        // SECTION-START[Properties]
232        // SECTION-END
233        // SECTION-START[Messages]
234        // <editor-fold defaultstate="collapsed" desc=" Generated Messages ">
235        /**
236         * Gets the text of the {@code <illegalObjectMessage>} message.
237         * <p><dl>
238         *   <dt><b>Languages:</b></dt>
239         *     <dd>English (default)</dd>
240         *     <dd>Deutsch</dd>
241         *   <dt><b>Final:</b></dt><dd>No</dd>
242         * </dl></p>
243         * @param locale The locale of the message to return.
244         * @param objectInfo Format argument.
245         * @param classInfo Format argument.
246         * @return The text of the {@code <illegalObjectMessage>} message for {@code locale}.
247         * @throws org.jomc.ObjectManagementException if getting the message instance fails.
248         */
249        @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.2.2", comments = "See http://jomc.sourceforge.net/jomc/1.2/jomc-tools-1.2.2" )
250        private static String getIllegalObjectMessage( final java.util.Locale locale, final java.lang.String objectInfo, final java.lang.String classInfo )
251        {
252            java.io.BufferedReader reader = null;
253            boolean suppressExceptionOnClose = true;
254    
255            try
256            {
257                final String message = java.text.MessageFormat.format( java.util.ResourceBundle.getBundle( "org/jomc/ri/DefaultLocator", locale ).getString( "illegalObjectMessage" ), objectInfo, classInfo, (Object) null );
258                final java.lang.StringBuilder builder = new java.lang.StringBuilder( message.length() );
259                reader = new java.io.BufferedReader( new java.io.StringReader( message ) );
260                final String lineSeparator = System.getProperty( "line.separator", "\n" );
261    
262                String line;
263                while ( ( line = reader.readLine() ) != null )
264                {
265                    builder.append( lineSeparator ).append( line );
266                }
267    
268                suppressExceptionOnClose = false;
269                return builder.length() > 0 ? builder.substring( lineSeparator.length() ) : "";
270            }
271            catch( final java.lang.ClassCastException e )
272            {
273                throw new org.jomc.ObjectManagementException( e.getMessage(), e );
274            }
275            catch( final java.lang.IllegalArgumentException e )
276            {
277                throw new org.jomc.ObjectManagementException( e.getMessage(), e );
278            }
279            catch( final java.util.MissingResourceException e )
280            {
281                throw new org.jomc.ObjectManagementException( e.getMessage(), e );
282            }
283            catch( final java.io.IOException e )
284            {
285                throw new org.jomc.ObjectManagementException( e.getMessage(), e );
286            }
287            finally
288            {
289                try
290                {
291                    if( reader != null )
292                    {
293                        reader.close();
294                    }
295                }
296                catch( final java.io.IOException e )
297                {
298                    if( !suppressExceptionOnClose )
299                    {
300                        throw new org.jomc.ObjectManagementException( e.getMessage(), e );
301                    }
302                }
303            }
304        }
305        /**
306         * Gets the text of the {@code <unsupportedUriSchemeMessage>} message.
307         * <p><dl>
308         *   <dt><b>Languages:</b></dt>
309         *     <dd>English (default)</dd>
310         *     <dd>Deutsch</dd>
311         *   <dt><b>Final:</b></dt><dd>No</dd>
312         * </dl></p>
313         * @param locale The locale of the message to return.
314         * @param schemeInfo Format argument.
315         * @return The text of the {@code <unsupportedUriSchemeMessage>} message for {@code locale}.
316         * @throws org.jomc.ObjectManagementException if getting the message instance fails.
317         */
318        @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.2.2", comments = "See http://jomc.sourceforge.net/jomc/1.2/jomc-tools-1.2.2" )
319        private static String getUnsupportedUriSchemeMessage( final java.util.Locale locale, final java.lang.String schemeInfo )
320        {
321            java.io.BufferedReader reader = null;
322            boolean suppressExceptionOnClose = true;
323    
324            try
325            {
326                final String message = java.text.MessageFormat.format( java.util.ResourceBundle.getBundle( "org/jomc/ri/DefaultLocator", locale ).getString( "unsupportedUriSchemeMessage" ), schemeInfo, (Object) null );
327                final java.lang.StringBuilder builder = new java.lang.StringBuilder( message.length() );
328                reader = new java.io.BufferedReader( new java.io.StringReader( message ) );
329                final String lineSeparator = System.getProperty( "line.separator", "\n" );
330    
331                String line;
332                while ( ( line = reader.readLine() ) != null )
333                {
334                    builder.append( lineSeparator ).append( line );
335                }
336    
337                suppressExceptionOnClose = false;
338                return builder.length() > 0 ? builder.substring( lineSeparator.length() ) : "";
339            }
340            catch( final java.lang.ClassCastException e )
341            {
342                throw new org.jomc.ObjectManagementException( e.getMessage(), e );
343            }
344            catch( final java.lang.IllegalArgumentException e )
345            {
346                throw new org.jomc.ObjectManagementException( e.getMessage(), e );
347            }
348            catch( final java.util.MissingResourceException e )
349            {
350                throw new org.jomc.ObjectManagementException( e.getMessage(), e );
351            }
352            catch( final java.io.IOException e )
353            {
354                throw new org.jomc.ObjectManagementException( e.getMessage(), e );
355            }
356            finally
357            {
358                try
359                {
360                    if( reader != null )
361                    {
362                        reader.close();
363                    }
364                }
365                catch( final java.io.IOException e )
366                {
367                    if( !suppressExceptionOnClose )
368                    {
369                        throw new org.jomc.ObjectManagementException( e.getMessage(), e );
370                    }
371                }
372            }
373        }
374        // </editor-fold>
375        // SECTION-END
376    }