xref: /AOO41X/main/xmloff/source/core/unointerfacetouniqueidentifiermapper.cxx (revision 63bba73cc51e0afb45f8a8d578158724bb5afee8)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 
25 // MARKER(update_precomp.py): autogen include statement, do not remove
26 #include "precompiled_xmloff.hxx"
27 #include "unointerfacetouniqueidentifiermapper.hxx"
28 
29 using ::com::sun::star::uno::Reference;
30 using ::com::sun::star::uno::XInterface;
31 using ::rtl::OUString;
32 
33 namespace comphelper
34 {
35 
UnoInterfaceToUniqueIdentifierMapper()36 UnoInterfaceToUniqueIdentifierMapper::UnoInterfaceToUniqueIdentifierMapper()
37 : mnNextId( 1 )
38 {
39 }
40 
41 /** returns a unique identifier for the given uno object. IF a uno object is
42     registered more than once, the returned identifier is always the same.
43 */
registerReference(const Reference<XInterface> & rInterface)44 const OUString& UnoInterfaceToUniqueIdentifierMapper::registerReference( const Reference< XInterface >& rInterface )
45 {
46     IdMap_t::const_iterator aIter;
47     if( findReference( rInterface, aIter ) )
48     {
49         return (*aIter).first;
50     }
51     else
52     {
53         OUString aId( RTL_CONSTASCII_USTRINGPARAM( "id" ) );
54         aId += OUString::valueOf( mnNextId++ );
55         return (*maEntries.insert( IdMap_t::value_type( aId, rInterface ) ).first).first;
56     }
57 }
58 
59 /** registers the given uno object with the given identifier.
60 
61     @returns
62         false, if the given identifier already exists and is not associated with the given interface
63 */
registerReference(const OUString & rIdentifier,const Reference<XInterface> & rInterface)64 bool UnoInterfaceToUniqueIdentifierMapper::registerReference( const OUString& rIdentifier, const Reference< XInterface >& rInterface )
65 {
66     IdMap_t::const_iterator aIter;
67     if( findReference( rInterface, aIter ) )
68     {
69         return rIdentifier != (*aIter).first;
70     }
71     else if( findIdentifier( rIdentifier, aIter ) )
72     {
73         return false;
74     }
75     else
76     {
77         maEntries.insert( IdMap_t::value_type( rIdentifier, rInterface ) );
78 
79         // see if this is a reference like something we would generate in the future
80         const sal_Unicode *p = rIdentifier.getStr();
81         sal_Int32 nLength = rIdentifier.getLength();
82 
83         // see if the identifier is 'id' followed by a pure integer value
84         if( nLength < 2 || p[0] != 'i' || p[1] != 'd' )
85             return true;
86 
87         nLength -= 2;
88         p += 2;
89 
90         while(nLength--)
91         {
92             if( (*p < '0') || (*p > '9') )
93                 return true; // a custom id, that will never conflict with genereated id's
94 
95             p++;
96         }
97 
98         // the identifier is a pure integer value
99         // so we make sure we will never generate
100         // an integer value like this one
101         sal_Int32 nId = rIdentifier.copy(2).toInt32();
102         if( mnNextId <= nId )
103             mnNextId = nId + 1;
104 
105         return true;
106     }
107 }
108 
109 /** @returns
110         the identifier for the given uno object. If this uno object is not already
111         registered, an empty string is returned
112 */
getIdentifier(const Reference<XInterface> & rInterface) const113 const OUString& UnoInterfaceToUniqueIdentifierMapper::getIdentifier( const Reference< XInterface >& rInterface ) const
114 {
115     IdMap_t::const_iterator aIter;
116     if( findReference( rInterface, aIter ) )
117     {
118         return (*aIter).first;
119     }
120     else
121     {
122         static const OUString aEmpty;
123         return aEmpty;
124     }
125 }
126 
127 /** @returns
128     the uno object that is registered with the given identifier. If no uno object
129     is registered with the given identifier, an empty reference is returned.
130 */
getReference(const OUString & rIdentifier) const131 const Reference< XInterface >& UnoInterfaceToUniqueIdentifierMapper::getReference( const OUString& rIdentifier ) const
132 {
133     IdMap_t::const_iterator aIter;
134     if( findIdentifier( rIdentifier, aIter ) )
135     {
136         return (*aIter).second;
137     }
138     else
139     {
140         static const Reference< XInterface > aEmpty;
141         return aEmpty;
142     }
143 }
144 
findReference(const Reference<XInterface> & rInterface,IdMap_t::const_iterator & rIter) const145 bool UnoInterfaceToUniqueIdentifierMapper::findReference( const Reference< XInterface >& rInterface, IdMap_t::const_iterator& rIter ) const
146 {
147     rIter = maEntries.begin();
148     const IdMap_t::const_iterator aEnd( maEntries.end() );
149     while( rIter != aEnd )
150     {
151         if( (*rIter).second == rInterface )
152             return true;
153 
154         rIter++;
155     }
156 
157     return false;
158 }
159 
findIdentifier(const OUString & rIdentifier,IdMap_t::const_iterator & rIter) const160 bool UnoInterfaceToUniqueIdentifierMapper::findIdentifier( const OUString& rIdentifier, IdMap_t::const_iterator& rIter ) const
161 {
162     rIter = maEntries.find( rIdentifier );
163     return rIter != maEntries.end();
164 }
165 
166 }
167 
168