/*
 * Copyright [2006] [University Corporation for Advanced Internet Development, Inc.]
 *
 * 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.opensaml.xml;

import java.util.HashMap;

import javax.xml.namespace.QName;

import org.apache.log4j.Logger;
import org.custommonkey.xmlunit.XMLTestCase;
import org.opensaml.xml.io.Marshaller;
import org.opensaml.xml.io.MarshallerFactory;
import org.opensaml.xml.io.UnmarshallerFactory;
import org.opensaml.xml.mock.SimpleXMLObject;
import org.opensaml.xml.parse.ParserPool;
import org.opensaml.xml.util.XMLHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Base test case class for tests that operate on XMLObjects.
 */
public class XMLObjectBaseTestCase extends XMLTestCase {
    
    /** Logger */
    private static Logger log = Logger.getLogger(XMLObjectBaseTestCase.class);

    /** Parser pool */
    protected static ParserPool parserPool;

    /** XMLObject builder factory */
    protected static XMLObjectBuilderFactory builderFactory;

    /** XMLObject marshaller factory */
    protected static MarshallerFactory marshallerFactory;

    /** XMLObject unmarshaller factory */
    protected static UnmarshallerFactory unmarshallerFactory;
    
    /** QName for SimpleXMLObject */
    protected static QName simpleXMLObjectQName;

    /**
     * Constructor
     */
    public XMLObjectBaseTestCase() {
        simpleXMLObjectQName = new QName(SimpleXMLObject.NAMESAPACE, SimpleXMLObject.LOCAL_NAME);
    }

    /**
     * Asserts a given XMLObject is equal to an expected DOM. The XMLObject is marshalled and the resulting DOM object
     * is compared against the expected DOM object for equality.
     * 
     * @param expectedDOM the expected DOM
     * @param xmlObject the XMLObject to be marshalled and compared against the expected DOM
     */
    public void assertEquals(Document expectedDOM, XMLObject xmlObject) {
        assertEquals("Marshalled DOM was not the same as the expected DOM", expectedDOM, xmlObject);
    }

    /**
     * Asserts a given XMLObject is equal to an expected DOM. The XMLObject is marshalled and the resulting DOM object
     * is compared against the expected DOM object for equality.
     * 
     * @param failMessage the message to display if the DOMs are not equal
     * @param expectedDOM the expected DOM
     * @param xmlObject the XMLObject to be marshalled and compared against the expected DOM
     */
    public void assertEquals(String failMessage, Document expectedDOM, XMLObject xmlObject) {
        Marshaller marshaller = marshallerFactory.getMarshaller(xmlObject);
        try {
            Element generatedDOM = marshaller.marshall(xmlObject, parserPool.newDocument());
            if(log.isDebugEnabled()) {
                log.debug("Marshalled DOM was " + XMLHelper.nodeToString(generatedDOM));
            }
            assertXMLEqual(failMessage, expectedDOM, generatedDOM.getOwnerDocument());
        } catch (Exception e) {
            fail("Marshalling failed with the following error: " + e);
        }
    }
    
    /**
     * Builds the requested XMLObject.
     * 
     * @param objectQName name of the XMLObject
     * 
     * @return the build XMLObject
     */
    public XMLObject buildXMLObject(QName objectQName){
        XMLObjectBuilder builder = Configuration.getBuilderFactory().getBuilder(objectQName);
        return builder.buildObject();
    }

    static {
        HashMap<String, Boolean> features = new HashMap<String, Boolean>();
        features.put("http://apache.org/xml/features/validation/schema/normalized-value", Boolean.FALSE);
        features.put("http://apache.org/xml/features/dom/defer-node-expansion", Boolean.FALSE);

        parserPool = new ParserPool(true, null, features);

        try {
            Document configureation = parserPool.parse(XMLObjectBaseTestCase.class
                    .getResourceAsStream("/conf/xmltooling-config.xml"));
            Configuration.load(configureation);

            builderFactory = Configuration.getBuilderFactory();
            marshallerFactory = Configuration.getMarshallerFactory();
            unmarshallerFactory = Configuration.getUnmarshallerFactory();
        } catch (Exception e) {
            System.err.println("Can not initialize XMLObjectBaseTestCase");
        }
    }
}
@@ -692,16 +692,38 @@
 HashMap;
+%0Aimport java.util.Map;
 %0A%0Aimport
@@ -3739,25 +3739,121 @@
 bject%0A     *
-/
+ @deprecated%0A     */%0A    // TODO - this class will disappear when all constructors take a context
 %0A    public 
@@ -3987,24 +3987,24 @@
 jectQName);%0A
-
         retu
@@ -4032,24 +4032,450 @@
 t();%0A    %7D%0A%0A
+    /**%0A     * Builds the requested XMLObject.%0A     * %0A     * @param objectQName name of the XMLObject%0A     * %0A     * @return the build XMLObject%0A     */%0A    public XMLObject buildXMLObject(QName objectQName, Map%3CString, Object%3E context)%7B%0A        ExtendedXMLObjectBuilder builder = (ExtendedXMLObjectBuilder) Configuration.getBuilderFactory().getBuilder(objectQName);%0A        return builder.buildObject(null, context);%0A    %7D%0A%0A
     static %7B

Add a buildXMLObject which takes a context