/*
 * Copyright 2004,2005 The Apache Software Foundation.
 * Copyright 2006 International Business Machines Corp.
 *
 * 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.axis2.jaxws.message.impl;

import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;

import org.apache.axiom.om.OMElement;
import org.apache.axis2.jaxws.message.Block;
import org.apache.axis2.jaxws.message.MessageException;
import org.apache.axis2.jaxws.message.Protocol;
import org.apache.axis2.jaxws.message.util.StackableReader;
import org.apache.axis2.jaxws.message.util.XMLStreamReaderFilter;

/**
 * XMLStreamReaderForXMLSpine
 * 
 * An XMLSpine is composed of many different parts: a sparse OM tree, 
 * header blocks, body blocks, etc.
 * 
 * The XMLStreamReaderForXMLSpine provides an XMLStreamReader that
 * over all of these combined objects (without building a full OM tree).
 * It does this by using a StackableXMLStreamReader for the underlying implementation and 
 * pushing the XMLStreamReaders for the blocks onto the stack at the appropriate points in 
 * the message.
 */
public class XMLStreamReaderForXMLSpine extends XMLStreamReaderFilter {

	// Components of an XMLSpine
	OMElement root;
	private List<Block> headerBlocks = null;
	private List<Block> bodyBlocks   = null;
	private List<Block> detailBlocks = null;
	private boolean consume = false;
	Protocol protocol = null;
	
	// Local Constants
	private static final String BODY = "Body";
	private static final String HEADER = "Header";
	private static final String FAULT = "Fault";
	private static final String DETAIL11 = "detail";
	private static final String DETAIL12 = "Detail";
	
	boolean inFault = false;
	private List<Block> insertBlocks = null;
	
	/**
	 * @param root of the XMLSpine
	 * @param headerBlocks 
	 * @param bodyBocks
	 * @param detailBlocks
	 * @param consume
	 */
	public XMLStreamReaderForXMLSpine(OMElement root, 
			Protocol protocol,
			List<Block> headerBlocks, 
			List<Block> bodyBlocks, 
			List<Block> detailBlocks, 
			boolean consume) {
		// Create a stackable reader and prime it with the root om tree
		// The XMLStreamReader's for the blocks will be pushed onto the
		// stack as the message is processed.
		super(new StackableReader(root.getXMLStreamReader()));
		this.root = root;
		this.protocol = protocol;
		this.headerBlocks = headerBlocks;
		this.bodyBlocks = bodyBlocks;
		this.detailBlocks = detailBlocks;
		this.consume = consume;
	}

	@Override
	public int next() throws XMLStreamException {
		// The next method is overridden so that we can push
		// the block's XMLStreamReaders onto the stack at the 
		// appropriate places in the message (pretty slick).
		
		// Insert pending blocks onto the stack
		if (insertBlocks != null) {
			pushBlocks(insertBlocks, consume);
			insertBlocks = null;
			
		}
		
		// Get the next event
		int event = super.next();
		
		// If this is a start element event, then we may need to insert
		// the blocks prior to the next event
		if (isStartElement()) {
			QName qName = super.getName();
			// Insert body blocks after the Body
			if (qName.getLocalPart().equals(BODY) &&
				qName.getNamespaceURI().equals(root.getNamespace().getName())) {
				if (bodyBlocks != null) {
					insertBlocks = bodyBlocks;
					bodyBlocks = null;
				}
			} 
			// Insert header blocks after the header
			else if (qName.getLocalPart().equals(HEADER) &&
					qName.getNamespaceURI().equals(root.getNamespace().getName())) {
				if (headerBlocks != null) {
					insertBlocks = headerBlocks;
					headerBlocks = null;
				}
			}
			else if (qName.getLocalPart().equals(FAULT) &&
					qName.getNamespaceURI().equals(root.getNamespace().getName())) {
				inFault = true;
			} 
			// Insert Detail blocks afger the detail...note that
			// the detail name is different in SOAP 1.1 and SOAP 1.2
			else if (inFault) {
				if (qName.getLocalPart().equals(DETAIL11) &&
				    protocol.equals(Protocol.soap11) ||
				    qName.getLocalPart().equals(DETAIL12) &&
				    protocol.equals(Protocol.soap12)) {
					if (detailBlocks != null) {
						insertBlocks = detailBlocks;
						detailBlocks = null;
					}
				}
			}
		}
		return event;
	}

	/**
	 * Push the XMLStreamReaders for the blocks
	 * @param blocks
	 */
	private void pushBlocks(List<Block> blocks, boolean consume) throws XMLStreamException{
		// Push the XMLStreamReaders for the blocks onto the 
		// delegate.  This is done in reverse order of the blocks so that the 
		// first  block's xmlstreamreader is ontop of the stack.
		try {
			StackableReader sr = (StackableReader) delegate;
			for (int i=blocks.size()-1; i>=0; i--) {
				Block block = blocks.get(i);
				if (block != null) {
					sr.push(block.getXMLStreamReader(consume));
				}
			}
		} catch (MessageException me) {
			throw new XMLStreamException(me);
		}
	}
}
