| /* |
| * Copyright 2001-2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.axis.message; |
| |
| /** |
| * |
| * @author Glen Daniels (gdaniels@allaire.com) |
| */ |
| |
| import org.apache.axis.AxisFault; |
| import org.apache.axis.Constants; |
| import org.apache.axis.MessageContext; |
| import org.apache.axis.Message; |
| import org.apache.axis.components.logger.LogFactory; |
| import org.apache.axis.description.OperationDesc; |
| import org.apache.axis.encoding.DeserializationContext; |
| import org.apache.axis.constants.Style; |
| import org.apache.axis.soap.SOAPConstants; |
| import org.apache.axis.utils.Messages; |
| import org.apache.commons.logging.Log; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.SAXException; |
| |
| import javax.xml.namespace.QName; |
| |
| public class BodyBuilder extends SOAPHandler |
| { |
| protected static Log log = |
| LogFactory.getLog(BodyBuilder.class.getName()); |
| |
| boolean gotRPCElement = false; |
| |
| private SOAPEnvelope envelope; |
| |
| BodyBuilder(SOAPEnvelope envelope) |
| { |
| this.envelope = envelope; |
| } |
| |
| public void startElement(String namespace, String localName, |
| String prefix, Attributes attributes, |
| DeserializationContext context) |
| throws SAXException |
| { |
| SOAPConstants soapConstants = context.getSOAPConstants(); |
| |
| if (soapConstants == SOAPConstants.SOAP12_CONSTANTS && |
| attributes.getValue(Constants.URI_SOAP12_ENV, Constants.ATTR_ENCODING_STYLE) != null) { |
| |
| AxisFault fault = new AxisFault(Constants.FAULT_SOAP12_SENDER, |
| null, Messages.getMessage("noEncodingStyleAttrAppear", "Body"), null, null, null); |
| |
| throw new SAXException(fault); |
| } |
| |
| // make a new body element |
| if (!context.isDoneParsing()) { |
| if (!context.isProcessingRef()) { |
| if (myElement == null) { |
| try { |
| myElement = new SOAPBody(namespace, localName, prefix, |
| attributes, context, envelope.getSOAPConstants()); |
| } catch (AxisFault axisFault) { |
| throw new SAXException(axisFault); |
| } |
| } |
| context.pushNewElement(myElement); |
| } |
| envelope.setBody((SOAPBody)myElement); |
| } |
| } |
| |
| // FIX: do we need this method ? |
| public MessageElement makeNewElement(String namespace, String localName, |
| String prefix, Attributes attributes, |
| DeserializationContext context) |
| throws AxisFault { |
| return new SOAPBody(namespace, |
| localName, |
| prefix, |
| attributes, |
| context, |
| context.getSOAPConstants()); |
| } |
| |
| public SOAPHandler onStartChild(String namespace, |
| String localName, |
| String prefix, |
| Attributes attributes, |
| DeserializationContext context) |
| throws SAXException |
| { |
| SOAPBodyElement element = null; |
| if (log.isDebugEnabled()) { |
| log.debug("Enter: BodyBuilder::onStartChild()"); |
| } |
| |
| QName qname = new QName(namespace, localName); |
| SOAPHandler handler = null; |
| |
| /** We're about to create a body element. So we really need |
| * to know at this point if this is an RPC service or not. It's |
| * possible that no one has set the service up until this point, |
| * so if that's the case we should attempt to set it based on the |
| * namespace of the first root body element. Setting the |
| * service may (should?) result in setting the service |
| * description, which can then tell us what to create. |
| */ |
| boolean isRoot = true; |
| String root = attributes.getValue(Constants.URI_DEFAULT_SOAP_ENC, |
| Constants.ATTR_ROOT); |
| if ((root != null) && root.equals("0")) isRoot = false; |
| |
| MessageContext msgContext = context.getMessageContext(); |
| OperationDesc [] operations = null; |
| try { |
| if(msgContext != null) { |
| operations = msgContext.getPossibleOperationsByQName(qname); |
| } |
| |
| // If there's only one match, set it in the MC now |
| if ((operations != null) && (operations.length == 1)) |
| msgContext.setOperation(operations[0]); |
| } catch (org.apache.axis.AxisFault e) { |
| // SAXException is already known to this method, so I |
| // don't have an exception-handling propogation explosion. |
| throw new SAXException(e); |
| } |
| |
| Style style = operations == null ? Style.RPC : operations[0].getStyle(); |
| SOAPConstants soapConstants = context.getSOAPConstants(); |
| |
| /** Now we make a plain SOAPBodyElement IF we either: |
| * a) have an non-root element, or |
| * b) have a non-RPC service |
| */ |
| if (localName.equals(Constants.ELEM_FAULT) && |
| namespace.equals(soapConstants.getEnvelopeURI())) { |
| try { |
| element = new SOAPFault(namespace, localName, prefix, |
| attributes, context); |
| } catch (AxisFault axisFault) { |
| throw new SAXException(axisFault); |
| } |
| element.setEnvelope(context.getEnvelope()); |
| handler = new SOAPFaultBuilder((SOAPFault)element, |
| context); |
| } else if (!gotRPCElement) { |
| if (isRoot && (style != Style.MESSAGE)) { |
| gotRPCElement = true; |
| |
| try { |
| |
| element = new RPCElement(namespace, localName, prefix, |
| attributes, context, operations); |
| |
| } catch (org.apache.axis.AxisFault e) { |
| // SAXException is already known to this method, so I |
| // don't have an exception-handling propogation explosion. |
| // |
| throw new SAXException(e); |
| } |
| |
| // Only deserialize this way if there is a unique operation |
| // for this QName. If there are overloads, |
| // we'll need to start recording. If we're making a high- |
| // fidelity recording anyway, don't bother (for now). |
| if (msgContext != null && !msgContext.isHighFidelity() && |
| (operations == null || operations.length == 1)) { |
| ((RPCElement)element).setNeedDeser(false); |
| boolean isResponse = false; |
| if (msgContext.getCurrentMessage() != null && |
| Message.RESPONSE.equals(msgContext.getCurrentMessage().getMessageType())) |
| isResponse = true; |
| handler = new RPCHandler((RPCElement)element, |
| isResponse); |
| if (operations != null) { |
| ((RPCHandler)handler).setOperation(operations[0]); |
| msgContext.setOperation(operations[0]); |
| } |
| } |
| } |
| } |
| |
| if (element == null) { |
| if ((style == Style.RPC) && |
| soapConstants == SOAPConstants.SOAP12_CONSTANTS) { |
| throw new SAXException(Messages.getMessage("onlyOneBodyFor12")); |
| } |
| try { |
| element = new SOAPBodyElement(namespace, localName, prefix, |
| attributes, context); |
| } catch (AxisFault axisFault) { |
| throw new SAXException(axisFault); |
| } |
| if (element.getFixupDeserializer() != null) |
| handler = (SOAPHandler)element.getFixupDeserializer(); |
| } |
| |
| if (handler == null) |
| handler = new SOAPHandler(); |
| |
| handler.myElement = element; |
| |
| //context.pushNewElement(element); |
| |
| if (log.isDebugEnabled()) { |
| log.debug("Exit: BodyBuilder::onStartChild()"); |
| } |
| return handler; |
| } |
| |
| public void onEndChild(String namespace, String localName, |
| DeserializationContext context) |
| { |
| } |
| } |