root/win32/xsd-3.1.0-i686/libxsd/xsd/cxx/tree/type-serializer-map.txx @ 111

Revision 111, 15.6 kB (checked in by mido, 16 years ago)

pridana knihovna XSD (a jeji chlebodarkyne XERCES), v ramci Win32 zprovoznen priklad tests/test_xsd_hello.cxx

Line 
1// file      : xsd/cxx/tree/type-serializer-map.txx
2// author    : Boris Kolpackov <boris@codesynthesis.com>
3// copyright : Copyright (c) 2005-2008 Code Synthesis Tools CC
4// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file
5
6#include <xsd/cxx/xml/bits/literals.hxx> // xml::bits::{xsi_namespace, type}
7#include <xsd/cxx/xml/dom/serialization-source.hxx> // dom::{create_*, prefix}
8
9#include <xsd/cxx/tree/types.hxx>
10#include <xsd/cxx/tree/bits/literals.hxx>
11
12namespace xsd
13{
14  namespace cxx
15  {
16    namespace tree
17    {
18      // type_serializer_map
19      //
20      template <typename C>
21      type_serializer_map<C>::
22      type_serializer_map ()
23      {
24        // Register serializers for built-in non-fundamental types.
25        //
26        std::basic_string<C> xsd (bits::xml_schema<C> ());
27
28
29        // anyType and anySimpleType.
30        //
31        register_type (
32          typeid (type),
33          qualified_name (bits::any_type<C> (), xsd),
34          &serializer_impl<type>,
35          false);
36
37        typedef simple_type<type> simple_type;
38        register_type (
39          typeid (simple_type),
40          qualified_name (bits::any_simple_type<C> (), xsd),
41          &serializer_impl<simple_type>,
42          false);
43
44
45        // Strings
46        //
47        typedef string<C, simple_type> string;
48        register_type (
49          typeid (string),
50          qualified_name (bits::string<C> (), xsd),
51          &serializer_impl<string>,
52          false);
53
54        typedef normalized_string<C, string> normalized_string;
55        register_type (
56          typeid (normalized_string),
57          qualified_name (bits::normalized_string<C> (), xsd),
58          &serializer_impl<normalized_string>,
59          false);
60
61        typedef token<C, normalized_string> token;
62        register_type (
63          typeid (token),
64          qualified_name (bits::token<C> (), xsd),
65          &serializer_impl<token>,
66          false);
67
68        typedef name<C, token> name;
69        register_type (
70          typeid (name),
71          qualified_name (bits::name<C> (), xsd),
72          &serializer_impl<name>,
73          false);
74
75        typedef nmtoken<C, token> nmtoken;
76        register_type (
77          typeid (nmtoken),
78          qualified_name (bits::nmtoken<C> (), xsd),
79          &serializer_impl<nmtoken>,
80          false);
81
82        typedef nmtokens<C, simple_type, nmtoken> nmtokens;
83        register_type (
84          typeid (nmtokens),
85          qualified_name (bits::nmtokens<C> (), xsd),
86          &serializer_impl<nmtokens>,
87          false);
88
89        typedef ncname<C, name> ncname;
90        register_type (
91          typeid (ncname),
92          qualified_name (bits::ncname<C> (), xsd),
93          &serializer_impl<ncname>,
94          false);
95
96        typedef language<C, token> language;
97        register_type (
98          typeid (language),
99          qualified_name (bits::language<C> (), xsd),
100          &serializer_impl<language>,
101          false);
102
103
104        // ID/IDREF.
105        //
106        typedef id<C, ncname> id;
107        register_type (
108          typeid (id),
109          qualified_name (bits::id<C> (), xsd),
110          &serializer_impl<id>,
111          false);
112
113        typedef idref<type, C, ncname> idref;
114        register_type (
115          typeid (idref),
116          qualified_name (bits::idref<C> (), xsd),
117          &serializer_impl<idref>,
118          false);
119
120        typedef idrefs<C, simple_type, idref> idrefs;
121        register_type (
122          typeid (idrefs),
123          qualified_name (bits::idrefs<C> (), xsd),
124          &serializer_impl<idrefs>,
125          false);
126
127
128        // URI.
129        //
130        typedef uri<C, simple_type> uri;
131        register_type (
132          typeid (uri),
133          qualified_name (bits::any_uri<C> (), xsd),
134          &serializer_impl<uri>,
135          false);
136
137
138        // Qualified name.
139        //
140        typedef qname<C, simple_type, uri, ncname> qname;
141        register_type (
142          typeid (qname),
143          qualified_name (bits::qname<C> (), xsd),
144          &serializer_impl<qname>,
145          false);
146
147
148        // Binary.
149        //
150        typedef base64_binary<C, simple_type> base64_binary;
151        register_type (
152          typeid (base64_binary),
153          qualified_name (bits::base64_binary<C> (), xsd),
154          &serializer_impl<base64_binary>,
155          false);
156
157        typedef hex_binary<C, simple_type> hex_binary;
158        register_type (
159          typeid (hex_binary),
160          qualified_name (bits::hex_binary<C> (), xsd),
161          &serializer_impl<hex_binary>,
162          false);
163
164
165        // Date/time.
166        //
167        typedef gday<C, simple_type> gday;
168        register_type (
169          typeid (gday),
170          qualified_name (bits::gday<C> (), xsd),
171          &serializer_impl<gday>,
172          false);
173
174        typedef gmonth<C, simple_type> gmonth;
175        register_type (
176          typeid (gmonth),
177          qualified_name (bits::gmonth<C> (), xsd),
178          &serializer_impl<gmonth>,
179          false);
180
181        typedef gyear<C, simple_type> gyear;
182        register_type (
183          typeid (gyear),
184          qualified_name (bits::gyear<C> (), xsd),
185          &serializer_impl<gyear>,
186          false);
187
188        typedef gmonth_day<C, simple_type> gmonth_day;
189        register_type (
190          typeid (gmonth_day),
191          qualified_name (bits::gmonth_day<C> (), xsd),
192          &serializer_impl<gmonth_day>,
193          false);
194
195        typedef gyear_month<C, simple_type> gyear_month;
196        register_type (
197          typeid (gyear_month),
198          qualified_name (bits::gyear_month<C> (), xsd),
199          &serializer_impl<gyear_month>,
200          false);
201
202        typedef date<C, simple_type> date;
203        register_type (
204          typeid (date),
205          qualified_name (bits::date<C> (), xsd),
206          &serializer_impl<date>,
207          false);
208
209        typedef time<C, simple_type> time;
210        register_type (
211          typeid (time),
212          qualified_name (bits::time<C> (), xsd),
213          &serializer_impl<time>,
214          false);
215
216        typedef date_time<C, simple_type> date_time;
217        register_type (
218          typeid (date_time),
219          qualified_name (bits::date_time<C> (), xsd),
220          &serializer_impl<date_time>,
221          false);
222
223        typedef duration<C, simple_type> duration;
224        register_type (
225          typeid (duration),
226          qualified_name (bits::duration<C> (), xsd),
227          &serializer_impl<duration>,
228          false);
229
230
231        // Entity.
232        //
233        typedef entity<C, ncname> entity;
234        register_type (
235          typeid (entity),
236          qualified_name (bits::entity<C> (), xsd),
237          &serializer_impl<entity>,
238          false);
239
240        typedef entities<C, simple_type, entity> entities;
241        register_type (
242          typeid (entities),
243          qualified_name (bits::entities<C> (), xsd),
244          &serializer_impl<entities>,
245          false);
246      }
247
248      template <typename C>
249      void type_serializer_map<C>::
250      register_type (const type_id& tid,
251                     const qualified_name& name,
252                     serializer s,
253                     bool override)
254      {
255        if (override || type_map_.find (&tid) == type_map_.end ())
256          type_map_[&tid] = type_info (name, s);
257      }
258
259      template <typename C>
260      void type_serializer_map<C>::
261      register_element (const qualified_name& root,
262                        const qualified_name& subst,
263                        const type_id& tid,
264                        serializer s)
265      {
266        element_map_[root][&tid] = type_info (subst, s);
267      }
268
269      template <typename C>
270      void type_serializer_map<C>::
271      serialize (const C* name, // element name
272                 const C* ns,   // element namespace
273                 bool global,
274                 bool qualified,
275                 xercesc::DOMElement& parent,
276                 const type& x) const
277      {
278        const type_id& tid (typeid (x));
279
280        // First see if we can find a substitution.
281        //
282        if (global)
283        {
284          typename element_map::const_iterator i (
285            element_map_.find (qualified_name (name, ns)));
286
287          if (i != element_map_.end ())
288          {
289            if (const type_info* ti = find_substitution (i->second, tid))
290            {
291              xercesc::DOMElement& e (
292                xml::dom::create_element (
293                  ti->name ().name ().c_str (),
294                  ti->name ().namespace_ ().c_str (),
295                  parent));
296
297              ti->serializer () (e, x);
298              return;
299            }
300          }
301        }
302
303        // The last resort is xsi:type.
304        //
305        if (const type_info* ti = find (tid))
306        {
307          xercesc::DOMElement& e (
308            qualified
309            ? xml::dom::create_element (name, ns, parent)
310            : xml::dom::create_element (name, parent));
311
312          ti->serializer () (e, x);
313          set_xsi_type (e, *ti);
314          return;
315        }
316
317        throw no_type_info<C> (std::basic_string<C> (),
318                               std::basic_string<C> ()); //@@ TODO
319      }
320
321      template <typename C>
322      void type_serializer_map<C>::
323      serialize (const C* static_name,
324                 const C* static_ns,
325                 xercesc::DOMElement& e,
326                 const qualified_name& qn,
327                 const type& x) const
328      {
329        const type_id& tid (typeid (x));
330
331        // First see if this is a substitution.
332        //
333        if (qn.name () != static_name || qn.namespace_ () != static_ns)
334        {
335          typename element_map::const_iterator i (
336            element_map_.find (qualified_name (static_name, static_ns)));
337
338          if (i != element_map_.end ())
339          {
340            if (const type_info* ti = find_substitution (i->second, tid))
341            {
342              if (ti->name ().name () != qn.name () ||
343                  ti->name ().namespace_ () != qn.namespace_ ())
344              {
345                throw unexpected_element<C> (
346                  qn.name (), qn.namespace_ (),
347                  ti->name ().name (), ti->name ().namespace_ ());
348              }
349
350              ti->serializer () (e, x);
351              return;
352            }
353          }
354
355          // This is not a valid substitution.
356          //
357          throw unexpected_element<C> (qn.name (), qn.namespace_ (),
358                                       static_name, static_ns);
359        }
360
361        // The last resort is xsi:type.
362        //
363        if (const type_info* ti = find (tid))
364        {
365          ti->serializer () (e, x);
366          set_xsi_type (e, *ti);
367          return;
368        }
369
370        throw no_type_info<C> (std::basic_string<C> (),
371                               std::basic_string<C> ()); //@@ TODO
372      }
373
374      template <typename C>
375      xml::dom::auto_ptr<xercesc::DOMDocument> type_serializer_map<C>::
376      serialize (const C* name,
377                 const C* ns,
378                 const xml::dom::namespace_infomap<C>& m,
379                 const type& x,
380                 unsigned long flags) const
381      {
382        const type_id& tid (typeid (x));
383
384        // See if we can find a substitution.
385        //
386        {
387          typename element_map::const_iterator i (
388            element_map_.find (qualified_name (name, ns)));
389
390          if (i != element_map_.end ())
391          {
392            if (const type_info* ti = find_substitution (i->second, tid))
393            {
394              return xml::dom::serialize<C> (
395                ti->name ().name (), ti->name ().namespace_ (), m, flags);
396            }
397          }
398        }
399
400        // If there is no substitution then serialize() will have to
401        // find suitable xsi:type.
402        //
403        return xml::dom::serialize<C> (name, ns, m, flags);
404      }
405
406      template <typename C>
407      const typename type_serializer_map<C>::type_info*
408      type_serializer_map<C>::
409      find (const type_id& tid) const
410      {
411        typename type_map::const_iterator i (type_map_.find (&tid));
412        return i == type_map_.end () ? 0 : &i->second;
413      }
414
415      template <typename C>
416      const typename type_serializer_map<C>::type_info*
417      type_serializer_map<C>::
418      find_substitution (const subst_map& start, const type_id& tid) const
419      {
420        typename subst_map::const_iterator i (start.find (&tid));
421
422        if (i != start.end ())
423          return &i->second;
424        else
425        {
426          for (i = start.begin (); i != start.end (); ++i)
427          {
428            typename element_map::const_iterator j (
429              element_map_.find (i->second.name ()));
430
431            if (j != element_map_.end ())
432            {
433              if (const type_info* ti = find_substitution (j->second, tid))
434                return ti;
435            }
436          }
437        }
438
439        return 0;
440      }
441
442      template <typename C>
443      void type_serializer_map<C>::
444      set_xsi_type (xercesc::DOMElement& e, const type_info& ti) const
445      {
446        try
447        {
448          xercesc::DOMAttr& a (
449            xml::dom::create_attribute (
450              xml::bits::type<C> (), xml::bits::xsi_namespace<C> (), e));
451
452          std::basic_string<C> id;
453          const std::basic_string<C>& ns (ti.name ().namespace_ ());
454
455          if (!ns.empty ())
456          {
457            id = xml::dom::prefix (ns, e);
458
459            if (!id.empty ())
460              id += C (':');
461          }
462
463          id += ti.name ().name ();
464
465          a << id;
466        }
467        catch (const xml::dom::no_prefix&)
468        {
469          // No prefix for xsi namespace. Let try to fix this for
470          // everybody.
471          //
472
473          // Check if 'xsi' is already taken.
474          //
475          if (e.lookupNamespaceURI (
476                xml::string (xml::bits::xsi_prefix<C> ()).c_str ()) != 0)
477          {
478            throw xsi_already_in_use<C> ();
479          }
480          std::basic_string<C> xsi (xml::bits::xmlns_prefix<C> ());
481          xsi += C(':');
482          xsi += xml::bits::xsi_prefix<C> ();
483
484          xercesc::DOMElement& root (
485            *e.getOwnerDocument ()->getDocumentElement ());
486
487          root.setAttributeNS (
488            xml::string (xml::bits::xmlns_namespace<C> ()).c_str (),
489            xml::string (xsi).c_str (),
490            xml::string (xml::bits::xsi_namespace<C> ()).c_str ());
491
492          set_xsi_type (e, ti);
493        }
494      }
495
496
497      // type_serializer_plate
498      //
499      template<unsigned long id, typename C>
500      type_serializer_plate<id, C>::
501      type_serializer_plate ()
502      {
503        if (count == 0)
504          map = new type_serializer_map<C>;
505
506        ++count;
507      }
508
509      template<unsigned long id, typename C>
510      type_serializer_plate<id, C>::
511      ~type_serializer_plate ()
512      {
513        if (--count == 0)
514          delete map;
515      }
516
517
518      //
519      //
520      template<typename X>
521      void
522      serializer_impl (xercesc::DOMElement& e, const type& x)
523      {
524        e << static_cast<const X&> (x);
525      }
526
527
528      // type_serializer_initializer
529      //
530      template<unsigned long id, typename C, typename X>
531      type_serializer_initializer<id, C, X>::
532      type_serializer_initializer (const C* name, const C* ns)
533      {
534        type_serializer_map_instance<id, C> ().register_type (
535          typeid (X),
536          xml::qualified_name<C> (name, ns),
537          &serializer_impl<X>);
538      }
539
540      template<unsigned long id, typename C, typename X>
541      type_serializer_initializer<id, C, X>::
542      type_serializer_initializer (const C* root_name,
543                             const C* root_ns,
544                             const C* subst_name,
545                             const C* subst_ns)
546      {
547        type_serializer_map_instance<id, C> ().register_element (
548          xml::qualified_name<C> (root_name, root_ns),
549          xml::qualified_name<C> (subst_name, subst_ns),
550          typeid (X),
551          &serializer_impl<X>);
552      }
553    }
554  }
555}
Note: See TracBrowser for help on using the browser.