xref: /trunk/main/xmloff/source/core/unointerfacetouniqueidentifiermapper.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_xmloff.hxx"
31 #include "unointerfacetouniqueidentifiermapper.hxx"
32 
33 using ::com::sun::star::uno::Reference;
34 using ::com::sun::star::uno::XInterface;
35 using ::rtl::OUString;
36 
37 namespace comphelper
38 {
39 
40 UnoInterfaceToUniqueIdentifierMapper::UnoInterfaceToUniqueIdentifierMapper()
41 : mnNextId( 1 )
42 {
43 }
44 
45 /** returns a unique identifier for the given uno object. IF a uno object is
46     registered more than once, the returned identifier is always the same.
47 */
48 const OUString& UnoInterfaceToUniqueIdentifierMapper::registerReference( const Reference< XInterface >& rInterface )
49 {
50     IdMap_t::const_iterator aIter;
51     if( findReference( rInterface, aIter ) )
52     {
53         return (*aIter).first;
54     }
55     else
56     {
57         OUString aId( RTL_CONSTASCII_USTRINGPARAM( "id" ) );
58         aId += OUString::valueOf( mnNextId++ );
59         return (*maEntries.insert( IdMap_t::value_type( aId, rInterface ) ).first).first;
60     }
61 }
62 
63 /** registers the given uno object with the given identifier.
64 
65     @returns
66         false, if the given identifier already exists and is not associated with the given interface
67 */
68 bool UnoInterfaceToUniqueIdentifierMapper::registerReference( const OUString& rIdentifier, const Reference< XInterface >& rInterface )
69 {
70     IdMap_t::const_iterator aIter;
71     if( findReference( rInterface, aIter ) )
72     {
73         return rIdentifier != (*aIter).first;
74     }
75     else if( findIdentifier( rIdentifier, aIter ) )
76     {
77         return false;
78     }
79     else
80     {
81         maEntries.insert( IdMap_t::value_type( rIdentifier, rInterface ) );
82 
83         // see if this is a reference like something we would generate in the future
84         const sal_Unicode *p = rIdentifier.getStr();
85         sal_Int32 nLength = rIdentifier.getLength();
86 
87         // see if the identifier is 'id' followed by a pure integer value
88         if( nLength < 2 || p[0] != 'i' || p[1] != 'd' )
89             return true;
90 
91         nLength -= 2;
92         p += 2;
93 
94         while(nLength--)
95         {
96             if( (*p < '0') || (*p > '9') )
97                 return true; // a custom id, that will never conflict with genereated id's
98 
99             p++;
100         }
101 
102         // the identifier is a pure integer value
103         // so we make sure we will never generate
104         // an integer value like this one
105         sal_Int32 nId = rIdentifier.copy(2).toInt32();
106         if( mnNextId <= nId )
107             mnNextId = nId + 1;
108 
109         return true;
110     }
111 }
112 
113 /** @returns
114         the identifier for the given uno object. If this uno object is not already
115         registered, an empty string is returned
116 */
117 const OUString& UnoInterfaceToUniqueIdentifierMapper::getIdentifier( const Reference< XInterface >& rInterface ) const
118 {
119     IdMap_t::const_iterator aIter;
120     if( findReference( rInterface, aIter ) )
121     {
122         return (*aIter).first;
123     }
124     else
125     {
126         static const OUString aEmpty;
127         return aEmpty;
128     }
129 }
130 
131 /** @returns
132     the uno object that is registered with the given identifier. If no uno object
133     is registered with the given identifier, an empty reference is returned.
134 */
135 const Reference< XInterface >& UnoInterfaceToUniqueIdentifierMapper::getReference( const OUString& rIdentifier ) const
136 {
137     IdMap_t::const_iterator aIter;
138     if( findIdentifier( rIdentifier, aIter ) )
139     {
140         return (*aIter).second;
141     }
142     else
143     {
144         static const Reference< XInterface > aEmpty;
145         return aEmpty;
146     }
147 }
148 
149 bool UnoInterfaceToUniqueIdentifierMapper::findReference( const Reference< XInterface >& rInterface, IdMap_t::const_iterator& rIter ) const
150 {
151     rIter = maEntries.begin();
152     const IdMap_t::const_iterator aEnd( maEntries.end() );
153     while( rIter != aEnd )
154     {
155         if( (*rIter).second == rInterface )
156             return true;
157 
158         rIter++;
159     }
160 
161     return false;
162 }
163 
164 bool UnoInterfaceToUniqueIdentifierMapper::findIdentifier( const OUString& rIdentifier, IdMap_t::const_iterator& rIter ) const
165 {
166     rIter = maEntries.find( rIdentifier );
167     return rIter != maEntries.end();
168 }
169 
170 }
171 
172