/*
 *  Author: bwilliams
 *  Created: April 6, 2012
 *
 *  Copyright (C) 2012-2016 VMware, Inc.  All rights reserved. -- VMware Confidential
 *
 *  This code was generated by the script "build/dev/codeGen/genCppXml". Please
 *  speak to Brian W. before modifying it by hand.
 *
 */

#include "stdafx.h"

#include "Doc/DocXml/SchemaTypesXml/ActionClassXml.h"
#include "Doc/DocXml/SchemaTypesXml/DataClassXml.h"

#include "Doc/ProviderResultsDoc/CSchemaDoc.h"
#include "Doc/SchemaTypesDoc/CActionClassDoc.h"
#include "Doc/SchemaTypesDoc/CDataClassDoc.h"
#include "Doc/SchemaTypesDoc/CLogicalRelationshipDoc.h"
#include "Doc/SchemaTypesDoc/CPhysicalRelationshipDoc.h"
#include "Xml/XmlUtils/CXmlElement.h"
#include "Doc/DocXml/ProviderResultsXml/SchemaXml.h"
#include "Doc/DocXml/SchemaTypesXml/LogicalRelationshipXml.h"
#include "Doc/DocXml/SchemaTypesXml/PhysicalRelationshipXml.h"

using namespace Caf;

void SchemaXml::add(
	const SmartPtrCSchemaDoc schemaDoc,
	const SmartPtrCXmlElement thisXml) {
	CAF_CM_STATIC_FUNC_VALIDATE("SchemaXml", "add");

	CAF_CM_ENTER {
		CAF_CM_VALIDATE_SMARTPTR(schemaDoc);
		CAF_CM_VALIDATE_SMARTPTR(thisXml);

		const std::deque<SmartPtrCDataClassDoc> dataClassVal =
			schemaDoc->getDataClassCollection();
		if (! dataClassVal.empty()) {
			for (TConstIterator<std::deque<SmartPtrCDataClassDoc> > dataClassIter(dataClassVal);
				dataClassIter; dataClassIter++) {
				const SmartPtrCXmlElement dataClassXml =
					thisXml->createAndAddElement("dataClass");
				DataClassXml::add(*dataClassIter, dataClassXml);
			}
		}

		const std::deque<SmartPtrCActionClassDoc> actionClassVal =
			schemaDoc->getActionClassCollection();
		if (! actionClassVal.empty()) {
			for (TConstIterator<std::deque<SmartPtrCActionClassDoc> > actionClassIter(actionClassVal);
				actionClassIter; actionClassIter++) {
				const SmartPtrCXmlElement actionClassXml =
					thisXml->createAndAddElement("actionClass");
				ActionClassXml::add(*actionClassIter, actionClassXml);
			}
		}

		const std::deque<SmartPtrCLogicalRelationshipDoc> logicalRelationshipVal =
			schemaDoc->getLogicalRelationshipCollection();
		if (! logicalRelationshipVal.empty()) {
			for (TConstIterator<std::deque<SmartPtrCLogicalRelationshipDoc> > logicalRelationshipIter(logicalRelationshipVal);
				logicalRelationshipIter; logicalRelationshipIter++) {
				const SmartPtrCXmlElement logicalRelationshipXml =
					thisXml->createAndAddElement("logicalRelationship");
				LogicalRelationshipXml::add(*logicalRelationshipIter, logicalRelationshipXml);
			}
		}

		const std::deque<SmartPtrCPhysicalRelationshipDoc> physicalRelationshipVal =
			schemaDoc->getPhysicalRelationshipCollection();
		if (! physicalRelationshipVal.empty()) {
			for (TConstIterator<std::deque<SmartPtrCPhysicalRelationshipDoc> > physicalRelationshipIter(physicalRelationshipVal);
				physicalRelationshipIter; physicalRelationshipIter++) {
				const SmartPtrCXmlElement physicalRelationshipXml =
					thisXml->createAndAddElement("physicalRelationship");
				PhysicalRelationshipXml::add(*physicalRelationshipIter, physicalRelationshipXml);
			}
		}
	}
	CAF_CM_EXIT;
}

