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.base;
059:
060: import java.util.HashMap;
061: import java.util.Iterator;
062: import java.util.List;
063: import java.util.Map;
064:
065: import javax.wsdl.Operation;
066: import javax.xml.namespace.QName;
067:
068: import org.apache.wsif.WSIFCorrelationId;
069: import org.apache.wsif.WSIFException;
070: import org.apache.wsif.WSIFMessage;
071: import org.apache.wsif.WSIFOperation;
072: import org.apache.wsif.WSIFPort;
073: import org.apache.wsif.WSIFResponseHandler;
074: import org.apache.wsif.compiler.util.TypeMapping;
075: import org.apache.wsif.logging.Trc;
076: import org.apache.wsif.util.WSIFUtils;
077: import org.apache.wsif.wsdl.extensions.jms.JMSProperty;
078: import org.apache.wsif.wsdl.extensions.jms.JMSPropertyValue;
079:
080: public abstract class WSIFDefaultOperation implements WSIFOperation {
081: private static final long serialVersionUID = 1L;
082: transient protected HashMap inJmsProps = new HashMap();
083: transient protected HashMap outJmsProps = new HashMap();
084: transient protected HashMap inJmsPropVals = new HashMap();
085: protected WSIFMessage context;
086: protected boolean closed = false;
087:
088: /**
089: * @see WSIFOperation#executeRequestResponseOperation(WSIFMessage, WSIFMessage, WSIFMessage)
090: */
091: public abstract boolean executeRequestResponseOperation(
092: WSIFMessage input, WSIFMessage output, WSIFMessage fault)
093: throws WSIFException;
094:
095: /**
096: * @see WSIFOperation#executeInputOnlyOperation(WSIFMessage)
097: */
098: public abstract void executeInputOnlyOperation(WSIFMessage input)
099: throws WSIFException;
100:
101: /**
102: * Default implementation of executeRequestResponseAsync.
103: * By default async operation is not supported so this just
104: * throws an exception.
105: * @see WSIFOperation#executeRequestResponseAsync(WSIFMessage, WSIFResponseHandler)
106: */
107: public WSIFCorrelationId executeRequestResponseAsync(
108: WSIFMessage input, WSIFResponseHandler handler)
109: throws WSIFException {
110: throw new WSIFException(
111: "asynchronous operations not supportted");
112: }
113:
114: /**
115: * Default implementation of executeRequestResponseAsync.
116: * By default async operation is not supported so this just
117: * throws an exception.
118: * @see WSIFOperation#executeRequestResponseAsync(WSIFMessage)
119: */
120: public WSIFCorrelationId executeRequestResponseAsync(
121: WSIFMessage input) throws WSIFException {
122: throw new WSIFException(
123: "asynchronous operations not supportted");
124: }
125:
126: /**
127: * Default implemantation of fireAsyncResponse.
128: * By default async operation is not supported so this just
129: * throws an exception.
130: * @see WSIFOperation#fireAsyncResponse(Object)
131: * @param response an Object representing the response
132: */
133: public void fireAsyncResponse(Object response) throws WSIFException {
134: throw new WSIFException(
135: "asynchronous operations not supportted");
136: }
137:
138: /**
139: * Default implemantation of processAsyncResponse.
140: * By default async operation is not supported so this just
141: * throws an exception.
142: * @see WSIFOperation#processAsyncResponse(Object,WSIFMessage,WSIFMessage)
143: */
144: public boolean processAsyncResponse(Object response,
145: WSIFMessage output, WSIFMessage fault) throws WSIFException {
146: throw new WSIFException(
147: "asynchronous operations not supportted");
148: }
149:
150: /**
151: * @see WSIFOperation#createInputMessage()
152: */
153: public WSIFMessage createInputMessage() {
154: Trc.entry(this );
155: WSIFMessage msg = new WSIFDefaultMessage();
156: if (msg != null) {
157: // Now find the javax.wsdl.Message & set it on the WSIFMessage
158: try {
159: msg.setMessageDefinition(getOperation().getInput()
160: .getMessage());
161: } catch (Exception e) {
162: Trc.ignoredException(e);
163: }
164: }
165: Trc.exit(msg);
166: return msg;
167: }
168:
169: /**
170: * @see WSIFOperation#createInputMessage(String)
171: */
172: public WSIFMessage createInputMessage(String name) {
173: Trc.entry(this , name);
174: WSIFMessage msg = new WSIFDefaultMessage();
175: if (msg != null) {
176: msg.setName(name);
177: // Now find the javax.wsdl.Message & set it on the WSIFMessage
178: try {
179: msg.setMessageDefinition(getOperation().getInput()
180: .getMessage());
181: } catch (Exception e) {
182: Trc.ignoredException(e);
183: }
184: }
185: Trc.exit(msg);
186: return msg;
187: }
188:
189: /**
190: * @see WSIFOperation#createOutputMessage()
191: */
192: public WSIFMessage createOutputMessage() {
193: Trc.entry(this );
194: WSIFMessage msg = new WSIFDefaultMessage();
195: if (msg != null) {
196: // Now find the javax.wsdl.Message & set it on the WSIFMessage
197: try {
198: msg.setMessageDefinition(getOperation().getOutput()
199: .getMessage());
200: } catch (Exception e) {
201: Trc.ignoredException(e);
202: }
203: }
204: Trc.exit(msg);
205: return msg;
206: }
207:
208: /**
209: * @see WSIFOperation#createOutputMessage(String)
210: */
211: public WSIFMessage createOutputMessage(String name) {
212: Trc.entry(this , name);
213: WSIFMessage msg = new WSIFDefaultMessage();
214: if (msg != null) {
215: msg.setName(name);
216: // Now find the javax.wsdl.Message & set it on the WSIFMessage
217: try {
218: msg.setMessageDefinition(getOperation().getOutput()
219: .getMessage());
220: } catch (Exception e) {
221: Trc.ignoredException(e);
222: }
223: }
224: Trc.exit(msg);
225: return msg;
226: }
227:
228: /**
229: * @see WSIFOperation#createFaultMessage()
230: */
231: public WSIFMessage createFaultMessage() {
232: Trc.entry(this );
233: WSIFMessage wm = new WSIFDefaultMessage();
234: Trc.exit(wm);
235: return wm;
236: }
237:
238: /**
239: * @see WSIFOperation#createFaultMessage(String)
240: */
241: public WSIFMessage createFaultMessage(String name) {
242: Trc.entry(this , name);
243: WSIFMessage msg = new WSIFDefaultMessage();
244: if (msg != null) {
245: msg.setName(name);
246: // Now find the javax.wsdl.Message & set it on the WSIFMessage
247: try {
248: msg.setMessageDefinition(getOperation().getFault(name)
249: .getMessage());
250: } catch (Exception e) {
251: Trc.ignoredException(e);
252: }
253: }
254: Trc.exit(msg);
255: return msg;
256: }
257:
258: /**
259: * Sets the input Jms properties for this operation
260: */
261: public void setInputJmsProperties(List list) throws WSIFException {
262: Trc.entry(this , list);
263: inJmsProps = makeSomeKindOfJmsMap(list);
264: Trc.exit();
265: }
266:
267: /**
268: * Sets the output Jms properties for this operation
269: */
270: public void setOutputJmsProperties(List list) throws WSIFException {
271: Trc.entry(this , list);
272: outJmsProps = makeSomeKindOfJmsMap(list);
273: Trc.exit();
274: }
275:
276: public void setInputJmsProperties(HashMap hm) {
277: Trc.entry(this , hm);
278: inJmsProps = hm;
279: Trc.exit();
280: }
281:
282: public void setOutputJmsProperties(HashMap hm) {
283: Trc.entry(this , hm);
284: outJmsProps = hm;
285: Trc.exit();
286: }
287:
288: public HashMap getInputJmsProperties() {
289: Trc.entry(this );
290: Trc.exit(inJmsProps);
291: return inJmsProps;
292: }
293:
294: public HashMap getOutputJmsProperties() {
295: Trc.entry(this );
296: Trc.exit(outJmsProps);
297: return outJmsProps;
298: }
299:
300: public abstract WSIFPort getWSIFPort();
301:
302: /**
303: * This method adds new property values to existing HashMap.
304: * Where a property value exists in the existing HashMap and the new list,
305: * this method replaces the existing property value with the new one from the list.
306: */
307: public void addInputJmsPropertyValues(List list)
308: throws WSIFException {
309: Trc.entry(this , list);
310: if (list != null && !list.isEmpty()) {
311: HashMap newPvs = makeSomeKindOfJmsMap(list);
312: newPvs.putAll(inJmsPropVals);
313: inJmsPropVals = newPvs;
314: }
315: Trc.exit();
316: }
317:
318: public void setInputJmsPropertyValues(HashMap hm) {
319: Trc.entry(this , hm);
320: inJmsPropVals = hm;
321: Trc.exit();
322: }
323:
324: public HashMap getInputJmsPropertyValues() {
325: Trc.entry(this );
326: Trc.exit(inJmsPropVals);
327: return inJmsPropVals;
328: }
329:
330: /**
331: * Utility method that sets the jms properties for this operation
332: */
333: protected HashMap makeSomeKindOfJmsMap(List list)
334: throws WSIFException {
335: Trc.entry(this , list);
336: Map simpleTypeReg = WSIFUtils.getSimpleTypesMap();
337: HashMap props = new HashMap(list.size());
338: for (Iterator it = list.iterator(); it.hasNext();) {
339: Object ee = it.next();
340: if (ee instanceof JMSProperty) {
341: JMSProperty prop = (JMSProperty) ee;
342: props.put(prop.getPart(), prop.getName());
343: } else if (ee instanceof JMSPropertyValue) {
344: JMSPropertyValue propVal = (JMSPropertyValue) ee;
345:
346: String name = propVal.getName();
347: if (name == null || name.length() == 0)
348: throw new WSIFException(
349: "jms:propertyValue found without a name");
350:
351: QName type = propVal.getType();
352: if (type == null)
353: throw new WSIFException("jms:propertyValue " + name
354: + " did not have a type");
355: if (type.getNamespaceURI() == null
356: || type.getLocalPart() == null)
357: throw new WSIFException("jms:propertyValue " + name
358: + " has a badly formed type");
359:
360: String value = propVal.getValue();
361: if (value == null || value.length() == 0)
362: throw new WSIFException("jms:propertyValue " + name
363: + " did not have a value");
364:
365: TypeMapping tm = (TypeMapping) (simpleTypeReg.get(type));
366: if (tm == null || tm.javaType == null)
367: throw new WSIFException("jms:propertyValue " + name
368: + " had a type that was "
369: + "unknown or was not a simple type");
370:
371: Class javaClass = null;
372: try {
373: javaClass = Class.forName(tm.javaType, true, Thread
374: .currentThread().getContextClassLoader());
375: } catch (ClassNotFoundException cce) {
376: Trc.exception(cce);
377: throw new WSIFException(
378: "Unexpected ClassNotFoundException when processing "
379: + "jms:propertyValue "
380: + name
381: + ". Could not convert the type to a java class. "
382: + cce);
383: }
384:
385: Object obj = null;
386: try {
387: if (javaClass.equals(String.class))
388: obj = value;
389: else if (javaClass.equals(Integer.class))
390: obj = new Integer(value);
391: else if (javaClass.equals(Boolean.class))
392: obj = new Boolean(value);
393: else if (javaClass.equals(Byte.class))
394: obj = new Byte(value);
395: else if (javaClass.equals(Double.class))
396: obj = new Double(value);
397: else if (javaClass.equals(Float.class))
398: obj = new Float(value);
399: else if (javaClass.equals(Long.class))
400: obj = new Long(value);
401: else if (javaClass.equals(Short.class))
402: obj = new Short(value);
403: else
404: throw new WSIFException("jms:propertyValue "
405: + name + " had an invalid type");
406: } catch (NumberFormatException nfe) {
407: Trc.exception(nfe);
408: throw new WSIFException(
409: "jms:propertyValue "
410: + name
411: + " a value that could not "
412: + "be converted into the specified type. Caught NumberFormatException. "
413: + nfe);
414: }
415:
416: props.put(name, obj);
417: }
418: }
419: Trc.exit(props);
420: return props;
421: }
422:
423: /**
424: * Allows the application programmer or stub to pass context
425: * information to the binding. The Port implementation may use
426: * this context - for example to update a SOAP header. There is
427: * no definition of how a Port may utilize the context.
428: */
429: public void setContext(WSIFMessage context) {
430: Trc.entry(this , context);
431: if (context == null) {
432: throw new IllegalArgumentException(
433: "context must not be null");
434: }
435: this .context = context;
436: Trc.exit();
437: }
438:
439: /**
440: * Gets the context information for this binding.
441: */
442: public WSIFMessage getContext() throws WSIFException {
443: Trc.entry(this );
444: WSIFMessage contextCopy;
445: try {
446: if (this .context == null) {
447: contextCopy = (WSIFMessage) getWSIFPort().getContext()
448: .clone();
449: } else {
450: contextCopy = (WSIFMessage) this .context.clone();
451: }
452: } catch (CloneNotSupportedException e) {
453: throw new WSIFException(
454: "CloneNotSupportedException cloning context", e);
455: }
456: Trc.exit(contextCopy);
457: return contextCopy;
458: }
459:
460: abstract protected Operation getOperation() throws Exception;
461:
462: protected void close() throws WSIFException {
463: Trc.entry(this );
464: if (closed)
465: throw new WSIFException(
466: "Cannot reuse a WSIFOperation to invoke multiple operations");
467: closed = true;
468: Trc.exit();
469: }
470: }
|