001: /*
002: * The Apache Software License, Version 1.1
003: *
004: *
005: * Copyright (c) 2002 The Apache Software Foundation. All rights
006: * 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: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * 2. 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: * 3. The end-user documentation included with the redistribution,
021: * if any, must include the following acknowledgment:
022: * "This product includes software developed by the
023: * Apache Software Foundation (http://www.apache.org/)."
024: * Alternately, this acknowledgment may appear in the software itself,
025: * if and wherever such third-party acknowledgments normally appear.
026: *
027: * 4. The names "WSIF" and "Apache Software Foundation" must
028: * not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact apache@apache.org.
031: *
032: * 5. Products derived from this software may not be called "Apache",
033: * nor may "Apache" appear in their name, without prior written
034: * permission of the Apache Software Foundation.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the Apache Software Foundation and was
052: * originally based on software copyright (c) 2001, 2002, International
053: * Business Machines, Inc., http://www.apache.org. For more
054: * information on the Apache Software Foundation, please see
055: * <http://www.apache.org/>.
056: */
057:
058: package org.apache.wsif.util.jms;
059:
060: import java.util.Hashtable;
061:
062: import javax.jms.Destination;
063: import javax.jms.Queue;
064: import javax.jms.QueueConnectionFactory;
065: import javax.naming.Context;
066: import javax.naming.NamingException;
067: import javax.naming.directory.InitialDirContext;
068: import org.apache.wsif.WSIFException;
069: import org.apache.wsif.logging.Trc;
070:
071: /**
072: * Finds JMS objects by looking them up in JNDI.
073: * @author Mark Whitlock <whitlock@apache.org>
074: */
075: public class WSIFJMSFinderForJndi extends WSIFJMSFinder {
076:
077: private InitialDirContext namedJndiContext = null;
078: private InitialDirContext containersJndiContext = null;
079: private QueueConnectionFactory factory;
080: private Destination initialDestination = null;
081: private String style;
082: private String portName;
083:
084: /**
085: * Package private constructor.
086: * @param jmsVendorURL uniquely identifies the JMS implementation. Unused at present.
087: * @param initialContextFactory used to get JNDI's InitialContext in a non-managed environment
088: * @param jndiProviderURL of the JNDI repository
089: * @param style is either queue or topic
090: * @param jndiConnectionFactory is the JNDI name of the qcf
091: * @param jndiDestinationName is the JNDI name of the initial queue.
092: * @param jmsproviderDestinationName is the JMS implementation's name of the initial queue.
093: */
094: public WSIFJMSFinderForJndi(String jmsVendorURL,
095: String initialContextFactory, String jndiProviderURL,
096: String style, String jndiConnectionFactory,
097: String jndiDestinationName, String portName)
098: throws WSIFException {
099: Trc.entry(this , jmsVendorURL, initialContextFactory,
100: jndiProviderURL, style, jndiConnectionFactory,
101: jndiDestinationName, portName);
102:
103: if (!allStyles.contains(style))
104: throw new WSIFException(
105: "Style must either be queue or topic");
106: this .style = style;
107: if (portName == null)
108: portName = "<null>";
109: this .portName = portName;
110:
111: if (((initialContextFactory == null) && (jndiProviderURL != null))
112: || ((initialContextFactory != null) && (jndiProviderURL == null)))
113: throw new WSIFException(
114: "Either both initialContextFactory and jndiProviderURL "
115: + "must be specified or neither of them must be specified. Port="
116: + portName);
117:
118: /*
119: * Go find the container's JNDI and the JNDI specified in the WSDL.
120: */
121: if (initialContextFactory != null && jndiProviderURL != null) {
122: Hashtable environment = new Hashtable();
123: environment.put(Context.INITIAL_CONTEXT_FACTORY,
124: initialContextFactory);
125: environment.put(Context.PROVIDER_URL, jndiProviderURL);
126:
127: try {
128: namedJndiContext = new InitialDirContext(environment);
129: } catch (NamingException ne) {
130: Trc.exception(ne);
131: throw new WSIFException("WSIFJMSFinderForJndi caught '"
132: + ne + "'. InitialContextFactory was '"
133: + initialContextFactory + "' ProviderUrl was '"
134: + jndiProviderURL + "'. Port=" + portName);
135: }
136: }
137:
138: try {
139: containersJndiContext = new InitialDirContext();
140: } catch (NamingException ne) {
141: Trc.exception(ne);
142: if (initialContextFactory == null
143: && jndiProviderURL == null)
144: throw new WSIFException("WSIFJMSFinderForJndi caught '"
145: + ne
146: + "' using the default JNDI repository. Port="
147: + portName);
148: }
149:
150: if (STYLE_TOPIC.equals(style))
151: throw new WSIFException("Topics not implemented. Port="
152: + portName);
153: else if (!STYLE_QUEUE.equals(style))
154: throw new WSIFException(
155: "jms:address must either be a queue or a topic not a '"
156: + (style == null ? "null" : style)
157: + "'. Port=" + portName);
158:
159: /*
160: * Go find the queue connection factory.
161: */
162: if (jndiConnectionFactory == null)
163: throw new WSIFException(
164: "jndiConnectionFactory must be specified in port "
165: + portName);
166: try {
167: factory = (QueueConnectionFactory) lookup(jndiConnectionFactory);
168: if (factory == null)
169: throw new WSIFException(
170: "WSIFJMSFinderForJndi was not able to lookup the ConnectionFactory "
171: + jndiConnectionFactory
172: + " in JNDI. Port=" + portName);
173: } catch (ClassCastException cce) {
174: Trc.exception(cce);
175: throw new WSIFException(
176: "WSIFJMSFinderForJndi caught ClassCastException. The ConnectionFactory "
177: + jndiConnectionFactory
178: + " in JNDI was not defined to be a connection factory. Port="
179: + portName + " " + cce);
180: } catch (NamingException ne) {
181: Trc.exception(ne);
182: throw new WSIFException(
183: "WSIFJMSFinderForJndi caught NamingException. The ConnectionFactory "
184: + jndiConnectionFactory
185: + " in JNDI was not defined to be a connection factory. Port="
186: + portName + " " + ne);
187: }
188:
189: /*
190: * Go find the initial destination.
191: */
192: if (jndiDestinationName != null)
193: try {
194: initialDestination = (Destination) lookup(jndiDestinationName);
195: if (initialDestination == null)
196: throw new WSIFException(
197: "WSIFJMSFinderForJndi was not able to lookup the Destination "
198: + jndiDestinationName
199: + " in JNDI. Port=" + portName);
200: } catch (ClassCastException cce) {
201: Trc.exception(cce);
202: throw new WSIFException(
203: "WSIFJMSFinderForJndi caught ClassCastException. The Destination "
204: + jndiDestinationName
205: + " in JNDI was not defined to be a destination. Port="
206: + portName + " " + cce);
207: } catch (NamingException cce) {
208: Trc.exception(cce);
209: throw new WSIFException(
210: "WSIFJMSFinderForJndi caught NamingException. The Destination "
211: + jndiDestinationName
212: + " in JNDI was not defined to be a destination. Port="
213: + portName + " " + cce);
214: }
215: if (Trc.ON)
216: Trc.exit(deep());
217: }
218:
219: public QueueConnectionFactory getFactory() {
220: Trc.entry(this );
221: Trc.exit(factory);
222: return factory;
223: }
224:
225: public Destination getInitialDestination() {
226: Trc.entry(this );
227: Trc.exit(initialDestination);
228: return initialDestination;
229: }
230:
231: String getStyle() {
232: Trc.entry(this );
233: Trc.exit(style);
234: return style;
235: }
236:
237: Queue findQueue(String name) throws WSIFException {
238: Trc.entry(this , name);
239: Queue q = null;
240: try {
241: q = (Queue) lookup(name);
242: if (q == null)
243: throw new WSIFException(
244: "WSIFJMSFinderForJndi was not able to lookup the Destination "
245: + name + " in JNDI.Port=" + portName);
246: } catch (ClassCastException cce) {
247: Trc.exception(cce);
248: throw new WSIFException(
249: "WSIFJMSFinderForJndi caught ClassCastException. The Queue "
250: + name
251: + " in JNDI was not defined to be a queue. Port="
252: + portName + " " + cce);
253: } catch (NamingException ne) {
254: Trc.exception(ne);
255: throw new WSIFException(
256: "WSIFJMSFinderForJndi caught NamingException. The Queue "
257: + name
258: + " in JNDI was not defined to be a queue. Port="
259: + portName + " " + ne);
260: }
261: Trc.exit(q);
262: return q;
263: }
264:
265: /**
266: * There is at least one and at most two JNDI databases to look
267: * objects up in :- the container's default JNDI database and the
268: * one specified in the WSDL. This code looks objects up in the
269: * container's JNDI first (if running in a container), and then
270: * looks the object up in the JNDI pointed at by the WSDL (assuming
271: * there is a JNDI mentioned in the WSDL). This allows a client
272: * administrator to override the JNDI specified in the WSDL. If
273: * both fail, then the exception from the WSDL's JNDI is returned.
274: */
275: private Object lookupJNDIName(String name) throws NamingException {
276: Trc.entry(name);
277: Object result = null;
278: if (containersJndiContext != null) {
279: try {
280: result = containersJndiContext.lookup(name);
281: } catch (NamingException ne) {
282: Trc.exception(ne);
283: if (namedJndiContext != null)
284: result = namedJndiContext.lookup(name);
285: else
286: throw ne;
287: }
288: } else
289: result = namedJndiContext.lookup(name);
290: Trc.exit(result);
291: return result;
292: }
293:
294: /**
295: * The argument name is prefixed with "java:comp/env/" context
296: * prior to the JNDI lookup. If an exception is thrown, the
297: * JNDI lookup is done on the argument name without the prefix.
298: * If the lookup fails, the error based off the lookup of the
299: * argument is returned.
300: */
301: private Object lookup(String name) throws NamingException {
302: Trc.entry(name);
303:
304: Object result = null;
305: try {
306: result = lookupJNDIName("java:comp/env/" + name);
307: } catch (NamingException ignored) {
308: Trc.exception(ignored);
309: result = lookupJNDIName(name);
310: }
311: Trc.exit(result);
312: return result;
313: }
314:
315: public String deep() {
316: StringBuffer buff = new StringBuffer();
317: try {
318: buff.append(this .toString() + "\n");
319: buff.append("containersJndiContext: "
320: + containersJndiContext);
321: buff.append(" namedJndiContext: " + namedJndiContext);
322: buff.append(" factory: " + factory);
323: buff.append(" initialDestination: " + initialDestination);
324: buff.append(" style: " + style);
325: } catch (Exception e) {
326: Trc.exceptionInTrace(e);
327: }
328: return buff.toString();
329: }
330: }
|