001 // Copyright 2004, 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.hivemind.lib.impl;
016
017 import java.util.Hashtable;
018
019 import javax.naming.Context;
020 import javax.naming.InitialContext;
021 import javax.naming.NamingException;
022
023 import org.apache.hivemind.ApplicationRuntimeException;
024 import org.apache.hivemind.HiveMind;
025 import org.apache.hivemind.lib.NameLookup;
026 import org.apache.hivemind.lib.RemoteExceptionCoordinator;
027 import org.apache.hivemind.lib.RemoteExceptionEvent;
028 import org.apache.hivemind.lib.RemoteExceptionListener;
029
030 /**
031 * Standard implementation of the {@link org.apache.hivemind.lib.NameLookup}
032 * service interface.
033 *
034 * @author Howard Lewis Ship
035 */
036 public class NameLookupImpl implements NameLookup, RemoteExceptionListener
037 {
038 private RemoteExceptionCoordinator _coordinator;
039 private Context _initialContext;
040 private String _initialFactory;
041 private String _URLPackages;
042 private String _providerURL;
043
044 public Object lookup(String name, Class expected)
045 {
046 int i = 0;
047
048 while (true)
049 {
050 Context context = null;
051 Object raw = null;
052
053 try
054 {
055 context = getInitialContext();
056
057 raw = context.lookup(name);
058 }
059 catch (NamingException ex)
060 {
061 if (i++ == 0)
062 _coordinator.fireRemoteExceptionDidOccur(this, ex);
063 else
064 throw new ApplicationRuntimeException(
065 ImplMessages.unableToLookup(name, context),
066 ex);
067 continue;
068 }
069
070 if (raw == null)
071 throw new ApplicationRuntimeException(ImplMessages.noObject(name, expected));
072
073 if (!expected.isAssignableFrom(raw.getClass()))
074 throw new ApplicationRuntimeException(ImplMessages.wrongType(name, raw, expected));
075
076 return raw;
077 }
078 }
079
080 private Context getInitialContext() throws NamingException
081 {
082 if (_initialContext == null)
083 {
084
085 Hashtable properties = new Hashtable();
086
087 if (!HiveMind.isBlank(_initialFactory))
088 properties.put(Context.INITIAL_CONTEXT_FACTORY, _initialFactory);
089
090 if (!HiveMind.isBlank(_providerURL))
091 properties.put(Context.PROVIDER_URL, _providerURL);
092
093 if (!HiveMind.isBlank(_URLPackages))
094 properties.put(Context.URL_PKG_PREFIXES, _URLPackages);
095
096 _initialContext = constructContext(properties);
097 }
098
099 return _initialContext;
100 }
101
102 /**
103 * Constructs the InitialContext (this is separated out in a standalone
104 * method so that it may be overridden in a testing subclass).
105 */
106 protected Context constructContext(Hashtable properties) throws NamingException
107 {
108 return new InitialContext(properties);
109 }
110
111 /**
112 * Sets the InitialContext to null.
113 */
114 public void remoteExceptionDidOccur(RemoteExceptionEvent event)
115 {
116 _initialContext = null;
117 }
118
119 /**
120 * Sets the initial factory used to create the initial JNDI context.
121 * Equivalent to the system property <code>java.naming.factory.initial</code>.
122 */
123 public void setInitialFactory(String string)
124 {
125 _initialFactory = string;
126 }
127
128 /**
129 * Sets the JNDI provider URL, used to create the initial JNDI context.
130 * Equivalent to the system property <code>java.naming.provider.url</code>.
131 */
132 public void setProviderURL(String string)
133 {
134 _providerURL = string;
135 }
136
137 /**
138 * Sets the URL packages, used to create the initial JNDI context.
139 * Equivalent to the system property
140 * <code>java.naming.factory.url.pkgs</code>
141 */
142
143 public void setURLPackages(String string)
144 {
145 _URLPackages = string;
146 }
147
148 public void setCoordinator(RemoteExceptionCoordinator coordinator)
149 {
150 _coordinator = coordinator;
151 }
152
153 }