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 _NAMECONTAINER_HXX
29 #define _NAMECONTAINER_HXX
30 
31 #include <cppuhelper/implbase1.hxx>
32 #include <map>
33 
34 #include <com/sun/star/container/XNameContainer.hpp>
35 #include <com/sun/star/container/NoSuchElementException.hpp>
36 #include <com/sun/star/lang/IllegalArgumentException.hpp>
37 #include <com/sun/star/lang/WrappedTargetException.hpp>
38 #include <com/sun/star/uno/Any.hxx>
39 #include <com/sun/star/uno/Reference.hxx>
40 #include <com/sun/star/uno/RuntimeException.hpp>
41 #include <com/sun/star/uno/Type.hxx>
42 
43 typedef cppu::WeakImplHelper1<
44     com::sun::star::container::XNameContainer
45 > NameContainer_t;
46 
47 template<class T>
48 class NameContainer : public NameContainer_t
49 {
50 protected:
51     typedef std::map<rtl::OUString,T> map_t;
52     map_t maItems;
53 
54 
55     bool hasItems()
56     {
57         return ! maItems.empty();
58     }
59 
60     typename map_t::const_iterator findItem( const rtl::OUString& rName )
61     {
62         return maItems.find( rName );
63     }
64 
65     bool hasItem( const rtl::OUString& rName )
66     {
67         return findItem( rName ) != maItems.end();
68     }
69 
70     T getItem( const rtl::OUString& rName )
71     {
72         OSL_ENSURE( hasItem( rName ), "can't get non-existant item" );
73         return maItems[ rName ];
74     }
75 
76 
77     void replace( const rtl::OUString& rName,
78                   const T& aElement )
79     {
80         OSL_ENSURE( hasItem( rName ), "unknown item" );
81         maItems[ rName ] = aElement;
82     }
83 
84     void insert( const rtl::OUString& rName,
85                  const T& aElement )
86     {
87         OSL_ENSURE( ! hasItem( rName ), "item already in set" );
88         maItems[ rName ] = aElement;
89     }
90 
91     void remove( const rtl::OUString& rName )
92     {
93         OSL_ENSURE( hasItem( rName ), "item not in set" );
94         maItems.erase( rName );
95     }
96 
97 
98 public:
99 
100     NameContainer() {}
101     virtual ~NameContainer() {}
102 
103     //
104     // methods for XElementAccess
105     //
106 
107     virtual com::sun::star::uno::Type SAL_CALL getElementType()
108         throw( com::sun::star::uno::RuntimeException )
109     {
110         return getCppuType( static_cast<T*>( NULL ) );
111     }
112 
113     virtual sal_Bool SAL_CALL hasElements()
114         throw( com::sun::star::uno::RuntimeException )
115     {
116         return hasItems();
117     }
118 
119 
120     //
121     // methods for XNameAccess (inherits XElementAccess)
122     //
123 
124     virtual com::sun::star::uno::Any SAL_CALL getByName(
125         const rtl::OUString& rName )
126         throw( com::sun::star::container::NoSuchElementException,
127                com::sun::star::lang::WrappedTargetException,
128                com::sun::star::uno::RuntimeException )
129     {
130         typename map_t::const_iterator aIter = findItem( rName );
131         if( aIter == maItems.end() )
132             throw com::sun::star::container::NoSuchElementException();
133         else
134             return com::sun::star::uno::makeAny( aIter->second );
135     }
136 
137     virtual com::sun::star::uno::Sequence<rtl::OUString> SAL_CALL getElementNames()
138         throw( com::sun::star::uno::RuntimeException )
139     {
140         com::sun::star::uno::Sequence<rtl::OUString> aSequence( maItems.size() );
141         typename map_t::const_iterator aIter = maItems.begin();
142         rtl::OUString* pStrings = aSequence.getArray();
143         while( aIter != maItems.end() )
144         {
145             *pStrings = aIter->first;
146             ++aIter;
147             ++pStrings;
148         }
149         OSL_ENSURE( pStrings == aSequence.getArray() + aSequence.getLength(),
150                     "sequence not of right size; possible buffer overflow" );
151         return aSequence;
152     }
153 
154     virtual sal_Bool SAL_CALL hasByName(
155         const rtl::OUString& rName )
156         throw( com::sun::star::uno::RuntimeException )
157     {
158         return hasItem( rName );
159     }
160 
161 
162     //
163     // methods for XNameReplace (inherits XNameAccess)
164     //
165 
166     virtual void SAL_CALL replaceByName(
167         const rtl::OUString& rName,
168         const com::sun::star::uno::Any& aElement )
169         throw( com::sun::star::lang::IllegalArgumentException,
170                com::sun::star::container::NoSuchElementException,
171                com::sun::star::lang::WrappedTargetException,
172                com::sun::star::uno::RuntimeException)
173     {
174         T aItem;
175         if( aElement >>= aItem )
176             if( hasByName( rName ) )
177                 replace( rName, aItem );
178             else
179                 throw com::sun::star::container::NoSuchElementException();
180         else
181             throw com::sun::star::lang::IllegalArgumentException();
182     }
183 
184 
185     //
186     // methods for XNameContainer (inherits XNameReplace)
187     //
188 
189     virtual void SAL_CALL insertByName(
190         const rtl::OUString& rName,
191         const com::sun::star::uno::Any& aElement )
192         throw( com::sun::star::lang::IllegalArgumentException,
193                com::sun::star::container::ElementExistException,
194                com::sun::star::lang::WrappedTargetException,
195                com::sun::star::uno::RuntimeException )
196     {
197         T aItem;
198         if( aElement >>= aItem )
199             if( ! hasByName( rName ) )
200                 insert( rName, aItem );
201             else
202                 throw com::sun::star::container::ElementExistException();
203         else
204             throw com::sun::star::lang::IllegalArgumentException();
205     }
206 
207     virtual void SAL_CALL removeByName(
208         const rtl::OUString& rName )
209         throw( com::sun::star::container::NoSuchElementException,
210                com::sun::star::lang::WrappedTargetException,
211                com::sun::star::uno::RuntimeException)
212     {
213         if( hasByName( rName ) )
214             remove( rName );
215         else
216             throw com::sun::star::container::NoSuchElementException();
217     }
218 
219 };
220 
221 #endif
222