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 // This file contains the implementation of the abstract Feature element.
27 
28 #include "kml/dom/feature.h"
29 #include "kml/dom/kml_cast.h"
30 #include "kml/dom/serializer.h"
31 
32 namespace kmldom {
33 
Feature()34 Feature::Feature() :
35   has_name_(false),
36   visibility_(true),
37   has_visibility_(false),
38   open_(false),
39   has_open_(false),
40   has_address_(false),
41   has_phonenumber_(false),
42   has_description_(false),
43   has_styleurl_(false),
44   gx_balloonvisibility_(false),
45   has_gx_balloonvisibility_(false) {
46 }
47 
~Feature()48 Feature::~Feature() {}
49 
AddElement(const ElementPtr & element)50 void Feature::AddElement(const ElementPtr& element) {
51   if (!element) {
52     return;
53   }
54   // Substitution groups.
55   if (element->IsA(Type_AbstractView)) {
56     set_abstractview(AsAbstractView(element));
57     return;
58   }
59   if (element->IsA(Type_TimePrimitive)) {
60     set_timeprimitive(AsTimePrimitive(element));
61     return;
62   }
63   if (element->IsA(Type_StyleSelector)) {
64     set_styleselector(AsStyleSelector(element));
65     return;
66   }
67 
68   // Explicit child elements.
69   switch(element->Type()) {
70     case Type_name:
71       has_name_ = element->SetString(&name_);
72       break;
73     case Type_visibility:
74       has_visibility_ = element->SetBool(&visibility_);
75       break;
76     case Type_open:
77       has_open_ = element->SetBool(&open_);
78       break;
79     case Type_AtomAuthor:
80       set_atomauthor(AsAtomAuthor(element));
81       break;
82     case Type_AtomLink:
83       set_atomlink(AsAtomLink(element));
84       break;
85     case Type_address:
86       has_address_ = element->SetString(&address_);
87       break;
88     case Type_XalAddressDetails:
89       set_xaladdressdetails(AsXalAddressDetails(element));
90       break;
91     case Type_phoneNumber:
92       has_phonenumber_ = element->SetString(&phonenumber_);
93       break;
94     case Type_Snippet:
95       set_snippet(AsSnippet(element));
96       break;
97 // TODO: intentionally do not process <snippet> and let it fall to unknown
98 #if 0
99     case Type_snippet:
100       // Recognize (little) <snippet> and save as a big <Snippet>.
101       SnippetPtr snippet = KmlFactory::GetFactory()->CreateSnippet();
102       snippet->set_text(element->get_char_data());
103       set_snippet(snippet);
104 #endif
105       break;
106     case Type_description:
107       has_description_ = element->SetString(&description_);
108       break;
109     case Type_styleUrl:
110       has_styleurl_ = element->SetString(&styleurl_);
111       break;
112     case Type_Region:
113       set_region(AsRegion(element));
114       break;
115 // TODO: intentionally do not process <Metadata> and let it fall to unknown
116 #if 0
117     case Type_Metadata:
118       // Recognize <Metdata> and save into <ExtendedData>.
119       break;
120 #endif
121     case Type_ExtendedData:
122       set_extendeddata(AsExtendedData(element));
123       break;
124     case Type_GxBalloonVisibility:
125       has_gx_balloonvisibility_ = element->SetBool(&gx_balloonvisibility_);
126       break;
127     default:
128       Object::AddElement(element);
129   }
130 }
131 
SerializeBeforeStyleSelector(Serializer & serializer) const132 void Feature::SerializeBeforeStyleSelector(Serializer& serializer) const {
133   if (has_name()) {
134     serializer.SaveFieldById(Type_name, name_);
135   }
136   if (has_visibility()) {
137     serializer.SaveFieldById(Type_visibility, visibility_);
138   }
139   if (has_open()) {
140     serializer.SaveFieldById(Type_open, open_);
141   }
142   if (has_atomauthor()) {
143     serializer.SaveElement(get_atomauthor());
144   }
145   if (has_atomlink()) {
146     serializer.SaveElement(get_atomlink());
147   }
148   if (has_address()) {
149     serializer.SaveFieldById(Type_address, get_address());
150   }
151   if (has_phonenumber()) {
152     serializer.SaveFieldById(Type_phoneNumber, get_phonenumber());
153   }
154   if (has_xaladdressdetails()) {
155     serializer.SaveElement(get_xaladdressdetails());
156   }
157   if (has_snippet()) {
158     serializer.SaveElement(get_snippet());
159   }
160   if (has_description()) {
161     serializer.SaveFieldById(Type_description, description_);
162   }
163   if (has_abstractview()) {
164     serializer.SaveElementGroup(get_abstractview(), Type_AbstractView);
165   }
166   if (has_timeprimitive()) {
167     serializer.SaveElementGroup(get_timeprimitive(), Type_TimePrimitive);
168   }
169   if (has_styleurl()) {
170     serializer.SaveFieldById(Type_styleUrl, styleurl_);
171   }
172 }
173 
SerializeAfterStyleSelector(Serializer & serializer) const174 void Feature::SerializeAfterStyleSelector(Serializer& serializer) const {
175   if (has_region()) {
176     serializer.SaveElement(get_region());
177   }
178   if (has_extendeddata()) {
179     serializer.SaveElement(get_extendeddata());
180   }
181   if (has_gx_balloonvisibility()) {
182     serializer.SaveFieldById(Type_GxBalloonVisibility, gx_balloonvisibility_);
183   }
184 }
185 
Serialize(Serializer & serializer) const186 void Feature::Serialize(Serializer& serializer) const {
187   Feature::SerializeBeforeStyleSelector(serializer);
188   if (has_styleselector()) {
189     serializer.SaveElementGroup(get_styleselector(), Type_StyleSelector);
190   }
191   Feature::SerializeAfterStyleSelector(serializer);
192 }
193 
AcceptChildren(VisitorDriver * driver)194 void Feature::AcceptChildren(VisitorDriver* driver) {
195   Object::AcceptChildren(driver);
196   if (has_snippet()) {
197     driver->Visit(get_snippet());
198   }
199   if (has_abstractview()) {
200     driver->Visit(get_abstractview());
201   }
202   if (has_timeprimitive()) {
203     driver->Visit(get_timeprimitive());
204   }
205   if (has_styleselector()) {
206     driver->Visit(get_styleselector());
207   }
208   if (has_region()) {
209     driver->Visit(get_region());
210   }
211   if (has_extendeddata()) {
212     driver->Visit(get_extendeddata());
213   }
214 }
215 
216 }  // namespace kmldom
217