/* * 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) { } }