SmartPtrCSchemaDoc SchemaXml::parse(
	const SmartPtrCXmlElement thisXml) {
	CAF_CM_STATIC_FUNC_VALIDATE("SchemaXml", "parse");

	SmartPtrCSchemaDoc schemaDoc;

	CAF_CM_ENTER {
		CAF_CM_VALIDATE_SMARTPTR(thisXml);

		const CXmlElement::SmartPtrCElementCollection dataClassChildrenXml =
			thisXml->findOptionalChildren("dataClass");

		std::deque<SmartPtrCDataClassDoc> dataClassVal;
		if (! dataClassChildrenXml.IsNull() && ! dataClassChildrenXml->empty()) {
			for (TConstIterator<CXmlElement::CElementCollection> dataClassXmlIter(*dataClassChildrenXml);
				dataClassXmlIter; dataClassXmlIter++) {
				const SmartPtrCXmlElement dataClassXml = dataClassXmlIter->second;
				const SmartPtrCDataClassDoc dataClassDoc =
					DataClassXml::parse(dataClassXml);
				dataClassVal.push_back(dataClassDoc);
			}
		}

		const CXmlElement::SmartPtrCElementCollection actionClassChildrenXml =
			thisXml->findOptionalChildren("actionClass");

		std::deque<SmartPtrCActionClassDoc> actionClassVal;
		if (! actionClassChildrenXml.IsNull() && ! actionClassChildrenXml->empty()) {
			for (TConstIterator<CXmlElement::CElementCollection> actionClassXmlIter(*actionClassChildrenXml);
				actionClassXmlIter; actionClassXmlIter++) {
				const SmartPtrCXmlElement actionClassXml = actionClassXmlIter->second;
				const SmartPtrCActionClassDoc actionClassDoc =
					ActionClassXml::parse(actionClassXml);
				actionClassVal.push_back(actionClassDoc);
			}
		}

		const CXmlElement::SmartPtrCElementCollection logicalRelationshipChildrenXml =
			thisXml->findOptionalChildren("logicalRelationship");

		std::deque<SmartPtrCLogicalRelationshipDoc> logicalRelationshipVal;
		if (! logicalRelationshipChildrenXml.IsNull() && ! logicalRelationshipChildrenXml->empty()) {
			for (TConstIterator<CXmlElement::CElementCollection> logicalRelationshipXmlIter(*logicalRelationshipChildrenXml);
				logicalRelationshipXmlIter; logicalRelationshipXmlIter++) {
				const SmartPtrCXmlElement logicalRelationshipXml = logicalRelationshipXmlIter->second;
				const SmartPtrCLogicalRelationshipDoc logicalRelationshipDoc =
					LogicalRelationshipXml::parse(logicalRelationshipXml);
				logicalRelationshipVal.push_back(logicalRelationshipDoc);
			}
		}

		const CXmlElement::SmartPtrCElementCollection physicalRelationshipChildrenXml =
			thisXml->findOptionalChildren("physicalRelationship");

		std::deque<SmartPtrCPhysicalRelationshipDoc> physicalRelationshipVal;
		if (! physicalRelationshipChildrenXml.IsNull() && ! physicalRelationshipChildrenXml->empty()) {
			for (TConstIterator<CXmlElement::CElementCollection> physicalRelationshipXmlIter(*physicalRelationshipChildrenXml);
				physicalRelationshipXmlIter; physicalRelationshipXmlIter++) {
				const SmartPtrCXmlElement physicalRelationshipXml = physicalRelationshipXmlIter->second;
				const SmartPtrCPhysicalRelationshipDoc physicalRelationshipDoc =
					PhysicalRelationshipXml::parse(physicalRelationshipXml);
				physicalRelationshipVal.push_back(physicalRelationshipDoc);
			}
		}

		schemaDoc.CreateInstance();
		schemaDoc->initialize(
			dataClassVal,
			actionClassVal,
			logicalRelationshipVal,
			physicalRelationshipVal);
	}
	CAF_CM_EXIT;

	return schemaDoc;
}

