1 // Copyright 2008, Google Inc. All rights reserved. 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are met: 5 // 6 // 1. Redistributions of source code must retain the above copyright notice, 7 // this list of conditions and the following disclaimer. 8 // 2. Redistributions in binary form must reproduce the above copyright notice, 9 // this list of conditions and the following disclaimer in the documentation 10 // and/or other materials provided with the distribution. 11 // 3. Neither the name of Google Inc. nor the names of its contributors may be 12 // used to endorse or promote products derived from this software without 13 // specific prior written permission. 14 // 15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26 #ifndef KML_XSD_XSD_COMPLEX_TYPE_H__ 27 #define KML_XSD_XSD_COMPLEX_TYPE_H__ 28 29 #include <vector> 30 #include "boost/intrusive_ptr.hpp" 31 #include "kml/base/attributes.h" 32 #include "kml/xsd/xsd_element.h" 33 #include "kml/xsd/xsd_type.h" 34 35 namespace kmlxsd { 36 37 class XsdComplexType; 38 39 // Use this typedef to manage the XsdComplexType pointer. For example: 40 // XsdComplexTypePtr complex_type = XsdComplexType::Create(attributes); 41 typedef boost::intrusive_ptr<XsdComplexType> XsdComplexTypePtr; 42 43 // Corresponds to <xs:complexType> with possible <xs:extension> and use of 44 // <xs:sequence> (order of <xs:element>'s matters in <xs:sequence>). 45 class XsdComplexType : public XsdType { 46 public: 47 // Create an XsdComplexType from the given attributes. The "name" attribute 48 // must exist for this to succeed. On success a pointer is returned which 49 // may be managed with intrusive_ptr using the recommended typedef above. Create(const kmlbase::Attributes & attributes)50 static XsdComplexType* Create(const kmlbase::Attributes& attributes) { 51 string name; 52 if (attributes.GetString("name", &name)) { 53 return new XsdComplexType(name); 54 } 55 return NULL; 56 } 57 58 // This dynamic cast to XsdComplexTypePtr returns non-NULL if the xsd_type 59 // is non-NULL and is_complex() is true. AsComplexType(const XsdTypePtr & xsd_type)60 static XsdComplexTypePtr AsComplexType(const XsdTypePtr& xsd_type) { 61 if (xsd_type && xsd_type->get_xsd_type_id() == XSD_TYPE_COMPLEX) { 62 return boost::static_pointer_cast<XsdComplexType>(xsd_type); 63 } 64 return NULL; 65 } 66 get_xsd_type_id()67 virtual XsdTypeEnum get_xsd_type_id() const { 68 return XSD_TYPE_COMPLEX; 69 } 70 is_complex()71 virtual bool is_complex() const { 72 return true; 73 } 74 75 // Get the value of the name attribute. get_name()76 virtual const string get_name() const { 77 return name_; 78 } 79 get_base()80 virtual const string get_base() const { 81 return extension_base_; 82 } 83 84 // Set the value of the "base" attribute of the complexType's 85 // <xs:extension> element. set_extension_base(const string & extension_base)86 void set_extension_base(const string& extension_base) { 87 extension_base_ = extension_base; 88 } 89 // Get the <xs:extension base=".."> value. get_extension_base()90 const string& get_extension_base() const { 91 return extension_base_; 92 } 93 // Return true IFF this complexType has an <xs:extension base="..."/>. has_extension_base()94 bool has_extension_base() const { 95 return !extension_base_.empty(); 96 } 97 98 // Append the given <xs:element> to this complexType's <xs:sequence>. add_element(const XsdElementPtr & element)99 void add_element(const XsdElementPtr& element) { 100 sequence_.push_back(element); 101 } 102 103 // Return the number of elements in the <xs:sequence>. get_sequence_size()104 size_t get_sequence_size() const { 105 return sequence_.size(); 106 } 107 // Return the index'th element in the <xs:sequence>. get_sequence_at(size_t index)108 const XsdElementPtr get_sequence_at(size_t index) const { 109 return sequence_[index]; 110 } 111 112 private: 113 bool ParseAttributes(const kmlbase::Attributes& attributes); XsdComplexType(const string & name)114 XsdComplexType(const string& name) 115 : name_(name) { 116 } 117 118 string name_; 119 string extension_base_; // <xs:extension base="xx"> 120 std::vector<XsdElementPtr> sequence_; // <xs:sequence> of <xs:element>'s. 121 }; 122 123 } // end namespace kmlxsd 124 125 #endif // KML_XSD_XSD_COMPLEX_TYPE_H__ 126