1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
31 #include <comphelper/numberedcollection.hxx>
33 //_______________________________________________
36 #include <com/sun/star/frame/UntitledNumbersConst.hpp>
38 //_______________________________________________
43 namespace css
= ::com::sun::star
;
45 //_______________________________________________
48 static const ::rtl::OUString ERRMSG_INVALID_COMPONENT_PARAM
= ::rtl::OUString::createFromAscii("NULL as component reference not allowed.");
49 static const ::rtl::OUString ERRMSG_INVALID_NUMBER_PARAM
= ::rtl::OUString::createFromAscii("Special valkud INVALID_NUMBER not allowed as input parameter.");
51 //-----------------------------------------------
52 NumberedCollection::NumberedCollection()
53 : ::cppu::BaseMutex ()
54 , m_sUntitledPrefix ()
60 //-----------------------------------------------
61 NumberedCollection::~NumberedCollection()
65 //-----------------------------------------------
66 void NumberedCollection::setOwner(const css::uno::Reference
< css::uno::XInterface
>& xOwner
)
69 ::osl::ResettableMutexGuard
aLock(m_aMutex
);
76 //-----------------------------------------------
77 void NumberedCollection::setUntitledPrefix(const ::rtl::OUString
& sPrefix
)
80 ::osl::ResettableMutexGuard
aLock(m_aMutex
);
82 m_sUntitledPrefix
= sPrefix
;
87 //-----------------------------------------------
88 ::sal_Int32 SAL_CALL
NumberedCollection::leaseNumber(const css::uno::Reference
< css::uno::XInterface
>& xComponent
)
89 throw (css::lang::IllegalArgumentException
,
90 css::uno::RuntimeException
)
93 ::osl::ResettableMutexGuard
aLock(m_aMutex
);
95 if ( ! xComponent
.is ())
96 throw css::lang::IllegalArgumentException (ERRMSG_INVALID_COMPONENT_PARAM
, m_xOwner
.get(), 1);
98 long pComponent
= (long) xComponent
.get ();
99 TNumberedItemHash::const_iterator pIt
= m_lComponents
.find (pComponent
);
101 // a) component already exists - return it's number directly
102 if (pIt
!= m_lComponents
.end())
103 return pIt
->second
.nNumber
;
105 // b) component must be added new to this container
107 // b1) collection is full - no further components possible
108 // -> return INVALID_NUMBER
109 ::sal_Int32 nFreeNumber
= impl_searchFreeNumber();
110 if (nFreeNumber
== css::frame::UntitledNumbersConst::INVALID_NUMBER
)
111 return css::frame::UntitledNumbersConst::INVALID_NUMBER
;
113 // b2) add component to collection and return its number
115 aItem
.xItem
= css::uno::WeakReference
< css::uno::XInterface
>(xComponent
);
116 aItem
.nNumber
= nFreeNumber
;
117 m_lComponents
[pComponent
] = aItem
;
124 //-----------------------------------------------
125 void SAL_CALL
NumberedCollection::releaseNumber(::sal_Int32 nNumber
)
126 throw (css::lang::IllegalArgumentException
,
127 css::uno::RuntimeException
)
130 ::osl::ResettableMutexGuard
aLock(m_aMutex
);
132 if (nNumber
== css::frame::UntitledNumbersConst::INVALID_NUMBER
)
133 throw css::lang::IllegalArgumentException (ERRMSG_INVALID_NUMBER_PARAM
, m_xOwner
.get(), 1);
135 TDeadItemList lDeadItems
;
136 TNumberedItemHash::iterator pComponent
;
138 for ( pComponent
= m_lComponents
.begin ();
139 pComponent
!= m_lComponents
.end ();
142 const TNumberedItem
& rItem
= pComponent
->second
;
143 const css::uno::Reference
< css::uno::XInterface
> xItem
= rItem
.xItem
.get();
147 lDeadItems
.push_back(pComponent
->first
);
151 if (rItem
.nNumber
== nNumber
)
153 m_lComponents
.erase (pComponent
);
158 impl_cleanUpDeadItems(m_lComponents
, lDeadItems
);
163 //-----------------------------------------------
164 void SAL_CALL
NumberedCollection::releaseNumberForComponent(const css::uno::Reference
< css::uno::XInterface
>& xComponent
)
165 throw (css::lang::IllegalArgumentException
,
166 css::uno::RuntimeException
)
169 ::osl::ResettableMutexGuard
aLock(m_aMutex
);
171 if ( ! xComponent
.is ())
172 throw css::lang::IllegalArgumentException (ERRMSG_INVALID_COMPONENT_PARAM
, m_xOwner
.get(), 1);
174 long pComponent
= (long) xComponent
.get ();
175 TNumberedItemHash::iterator pIt
= m_lComponents
.find (pComponent
);
177 // a) component exists and will be removed
178 if (pIt
!= m_lComponents
.end())
179 m_lComponents
.erase(pIt
);
182 // b) component does not exists - nothing todo here (ignore request!)
187 //-----------------------------------------------
188 ::rtl::OUString SAL_CALL
NumberedCollection::getUntitledPrefix()
189 throw (css::uno::RuntimeException
)
192 ::osl::ResettableMutexGuard
aLock(m_aMutex
);
194 return m_sUntitledPrefix
;
199 //-----------------------------------------------
200 /** create an ordered list of all possible numbers ...
201 e.g. {1,2,3,...,N} Max size of these list will be
202 current size of component list + 1 .
204 "+1" ... because in case all numbers in range 1..n
205 are in use we need a new number n+1 :-)
207 Every item which is already used as unique number
208 will be removed. At the end a list of e.g. {3,6,...,M}
209 exists where the first item represent the lowest free
210 number (in this example 3).
212 ::sal_Int32
NumberedCollection::impl_searchFreeNumber ()
214 // create ordered list of all possible numbers.
215 ::std::vector
< ::sal_Int32
> lPossibleNumbers
;
216 ::sal_Int32 c
= (::sal_Int32
)m_lComponents
.size ();
219 // c cant be less then 0 ... otherwhise hash.size() has an error :-)
220 // But we need at least n+1 numbers here.
224 lPossibleNumbers
.push_back (i
);
227 ::osl::ResettableMutexGuard
aLock(m_aMutex
);
229 TDeadItemList lDeadItems
;
230 TNumberedItemHash::const_iterator pComponent
;
232 for ( pComponent
= m_lComponents
.begin ();
233 pComponent
!= m_lComponents
.end ();
236 const TNumberedItem
& rItem
= pComponent
->second
;
237 const css::uno::Reference
< css::uno::XInterface
> xItem
= rItem
.xItem
.get();
241 lDeadItems
.push_back(pComponent
->first
);
245 ::std::vector
< ::sal_Int32
>::iterator pPossible
= ::std::find(lPossibleNumbers
.begin (), lPossibleNumbers
.end (), rItem
.nNumber
);
246 if (pPossible
!= lPossibleNumbers
.end ())
247 lPossibleNumbers
.erase (pPossible
);
250 impl_cleanUpDeadItems(m_lComponents
, lDeadItems
);
252 // a) non free numbers ... return INVALID_NUMBER
253 if (lPossibleNumbers
.size () < 1)
254 return css::frame::UntitledNumbersConst::INVALID_NUMBER
;
256 // b) return first free number
257 return *(lPossibleNumbers
.begin ());
262 void NumberedCollection::impl_cleanUpDeadItems ( TNumberedItemHash
& lItems
,
263 const TDeadItemList
& lDeadItems
)
265 TDeadItemList::const_iterator pIt
;
267 for ( pIt
= lDeadItems
.begin ();
268 pIt
!= lDeadItems
.end ();
271 const long& rDeadItem
= *pIt
;
272 lItems
.erase(rDeadItem
);
276 } // namespace comphelper