2 //=============================================================================
6 * This file contains the ID_Map class which has the responsibility of linking
7 * XML IDREF objects to their XML ID counterparts. In the output files, this
8 * means that a <IDREF name>_ptr() will return a pointer to the identified
11 * Exception NULL_PTR_Entry is thrown when a program attempts to add a NULL_PTR
12 * to either the id_map or idref_map.
14 * Exception Unresolved_IDREF is thrown if an element in an XML document attempts
15 * to reference an ID that does not exist.
17 * @author Jason R. Cody <jason.r.cody@vanderbilt.edu; jason.r.cody@gmail.com>
19 //=============================================================================
24 //ID_Map makes use of the Types::idref_ data member to set it to the appropriate
25 //object created during parsing
26 #include "ace/XML_Utils/XMLSchema/Types.hpp"
28 //The ID_Map is a Thread Specific Storage element.
29 #include "ace/TSS_T.h"
30 #include "ace/ace_wchar.h"
35 * @brief A class that handles the mapping of IDREF objects to objects with the
41 //Trait to allow for ease of thread specific storage.
42 typedef ACE_TSS
<ID_Map
> TSS_ID_Map
;
43 typedef std::map
<std::basic_string
<ACE_TCHAR
>, XSCRT::Type
*>::iterator id_iterator
;
44 typedef std::multimap
<std::basic_string
<ACE_TCHAR
>, XSCRT::Type
*>::iterator idref_iterator
;
45 typedef std::map
<std::basic_string
<ACE_TCHAR
>, XSCRT::Type
*> ID_MAP
;
46 typedef std::multimap
<std::basic_string
<ACE_TCHAR
>, XSCRT::Type
*> IDREF_MAP
;
50 //NULL_PTR_Entry thrown when a NULL PTR is added to the
52 class NULL_PTR_Entry
{};
54 //Unresolved_IDREF thrown when there are IDREF's in the
56 class Unresolved_IDREF
{
58 explicit Unresolved_IDREF(const std::basic_string
<ACE_TCHAR
> &message
) : message(message
)
61 std::basic_string
<ACE_TCHAR
> get_message ( void )
66 std::basic_string
<ACE_TCHAR
> message
;
69 //Only a default constructor and destructor are needed
76 // Add an ID to the ID map
77 void add_id (const std::basic_string
<ACE_TCHAR
>& id
, XSCRT::Type
*obj_ref
)
81 this->id_map_
.insert (ID_MAP::value_type(id
, obj_ref
));
85 throw NULL_PTR_Entry();
89 // Add an IDREF to the IDREF map
90 void add_idref (const std::basic_string
<ACE_TCHAR
>& idref
, XSCRT::Type
*obj_ref
)
94 this->idref_map_
.insert (IDREF_MAP::value_type(idref
, obj_ref
));
98 throw NULL_PTR_Entry();
102 void resolve_single_idref (const std::basic_string
<ACE_TCHAR
>& idref
, ::XSCRT::Type
* element
)
104 ID_Map::id_iterator id_iterator
= this->id_map_
.find(idref
);
105 if (id_iterator
!= this->id_map_
.end())
107 element
->set_idref(idref
, id_iterator
->second
);
111 throw Unresolved_IDREF(idref
);
115 //Sets the referencing elements XSCRT::Type::idref_ to point to the
116 //referenced element.
117 //Note: The pointer is of type "XSCRT::Type*"
118 void resolve_idref ()
120 // Declare iterators to navigate the maps
121 for (ID_Map::idref_iterator idref_iterator
= this->idref_map_
.begin();
122 idref_iterator
!= this->idref_map_
.end();
125 //Find the ID that matches the IDREF element
126 ID_Map::id_iterator id_iterator
= this->id_map_
.find(idref_iterator
->first
);
127 if (id_iterator
!= this->id_map_
.end())
129 // Add the IDREF identifier and the reference to the
131 std::basic_string
<ACE_TCHAR
> temp_id
= id_iterator
->first
;
132 idref_iterator
->second
->set_idref(temp_id
, id_iterator
->second
);
136 throw Unresolved_IDREF(idref_iterator
->first
);
148 /// Maps the ID string to the element with the
151 /// Multimap that maps the IDREF string to the
152 /// element with the IDREF attribute
153 IDREF_MAP idref_map_
;
156 #endif /* _ID_MAP_HPP */