1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20
21 package org.apache.axis2.transport;
22
23 import org.apache.axiom.attachments.Attachments;
24 import org.apache.axiom.attachments.CachedFileDataSource;
25 import org.apache.axiom.attachments.lifecycle.LifecycleManager;
26 import org.apache.axiom.om.OMElement;
27 import org.apache.axiom.om.OMException;
28 import org.apache.axiom.om.OMOutputFormat;
29 import org.apache.axiom.om.impl.builder.StAXBuilder;
30 import org.apache.axiom.om.util.DetachableInputStream;
31 import org.apache.axiom.soap.SOAP11Constants;
32 import org.apache.axiom.soap.SOAP12Constants;
33 import org.apache.axiom.soap.SOAPEnvelope;
34 import org.apache.axiom.soap.SOAPFactory;
35 import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory;
36 import org.apache.axis2.AxisFault;
37 import org.apache.axis2.Constants;
38 import org.apache.axis2.builder.Builder;
39 import org.apache.axis2.builder.BuilderUtil;
40 import org.apache.axis2.context.MessageContext;
41 import org.apache.axis2.context.OperationContext;
42 import org.apache.axis2.deployment.DeploymentConstants;
43 import org.apache.axis2.description.Parameter;
44 import org.apache.axis2.i18n.Messages;
45 import org.apache.axis2.transport.http.ApplicationXMLFormatter;
46 import org.apache.axis2.transport.http.HTTPConstants;
47 import org.apache.axis2.transport.http.SOAPMessageFormatter;
48 import org.apache.axis2.transport.http.XFormURLEncodedFormatter;
49 import org.apache.axis2.util.JavaUtils;
50 import org.apache.axis2.wsdl.WSDLConstants;
51 import org.apache.commons.logging.Log;
52 import org.apache.commons.logging.LogFactory;
53
54 import javax.activation.DataSource;
55 import javax.xml.parsers.FactoryConfigurationError;
56 import javax.xml.stream.XMLStreamException;
57 import java.io.File;
58 import java.io.InputStream;
59 import java.io.OutputStream;
60 import java.util.List;
61
62 public class TransportUtils {
63
64 private static final Log log = LogFactory.getLog(TransportUtils.class);
65
66 public static SOAPEnvelope createSOAPMessage(MessageContext msgContext) throws AxisFault {
67 return createSOAPMessage(msgContext, false);
68 }
69
70 /**
71 * This method will create a SOAPEnvelope based on the InputStream stored on
72 * the MessageContext. The 'detach' parameter controls whether or not the
73 * underlying DetachableInputStream is detached at the end of the method. Note,
74 * detaching the DetachableInputStream closes the underlying InputStream that
75 * is stored on the MessageContext.
76 */
77 public static SOAPEnvelope createSOAPMessage(MessageContext msgContext,
78 boolean detach) throws AxisFault {
79 try {
80 InputStream inStream = (InputStream) msgContext
81 .getProperty(MessageContext.TRANSPORT_IN);
82 msgContext.setProperty(MessageContext.TRANSPORT_IN, null);
83
84 // this inputstram is set by the TransportSender represents a two
85 // way transport or a Transport Recevier
86 if (inStream == null) {
87 throw new AxisFault(Messages.getMessage("inputstreamNull"));
88 }
89
90 String contentType = (String) msgContext
91 .getProperty(Constants.Configuration.CONTENT_TYPE);
92
93 // get the type of char encoding
94 String charSetEnc = (String) msgContext
95 .getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
96 if (charSetEnc == null && contentType != null) {
97 charSetEnc = BuilderUtil.getCharSetEncoding(contentType);
98 } else if (charSetEnc == null) {
99 charSetEnc = MessageContext.DEFAULT_CHAR_SET_ENCODING;
100 }
101 msgContext.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING, charSetEnc);
102
103 SOAPEnvelope env = createSOAPMessage(msgContext, inStream, contentType);
104
105 // if we were told to detach, we will make the call here, this is only applicable
106 // if a DetachableInputStream instance is found on the MessageContext
107 if(detach) {
108 DetachableInputStream dis = (DetachableInputStream) msgContext.getProperty(Constants.DETACHABLE_INPUT_STREAM);
109 if(dis != null) {
110 if(log.isDebugEnabled()) {
111 log.debug("Detaching input stream after SOAPEnvelope construction");
112 }
113 dis.detach();
114 }
115 }
116 return env;
117 } catch (Exception e) {
118 throw AxisFault.makeFault(e);
119 }
120 }
121
122 /**
123 * Objective of this method is to capture the SOAPEnvelope creation logic
124 * and make it a common for all the transports and to in/out flows.
125 *
126 * @param msgContext
127 * @param inStream
128 * @param contentType
129 * @return the SOAPEnvelope
130 * @throws AxisFault
131 * @throws OMException
132 * @throws XMLStreamException
133 * @throws FactoryConfigurationError
134 */
135 public static SOAPEnvelope createSOAPMessage(MessageContext msgContext,
136 InputStream inStream,
137 String contentType)
138 throws AxisFault, OMException, XMLStreamException,
139 FactoryConfigurationError {
140 OMElement documentElement = createDocumentElement(contentType, msgContext, inStream);
141 return createSOAPEnvelope(documentElement);
142 }
143
144 public static SOAPEnvelope createSOAPEnvelope(OMElement documentElement) {
145 SOAPEnvelope envelope;
146 // Check whether we have received a SOAPEnvelope or not
147 if (documentElement instanceof SOAPEnvelope) {
148 envelope = (SOAPEnvelope) documentElement;
149 } else {
150 // If it is not a SOAPEnvelope we wrap that with a fake
151 // SOAPEnvelope.
152 SOAPFactory soapFactory = new SOAP11Factory();
153 envelope = soapFactory.getDefaultEnvelope();
154 envelope.getBody().addChild(documentElement);
155 }
156 return envelope;
157 }
158
159 public static OMElement createDocumentElement(String contentType,
160 MessageContext msgContext,
161 InputStream inStream) throws AxisFault, XMLStreamException {
162 OMElement documentElement = null;
163 String type = null;
164 if (contentType != null) {
165 int index = contentType.indexOf(';');
166 if (index > 0) {
167 type = contentType.substring(0, index);
168 } else {
169 type = contentType;
170 }
171 // Some services send REST responces as text/xml. We should convert it to
172 // application/xml if its a REST response, if not it will try to use the SOAPMessageBuilder.
173 // isDoingREST should already be properly set by HTTPTransportUtils.initializeMessageContext
174 if (msgContext.isDoingREST() && HTTPConstants.MEDIA_TYPE_TEXT_XML.equals(type)) {
175 // if (HTTPConstants.MEDIA_TYPE_TEXT_XML.equals(type)) {
176 if (msgContext.isServerSide()) {
177 if (msgContext.getSoapAction() == null) {
178 type = HTTPConstants.MEDIA_TYPE_APPLICATION_XML;
179 }
180 // } else if (msgContext.isDoingREST() &&
181 // !msgContext.isPropertyTrue(Constants.Configuration.SOAP_RESPONSE_MEP)) {
182 } else if (!msgContext.isPropertyTrue(Constants.Configuration.SOAP_RESPONSE_MEP)) {
183 type = HTTPConstants.MEDIA_TYPE_APPLICATION_XML;
184 }
185 }
186 Builder builder = BuilderUtil.getBuilderFromSelector(type, msgContext);
187 if (builder != null) {
188 if (log.isDebugEnabled()) {
189 log.debug("createSOAPEnvelope using Builder (" +
190 builder.getClass() + ") selected from type (" + type +")");
191 }
192 documentElement = builder.processDocument(inStream, contentType, msgContext);
193 }
194 }
195 if (documentElement == null) {
196 if (msgContext.isDoingREST()) {
197 if (log.isDebugEnabled()) {
198 log.debug("Could not find a Builder for type (" + type + "). Using REST.");
199 }
200 StAXBuilder builder = BuilderUtil.getPOXBuilder(inStream, null);
201 documentElement = builder.getDocumentElement();
202 } else {
203 // FIXME making soap defualt for the moment..might effect the
204 // performance
205 if (log.isDebugEnabled()) {
206 log.debug("Could not find a Builder for type (" + type + "). Using SOAP.");
207 }
208 String charSetEnc = (String) msgContext
209 .getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
210 StAXBuilder builder = BuilderUtil.getSOAPBuilder(inStream, charSetEnc);
211 documentElement = builder.getDocumentElement();
212 }
213 }
214 return documentElement;
215 }
216
217 /**
218 * Extracts and returns the character set encoding from the
219 * Content-type header
220 * Example:
221 * Content-Type: text/xml; charset=utf-8
222 *
223 * @param contentType
224 */
225 public static String getCharSetEncoding(String contentType) {
226 if (log.isDebugEnabled()) {
227 log.debug("Input contentType (" + contentType + ")");
228 }
229 int index = contentType.indexOf(HTTPConstants.CHAR_SET_ENCODING);
230
231 if (index == -1) { // Charset encoding not found in the content-type header
232 // Using the default UTF-8
233 if (log.isDebugEnabled()) {
234 log.debug("CharSetEncoding defaulted (" + MessageContext.DEFAULT_CHAR_SET_ENCODING + ")");
235 }
236 return MessageContext.DEFAULT_CHAR_SET_ENCODING;
237 }
238
239 // If there are spaces around the '=' sign
240 int indexOfEq = contentType.indexOf("=", index);
241
242 // There can be situations where "charset" is not the last parameter of the Content-Type header
243 int indexOfSemiColon = contentType.indexOf(";", indexOfEq);
244 String value;
245
246 if (indexOfSemiColon > 0) {
247 value = (contentType.substring(indexOfEq + 1, indexOfSemiColon));
248 } else {
249 value = (contentType.substring(indexOfEq + 1, contentType.length())).trim();
250 }
251
252 // There might be "" around the value - if so remove them
253 if (value.indexOf('\"') != -1) {
254 value = value.replaceAll("\"", "");
255 }
256 value = value.trim();
257 if (log.isDebugEnabled()) {
258 log.debug("CharSetEncoding from content-type (" + value + ")");
259 }
260 return value;
261 }
262
263 public static void writeMessage(MessageContext msgContext, OutputStream out) throws AxisFault {
264 SOAPEnvelope envelope = msgContext.getEnvelope();
265 OMElement outputMessage = envelope;
266
267 if ((envelope != null) && msgContext.isDoingREST()) {
268 outputMessage = envelope.getBody().getFirstElement();
269 }
270
271 if (outputMessage != null) {
272 try {
273 OMOutputFormat format = new OMOutputFormat();
274
275 // Pick the char set encoding from the msgContext
276 String charSetEnc =
277 (String) msgContext
278 .getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
279
280 format.setDoOptimize(false);
281 format.setDoingSWA(false);
282 format.setCharSetEncoding(charSetEnc);
283 outputMessage.serializeAndConsume(out, format);
284 out.flush();
285 } catch (Exception e) {
286 throw AxisFault.makeFault(e);
287 }
288 } else {
289 throw new AxisFault(Messages.getMessage("outMessageNull"));
290 }
291 }
292
293 /**
294 * Initial work for a builder selector which selects the builder for a given message format based on the the content type of the recieved message.
295 * content-type to builder mapping can be specified through the Axis2.xml.
296 *
297 * @param msgContext
298 * @return the builder registered against the given content-type
299 * @throws AxisFault
300 */
301 public static MessageFormatter getMessageFormatter(MessageContext msgContext)
302 throws AxisFault {
303 MessageFormatter messageFormatter = null;
304 String messageFormatString = getMessageFormatterProperty(msgContext);
305 if (messageFormatString != null) {
306 messageFormatter = msgContext.getConfigurationContext()
307 .getAxisConfiguration().getMessageFormatter(messageFormatString);
308
309 }
310 if (messageFormatter == null) {
311 messageFormatter = (MessageFormatter) msgContext.getProperty(Constants.Configuration.MESSAGE_FORMATTER);
312 if(messageFormatter != null) {
313 return messageFormatter;
314 }
315 }
316 if (messageFormatter == null) {
317
318 // If we are doing rest better default to Application/xml formatter
319 if (msgContext.isDoingREST()) {
320 String httpMethod = (String) msgContext.getProperty(Constants.Configuration.HTTP_METHOD);
321 if (Constants.Configuration.HTTP_METHOD_GET.equals(httpMethod) ||
322 Constants.Configuration.HTTP_METHOD_DELETE.equals(httpMethod)) {
323 return new XFormURLEncodedFormatter();
324 }
325 return new ApplicationXMLFormatter();
326 } else {
327 // Lets default to SOAP formatter
328 //TODO need to improve this to use the stateless nature
329 messageFormatter = new SOAPMessageFormatter();
330 }
331 }
332 return messageFormatter;
333 }
334
335
336 /**
337 * @param contentType The contentType of the incoming message. It may be null
338 * @param defaultSOAPNamespace Usually set the version that is expected. This a fallback if the contentType is unavailable or
339 * does not match our expectations
340 * @return null or the soap namespace. A null indicates that the message will be interpretted as a non-SOAP (i.e. REST) message
341 */
342 private static String getSOAPNamespaceFromContentType(String contentType,
343 String defaultSOAPNamespace) {
344
345 String returnNS = defaultSOAPNamespace;
346 // Discriminate using the content Type
347 if (contentType != null) {
348
349 /*
350 * SOAP11 content-type is "text/xml"
351 * SOAP12 content-type is "application/soap+xml"
352 *
353 * What about other content-types?
354 *
355 * TODO: I'm not fully convinced this method is complete, given the media types
356 * listed in HTTPConstants. Should we assume all application/* is SOAP12?
357 * Should we assume all text/* is SOAP11?
358 *
359 * So, we'll follow this pattern:
360 * 1) find the content-type main setting
361 * 2) if (1) not understood, find the "type=" param
362 * Thilina: I merged (1) & (2)
363 */
364
365 if (JavaUtils.indexOfIgnoreCase(contentType, SOAP12Constants.SOAP_12_CONTENT_TYPE) > -1)
366 {
367 returnNS = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
368 }
369 // search for "type=text/xml"
370 else
371 if (JavaUtils.indexOfIgnoreCase(contentType, SOAP11Constants.SOAP_11_CONTENT_TYPE) > -1)
372 {
373 returnNS = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
374 }
375 }
376
377 if (returnNS == null) {
378 if (log.isDebugEnabled()) {
379 log.debug("No content-type or \"type=\" parameter was found in the content-type " +
380 "header and no default was specified, thus defaulting to SOAP 1.1.");
381 }
382 returnNS = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
383 }
384
385 if (log.isDebugEnabled()) {
386 log.debug("content-type: " + contentType);
387 log.debug("defaultSOAPNamespace: " + defaultSOAPNamespace);
388 log.debug("Returned namespace: " + returnNS);
389 }
390 return returnNS;
391
392 }
393
394 public static void processContentTypeForAction(String contentType, MessageContext msgContext) {
395 //Check for action header and set it in as soapAction in MessageContext
396 int index = contentType.indexOf("action");
397 if (index > -1) {
398 String transientString = contentType.substring(index, contentType.length());
399 int equal = transientString.indexOf("=");
400 int firstSemiColon = transientString.indexOf(";");
401 String soapAction; // This will contain "" in the string
402 if (firstSemiColon > -1) {
403 soapAction = transientString.substring(equal + 1, firstSemiColon);
404 } else {
405 soapAction = transientString.substring(equal + 1, transientString.length());
406 }
407 if ((soapAction != null) && soapAction.startsWith("\"")
408 && soapAction.endsWith("\"")) {
409 soapAction = soapAction
410 .substring(1, soapAction.length() - 1);
411 }
412 msgContext.setSoapAction(soapAction);
413 }
414 }
415
416
417 private static String getMessageFormatterProperty(MessageContext msgContext) {
418 String messageFormatterProperty = null;
419 Object property = msgContext
420 .getProperty(Constants.Configuration.MESSAGE_TYPE);
421 if (property != null) {
422 messageFormatterProperty = (String) property;
423 }
424 if (messageFormatterProperty == null) {
425 Parameter parameter = msgContext
426 .getParameter(Constants.Configuration.MESSAGE_TYPE);
427 if (parameter != null) {
428 messageFormatterProperty = (String) parameter.getValue();
429 }
430 }
431 return messageFormatterProperty;
432 }
433
434
435 /**
436 * This is a helper method to get the response written flag from the RequestResponseTransport
437 * instance.
438 */
439 public static boolean isResponseWritten(MessageContext messageContext) {
440 RequestResponseTransport reqResTransport = getRequestResponseTransport(messageContext);
441 if (reqResTransport != null) {
442 if (log.isDebugEnabled()) {
443 log.debug("Found RequestResponseTransport returning isResponseWritten()");
444 }
445 return reqResTransport.isResponseWritten();
446 } else {
447 if (log.isDebugEnabled()) {
448 log.debug("Did not find RequestResponseTransport returning false from get"
449 + "ResponseWritten()");
450 }
451 return false;
452 }
453 }
454
455 /**
456 * This is a helper method to set the response written flag on the RequestResponseTransport
457 * instance.
458 */
459 public static void setResponseWritten(MessageContext messageContext, boolean responseWritten) {
460 RequestResponseTransport reqResTransport = getRequestResponseTransport(messageContext);
461 if (reqResTransport != null) {
462 if (log.isDebugEnabled()) {
463 log.debug("Found RequestResponseTransport setting response written");
464 }
465 reqResTransport.setResponseWritten(responseWritten);
466 } else {
467 if (log.isDebugEnabled()) {
468 log.debug("Did not find RequestResponseTransport cannot set response written");
469 }
470 }
471 }
472
473 /**
474 * This is an internal helper method to retrieve the RequestResponseTransport instance
475 * from the MessageContext object. The MessageContext may be the response MessageContext so
476 * in that case we will have to retrieve the request MessageContext from the OperationContext.
477 */
478 private static RequestResponseTransport getRequestResponseTransport(MessageContext messageContext) {
479 try {
480 // If this is the request MessageContext we should find it directly by the getProperty()
481 // method
482 if (messageContext.getProperty(RequestResponseTransport.TRANSPORT_CONTROL)
483 != null) {
484 return (RequestResponseTransport) messageContext.getProperty(
485 RequestResponseTransport.TRANSPORT_CONTROL);
486 }
487 // If this is the response MessageContext we need to look for the request MessageContext
488 else if (messageContext.getOperationContext() != null
489 && messageContext.getOperationContext()
490 .getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE) != null) {
491 return (RequestResponseTransport) messageContext.
492 getOperationContext().getMessageContext(
493 WSDLConstants.MESSAGE_LABEL_IN_VALUE).getProperty(
494 RequestResponseTransport.TRANSPORT_CONTROL);
495 }
496 else {
497 return null;
498 }
499 }
500 catch(AxisFault af) {
501 // probably should not be fatal, so just log the message
502 String msg = Messages.getMessage("getMessageContextError", af.toString());
503 log.debug(msg);
504 return null;
505 }
506 }
507
508 /**
509 * Clean up cached attachment file
510 * @param msgContext
511 */
512 public static void deleteAttachments(MessageContext msgContext) {
513 if (log.isDebugEnabled()) {
514 log.debug("Entering deleteAttachments()");
515 }
516
517 Attachments attachments = msgContext.getAttachmentMap();
518 LifecycleManager lcm = (LifecycleManager)msgContext.getRootContext().getAxisConfiguration().getParameterValue(DeploymentConstants.ATTACHMENTS_LIFECYCLE_MANAGER);
519 if (attachments != null) {
520 // Get the list of Content IDs for the attachments...but does not try to pull the stream for new attachments.
521 // (Pulling the stream for new attachments will probably fail...the stream is probably closed)
522 List keys = attachments.getContentIDList();
523 if (keys != null) {
524 String key = null;
525 File file = null;
526 DataSource dataSource = null;
527 for (int i = 0; i < keys.size(); i++) {
528 try {
529 key = (String) keys.get(i);
530 dataSource = attachments.getDataHandler(key).getDataSource();
531 if(dataSource instanceof CachedFileDataSource){
532 file = ((CachedFileDataSource)dataSource).getFile();
533 if (log.isDebugEnabled()) {
534 log.debug("Delete cache attachment file: "+file.getName());
535 }
536 if(lcm!=null){
537 if(log.isDebugEnabled()){
538 log.debug("deleting file using lifecyclemanager");
539 }
540 lcm.delete(file);
541 }else{
542 file.delete();
543 }
544 }
545 }
546 catch (Exception e) {
547 if (log.isDebugEnabled()) {
548 log.debug("Delete cache attachment file failed"+ e.getMessage());
549 }
550
551 if (file != null) {
552 if(lcm!=null){
553 try{
554 lcm.deleteOnExit(file);
555 }catch(Exception ex){
556 file.deleteOnExit();
557 }
558 }
559 else{
560 file.deleteOnExit();
561 }
562 }
563 }
564 }
565 }
566 }
567
568 if (log.isDebugEnabled()) {
569 log.debug("Exiting deleteAttachments()");
570 }
571 }
572
573 /**
574 * This method can be called by components wishing to detach the DetachableInputStream
575 * object that is present on the MessageContext. This is meant to shield components
576 * from any logic that needs to be executed on the DetachableInputStream in order to
577 * have it effectively detached. If the DetachableInputStream is not present, or if
578 * the supplied MessageContext is null, no action will be taken.
579 */
580 public static void detachInputStream(MessageContext msgContext) throws AxisFault {
581 try {
582 if(msgContext != null
583 &&
584 msgContext.getProperty(Constants.DETACHABLE_INPUT_STREAM) != null) {
585 DetachableInputStream dis = (DetachableInputStream) msgContext.getProperty(Constants.DETACHABLE_INPUT_STREAM);
586 if(log.isDebugEnabled()) {
587 log.debug("Detaching DetachableInputStream: " + dis);
588 }
589 dis.detach();
590 }
591 else {
592 if(log.isDebugEnabled()) {
593 log.debug("Detach not performed for MessageContext: " + msgContext);
594 }
595 }
596 }
597 catch(Throwable t) {
598 throw AxisFault.makeFault(t);
599 }
600 }
601
602 /**
603 * <p>
604 * Checks whether MTOM needs to be enabled for the message represented by
605 * the msgContext. We check value assigned to the "enableMTOM" property
606 * either using the config files (axis2.xml, services.xml) or
607 * programatically. Programatic configuration is given priority. If the
608 * given value is "optional", MTOM will be enabled only if the incoming
609 * message was an MTOM message.
610 * </p>
611 *
612 * @param msgContext the active MessageContext
613 * @return true if SwA needs to be enabled
614 */
615 public static boolean doWriteMTOM(MessageContext msgContext) {
616 boolean enableMTOM;
617 Object enableMTOMObject = null;
618 // First check the whether MTOM is enabled by the configuration
619 // (Eg:Axis2.xml, services.xml)
620 Parameter parameter = msgContext.getParameter(Constants.Configuration.ENABLE_MTOM);
621 if (parameter != null) {
622 enableMTOMObject = parameter.getValue();
623 }
624 // Check whether the configuration is overridden programatically..
625 // Priority given to programatically setting of the value
626 Object property = msgContext.getProperty(Constants.Configuration.ENABLE_MTOM);
627 if (property != null) {
628 enableMTOMObject = property;
629 }
630 enableMTOM = JavaUtils.isTrueExplicitly(enableMTOMObject);
631 // Handle the optional value for enableMTOM
632 // If the value for 'enableMTOM' is given as optional and if the request
633 // message was a MTOM message we sent out MTOM
634 if (!enableMTOM && msgContext.isDoingMTOM() && (enableMTOMObject instanceof String)) {
635 if (((String) enableMTOMObject).equalsIgnoreCase(Constants.VALUE_OPTIONAL)) {
636 //In server side, we check whether request was MTOM
637 if (msgContext.isServerSide()) {
638 if (msgContext.isDoingMTOM()) {
639 enableMTOM = true;
640 }
641 // in the client side, we enable MTOM if it is optional
642 } else {
643 enableMTOM = true;
644 }
645 }
646 }
647 return enableMTOM;
648 }
649
650 /**
651 * <p>
652 * Checks whether SOAP With Attachments (SwA) needs to be enabled for the
653 * message represented by the msgContext. We check value assigned to the
654 * "enableSwA" property either using the config files (axis2.xml,
655 * services.xml) or programatically. Programatic configuration is given
656 * priority. If the given value is "optional", SwA will be enabled only if
657 * the incoming message was SwA type.
658 * </p>
659 *
660 * @param msgContext the active MessageContext
661 * @return true if SwA needs to be enabled
662 */
663 public static boolean doWriteSwA(MessageContext msgContext) {
664 boolean enableSwA;
665 Object enableSwAObject = null;
666 // First check the whether SwA is enabled by the configuration
667 // (Eg:Axis2.xml, services.xml)
668 Parameter parameter = msgContext.getParameter(Constants.Configuration.ENABLE_SWA);
669 if (parameter != null) {
670 enableSwAObject = parameter.getValue();
671 }
672 // Check whether the configuration is overridden programatically..
673 // Priority given to programatically setting of the value
674 Object property = msgContext.getProperty(Constants.Configuration.ENABLE_SWA);
675 if (property != null) {
676 enableSwAObject = property;
677 }
678 enableSwA = JavaUtils.isTrueExplicitly(enableSwAObject);
679 // Handle the optional value for enableSwA
680 // If the value for 'enableSwA' is given as optional and if the request
681 // message was a SwA message we sent out SwA
682 if (!enableSwA && msgContext.isDoingSwA() && (enableSwAObject instanceof String)) {
683 if (((String) enableSwAObject).equalsIgnoreCase(Constants.VALUE_OPTIONAL)) {
684 enableSwA = true;
685 }
686 }
687 return enableSwA;
688 }
689
690 public static boolean isDoingREST(MessageContext msgContext) {
691 boolean enableREST = false;
692
693 // check whether isDoingRest is already true in the message context
694 if (msgContext.isDoingREST()) {
695 return true;
696 }
697
698 Object enableRESTProperty = msgContext.getProperty(Constants.Configuration.ENABLE_REST);
699 if (enableRESTProperty != null) {
700 enableREST = JavaUtils.isTrueExplicitly(enableRESTProperty);
701 }
702
703 msgContext.setDoingREST(enableREST);
704
705 return enableREST;
706 }
707
708 /**
709 * Utility method to query CharSetEncoding. First look in the
710 * MessageContext. If it's not there look in the OpContext. Use the defualt,
711 * if it's not given in either contexts.
712 *
713 * @param msgContext the active MessageContext
714 * @return String the CharSetEncoding
715 */
716 public static String getCharSetEncoding(MessageContext msgContext) {
717 String charSetEnc = (String) msgContext
718 .getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
719
720 if (charSetEnc == null) {
721 OperationContext opctx = msgContext.getOperationContext();
722 if (opctx != null) {
723 charSetEnc = (String) opctx
724 .getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
725 }
726 /**
727 * If the char set enc is still not found use the default
728 */
729 if (charSetEnc == null) {
730 charSetEnc = MessageContext.DEFAULT_CHAR_SET_ENCODING;
731 }
732 }
733 return charSetEnc;
734 }
735
736 }