/*******************************************************************************

* Copyright (c) 2006 IONA Technologies PLC

* All rights reserved. This program and the accompanying materials

* are made available under the terms of the Eclipse Public License v1.0

* which accompanies this distribution, and is available at

* http://www.eclipse.org/legal/epl-v10.html

* 

* Contributors:

*     IONA Technologies PLC - initial API and implementation

*******************************************************************************/
package org.eclipse.stp.sc.common.validator;

import java.util.Iterator;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.jdt.core.dom.BooleanLiteral;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.NumberLiteral;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.stp.common.logging.LoggingProxy;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * This class is used to build xml tree from annotation
 * @author jma
 *
 */
public class AnnXMLTreeBuilder {
	
	private static final LoggingProxy LOG = LoggingProxy.getlogger(AnnXMLTreeBuilder.class);
	public static final String ATTR_XMLNS = "xmlns";
	public static final String ATTR_PREFIX = "tns";
	
	private DocumentBuilderFactory factory = null;
	private DocumentBuilder builder = null;
		
	public AnnXMLTreeBuilder() {
		try {
			factory = DocumentBuilderFactory.newInstance();
			factory.setNamespaceAware(true);
			builder = factory.newDocumentBuilder();
		} catch (FactoryConfigurationError e) {
			LOG.error("factory error", e);
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			LOG.error("parser config error", e);
		}	
		
	}
	
	/**
	 * build the xml tree from annotation node.
	 * @return
	 */
    public Document buildTreeFromOneAnn(NormalAnnotation annotation) {
    	Document document = builder.newDocument();
    	Name typeName = annotation.getTypeName();
    	    	
    	String namespaceURI = XMLUtils.getNSFromClsName(typeName.getFullyQualifiedName());
    	String rootName = typeName.getFullyQualifiedName();
    	if (rootName.indexOf(".") > 0) {
    		rootName = rootName.substring(rootName.lastIndexOf(".") + 1, rootName.length());
    	}
    	
    	Element root = document.createElementNS(namespaceURI, rootName);
    	root.setAttribute(ATTR_XMLNS + ":" + ATTR_PREFIX, namespaceURI);
    	root.setPrefix(ATTR_PREFIX);
    	Iterator itor = annotation.values().iterator();
    	while (itor.hasNext()) {
    		MemberValuePair member = (MemberValuePair)itor.next();
    		Element child = document.createElement(member.getName().getFullyQualifiedName());
    		String strValue = convertExpressToStr(member.getValue()); 
    		child.setTextContent(strValue);
    		root.appendChild(child);
    	}
    	
    	document.appendChild(root);
    	LOG.debug("xml generate from ann:" + XMLUtils.getXMLAsString(document));
    	return document;
    	
    }
    
    private String convertExpressToStr(Expression exp) {
    	if (exp instanceof StringLiteral) {
    		return ((StringLiteral)exp).getLiteralValue();
    	}
    	else if (exp instanceof BooleanLiteral) {
    		boolean value = ((BooleanLiteral)exp).booleanValue(); 
    		return Boolean.toString(value);
    	} else if (exp instanceof NumberLiteral) {
    		((NumberLiteral)exp).getToken();
    	} 
    	LOG.debug("Unsupported express type:" + exp.getClass().getName());
    	return exp.toString();
    }
    
    /**
     * 
     *
     */
    public Document buildTreeFromJavaUnit() {
    	return null;
    }
}
