xref: /trunk/main/comphelper/inc/comphelper/numberedcollection.hxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 #ifndef _COMPHELPER_NUMBEREDCOLLECTION_HXX_
25 #define _COMPHELPER_NUMBEREDCOLLECTION_HXX_
26 
27 //_______________________________________________
28 // includes
29 
30 #include "comphelper/comphelperdllapi.h"
31 
32 #include <com/sun/star/uno/Reference.hxx>
33 #include <com/sun/star/lang/IllegalArgumentException.hpp>
34 #include <com/sun/star/uno/XInterface.hpp>
35 #include <com/sun/star/frame/XUntitledNumbers.hpp>
36 
37 #include <cppuhelper/basemutex.hxx>
38 #include <cppuhelper/weakref.hxx>
39 #include <cppuhelper/implbase1.hxx>
40 
41 #include <vector>
42 #include <hash_map>
43 
44 //_______________________________________________
45 // namespace
46 
47 namespace comphelper{
48 
49 #ifdef css
50     #error "Ambigious namespace definition of css."
51 #else
52     #define css ::com::sun::star
53 #endif
54 
55 //_______________________________________________
56 // definitions
57 
58 /** @short  defines a collection of UNO components, where every component will get it's own unique number.
59 
60     @descr  Such number will be unique at runtime only ... but it supports fragmentation.
61             Note: This collection uses weak references only to know her components.
62             So lifetime of thise components must be controlled outside.
63 
64     @threadsafe
65  */
66 class COMPHELPER_DLLPUBLIC NumberedCollection : private ::cppu::BaseMutex
67                                               , public  ::cppu::WeakImplHelper1< css::frame::XUntitledNumbers >
68 {
69     //-------------------------------------------
70     // types, const
71     private:
72 
73         struct TNumberedItem
74         {
75             css::uno::WeakReference< css::uno::XInterface > xItem;
76             ::sal_Int32 nNumber;
77         };
78 
79         typedef ::std::hash_map<
80                     long                    ,
81                     TNumberedItem           ,
82                     ::std::hash< long >     ,
83                     ::std::equal_to< long > > TNumberedItemHash;
84 
85         typedef ::std::vector< long > TDeadItemList;
86 
87     //-------------------------------------------
88     // interface
89     public:
90 
91         //---------------------------------------
92         /** @short  lightweight constructor.
93          */
94         NumberedCollection();
95 
96         //---------------------------------------
97         /** @short  free all internally used resources.
98          */
99         virtual ~NumberedCollection();
100 
101         //---------------------------------------
102         /** set an outside component which uses this container and must be set
103             as source of all broadcasted messages, exceptions.
104 
105             It's holded weak only so we do not need any complex dispose sessions.
106 
107             Note: Passing NULL as parameter will be allowed. It will reset the internal
108             member reference only.
109 
110             @param  xOwner
111                     the new owner of this collection.
112          */
113         void setOwner (const css::uno::Reference< css::uno::XInterface >& xOwner);
114 
115         //---------------------------------------
116         /** set the localized prefix to be used for untitled components.
117 
118             Localization has to be done outside. This container will return
119             those value then. There are no further checks. Its up to you to define
120             a suitable string here :-)
121 
122             @param  sPrefix
123                     the new prefix for untitled components.
124          */
125         void setUntitledPrefix(const ::rtl::OUString& sPrefix);
126 
127         //---------------------------------------
128         /** @see css.frame.XUntitledNumbers */
129         virtual ::sal_Int32 SAL_CALL leaseNumber(const css::uno::Reference< css::uno::XInterface >& xComponent);
130 
131         //---------------------------------------
132         /** @see css.frame.XUntitledNumbers */
133         virtual void SAL_CALL releaseNumber(::sal_Int32 nNumber);
134 
135         //---------------------------------------
136         /** @see css.frame.XUntitledNumbers */
137         virtual void SAL_CALL releaseNumberForComponent(const css::uno::Reference< css::uno::XInterface >& xComponent);
138 
139         //---------------------------------------
140         /** @see css.frame.XUntitledNumbers */
141         virtual ::rtl::OUString SAL_CALL getUntitledPrefix();
142 
143     //-------------------------------------------
144     // internal
145     private:
146 
147         //---------------------------------------
148         /** @short  trys to find an unique number not already used within this collection.
149 
150             @descr  It reuses the smalles number which isn't used by any component
151                     of this collection. (fragmentation!) If collection is full (means there
152                     is no free number) the special value INVALID_NUMBER will be returned.
153 
154             @note   Those method can't be called within a multithreaded environment ..
155                     Because such number won't be "reserved" for the calli of these method
156                     it can happen that two calls returns the same number (reasoned by the fact that first calli
157                     doesn't used the returned number already.
158 
159                     So the outside code has to make sure that retrieving and using of those number
160                     will be an atomic operation.
161 
162             @return an unique number or special value INVALID_NUMBER if collection is full.
163          */
164         ::sal_Int32 impl_searchFreeNumber ();
165 
166         void impl_cleanUpDeadItems (      TNumberedItemHash& lItems    ,
167                                     const TDeadItemList&     lDeadItems);
168 
169     //-------------------------------------------
170     // member
171     private:
172 
173         /// localized string to be used for untitled components
174         ::rtl::OUString m_sUntitledPrefix;
175 
176         /// cache of all "leased numbers" and its bound components
177         TNumberedItemHash m_lComponents;
178 
179         /// used as source of broadcasted messages or exceptions (can be null !)
180         css::uno::WeakReference< css::uno::XInterface > m_xOwner;
181 };
182 
183 #undef css
184 
185 } // namespace comphelper
186 
187 #endif // _COMPHELPER_NUMBEREDCOLLECTION_HXX_
188