001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.jaxws.core;
020:
021: import org.apache.axis2.AxisFault;
022: import org.apache.axis2.description.AxisService;
023: import org.apache.axis2.jaxws.description.EndpointDescription;
024: import org.apache.axis2.jaxws.description.OperationDescription;
025: import org.apache.axis2.jaxws.handler.MEPContext;
026: import org.apache.axis2.jaxws.message.Message;
027: import org.apache.axis2.jaxws.message.util.MessageUtils;
028:
029: import javax.xml.namespace.QName;
030: import javax.xml.ws.BindingProvider;
031: import javax.xml.ws.Service.Mode;
032: import javax.xml.ws.WebServiceException;
033: import java.util.HashMap;
034: import java.util.Map;
035: import java.util.AbstractMap;
036: import java.util.Collection;
037: import java.util.Iterator;
038: import java.util.Set;
039:
040: /**
041: * The <code>org.apache.axis2.jaxws.core.MessageContext</code> is an interface that extends the
042: * JAX-WS 2.0 <code>javax.xml.ws.handler.MessageContext</code> defined in the spec. This
043: * encapsulates all of the functionality needed of the MessageContext for the other JAX-WS spec
044: * pieces (the handlers for example) and also provides the needed bits of contextual information for
045: * the rest of the JAX-WS implementation.
046: * <p/>
047: * Specifically, this is responsible for providing APIs so that the client and server implementation
048: * portions can get to the Message, defined by the Message Model format and also any metadata that
049: * is available.
050: */
051: public class MessageContext {
052:
053: private InvocationContext invocationCtx;
054: private org.apache.axis2.context.MessageContext axisMsgCtx;
055: private Map<String, Object> properties;
056: private EndpointDescription endpointDesc;
057: private OperationDescription operationDesc;
058: private QName operationName; //FIXME: This should become the OperationDescription
059: private Message message;
060: private Mode mode;
061: private boolean isOutbound; // Outbound or inbound message context
062:
063: // TODO: flag to set whether we delegate property setting up to the
064: // axis2 message context object or keep it local
065: private boolean DELEGATE_TO_AXISMC = true;
066:
067: /*
068: * JAXWS runtime uses a request and response mc, but we need to know the pair.
069: * We will use this mepCtx as a wrapper to the request and response message contexts
070: * where the requestMC and responseMC have the same parent MEPContext to
071: * preserve the relationship.
072: */
073: private MEPContext mepCtx;
074:
075: // If a local exception is thrown, the exception is placed on the message context.
076: // It is not converted into a Message.
077: private Throwable localException = null;
078: private AxisFault causedByException = null;
079:
080: /**
081: * Construct a MessageContext without a prior Axis2 MessageContext
082: * (usage outbound dispatch/proxy)
083: */
084: public MessageContext() {
085: axisMsgCtx = new org.apache.axis2.context.MessageContext();
086: isOutbound = true;
087: if (!DELEGATE_TO_AXISMC) {
088: properties = new HashMap<String, Object>();
089: }
090:
091: }
092:
093: /**
094: * Construct a MessageContext with a prior MessageContext
095: * (usage inbound client/server or outbound server)
096: * @param mc
097: * @throws WebServiceException
098: */
099: public MessageContext(org.apache.axis2.context.MessageContext mc)
100: throws WebServiceException {
101: if (!DELEGATE_TO_AXISMC) {
102: properties = new HashMap<String, Object>();
103: }
104: // Assume inbound (caller must setOutbound)
105: isOutbound = false;
106:
107: /*
108: * Instead of creating a member MEPContext object every time, we will
109: * rely on users of this MessageContext class to create a new
110: * MEPContext and call setMEPContext(MEPContext)
111: */
112:
113: if (mc != null) {
114: axisMsgCtx = mc;
115: message = MessageUtils.getMessageFromMessageContext(mc);
116: if (message != null) {
117: message.setMessageContext(this );
118: }
119: } else {
120: axisMsgCtx = new org.apache.axis2.context.MessageContext();
121: }
122: }
123:
124: public InvocationContext getInvocationContext() {
125: return invocationCtx;
126: }
127:
128: public void setInvocationContext(InvocationContext ic) {
129: invocationCtx = ic;
130: }
131:
132: public Map<String, Object> getProperties() {
133: if (DELEGATE_TO_AXISMC) {
134: // only use properties that are local to the axis2 MC,
135: // not the options bag. See org.apache.axis2.context.AbstractContext
136: Iterator names = axisMsgCtx.getPropertyNames();
137: HashMap tempProps = new HashMap<String, Object>();
138: for (; names.hasNext();) {
139: String name = (String) names.next();
140: tempProps.put(name, axisMsgCtx.getProperty(name));
141: }
142: //return new ReadOnlyProperties(tempProps);
143: return tempProps;
144: }
145: return properties;
146: }
147:
148: public void setProperties(Map<String, Object> _properties) {
149: if (DELEGATE_TO_AXISMC) {
150: // make sure copy is made, not just reference:
151: _properties
152: .put(
153: org.apache.axis2.context.MessageContext.COPY_PROPERTIES,
154: true);
155: axisMsgCtx.setProperties(_properties);
156: } else {
157: getProperties().putAll(_properties);
158: }
159: }
160:
161: public Object getProperty(String key) {
162: if (DELEGATE_TO_AXISMC) {
163: // only use properties that are local to the axis2 MC,
164: // not the options bag. See org.apache.axis2.context.AbstractContext
165: Iterator names = axisMsgCtx.getPropertyNames();
166: for (; names.hasNext();) {
167: String name = (String) names.next();
168: if (name.equals(key)) {
169: return axisMsgCtx.getProperty(key);
170: }
171: }
172: return null;
173: }
174: return getProperties().get(key);
175: }
176:
177: // acts like Map.put(key, value)
178: public Object setProperty(String key, Object value) {
179: if (DELEGATE_TO_AXISMC) {
180: // only use properties that are local to the axis2 MC,
181: // not the options bag. See org.apache.axis2.context.AbstractContext
182: Object retval = null;
183: Iterator names = axisMsgCtx.getPropertyNames();
184: for (; names.hasNext();) {
185: String name = (String) names.next();
186: if (name.equals(key)) {
187: retval = axisMsgCtx.getProperty(key);
188: }
189: }
190: axisMsgCtx.setProperty(key, value);
191: return retval;
192: } else {
193: return getProperties().put(key, value);
194: }
195: }
196:
197: public EndpointDescription getEndpointDescription() {
198: return endpointDesc;
199: }
200:
201: public void setEndpointDescription(EndpointDescription ed) {
202: endpointDesc = ed;
203: }
204:
205: public OperationDescription getOperationDescription() {
206: return operationDesc;
207: }
208:
209: public void setOperationDescription(OperationDescription od) {
210: operationDesc = od;
211: }
212:
213: public Mode getMode() {
214: return mode;
215: }
216:
217: public void setMode(Mode m) {
218: mode = m;
219: }
220:
221: //FIXME: This should become the OperationDescription
222: public QName getOperationName() {
223: return operationName;
224: }
225:
226: //FIXME: This should become the OperationDescription
227: public void setOperationName(QName op) {
228: operationName = op;
229: }
230:
231: public void setMessage(Message msg) {
232: message = msg;
233: msg.setMessageContext(this );
234: }
235:
236: public Message getMessage() {
237: return message;
238: }
239:
240: public org.apache.axis2.context.MessageContext getAxisMessageContext() {
241: return axisMsgCtx;
242: }
243:
244: public ClassLoader getClassLoader() {
245: AxisService svc = axisMsgCtx.getAxisService();
246: if (svc != null)
247: return svc.getClassLoader();
248: else
249: return null;
250: }
251:
252: /**
253: * Used to determine whether or not session state has been enabled.
254: *
255: * @return
256: */
257: public boolean isMaintainSession() {
258: boolean maintainSession = false;
259:
260: Boolean value = (Boolean) getProperty(BindingProvider.SESSION_MAINTAIN_PROPERTY);
261: if (value != null && value.booleanValue()) {
262: maintainSession = true;
263: }
264:
265: return maintainSession;
266: }
267:
268: /**
269: * The local exception is the Throwable object held on the Message from a problem that occurred
270: * due to something other than the server. In other words, no message ever travelled across
271: * the wire.
272: *
273: * @return the Throwable object or null
274: */
275: public Throwable getLocalException() {
276: return localException;
277: }
278:
279: /**
280: * The local exception is the Throwable object held on the Message from a problem that occurred
281: * due to something other than the server. In other words, no message ever travelled across the
282: * wire.
283: *
284: * @param t
285: * @see Throwable
286: */
287: public void setLocalException(Throwable t) {
288: localException = t;
289: }
290:
291: /**
292: * @param t
293: */
294: public void setCausedByException(AxisFault t) {
295: this .causedByException = t;
296: }
297:
298: /**
299: * @return
300: */
301: public AxisFault getCausedByException() {
302: return this .causedByException;
303: }
304:
305: /**
306: * Set the wrapper MEPContext. Internally, this method also sets
307: * the MEPContext's children so the pointer is bi-directional; you can
308: * get the MEPContext from the MessageContext and vice-versa.
309: *
310: * @param mepCtx
311: */
312: public void setMEPContext(MEPContext mepCtx) {
313: if (this .mepCtx == null) {
314: this .mepCtx = mepCtx;
315: // and set parent's child pointer
316: this .mepCtx.setResponseMessageContext(this );
317: }
318: }
319:
320: public MEPContext getMEPContext() {
321: if (mepCtx == null) {
322: setMEPContext(new MEPContext(this ));
323: }
324: return mepCtx;
325: }
326:
327: /**
328: * @return if outbound MessageContext
329: */
330: public boolean isOutbound() {
331: return isOutbound;
332: }
333:
334: /**
335: * @param isOutbound true if outbound MessageContext
336: */
337: public void setOutbound(boolean isOutbound) {
338: this.isOutbound = isOutbound;
339: }
340:
341: }
|