summaryrefslogtreecommitdiff
path: root/cpp/src/Slice/XsdVisitor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Slice/XsdVisitor.cpp')
-rw-r--r--cpp/src/Slice/XsdVisitor.cpp518
1 files changed, 518 insertions, 0 deletions
diff --git a/cpp/src/Slice/XsdVisitor.cpp b/cpp/src/Slice/XsdVisitor.cpp
new file mode 100644
index 00000000000..435989abd99
--- /dev/null
+++ b/cpp/src/Slice/XsdVisitor.cpp
@@ -0,0 +1,518 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Slice/XsdVisitor.h>
+#include <IceUtil/Functional.h>
+#include <Slice/CPlusPlusUtil.h> // TODO: ???
+
+using namespace std;
+using namespace Slice;
+using namespace IceUtil;
+
+static const string internalId = "_internal.";
+
+Slice::XsdVisitor::XsdVisitor() :
+ _emitElements(true)
+{
+}
+
+Slice::XsdVisitor::XsdVisitor(::std::ostream& os) :
+ O(os),
+ _emitElements(true)
+{
+}
+
+void
+Slice::XsdVisitor::emitElements(bool emitElements)
+{
+ _emitElements = emitElements;
+}
+
+bool
+Slice::XsdVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ O << sp;
+
+ string scopeId = containedToId(p);
+
+ //
+ // Emit class-name-type
+ //
+ ostringstream os;
+ os << "xs:complexType name=\"" << internalId << scopeId << p->name() << "Type\" id=\"" << p->scoped() << "\"";
+ O << se(os.str());
+
+ annotate("class");
+
+ O << se("xs:complexContent");
+
+ string extension = "xs:extension base=\"";
+ ClassList bases = p->bases();
+ if (bases.empty() || bases.front()->isInterface())
+ {
+ extension += "ice:_internal.object";
+ }
+ else
+ {
+ extension += "tns:";
+ ClassDefPtr base = bases.front();
+ extension += internalId + containedToId(base) + base->name();
+ }
+ extension += "Type\"";
+
+ O << se(extension);
+
+ DataMemberList dataMembers = p->dataMembers();
+ O << se("xs:sequence");
+ for (DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ emitElement(*q);
+ }
+ O << ee; // xs:sequence
+
+ O << ee; // xs:extension
+ O << ee; // xs:complexContent
+ O << ee; // xs:complexType
+
+ if (_emitElements)
+ {
+ O << sp << nl << "<xs:element name=\"" << scopeId << p->name()
+ << "\" type=\"tns:" << internalId << scopeId << p->name() << "Type\" nillable=\"true\"/>";
+ }
+
+ return true;
+}
+
+bool
+Slice::XsdVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ O << sp;
+
+ string scopeId = containedToId(p);
+
+ //
+ // Emit exception-name-type
+ //
+ ostringstream os;
+ os << "xs:complexType name=\"" << internalId << scopeId << p->name() << "Type\" id=\"" << p->scoped() << "\"";
+ O << se(os.str());
+
+ annotate("exception");
+
+ //
+ // Emit base Data
+ //
+ ExceptionPtr base = p->base();
+ if (base)
+ {
+ string baseScopeId = containedToId(base);
+
+ O << se("xs:complexContent");
+
+ string extension = "xs:extension base=\"";
+ extension += "tns:";
+ extension += internalId + baseScopeId + base->name();
+ extension += "Type\"";
+ O << se(extension);
+ }
+
+ DataMemberList dataMembers = p->dataMembers();
+
+ O << se("xs:sequence");
+
+ for (DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ emitElement(*q);
+ }
+
+ O << ee; // xs:sequence
+
+ if (base)
+ {
+ O << ee; // xs:extension
+ O << ee; // xs:complexContent
+ }
+
+ O << ee; // xs:complexType
+
+ if (_emitElements)
+ {
+ O << sp << nl << "<xs:element name=\"" << scopeId << p->name()
+ << "\" type=\"tns:" << internalId << scopeId << p->name() << "Type\"/>";
+ }
+
+ return true;
+}
+
+bool
+Slice::XsdVisitor::visitStructStart(const StructPtr& p)
+{
+ O << sp;
+
+ string scopeId = containedToId(p);
+
+ ostringstream os;
+ os << "xs:complexType name=\"" << internalId << scopeId << p->name() << "Type\" id=\"" << p->scoped() << "\"";
+ O << se(os.str());
+
+ annotate("struct");
+
+ DataMemberList dataMembers = p->dataMembers();
+ O << se("xs:sequence");
+
+ for (DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ O << nl << "<xs:element name=\"" << (*q)->name() << "\" type=\"";
+ O << toString((*q)->type());
+ O << "\"/>";
+ }
+
+ O << ee; // xs:sequence
+
+ O << ee; // xs:complexType
+
+ if (_emitElements)
+ {
+ O << sp << nl << "<xs:element name=\"" << scopeId << p->name()
+ << "\" type=\"tns:" << internalId << scopeId << p->name() << "Type\"/>";
+ }
+
+ return true;
+}
+
+void
+Slice::XsdVisitor::visitOperation(const OperationPtr& p)
+{
+ TypeStringList in = p->inputParameters();
+ TypeStringList out = p->outputParameters();
+ TypePtr ret = p->returnType();
+ string scopeId = containedToId(p);
+ ostringstream os;
+
+ O << sp;
+
+ os << "xs:element name=\"" << scopeId << "request." << p->name() << "\"";
+ O << se(os.str());
+ O << se("xs:complexType");
+
+ annotate("operation");
+
+ O << se("xs:sequence");
+ TypeStringList::const_iterator q;
+ for (q = in.begin(); q != in.end(); ++q)
+ {
+ emitElement(*q);
+ }
+ O << ee; // xs:sequence
+
+ O << ee; // xs:complexType
+ O << ee; // xs:element
+
+ os.str(""); // Reset stream
+
+ O << sp;
+
+ os << "xs:element name=\"" << scopeId << "reply." << p->name() << "\"";
+ O << se(os.str());
+ O << se("xs:complexType");
+
+ annotate("operation");
+
+ O << se("xs:sequence");
+ if (ret)
+ {
+ O << nl << "<xs:element name=\"__return\" type=\"" << toString(ret) << "\"/>";
+ }
+ for (q = out.begin(); q != out.end(); ++q)
+ {
+ emitElement(*q);
+ }
+ O << ee; // xs:sequence
+
+ O << ee; // xs:complexType
+ O << ee; // xs:element
+}
+
+void
+Slice::XsdVisitor::visitEnum(const EnumPtr& p)
+{
+ string scopeId = containedToId(p);
+
+ O << sp;
+
+ ostringstream os;
+ os << "xs:simpleType name=\"" << internalId << scopeId << p->name() << "Type\" id=\"" << p->scoped() << "\"";
+ O << se(os.str());
+
+ annotate("enumeration");
+
+ EnumeratorList enumerators = p->getEnumerators();
+ assert (!enumerators.empty());
+
+ O << se("xs:restriction base=\"xs:string\"");
+
+ for (EnumeratorList::const_iterator q = enumerators.begin(); q != enumerators.end(); ++q)
+ {
+ O << nl << "<xs:enumeration value=\"" << (*q)->name() << "\"/>";
+ }
+
+ O << ee; // xs:restriction
+ O << ee; // xs:simpleType
+
+ if (_emitElements)
+ {
+ O << sp << nl << "<xs:element name=\"" << scopeId << p->name()
+ << "\" type=\"tns:" << internalId << scopeId << p->name() << "Type\"/>";
+ }
+}
+
+void
+Slice::XsdVisitor::visitSequence(const SequencePtr& p)
+{
+ O << sp;
+
+ string scopeId = containedToId(p);
+
+ ostringstream os;
+ os << "xs:complexType name=\"" << internalId << scopeId << p->name() << "Type\" id=\"" << p->scoped() << "\"";
+
+ O << se(os.str());
+
+ annotate("sequence");
+
+ O << se("xs:sequence");
+
+ O << nl << "<xs:element name=\"e\" type=\"" << toString(p->type())
+ << "\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>";
+
+ O << ee; // xs:sequence
+
+ O << nl << "<xs:attribute name=\"length\" type=\"xs:long\"/>";
+
+ O << ee; // xs:complexType
+
+ if (_emitElements)
+ {
+ O << sp << nl << "<xs:element name=\"" << scopeId << p->name() << "\" type=\"tns:"
+ << internalId << scopeId << p->name() << "Type\"/>";
+ }
+}
+
+void
+Slice::XsdVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ O << sp;
+
+ string scopeId = containedToId(p);
+
+ //
+ // First the dictionary content.
+ //
+ ostringstream os;
+ os << "xs:complexType name=\"" << internalId << scopeId << p->name() << "ContentType\"";
+ O << se(os.str());
+
+ annotate("dictionaryContent");
+
+ O << se("xs:sequence");
+
+ O.inc();
+ O << nl << "<xs:element name=\"key\" type=\"" << toString(p->keyType()) << "\"/>";
+ O << nl << "<xs:element name=\"value\" type=\"" << toString(p->valueType()) << "\"/>";
+ O.dec();
+
+ O << ee; // xs:sequence
+ O << ee; // xs:complexType
+
+ O << sp;
+
+ //
+ // Next the dictionary sequence data.
+ //
+ os.str("");
+ os << "xs:complexType name=\"" << internalId << scopeId << p->name() << "Type\" id=\"" << p->scoped() << "\"";
+ O << se(os.str());
+
+ annotate("dictionary");
+
+ O << se("xs:sequence");
+
+ O << nl << "<xs:element name=\"e\" type=\"tns:" << internalId << scopeId << p->name() << "ContentType\""
+ << " minOccurs=\"0\" maxOccurs=\"unbounded\"/>";
+
+ O << ee; // xs:sequence
+
+ O << nl << "<xs:attribute name=\"length\" type=\"xs:long\"/>";
+
+ O << ee; // xs:complexType
+
+ if (_emitElements)
+ {
+ O << sp << nl << "<xs:element name=\"" << scopeId << p->name() << "\" type=\"tns:"
+ << internalId << scopeId << p->name() << "Type\"/>";
+ }
+}
+
+void
+Slice::XsdVisitor::annotate(const ::std::string& type)
+{
+ O << se("xs:annotation");
+ O << se("xs:appinfo");
+ O << nl << "<type>" << type << "</type>";
+ O << ee; // xs:annotation
+ O << ee; // xs:appinfo
+}
+
+void
+Slice::XsdVisitor::emitElement(const DataMemberPtr& q)
+{
+ ostringstream os;
+ os << "xs:element name=\"" << q->name() << "\" type=\"" << toString(q->type()) << '"';
+ O << se(os.str());
+ ProxyPtr proxy = ProxyPtr::dynamicCast(q->type());
+ if (proxy)
+ {
+ annotate(proxy->_class()->scoped());
+ }
+ O << ee; // xs:element
+}
+
+void
+Slice::XsdVisitor::emitElement(const TypeString& q)
+{
+ ostringstream os;
+ os << "xs:element name=\"" << q.second << "\" type=\"" << toString(q.first) << '"';
+ O << se(os.str());
+ ProxyPtr proxy = ProxyPtr::dynamicCast(q.first);
+ if (proxy)
+ {
+ annotate(proxy->_class()->scoped());
+ }
+ O << ee; // xs:element
+}
+
+string
+Slice::XsdVisitor::containedToId(const ContainedPtr& contained)
+{
+ assert(contained);
+
+ string scoped = contained->scope();
+ if (scoped[0] == ':')
+ {
+ scoped.erase(0, 2);
+ }
+
+ string id;
+
+ id.reserve(scoped.size());
+
+ for (unsigned int i = 0; i < scoped.size(); ++i)
+ {
+ if (scoped[i] == ':')
+ {
+ id += '.';
+ ++i;
+ }
+ else
+ {
+ id += scoped[i];
+ }
+ }
+
+ return id;
+}
+
+string
+Slice::XsdVisitor::toString(const SyntaxTreeBasePtr& p)
+{
+ string tag;
+ string linkend;
+ string s;
+
+ static const char* builtinTable[] =
+ {
+ "xs:byte",
+ "xs:boolean",
+ "xs;short",
+ "xs:int",
+ "xs:long",
+ "xs:float",
+ "xs:double",
+ "xs:string",
+ "ice:_internal.reference", /* Object */
+ "ice:_internal.proxyType", /* Object* */
+ "???" /* LocalObject */
+ };
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p);
+ if (builtin)
+ {
+ s = builtinTable[builtin->kind()];
+ //tag = "type";
+ }
+
+ ProxyPtr proxy = ProxyPtr::dynamicCast(p);
+ if (proxy)
+ {
+ s = "ice:_internal.proxyType";
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(p);
+ if (cl)
+ {
+ string scopeId = containedToId(cl);
+ //s = "tns:" + internalId + scopeId + cl->name() + "Type";
+ s = "ice:_internal.reference";
+ }
+
+ ExceptionPtr ex = ExceptionPtr::dynamicCast(p);
+ if (ex)
+ {
+ string scopeId = containedToId(ex);
+ s = "tns:" + internalId + scopeId + ex->name() + "Type";
+ }
+
+ StructPtr st = StructPtr::dynamicCast(p);
+ if (st)
+ {
+ string scopeId = containedToId(st);
+ s = "tns:" + internalId + scopeId + st->name() + "Type";
+ }
+
+ EnumeratorPtr en = EnumeratorPtr::dynamicCast(p);
+ if (en)
+ {
+ string scopeId = containedToId(en);
+ s = "tns:" + internalId + scopeId + en->name() + "Type";
+ }
+
+ SequencePtr sq = SequencePtr::dynamicCast(p);
+ if (sq)
+ {
+ string scopeId = containedToId(sq);
+ s = "tns:" + internalId + scopeId + sq->name() + "Type";
+ }
+
+ DictionaryPtr di = DictionaryPtr::dynamicCast(p);
+ if (di)
+ {
+ string scopeId = containedToId(di);
+ s = "tns:" + internalId + scopeId + di->name() + "Type";
+ }
+
+ EnumPtr em = EnumPtr::dynamicCast(p);
+ if (em)
+ {
+ string scopeId = containedToId(em);
+ s = "tns:" + internalId + scopeId + em->name() + "Type";
+ }
+
+ return s;
+}