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