001 // SECTION-START[License Header]
002 /*
003 * Copyright (c) 2009 The JOMC Project
004 * Copyright (c) 2005 Christian Schulte <cs@jomc.org>
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without
008 * modification, are permitted provided that the following conditions
009 * are met:
010 *
011 * o Redistributions of source code must retain the above copyright
012 * notice, this list of conditions and the following disclaimer.
013 *
014 * o Redistributions in binary form must reproduce the above copyright
015 * notice, this list of conditions and the following disclaimer in
016 * the documentation and/or other materials provided with the
017 * distribution.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
022 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
023 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
024 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
025 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
026 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
027 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
028 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
029 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
030 *
031 * $Id$
032 *
033 */
034 // SECTION-END
035 package org.jomc.ri;
036
037 import java.io.IOException;
038 import java.net.URI;
039 import java.text.MessageFormat;
040 import java.util.ResourceBundle;
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 /**
049 *
050 * Default {@code Locator} implementation.
051 *
052 * The default {@code Locator} implementation looks up objects using JNDI.
053 * It supports location URI schemes {@code jndi} and {@code jndi+rmi}.
054 *
055 *
056 * @author <a href="mailto:cs@jomc.org">Christian Schulte</a> 1.0
057 * @version $Id$
058 */
059 // SECTION-END
060 // SECTION-START[Annotations]
061 @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
062 comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-4/jomc-tools" )
063 // SECTION-END
064 public class DefaultLocator implements Locator
065 {
066 // SECTION-START[DefaultLocator]
067
068 /** Constant for the {@code 'jndi'} URI scheme. */
069 private static final String JNDI_URI_SCHEME = "jndi";
070
071 /** Constant for the {@code 'jndi+rmi'} URI scheme. */
072 private static final String JNDI_RMI_URI_SCHEME = "jndi+rmi";
073
074 /** URI schemes supported by this {@code Locator} implementation. */
075 private static final String[] SUPPORTED_URI_SCHEMES =
076 {
077 JNDI_URI_SCHEME, JNDI_RMI_URI_SCHEME
078 };
079
080 /** The JNDI context of the instance. */
081 private Context jndiContext;
082
083 /**
084 * Gets a flag indicating support for a given location URI.
085 *
086 * @param location The location URI to test support for.
087 *
088 * @return {@code true} if {@code location} is supported by this implementation; {@code false} else.
089 *
090 * @throws NullPointerException if {@code location} is {@code null}.
091 */
092 public boolean isLocationSupported( final URI location )
093 {
094 if ( location == null )
095 {
096 throw new NullPointerException( "location" );
097 }
098
099 final String scheme = location.getScheme();
100 for ( String s : SUPPORTED_URI_SCHEMES )
101 {
102 if ( s.equals( scheme ) )
103 {
104 return true;
105 }
106 }
107
108 return false;
109 }
110
111 /**
112 * Gets the JNDI context of the instance.
113 *
114 * @return The JNDI context of the instance.
115 *
116 * @throws NamingException if getting the context fails.
117 */
118 public Context getJndiContext() throws NamingException
119 {
120 if ( this.jndiContext == null )
121 {
122 this.jndiContext = new InitialContext();
123 }
124
125 return this.jndiContext;
126 }
127
128 /**
129 * Gets the JNDI name for a given location.
130 *
131 * @param location The location to get a JNDI name for.
132 *
133 * @return The JNDI name for {@code location}.
134 *
135 * @throws NullPointerException if {@code location} is {@code null}.
136 */
137 public String getJndiName( final URI location )
138 {
139 if ( location == null )
140 {
141 throw new NullPointerException( "location" );
142 }
143
144 String name = location.getSchemeSpecificPart();
145 if ( name == null || name.replace( '/', ' ' ).trim().length() == 0 )
146 {
147 name = "";
148 }
149 if ( location.getFragment() != null )
150 {
151 name += '#' + location.getFragment();
152 }
153
154 return name;
155 }
156
157 public <T> T getObject( final Class<T> specification, final URI location ) throws IOException
158 {
159 if ( specification == null )
160 {
161 throw new NullPointerException( "specification" );
162 }
163 if ( location == null )
164 {
165 throw new NullPointerException( "location" );
166 }
167
168 try
169 {
170 T object = null;
171
172 final String scheme = location.getScheme();
173 if ( !this.isLocationSupported( location ) )
174 {
175 throw new IOException( this.getMessage( "unsupportedUriScheme", new Object[]
176 {
177 location.getScheme()
178 } ) );
179
180 }
181
182 final Object jndiObject = this.getJndiContext().lookup( this.getJndiName( location ) );
183
184 if ( JNDI_URI_SCHEME.equals( scheme ) )
185 {
186 object = (T) jndiObject;
187 }
188 else if ( JNDI_RMI_URI_SCHEME.equals( scheme ) )
189 {
190 object = (T) PortableRemoteObject.narrow( jndiObject, specification );
191 }
192
193 return object;
194 }
195 catch ( final NamingException e )
196 {
197 throw (IOException) new IOException( e.getMessage() ).initCause( e );
198 }
199 }
200
201 private String getMessage( final String key, final Object args )
202 {
203 return new MessageFormat( ResourceBundle.getBundle( DefaultLocator.class.getName().replace( '.', '/' ) ).
204 getString( key ) ).format( args );
205
206 }
207
208 // SECTION-END
209 // SECTION-START[Constructors]
210
211 /** Creates a new {@code DefaultLocator} instance. */
212 @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
213 comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-4/jomc-tools" )
214 public DefaultLocator()
215 {
216 // SECTION-START[Default Constructor]
217 super();
218 // SECTION-END
219 }
220 // SECTION-END
221 // SECTION-START[Dependencies]
222 // SECTION-END
223 // SECTION-START[Properties]
224 // SECTION-END
225 // SECTION-START[Messages]
226 // SECTION-END
227 }