001 /* ====================================================================
002 * The Apache Software License, Version 1.1
003 *
004 * Copyright (c) 2003 The Apache Software Foundation. All rights
005 * 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 * 1. Redistributions of source code must retain the above copyright
012 * notice, this list of conditions and the following disclaimer.
013 *
014 * 2. 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 * 3. The end-user documentation included with the redistribution,
020 * if any, must include the following acknowledgment:
021 * "This product includes software developed by the
022 * Apache Software Foundation (http://www.apache.org/)."
023 * Alternately, this acknowledgment may appear in the software itself,
024 * if and wherever such third-party acknowledgments normally appear.
025 *
026 * 4. The names "The Jakarta Project", "Commons", and "Apache Software
027 * Foundation" must not be used to endorse or promote products derived
028 * from this software without prior written permission. For written
029 * permission, please contact apache@apache.org.
030 *
031 * 5. Products derived from this software may not be called "Apache",
032 * nor may "Apache" appear in their name, without prior written
033 * permission of the Apache Software Foundation.
034 *
035 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046 * SUCH DAMAGE.
047 * ====================================================================
048 *
049 * This software consists of voluntary contributions made by many
050 * individuals on behalf of the Apache Software Foundation. For more
051 * information on the Apache Software Foundation, please see
052 * <http://www.apache.org/>.
053 *
054 */
055 package org.jpu.patterns.serviceLocator;
056
057 import java.lang.reflect.Method;
058
059 import org.apache.commons.logging.Log;
060 import org.apache.commons.logging.LogFactory;
061
062 /**
063 * Subclass of {@link Locator} specialized for stateless session beans.
064 * This class overrides the <code>lookup()</code> method to call
065 * <code>create()</code> on the home object. Any exceptions thrown
066 * from <code>create()</code> are rethrown wrapped in {@link ServiceLocatorException}.
067 * Of course the home interface must define a public no-arg <code>create()</code>
068 * method (as all SLSB's must); else a <code>ServiceLocatorException</code> will
069 * result.
070 */
071 public class SLSBLocator extends Locator implements ISLSBLocator {
072
073 /**
074 * Alias for "<code>getSLSB(homeNamingIdentifier, (ServiceLocatorOptions)null)</code>".
075 */
076 public Object getSLSB(String homeNamingIdentifier) throws ServiceLocatorException {
077 return getSLSB(homeNamingIdentifier, (ServiceLocatorOptions)null);
078 }
079
080 /**
081 * Alias for "<code>getObject(homeNamingIdentifier, c)</code>".
082 */
083 public Object getSLSB(String homeNamingIdentifier, Class c) throws ServiceLocatorException {
084 return getObject(homeNamingIdentifier, c);
085 }
086
087 /**
088 * Alias for "<code>getObject(homeNamingIdentifier, options)</code>".
089 */
090 public Object getSLSB(String homeNamingIdentifier, ServiceLocatorOptions options) throws ServiceLocatorException {
091 return getObject(homeNamingIdentifier, options);
092 }
093
094 /**
095 * Overrides the superclass version to create the SLSB from its remote interface.
096 * To change the way the SLSB is created, override {@link #createSLSB(Object,ServiceLocatorOptions)}.
097 */
098 public Object lookup(String namingIdentifier, ServiceLocatorOptions options) throws ServiceLocatorException {
099 Object homeobj = super.lookup(namingIdentifier, options);
100 try {
101 if ( _log.isDebugEnabled() ) {
102 _log.debug( "homeobj for [jndi=" + namingIdentifier + "] is '" + homeobj + "'." );
103 }
104 Object slsb = createSLSB(homeobj, options);
105 return slsb;
106 }
107 catch( Exception e ) {
108 throw new ServiceLocatorException(e);
109 }
110 }
111
112 /**
113 * Narrows the reference to the given home to the appropriate type. The default implementation examines <code>options</code>
114 * and, if it is of type {@link SLSBLocatorOptions} with <code>castHomeTo</code> non-<code>null</code>, calls
115 * {@link Locator#narrow(Object, Class)} to narrow to this type;
116 * else it returns the original <code>homeobj</code>.
117 * <p>
118 * This method will be called by {@link #createSLSB(Object, ServiceLocatorOptions)} just before it calls the
119 * home object's accessible no-arg <code>create()</code> method.
120 */
121 public Object narrowSLSBHome(Object homeobj, ServiceLocatorOptions options) throws ServiceLocatorException {
122 if ( options instanceof SLSBLocatorOptions ) {
123 SLSBLocatorOptions myOptions = (SLSBLocatorOptions)options;
124 if ( myOptions.castHomeTo != null ) {
125 homeobj = narrow(homeobj, myOptions.castHomeTo);
126 }
127 }
128 return homeobj;
129 }
130
131 /**
132 * Creates a SLSB given its home. Uses reflection to call the accessible no-arg
133 * <code>create()</code> method on the given home object. <i>Does not</i>
134 * narrow the resulting <code>EJBObject</code>. Calls {@link #narrowSLSBHome(Object, ServiceLocatorOptions)}
135 * to narrow the <code>EJBHome</code> before calling <code>create()</code> on it.
136 * Subclasses are free to override this behavior as needed.
137 */
138 public Object createSLSB(Object homeobj, ServiceLocatorOptions options) throws ServiceLocatorException {
139 try {
140 homeobj = narrowSLSBHome(homeobj, options);
141 Method createMethod = homeobj.getClass().getMethod( "create", new Class[0] );
142 if ( _log.isDebugEnabled() ) {
143 _log.debug( "Calling method '" + createMethod + "'" );
144 }
145 Object svc = createMethod.invoke( homeobj, new Object[0] );
146 if ( _log.isDebugEnabled() ) {
147 _log.debug( "Back from create(). svc='" + svc + "'" );
148 }
149 return svc;
150 }
151 catch( Exception e ) {
152 throw new ServiceLocatorException(e);
153 }
154 }
155
156 private static Log _log = LogFactory.getLog(SLSBLocator.class);
157 }
158