/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */

/*
 * XSEC
 *
 * DSIGTransformEnvelope := Class that calculates an Envelope with an XPath evaluator
 *
 * $Id$
 *
 */

// XSEC

#include <xsec/dsig/DSIGTransformEnvelope.hpp>
#include <xsec/dsig/DSIGSignature.hpp>
#include <xsec/framework/XSECException.hpp>
#include <xsec/framework/XSECEnv.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/transformers/TXFMEnvelope.hpp>
#include <xsec/transformers/TXFMC14n.hpp>
#include <xsec/transformers/TXFMChain.hpp>
#include <xsec/transformers/TXFMXPath.hpp>

#include "../utils/XSECDOMUtils.hpp"

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           Constructors and Destructors
// --------------------------------------------------------------------------------

DSIGTransformEnvelope::DSIGTransformEnvelope(const XSECEnv * env, DOMNode * node) :
DSIGTransform(env, node) {};


DSIGTransformEnvelope::DSIGTransformEnvelope(const XSECEnv * env) :
DSIGTransform(env) {};
		  

DSIGTransformEnvelope::~DSIGTransformEnvelope() {};

// --------------------------------------------------------------------------------
//           Interface Methods
// --------------------------------------------------------------------------------


void DSIGTransformEnvelope::appendTransformer(TXFMChain * input) {

#ifdef XSEC_USE_XPATH_ENVELOPE

	TXFMXPath *x;
	
	// Special XPath transform
	XSECnew(x, TXFMXPath(mp_txfmNode->getOwnerDocument()));
	input->appendTxfm(x);
	
	// Execute the envelope expression
	x->evaluateEnvelope(mp_txfmNode);
#else

	TXFMEnvelope *x;

	// Use the Envelope transform
	
	XSECnew(x, TXFMEnvelope(mp_txfmNode->getOwnerDocument()));
	input->appendTxfm(x);

	// Execute envelope
	x->evaluateEnvelope(mp_txfmNode);

#endif

}

DOMElement * DSIGTransformEnvelope::createBlankTransform(DOMDocument * parentDoc) {

	safeBuffer str;
	const XMLCh * prefix;
	DOMElement *ret;
	DOMDocument *doc = mp_env->getParentDocument();

	prefix = mp_env->getDSIGNSPrefix();
	
	// Create the transform node
	makeQName(str, prefix, "Transform");
	ret = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
	ret->setAttributeNS(NULL,DSIGConstants::s_unicodeStrAlgorithm, DSIGConstants::s_unicodeStrURIENVELOPE);

	mp_txfmNode = ret;

	return ret;

}

void DSIGTransformEnvelope::load(void) {

	// Do nothing for an Envelope transform

}
