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 refrences 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 internaly 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             throw (css::lang::IllegalArgumentException,
131                    css::uno::RuntimeException         );
132 
133         //---------------------------------------
134         /** @see css.frame.XUntitledNumbers */
135         virtual void SAL_CALL releaseNumber(::sal_Int32 nNumber)
136             throw (css::lang::IllegalArgumentException,
137                    css::uno::RuntimeException         );
138 
139         //---------------------------------------
140         /** @see css.frame.XUntitledNumbers */
141         virtual void SAL_CALL releaseNumberForComponent(const css::uno::Reference< css::uno::XInterface >& xComponent)
142             throw (css::lang::IllegalArgumentException,
143                    css::uno::RuntimeException         );
144 
145         //---------------------------------------
146         /** @see css.frame.XUntitledNumbers */
147         virtual ::rtl::OUString SAL_CALL getUntitledPrefix()
148             throw (css::uno::RuntimeException);
149 
150     //-------------------------------------------
151     // internal
152     private:
153 
154         //---------------------------------------
155         /** @short  trys to find an unique number not already used within this collection.
156 
157             @descr  It reuses the smalles number which isnt used by any component
158                     of this collection. (fragmentation!) If collection is full (means there
159                     is no free number) the special value INVALID_NUMBER will be returned.
160 
161             @note   Those method cant be called within a multithreaded environment ..
162                     Because such number wont be "reserved" for the calli of these method
163                     it can happen that two calls returns the same number (reasoned by the fact that first calli
164                     doesnt used the returned number already.
165 
166                     So the outside code has to make sure that retrieving and using of those number
167                     will be an atomic operation.
168 
169             @return an unique number or special value INVALID_NUMBER if collection is full.
170          */
171         ::sal_Int32 impl_searchFreeNumber ();
172 
173         void impl_cleanUpDeadItems (      TNumberedItemHash& lItems    ,
174                                     const TDeadItemList&     lDeadItems);
175 
176     //-------------------------------------------
177     // member
178     private:
179 
180         /// localized string to be used for untitled components
181         ::rtl::OUString m_sUntitledPrefix;
182 
183         /// cache of all "leased numbers" and its bound components
184         TNumberedItemHash m_lComponents;
185 
186         /// used as source of broadcasted messages or exceptions (can be null !)
187         css::uno::WeakReference< css::uno::XInterface > m_xOwner;
188 };
189 
190 #undef css
191 
192 } // namespace comphelper
193 
194 #endif // _COMPHELPER_NUMBEREDCOLLECTION_HXX_
195