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