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 4588 2012-06-03 06:01:30Z schulte2005 $
032 *
033 */
034// </editor-fold>
035// SECTION-END
036package org.jomc.ri;
037
038import java.io.IOException;
039import java.net.URI;
040import java.util.Locale;
041import javax.naming.Context;
042import javax.naming.InitialContext;
043import javax.naming.NamingException;
044import javax.rmi.PortableRemoteObject;
045import 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.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" )
068// </editor-fold>
069// SECTION-END
070public 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.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" )
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    @SuppressWarnings("unused")
250    @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" )
251    private static String getIllegalObjectMessage( final java.util.Locale locale, final java.lang.String objectInfo, final java.lang.String classInfo )
252    {
253        java.io.BufferedReader reader = null;
254        boolean suppressExceptionOnClose = true;
255
256        try
257        {
258            final String message = java.text.MessageFormat.format( java.util.ResourceBundle.getBundle( "org/jomc/ri/DefaultLocator", locale ).getString( "illegalObjectMessage" ), objectInfo, classInfo, (Object) null );
259            final java.lang.StringBuilder builder = new java.lang.StringBuilder( message.length() );
260            reader = new java.io.BufferedReader( new java.io.StringReader( message ) );
261            final String lineSeparator = System.getProperty( "line.separator", "\n" );
262
263            String line;
264            while ( ( line = reader.readLine() ) != null )
265            {
266                builder.append( lineSeparator ).append( line );
267            }
268
269            suppressExceptionOnClose = false;
270            return builder.length() > 0 ? builder.substring( lineSeparator.length() ) : "";
271        }
272        catch( final java.lang.ClassCastException e )
273        {
274            throw new org.jomc.ObjectManagementException( e.getMessage(), e );
275        }
276        catch( final java.lang.IllegalArgumentException e )
277        {
278            throw new org.jomc.ObjectManagementException( e.getMessage(), e );
279        }
280        catch( final java.util.MissingResourceException e )
281        {
282            throw new org.jomc.ObjectManagementException( e.getMessage(), e );
283        }
284        catch( final java.io.IOException e )
285        {
286            throw new org.jomc.ObjectManagementException( e.getMessage(), e );
287        }
288        finally
289        {
290            try
291            {
292                if( reader != null )
293                {
294                    reader.close();
295                }
296            }
297            catch( final java.io.IOException e )
298            {
299                if( !suppressExceptionOnClose )
300                {
301                    throw new org.jomc.ObjectManagementException( e.getMessage(), e );
302                }
303            }
304        }
305    }
306    /**
307     * Gets the text of the {@code <unsupportedUriSchemeMessage>} message.
308     * <p><dl>
309     *   <dt><b>Languages:</b></dt>
310     *     <dd>English (default)</dd>
311     *     <dd>Deutsch</dd>
312     *   <dt><b>Final:</b></dt><dd>No</dd>
313     * </dl></p>
314     * @param locale The locale of the message to return.
315     * @param schemeInfo Format argument.
316     * @return The text of the {@code <unsupportedUriSchemeMessage>} message for {@code locale}.
317     * @throws org.jomc.ObjectManagementException if getting the message instance fails.
318     */
319    @SuppressWarnings("unused")
320    @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" )
321    private static String getUnsupportedUriSchemeMessage( final java.util.Locale locale, final java.lang.String schemeInfo )
322    {
323        java.io.BufferedReader reader = null;
324        boolean suppressExceptionOnClose = true;
325
326        try
327        {
328            final String message = java.text.MessageFormat.format( java.util.ResourceBundle.getBundle( "org/jomc/ri/DefaultLocator", locale ).getString( "unsupportedUriSchemeMessage" ), schemeInfo, (Object) null );
329            final java.lang.StringBuilder builder = new java.lang.StringBuilder( message.length() );
330            reader = new java.io.BufferedReader( new java.io.StringReader( message ) );
331            final String lineSeparator = System.getProperty( "line.separator", "\n" );
332
333            String line;
334            while ( ( line = reader.readLine() ) != null )
335            {
336                builder.append( lineSeparator ).append( line );
337            }
338
339            suppressExceptionOnClose = false;
340            return builder.length() > 0 ? builder.substring( lineSeparator.length() ) : "";
341        }
342        catch( final java.lang.ClassCastException e )
343        {
344            throw new org.jomc.ObjectManagementException( e.getMessage(), e );
345        }
346        catch( final java.lang.IllegalArgumentException e )
347        {
348            throw new org.jomc.ObjectManagementException( e.getMessage(), e );
349        }
350        catch( final java.util.MissingResourceException e )
351        {
352            throw new org.jomc.ObjectManagementException( e.getMessage(), e );
353        }
354        catch( final java.io.IOException e )
355        {
356            throw new org.jomc.ObjectManagementException( e.getMessage(), e );
357        }
358        finally
359        {
360            try
361            {
362                if( reader != null )
363                {
364                    reader.close();
365                }
366            }
367            catch( final java.io.IOException e )
368            {
369                if( !suppressExceptionOnClose )
370                {
371                    throw new org.jomc.ObjectManagementException( e.getMessage(), e );
372                }
373            }
374        }
375    }
376    // </editor-fold>
377    // SECTION-END
378}