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.description;
020:
021: import org.apache.axiom.om.util.UUIDGenerator;
022: import org.apache.axis2.AxisFault;
023: import org.apache.axis2.addressing.AddressingConstants.Final;
024: import org.apache.axis2.addressing.EndpointReference;
025: import org.apache.axis2.client.OperationClient;
026: import org.apache.axis2.client.Options;
027: import org.apache.axis2.client.async.Callback;
028: import org.apache.axis2.context.ConfigurationContext;
029: import org.apache.axis2.context.MessageContext;
030: import org.apache.axis2.context.OperationContext;
031: import org.apache.axis2.context.ServiceContext;
032: import org.apache.axis2.engine.AxisEngine;
033: import org.apache.axis2.i18n.Messages;
034: import org.apache.axis2.wsdl.WSDLConstants;
035:
036: import javax.xml.namespace.QName;
037: import java.util.ArrayList;
038: import java.util.HashMap;
039:
040: public class OutOnlyAxisOperation extends AxisOperation {
041:
042: private AxisMessage inFaultMessage;
043:
044: // just to keep the inflow , there won't be any usage
045: private ArrayList inPhases;
046:
047: private AxisMessage outFaultMessage;
048:
049: private AxisMessage outMessage;
050:
051: public OutOnlyAxisOperation() {
052: super ();
053: //setup a temporary name
054: QName tmpName = new QName(this .getClass().getName() + "_"
055: + UUIDGenerator.getUUID());
056: this .setName(tmpName);
057: createMessage();
058: setMessageExchangePattern(WSDL2Constants.MEP_URI_OUT_ONLY);
059: }
060:
061: public OutOnlyAxisOperation(QName name) {
062: super (name);
063: createMessage();
064: setMessageExchangePattern(WSDL2Constants.MEP_URI_OUT_ONLY);
065: }
066:
067: public void addMessage(AxisMessage message, String label) {
068: if (WSDLConstants.MESSAGE_LABEL_OUT_VALUE.equals(label)) {
069: outMessage = message;
070: } else {
071: throw new UnsupportedOperationException(
072: "Not yet implemented");
073: }
074: }
075:
076: public void addMessageContext(MessageContext msgContext,
077: OperationContext opContext) throws AxisFault {
078: if (!opContext.isComplete()) {
079: opContext.getMessageContexts().put(MESSAGE_LABEL_OUT_VALUE,
080: msgContext);
081: opContext.setComplete(true);
082: } else {
083: throw new AxisFault(Messages.getMessage("mepcompleted"));
084: }
085: }
086:
087: public void addFaultMessageContext(MessageContext msgContext,
088: OperationContext opContext) throws AxisFault {
089: HashMap mep = opContext.getMessageContexts();
090: MessageContext faultMessageCtxt = (MessageContext) mep
091: .get(MESSAGE_LABEL_FAULT_VALUE);
092:
093: if (faultMessageCtxt != null) {
094: throw new AxisFault(Messages.getMessage("mepcompleted"));
095: } else {
096: mep.put(MESSAGE_LABEL_FAULT_VALUE, msgContext);
097: opContext.setComplete(true);
098: opContext.cleanup();
099: }
100: }
101:
102: private void createMessage() {
103: outMessage = new AxisMessage();
104: outMessage
105: .setDirection(WSDLConstants.WSDL_MESSAGE_DIRECTION_OUT);
106: outMessage.setParent(this );
107: inFaultMessage = new AxisMessage();
108: inFaultMessage.setParent(this );
109: outFaultMessage = new AxisMessage();
110: outFaultMessage.setParent(this );
111: inPhases = new ArrayList();
112: }
113:
114: public AxisMessage getMessage(String label) {
115: if (WSDLConstants.MESSAGE_LABEL_OUT_VALUE.equals(label)) {
116: return outMessage;
117: } else {
118: throw new UnsupportedOperationException(
119: "Not yet implemented");
120: }
121: }
122:
123: public ArrayList getPhasesInFaultFlow() {
124: return inFaultMessage.getMessageFlow();
125: }
126:
127: public ArrayList getPhasesOutFaultFlow() {
128: return outFaultMessage.getMessageFlow();
129: }
130:
131: public ArrayList getPhasesOutFlow() {
132: return outMessage.getMessageFlow();
133: }
134:
135: public ArrayList getRemainingPhasesInFlow() {
136: return inPhases;
137: }
138:
139: public void setPhasesInFaultFlow(ArrayList list) {
140: inFaultMessage.setMessageFlow(list);
141: }
142:
143: public void setPhasesOutFaultFlow(ArrayList list) {
144: outFaultMessage.setMessageFlow(list);
145: }
146:
147: public void setPhasesOutFlow(ArrayList list) {
148: outMessage.setMessageFlow(list);
149: }
150:
151: public void setRemainingPhasesInFlow(ArrayList list) {
152: inPhases = list;
153: }
154:
155: /**
156: * Returns a MEP client for an Out-only operation. This client can be used to
157: * interact with a server which is offering an In-only operation. To use the
158: * client, you must call addMessageContext() with a message context and then
159: * call execute() to execute the client. Note that the execute method's
160: * block parameter is ignored by this client and also the setMessageReceiver
161: * method cannot be used.
162: *
163: * @param sc The service context for this client to live within. Cannot be
164: * null.
165: * @param options Options to use as defaults for this client. If any options are
166: * set specifically on the client then those override options
167: * here.
168: */
169: public OperationClient createClient(ServiceContext sc,
170: Options options) {
171: return new OutOnlyAxisOperationClient(this , sc, options);
172: }
173: }
174:
175: /**
176: * MEP client for moi.
177: */
178: class OutOnlyAxisOperationClient extends OperationClient {
179:
180: private MessageContext mc;
181:
182: OutOnlyAxisOperationClient(OutOnlyAxisOperation axisOp,
183: ServiceContext sc, Options options) {
184: super (axisOp, sc, options);
185: }
186:
187: /**
188: * Adds a message context to the client for processing. This method must not
189: * process the message - it only records it in the MEP client. Processing
190: * only occurs when execute() is called.
191: *
192: * @param mc the message context
193: * @throws AxisFault if this is called inappropriately.
194: */
195: public void addMessageContext(MessageContext mc) throws AxisFault {
196: if (this .mc != null) {
197: throw new AxisFault(Messages.getMessage("cannotaddmsgctx"));
198: }
199: this .mc = mc;
200: if (mc.getMessageID() == null) {
201: setMessageID(mc);
202: }
203: mc.setServiceContext(sc);
204: axisOp.registerOperationContext(mc, oc);
205: this .completed = false;
206: }
207:
208: /**
209: * Returns a message from the client - will return null if the requested
210: * message is not available.
211: *
212: * @param messageLabel the message label of the desired message context
213: * @return Returns the desired message context or null if its not available.
214: * @throws AxisFault if the message label is invalid
215: */
216: public MessageContext getMessageContext(String messageLabel)
217: throws AxisFault {
218: if (messageLabel.equals(WSDLConstants.MESSAGE_LABEL_OUT_VALUE)) {
219: return mc;
220: }
221: throw new AxisFault(Messages.getMessage("unknownMsgLabel",
222: messageLabel));
223: }
224:
225: /**
226: * Sets the message receiver to be executed when a message comes into the MEP
227: * and the MEP is executed. This is the way the MEP client provides
228: * notification that a message has been received by it. Exactly when its
229: * executed and under what conditions is a function of the specific MEP
230: * client.
231: */
232: public void setCallback(Callback callback) {
233: throw new UnsupportedOperationException(
234: "This feature is not supported by this MEP");
235: }
236:
237: /**
238: * Executes the MEP. What this does depends on the specific MEP client. The
239: * basic idea is to have the MEP client execute and do something with the
240: * messages that have been added to it so far. For example, if its an Out-In
241: * MEP, then if the Out message has been set, then executing the client asks
242: * it to send the message and get the In message, possibly using a different
243: * thread.
244: *
245: * @param block Indicates whether execution should block or return ASAP. What
246: * block means is of course a function of the specific MEP
247: * client. IGNORED BY THIS MEP CLIENT.
248: * @throws AxisFault if something goes wrong during the execution of the MEP.
249: */
250: public void executeImpl(boolean block) throws AxisFault {
251: if (completed) {
252: throw new AxisFault(Messages.getMessage("mepiscomplted"));
253: }
254: ConfigurationContext cc = sc.getConfigurationContext();
255: prepareMessageContext(cc, mc);
256:
257: //As this is an out-only MEP we add a sensible default for
258: //the replyTo.
259: EndpointReference epr = mc.getReplyTo();
260: if (epr == null)
261: mc.setReplyTo(new EndpointReference(Final.WSA_NONE_URI));
262:
263: // create the operation context for myself
264: OperationContext oc = sc.createOperationContext(axisOp);
265: oc.addMessageContext(mc);
266:
267: // ship it out
268: AxisEngine engine = new AxisEngine(cc);
269: if (!block) {
270: mc.setProperty(MessageContext.TRANSPORT_NON_BLOCKING,
271: Boolean.TRUE);
272: }
273: engine.send(mc);
274: // all done
275: completed = true;
276: }
277: }
|