1*dde7d3faSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*dde7d3faSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*dde7d3faSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*dde7d3faSAndrew Rist * distributed with this work for additional information 6*dde7d3faSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*dde7d3faSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*dde7d3faSAndrew Rist * "License"); you may not use this file except in compliance 9*dde7d3faSAndrew Rist * with the License. You may obtain a copy of the License at 10*dde7d3faSAndrew Rist * 11*dde7d3faSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*dde7d3faSAndrew Rist * 13*dde7d3faSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*dde7d3faSAndrew Rist * software distributed under the License is distributed on an 15*dde7d3faSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*dde7d3faSAndrew Rist * KIND, either express or implied. See the License for the 17*dde7d3faSAndrew Rist * specific language governing permissions and limitations 18*dde7d3faSAndrew Rist * under the License. 19*dde7d3faSAndrew Rist * 20*dde7d3faSAndrew Rist *************************************************************/ 21*dde7d3faSAndrew Rist 22*dde7d3faSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_comphelper.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <comphelper/numberedcollection.hxx> 28cdf0e10cSrcweir 29cdf0e10cSrcweir //_______________________________________________ 30cdf0e10cSrcweir // includes 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include <com/sun/star/frame/UntitledNumbersConst.hpp> 33cdf0e10cSrcweir 34cdf0e10cSrcweir //_______________________________________________ 35cdf0e10cSrcweir // namespace 36cdf0e10cSrcweir 37cdf0e10cSrcweir namespace comphelper{ 38cdf0e10cSrcweir 39cdf0e10cSrcweir namespace css = ::com::sun::star; 40cdf0e10cSrcweir 41cdf0e10cSrcweir //_______________________________________________ 42cdf0e10cSrcweir // definitions 43cdf0e10cSrcweir 44cdf0e10cSrcweir static const ::rtl::OUString ERRMSG_INVALID_COMPONENT_PARAM = ::rtl::OUString::createFromAscii("NULL as component reference not allowed."); 45cdf0e10cSrcweir static const ::rtl::OUString ERRMSG_INVALID_NUMBER_PARAM = ::rtl::OUString::createFromAscii("Special valkud INVALID_NUMBER not allowed as input parameter."); 46cdf0e10cSrcweir 47cdf0e10cSrcweir //----------------------------------------------- 48cdf0e10cSrcweir NumberedCollection::NumberedCollection() 49cdf0e10cSrcweir : ::cppu::BaseMutex () 50cdf0e10cSrcweir , m_sUntitledPrefix () 51cdf0e10cSrcweir , m_lComponents () 52cdf0e10cSrcweir , m_xOwner () 53cdf0e10cSrcweir { 54cdf0e10cSrcweir } 55cdf0e10cSrcweir 56cdf0e10cSrcweir //----------------------------------------------- 57cdf0e10cSrcweir NumberedCollection::~NumberedCollection() 58cdf0e10cSrcweir { 59cdf0e10cSrcweir } 60cdf0e10cSrcweir 61cdf0e10cSrcweir //----------------------------------------------- 62cdf0e10cSrcweir void NumberedCollection::setOwner(const css::uno::Reference< css::uno::XInterface >& xOwner) 63cdf0e10cSrcweir { 64cdf0e10cSrcweir // SYNCHRONIZED -> 65cdf0e10cSrcweir ::osl::ResettableMutexGuard aLock(m_aMutex); 66cdf0e10cSrcweir 67cdf0e10cSrcweir m_xOwner = xOwner; 68cdf0e10cSrcweir 69cdf0e10cSrcweir // <- SYNCHRONIZED 70cdf0e10cSrcweir } 71cdf0e10cSrcweir 72cdf0e10cSrcweir //----------------------------------------------- 73cdf0e10cSrcweir void NumberedCollection::setUntitledPrefix(const ::rtl::OUString& sPrefix) 74cdf0e10cSrcweir { 75cdf0e10cSrcweir // SYNCHRONIZED -> 76cdf0e10cSrcweir ::osl::ResettableMutexGuard aLock(m_aMutex); 77cdf0e10cSrcweir 78cdf0e10cSrcweir m_sUntitledPrefix = sPrefix; 79cdf0e10cSrcweir 80cdf0e10cSrcweir // <- SYNCHRONIZED 81cdf0e10cSrcweir } 82cdf0e10cSrcweir 83cdf0e10cSrcweir //----------------------------------------------- 84cdf0e10cSrcweir ::sal_Int32 SAL_CALL NumberedCollection::leaseNumber(const css::uno::Reference< css::uno::XInterface >& xComponent) 85cdf0e10cSrcweir throw (css::lang::IllegalArgumentException, 86cdf0e10cSrcweir css::uno::RuntimeException ) 87cdf0e10cSrcweir { 88cdf0e10cSrcweir // SYNCHRONIZED -> 89cdf0e10cSrcweir ::osl::ResettableMutexGuard aLock(m_aMutex); 90cdf0e10cSrcweir 91cdf0e10cSrcweir if ( ! xComponent.is ()) 92cdf0e10cSrcweir throw css::lang::IllegalArgumentException (ERRMSG_INVALID_COMPONENT_PARAM, m_xOwner.get(), 1); 93cdf0e10cSrcweir 94cdf0e10cSrcweir long pComponent = (long) xComponent.get (); 95cdf0e10cSrcweir TNumberedItemHash::const_iterator pIt = m_lComponents.find (pComponent); 96cdf0e10cSrcweir 97cdf0e10cSrcweir // a) component already exists - return it's number directly 98cdf0e10cSrcweir if (pIt != m_lComponents.end()) 99cdf0e10cSrcweir return pIt->second.nNumber; 100cdf0e10cSrcweir 101cdf0e10cSrcweir // b) component must be added new to this container 102cdf0e10cSrcweir 103cdf0e10cSrcweir // b1) collection is full - no further components possible 104cdf0e10cSrcweir // -> return INVALID_NUMBER 105cdf0e10cSrcweir ::sal_Int32 nFreeNumber = impl_searchFreeNumber(); 106cdf0e10cSrcweir if (nFreeNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER) 107cdf0e10cSrcweir return css::frame::UntitledNumbersConst::INVALID_NUMBER; 108cdf0e10cSrcweir 109cdf0e10cSrcweir // b2) add component to collection and return its number 110cdf0e10cSrcweir TNumberedItem aItem; 111cdf0e10cSrcweir aItem.xItem = css::uno::WeakReference< css::uno::XInterface >(xComponent); 112cdf0e10cSrcweir aItem.nNumber = nFreeNumber; 113cdf0e10cSrcweir m_lComponents[pComponent] = aItem; 114cdf0e10cSrcweir 115cdf0e10cSrcweir return nFreeNumber; 116cdf0e10cSrcweir 117cdf0e10cSrcweir // <- SYNCHRONIZED 118cdf0e10cSrcweir } 119cdf0e10cSrcweir 120cdf0e10cSrcweir //----------------------------------------------- 121cdf0e10cSrcweir void SAL_CALL NumberedCollection::releaseNumber(::sal_Int32 nNumber) 122cdf0e10cSrcweir throw (css::lang::IllegalArgumentException, 123cdf0e10cSrcweir css::uno::RuntimeException ) 124cdf0e10cSrcweir { 125cdf0e10cSrcweir // SYNCHRONIZED -> 126cdf0e10cSrcweir ::osl::ResettableMutexGuard aLock(m_aMutex); 127cdf0e10cSrcweir 128cdf0e10cSrcweir if (nNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER) 129cdf0e10cSrcweir throw css::lang::IllegalArgumentException (ERRMSG_INVALID_NUMBER_PARAM, m_xOwner.get(), 1); 130cdf0e10cSrcweir 131cdf0e10cSrcweir TDeadItemList lDeadItems; 132cdf0e10cSrcweir TNumberedItemHash::iterator pComponent; 133cdf0e10cSrcweir 134cdf0e10cSrcweir for ( pComponent = m_lComponents.begin (); 135cdf0e10cSrcweir pComponent != m_lComponents.end (); 136cdf0e10cSrcweir ++pComponent ) 137cdf0e10cSrcweir { 138cdf0e10cSrcweir const TNumberedItem& rItem = pComponent->second; 139cdf0e10cSrcweir const css::uno::Reference< css::uno::XInterface > xItem = rItem.xItem.get(); 140cdf0e10cSrcweir 141cdf0e10cSrcweir if ( ! xItem.is ()) 142cdf0e10cSrcweir { 143cdf0e10cSrcweir lDeadItems.push_back(pComponent->first); 144cdf0e10cSrcweir continue; 145cdf0e10cSrcweir } 146cdf0e10cSrcweir 147cdf0e10cSrcweir if (rItem.nNumber == nNumber) 148cdf0e10cSrcweir { 149cdf0e10cSrcweir m_lComponents.erase (pComponent); 150cdf0e10cSrcweir break; 151cdf0e10cSrcweir } 152cdf0e10cSrcweir } 153cdf0e10cSrcweir 154cdf0e10cSrcweir impl_cleanUpDeadItems(m_lComponents, lDeadItems); 155cdf0e10cSrcweir 156cdf0e10cSrcweir // <- SYNCHRONIZED 157cdf0e10cSrcweir } 158cdf0e10cSrcweir 159cdf0e10cSrcweir //----------------------------------------------- 160cdf0e10cSrcweir void SAL_CALL NumberedCollection::releaseNumberForComponent(const css::uno::Reference< css::uno::XInterface >& xComponent) 161cdf0e10cSrcweir throw (css::lang::IllegalArgumentException, 162cdf0e10cSrcweir css::uno::RuntimeException ) 163cdf0e10cSrcweir { 164cdf0e10cSrcweir // SYNCHRONIZED -> 165cdf0e10cSrcweir ::osl::ResettableMutexGuard aLock(m_aMutex); 166cdf0e10cSrcweir 167cdf0e10cSrcweir if ( ! xComponent.is ()) 168cdf0e10cSrcweir throw css::lang::IllegalArgumentException (ERRMSG_INVALID_COMPONENT_PARAM, m_xOwner.get(), 1); 169cdf0e10cSrcweir 170cdf0e10cSrcweir long pComponent = (long) xComponent.get (); 171cdf0e10cSrcweir TNumberedItemHash::iterator pIt = m_lComponents.find (pComponent); 172cdf0e10cSrcweir 173cdf0e10cSrcweir // a) component exists and will be removed 174cdf0e10cSrcweir if (pIt != m_lComponents.end()) 175cdf0e10cSrcweir m_lComponents.erase(pIt); 176cdf0e10cSrcweir 177cdf0e10cSrcweir // else 178cdf0e10cSrcweir // b) component does not exists - nothing todo here (ignore request!) 179cdf0e10cSrcweir 180cdf0e10cSrcweir // <- SYNCHRONIZED 181cdf0e10cSrcweir } 182cdf0e10cSrcweir 183cdf0e10cSrcweir //----------------------------------------------- 184cdf0e10cSrcweir ::rtl::OUString SAL_CALL NumberedCollection::getUntitledPrefix() 185cdf0e10cSrcweir throw (css::uno::RuntimeException) 186cdf0e10cSrcweir { 187cdf0e10cSrcweir // SYNCHRONIZED -> 188cdf0e10cSrcweir ::osl::ResettableMutexGuard aLock(m_aMutex); 189cdf0e10cSrcweir 190cdf0e10cSrcweir return m_sUntitledPrefix; 191cdf0e10cSrcweir 192cdf0e10cSrcweir // <- SYNCHRONIZED 193cdf0e10cSrcweir } 194cdf0e10cSrcweir 195cdf0e10cSrcweir //----------------------------------------------- 196cdf0e10cSrcweir /** create an ordered list of all possible numbers ... 197cdf0e10cSrcweir e.g. {1,2,3,...,N} Max size of these list will be 198cdf0e10cSrcweir current size of component list + 1 . 199cdf0e10cSrcweir 200cdf0e10cSrcweir "+1" ... because in case all numbers in range 1..n 201cdf0e10cSrcweir are in use we need a new number n+1 :-) 202cdf0e10cSrcweir 203cdf0e10cSrcweir Every item which is already used as unique number 204cdf0e10cSrcweir will be removed. At the end a list of e.g. {3,6,...,M} 205cdf0e10cSrcweir exists where the first item represent the lowest free 206cdf0e10cSrcweir number (in this example 3). 207cdf0e10cSrcweir */ 208cdf0e10cSrcweir ::sal_Int32 NumberedCollection::impl_searchFreeNumber () 209cdf0e10cSrcweir { 210cdf0e10cSrcweir // create ordered list of all possible numbers. 211cdf0e10cSrcweir ::std::vector< ::sal_Int32 > lPossibleNumbers; 212cdf0e10cSrcweir ::sal_Int32 c = (::sal_Int32)m_lComponents.size (); 213cdf0e10cSrcweir ::sal_Int32 i = 1; 214cdf0e10cSrcweir 215cdf0e10cSrcweir // c cant be less then 0 ... otherwhise hash.size() has an error :-) 216cdf0e10cSrcweir // But we need at least n+1 numbers here. 217cdf0e10cSrcweir c += 1; 218cdf0e10cSrcweir 219cdf0e10cSrcweir for (i=1; i<=c; ++i) 220cdf0e10cSrcweir lPossibleNumbers.push_back (i); 221cdf0e10cSrcweir 222cdf0e10cSrcweir // SYNCHRONIZED -> 223cdf0e10cSrcweir ::osl::ResettableMutexGuard aLock(m_aMutex); 224cdf0e10cSrcweir 225cdf0e10cSrcweir TDeadItemList lDeadItems; 226cdf0e10cSrcweir TNumberedItemHash::const_iterator pComponent; 227cdf0e10cSrcweir 228cdf0e10cSrcweir for ( pComponent = m_lComponents.begin (); 229cdf0e10cSrcweir pComponent != m_lComponents.end (); 230cdf0e10cSrcweir ++pComponent ) 231cdf0e10cSrcweir { 232cdf0e10cSrcweir const TNumberedItem& rItem = pComponent->second; 233cdf0e10cSrcweir const css::uno::Reference< css::uno::XInterface > xItem = rItem.xItem.get(); 234cdf0e10cSrcweir 235cdf0e10cSrcweir if ( ! xItem.is ()) 236cdf0e10cSrcweir { 237cdf0e10cSrcweir lDeadItems.push_back(pComponent->first); 238cdf0e10cSrcweir continue; 239cdf0e10cSrcweir } 240cdf0e10cSrcweir 241cdf0e10cSrcweir ::std::vector< ::sal_Int32 >::iterator pPossible = ::std::find(lPossibleNumbers.begin (), lPossibleNumbers.end (), rItem.nNumber); 242cdf0e10cSrcweir if (pPossible != lPossibleNumbers.end ()) 243cdf0e10cSrcweir lPossibleNumbers.erase (pPossible); 244cdf0e10cSrcweir } 245cdf0e10cSrcweir 246cdf0e10cSrcweir impl_cleanUpDeadItems(m_lComponents, lDeadItems); 247cdf0e10cSrcweir 248cdf0e10cSrcweir // a) non free numbers ... return INVALID_NUMBER 249cdf0e10cSrcweir if (lPossibleNumbers.size () < 1) 250cdf0e10cSrcweir return css::frame::UntitledNumbersConst::INVALID_NUMBER; 251cdf0e10cSrcweir 252cdf0e10cSrcweir // b) return first free number 253cdf0e10cSrcweir return *(lPossibleNumbers.begin ()); 254cdf0e10cSrcweir 255cdf0e10cSrcweir // <- SYNCHRONIZED 256cdf0e10cSrcweir } 257cdf0e10cSrcweir 258cdf0e10cSrcweir void NumberedCollection::impl_cleanUpDeadItems ( TNumberedItemHash& lItems , 259cdf0e10cSrcweir const TDeadItemList& lDeadItems) 260cdf0e10cSrcweir { 261cdf0e10cSrcweir TDeadItemList::const_iterator pIt; 262cdf0e10cSrcweir 263cdf0e10cSrcweir for ( pIt = lDeadItems.begin (); 264cdf0e10cSrcweir pIt != lDeadItems.end (); 265cdf0e10cSrcweir ++pIt ) 266cdf0e10cSrcweir { 267cdf0e10cSrcweir const long& rDeadItem = *pIt; 268cdf0e10cSrcweir lItems.erase(rDeadItem); 269cdf0e10cSrcweir } 270cdf0e10cSrcweir } 271cdf0e10cSrcweir 272cdf0e10cSrcweir } // namespace comphelper 273