001: /* ====================================================================
002: * The LateralNZ Software License, Version 1.0
003: *
004: * Copyright (c) 2003 LateralNZ. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by
021: * LateralNZ (http://www.lateralnz.org/) and other third parties."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. The names "LateralNZ" must not be used to endorse or promote
026: * products derived from this software without prior written
027: * permission. For written permission, please
028: * contact oss@lateralnz.org.
029: *
030: * 5. Products derived from this software may not be called "Panther",
031: * or "Lateral" or "LateralNZ", nor may "PANTHER" or "LATERAL" or
032: * "LATERALNZ" appear in their name, without prior written
033: * permission of LateralNZ.
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 LateralNZ. For more
051: * information on Lateral, please see http://www.lateralnz.com/ or
052: * http://www.lateralnz.org
053: *
054: */
055: package org.lateralnz.common.util;
056:
057: import java.util.HashMap;
058: import java.util.Hashtable;
059: import java.util.Map;
060: import java.util.MissingResourceException;
061: import java.util.ResourceBundle;
062: import java.util.StringTokenizer;
063:
064: import javax.ejb.EJBHome;
065: import javax.ejb.EJBObject;
066: import javax.naming.Context;
067: import javax.naming.InitialContext;
068: import javax.naming.Name;
069: import javax.naming.NameNotFoundException;
070: import javax.naming.NamingException;
071: import javax.naming.spi.ObjectFactory;
072: import javax.naming.Reference;
073: import javax.naming.RefAddr;
074: import javax.naming.StringRefAddr;
075: import javax.rmi.PortableRemoteObject;
076:
077: import org.apache.log4j.Logger;
078:
079: /**
080: * common utilities for looking up objects (EJBs, Datasources, etc)
081: * in the JNDI tree
082: *
083: * @author J R Briggs
084: */
085: public final class JNDIUtils implements Constants, ObjectFactory {
086: private static final Logger log = Logger.getLogger(JNDIUtils.class
087: .getName());
088: private static final String NAME = "name";
089: private static final String LOCALHOST = "localhost";
090: private static final String DOT_ALIAS = ".alias";
091:
092: private static final NamingException NO_DEFAULT_CONTEXT = new NamingException(
093: "no default context");
094:
095: private static Context DEFAULT_CONTEXT = null;
096: private static Context EJB_CONTEXT = null;
097: public static Context DAO_CONTEXT = null;
098:
099: private static String defaultContextName = null;
100: private static String ejbContextName = null;
101: private static String daoContextName = null;
102:
103: private static String ejbPrefix = null;
104:
105: private static ResourceBundle resources;
106: private static Map contexts = new HashMap();
107: private static Map nonSerializableObjects = new HashMap();
108:
109: static {
110: resources = ResourceUtils.getStaticBundle(JNDIUtils.class);
111: try {
112: defaultContextName = resources
113: .getString("default_context.alias");
114: } catch (Exception e) {
115: }
116:
117: try {
118: ejbContextName = resources.getString("ejb_context.alias");
119: } catch (Exception e) {
120: }
121:
122: try {
123: daoContextName = resources.getString("dao_context.alias");
124: } catch (Exception e) {
125: }
126:
127: if (defaultContextName != null) {
128: try {
129: DEFAULT_CONTEXT = getContext(defaultContextName);
130: log.info("got default context " + DEFAULT_CONTEXT);
131: } catch (Exception e) {
132: log.error("error loading default context");
133: e.printStackTrace();
134: }
135: }
136:
137: if (ejbContextName != null) {
138: try {
139: EJB_CONTEXT = getContext(ejbContextName);
140: } catch (Exception e) {
141: log.error("error loading ejb context");
142: e.printStackTrace();
143: }
144:
145: }
146:
147: if (daoContextName != null) {
148: try {
149: DAO_CONTEXT = getContext(daoContextName);
150: } catch (Exception e) {
151: log.error("error loading dao context");
152: e.printStackTrace();
153: }
154: }
155: }
156:
157: /**
158: * get a named context for localhost
159: */
160: public static final Context getContext(String contextName)
161: throws NamingException {
162: return getContext(contextName, LOCALHOST);
163: }
164:
165: /**
166: * get a named context for the specified server
167: */
168: public static final Context getContext(String contextName,
169: String server) throws NamingException {
170: Context ctx = null;
171: if (log.isDebugEnabled()) {
172: log.debug("getContext(" + contextName + "," + server + ")");
173: }
174:
175: if (ResourceUtils.hasString(resources, contextName + DOT_ALIAS)) {
176: contextName = resources.getString(contextName + DOT_ALIAS);
177: if (log.isDebugEnabled()) {
178: log.debug("found alias, context now " + contextName);
179: }
180: }
181:
182: String name = contextName + UNDERSCORE + server;
183:
184: if (contexts.containsKey(name)) {
185: ctx = (Context) contexts.get(name);
186: } else {
187: Hashtable ht = new Hashtable();
188: String ctxparams = null;
189: try {
190: ctxparams = resources
191: .getString(contextName + ".params");
192: } catch (MissingResourceException mre) {
193: // do nothing
194: }
195:
196: if (!StringUtils.isEmpty(ctxparams)) {
197: StringTokenizer st = new StringTokenizer(ctxparams,
198: COMMA);
199:
200: while (st.hasMoreTokens()) {
201: String param = st.nextToken();
202: try {
203: ht.put(param, resources.getString(contextName
204: + DOT + param));
205: } catch (MissingResourceException mre) {
206: throw new NamingException("param " + param
207: + " does not contain a value");
208: }
209: }
210: }
211:
212: if (ht.size() < 1) {
213: ctx = new InitialContext();
214: } else {
215: String tmp = (String) ht.get(Context.PROVIDER_URL);
216: if (!StringUtils.isEmpty(tmp)) {
217: ht.put(Context.PROVIDER_URL, StringUtils.replace(
218: tmp, "<!--server-->", server));
219: }
220:
221: ctx = new InitialContext(ht);
222: }
223:
224: if (log.isDebugEnabled()) {
225: log.debug("context " + name + " = " + ctx + ", env="
226: + ht.toString());
227: }
228: contexts.put(name, ctx);
229: }
230: return ctx;
231: }
232:
233: public static final Context getDefaultContext() {
234: return DEFAULT_CONTEXT;
235: }
236:
237: /**
238: * bind a named object to the JNDI tree using the default context
239: */
240: public static void bind(String objectName, Object obj)
241: throws NamingException {
242: if (DEFAULT_CONTEXT == null) {
243: throw NO_DEFAULT_CONTEXT;
244: } else {
245: bind(DEFAULT_CONTEXT, objectName, obj);
246: }
247: }
248:
249: /**
250: * bind a named object to the JNDI tree using the specified context
251: */
252: public static void bind(Context ctx, String objectName, Object obj)
253: throws NamingException {
254: if (log.isDebugEnabled()) {
255: log.debug("binding " + objectName
256: + " into default context " + ctx);
257: }
258: ctx.rebind(objectName, obj);
259: }
260:
261: /**
262: * bind a non serializable object
263: */
264: public static final void bindNonSerializable(String name,
265: Object obj, Context ctx) throws NamingException {
266: Reference ref = new Reference(obj.getClass().getName(),
267: JNDIUtils.class.getName(), null);
268: ref.add(new StringRefAddr(NAME, name));
269: ctx.rebind(name, ref);
270: nonSerializableObjects.put(name, obj);
271: }
272:
273: public static final Context createSubcontext(Context ctx,
274: String name) throws NamingException {
275: Context context;
276: try {
277: context = (Context) ctx.lookup(name);
278: } catch (NameNotFoundException nnfe) {
279: context = ctx.createSubcontext(name);
280: }
281: return context;
282: }
283:
284: /**
285: * unbind an object from the JNDI tree using the default context
286: */
287: public static void unbind(String objectName) throws NamingException {
288: if (DEFAULT_CONTEXT == null) {
289: throw NO_DEFAULT_CONTEXT;
290: } else {
291: unbind(DEFAULT_CONTEXT, objectName);
292: }
293: }
294:
295: /**
296: * unbind an object from the JNDI tree using the specified context
297: */
298: public static void unbind(Context ctx, String objectName)
299: throws NamingException {
300: ctx.unbind(objectName);
301: }
302:
303: /**
304: * get an object from the JNDI tree using the default context
305: */
306: public static final Object get(String objectName)
307: throws NamingException {
308: if (DEFAULT_CONTEXT == null) {
309: throw NO_DEFAULT_CONTEXT;
310: } else {
311: return get(DEFAULT_CONTEXT, objectName);
312: }
313: }
314:
315: /**
316: * get an object from the JNDI tree using the specified context
317: */
318: public static final Object get(Context ctx, String objectName)
319: throws NamingException {
320: if (StringUtils.isEmpty(objectName)) {
321: throw new NamingException("no object name specified");
322: }
323:
324: return ctx.lookup(objectName);
325: }
326:
327: /**
328: * get an EJB home using the default context
329: */
330: public static final EJBHome getEJBHome(String ejbName,
331: Class ejbHomeClass) throws NamingException {
332: if (EJB_CONTEXT == null) {
333: throw NO_DEFAULT_CONTEXT;
334: } else {
335: return getEJBHome(EJB_CONTEXT, ejbName, ejbHomeClass);
336: }
337: }
338:
339: /**
340: * get an EJB home using the specified context
341: */
342: public static final EJBHome getEJBHome(Context ctx, String ejbName,
343: Class ejbHomeClass) throws NamingException {
344: Object tmp = get(ctx, ejbName);
345:
346: return (EJBHome) PortableRemoteObject.narrow(tmp, ejbHomeClass);
347: }
348:
349: /**
350: * call the remove() method on an EJB -- and ignore any exceptions
351: */
352: public static final void remove(EJBObject obj) {
353: if (obj != null) {
354: try {
355: obj.remove();
356: //if(log.isInfoEnabled()) {
357: //log.info("### ejb removed ###");
358: //}
359: } catch (Exception e) {
360: }
361: }
362: }
363:
364: public Object getObjectInstance(Object obj, Name name, Context ctx,
365: Hashtable environment) throws NamingException {
366: Reference ref = (Reference) obj;
367: Object rtn = nonSerializableObjects
368: .get(getProperty(ref, "name"));
369: System.out.println("JNDI " + getProperty(ref, "name") + ", "
370: + rtn.getClass().getName());
371: return rtn;
372: }
373:
374: protected String getProperty(Reference ref, String s) {
375: RefAddr addr = ref.get(s);
376: if (addr == null) {
377: return null;
378: }
379: return (String) addr.getContent();
380: }
381:
382: public static final void main(String[] args) {
383: try {
384: Object obj = JNDIUtils.getEJBHome(args[0], Class
385: .forName(args[1]));
386: System.out.println(">> got object "
387: + obj.getClass().getName());
388: java.lang.reflect.Method method = obj.getClass().getMethod(
389: "create", null);
390: Object ejb = method.invoke(obj, null);
391: System.out
392: .println(">> got ejb " + ejb.getClass().getName());
393: java.lang.reflect.Method ejbmethod = ejb.getClass()
394: .getMethod(args[2], null);
395: System.out.println(ejbmethod.invoke(ejb, null));
396: } catch (Exception e) {
397: e.printStackTrace();
398: }
399: }
400: }
|