//
// See the file LICENSE for redistribution information.
//
// Copyright (c) 2002-2003
//	Sleepycat Software.  All rights reserved.
//

static const char revid[] = "$Id: XmlDocument.cpp,v 1.43 2003/12/01 15:52:02 gmf Exp $";

#include "dbxml_config.h"
#include <dbxml/XmlPortability.hpp>
#include <dbxml/XmlDocument.hpp>
#include <dbxml/XmlResults.hpp>
#include <dbxml/XmlQueryContext.hpp>
#include <dbxml/XmlQueryExpression.hpp>
#include "Document.hpp"
#include "QueryContext.hpp"
#include "UTF8.hpp"

#if defined(DBXML_DOM_XERCES2)
#include <xercesc/parsers/XercesDOMParser.hpp>
#if defined(XERCES_HAS_CPP_NAMESPACE)
  XERCES_CPP_NAMESPACE_USE
#endif
#endif

#if defined(DBXML_XPATH_PATHAN)
#include <pathan/XPathEvaluator.hpp>
#include <pathan/XPathNSResolver.hpp>
#endif

using namespace DbXml;

XmlDocument::XmlDocument()
	: document_(new Document())
{
	document_->acquire();
}

XmlDocument::~XmlDocument()
{
	if (document_ != 0)
		document_->release();
}

XmlDocument::XmlDocument(const XmlDocument &o)
	: document_(o.document_)
{
	if (document_ != 0)
		document_->acquire();
}

XmlDocument &XmlDocument::operator=(const XmlDocument &o)
{
	if (this != &o && document_ != o.document_) {
		if (document_ != 0)
			document_->release();
		document_ = o.document_;
		if (document_ != 0)
			document_->acquire();
	}
	return *this;
}

u_int32_t XmlDocument::getID() const
{
	return document_->getID().raw();
}

void XmlDocument::setName(const std::string &name)
{
	document_->setName(name);
}

std::string XmlDocument::getName() const
{
	return document_->getName();
}

void XmlDocument::setContent(const std::string &content)
{
	DbtOut dbtContent((void*)content.c_str(), content.length());
	document_->setContent(dbtContent);
}

void XmlDocument::setContent(Dbt &content)
{
	document_->setContent(content);
}

const Dbt *XmlDocument::getContent() const
{
	return document_->getContent();
}

void XmlDocument::setMetaData(const std::string &uri, const std::string &prefix, const std::string &name, const XmlValue &value)
{
	Name n(uri, prefix, name);
	document_->setMetaData(n, value);
}

bool XmlDocument::getMetaData(const std::string &uri, const std::string &name, XmlValue &value)
{
	Name n(uri.c_str(), 0, name.c_str());
	return document_->getMetaData(n, value);
}

void XmlDocument::setMetaData(const std::string &uri, const std::string &prefix, const std::string &name, const Dbt &value)
{
	Name n(uri, prefix, name);
	document_->setMetaData(n, XmlValue::BINARY, value);
}

bool XmlDocument::getMetaData(const std::string &uri, const std::string &name, Dbt &value)
{
	Name n(uri.c_str(), 0, name.c_str());
	return document_->getMetaData(n, value);
}

#if defined(DBXML_DOM_XERCES2)
XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *XmlDocument::getDOM(bool withMetaData, bool adopt) const
{
	XercesDOMParser xmlParser;
	return document_->getDOM(xmlParser, withMetaData, adopt);
}
#endif

std::string &XmlDocument::getContentAsString(std::string &s) const
{
	const Dbt *dbt = document_->getContent();
	if (dbt != 0 && dbt->get_size() > 0) {
		s.assign((const char *)dbt->get_data(), dbt->get_size());
	} else {
		s.erase();
	}
	return s;
}

XmlResults XmlDocument::queryWithXPath(const std::string &xpath, XmlQueryContext *context) const
{
	if (context == 0) {
		XmlQueryContext defaultContext(XmlQueryContext::ResultValues, XmlQueryContext::Eager);
		XmlResults results(defaultContext, NULL);
		document_->queryWithXPath(*this, xpath, *results, defaultContext);
		return results;
	} else {
		XmlResults results(*context, NULL);
		document_->queryWithXPath(*this, xpath, *results, *context);
		return results;
	}
}

XmlResults XmlDocument::queryWithXPath(XmlQueryExpression &xpath) const
{
	XmlResults results(xpath.getQueryContext(), NULL);
	document_->queryWithXPath(*this, xpath.getXPathQuery(), *results, xpath.getQueryContext());
	return results;
}

void XmlDocument::modifyDocument(const XmlModify &xmlModify)
{
	document_->modifyDocument(*this, (const Modify&)xmlModify);
}

