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 #ifndef __FILTER_CONFIG_BASECONTAINER_HXX_
24 #define __FILTER_CONFIG_BASECONTAINER_HXX_
25 
26 //_______________________________________________
27 // includes
28 
29 #include "filtercache.hxx"
30 #include <com/sun/star/uno/Exception.hpp>
31 #include <com/sun/star/lang/XServiceInfo.hpp>
32 #include <com/sun/star/util/XRefreshable.hpp>
33 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <com/sun/star/container/XNameContainer.hpp>
35 #include <com/sun/star/container/XContainerQuery.hpp>
36 #include <com/sun/star/util/XFlushable.hpp>
37 #include <cppuhelper/interfacecontainer.h>
38 #include <salhelper/singletonref.hxx>
39 #include <cppuhelper/implbase4.hxx>
40 #include <cppuhelper/weakref.hxx>
41 #include <rtl/ustring.hxx>
42 
43 //_______________________________________________
44 // namespace
45 
46 namespace filter{
47     namespace config{
48 
49 //_______________________________________________
50 // definitions
51 
52 //_______________________________________________
53 
54 /** @short      implements the interface css::container::XNameContainer
55                 on top of a FilterCache reference.
56 
57     @descr      This class can be used as base for own service implementations,
58                 which must provide read/write access to the filter configuration.
59                 Parameters regulate read/write access, which sub set of informations
60                 should be available etc.
61 
62     @attention  The base class BaseLock must be the first of declared ones.
63                 Otherwise we can't be sure, that our own mutex member (which is
64                 present by this base class!) was full initialized inside our own
65                 ctor as first!
66  */
67 class BaseContainer : public BaseLock
68                     , public ::cppu::WeakImplHelper4< css::lang::XServiceInfo         ,
69                                                       css::container::XNameContainer  , // => XNameReplace => XNameAccess => XElementAccess
70                                                       css::container::XContainerQuery ,
71                                                       css::util::XFlushable           >
72 {
73     //-------------------------------------------
74     // member
75 
76     protected:
77 
78         /** @short  reference to an uno service manager, which can be used
79                     to create own needed services. */
80         css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
81 
82         // TODO
83         css::uno::WeakReference< css::util::XRefreshable > m_xRefreshBroadcaster;
84 
85         /** @short  the implementation name of our derived class, which we provide
86                     at the interface XServiceInfo of our class ... */
87         ::rtl::OUString m_sImplementationName;
88 
89         /** @short  the list of supported uno service names of our derived class, which we provide
90                     at the interface XServiceInfo of our class ... */
91         css::uno::Sequence< ::rtl::OUString > m_lServiceNames;
92 
93         /** @short  reference(!) to a singleton filter cache implementation,
94                     which is used to work with the underlying configuration. */
95         ::salhelper::SingletonRef< FilterCache > m_rCache;
96 
97         /** @short  local filter cache, which is used to collect changes on the
98                     filter configuration first and flush it later.
99 
100             @descr  Normally this member isn't used nor initialized. That's true,
101                     if this container is used for reading only. The first write access
102                     (e.g. by calling insertByName()) creates a copy of the current
103                     global cache m_rCache to initialize the m_pFlushCache member.
104 
105                     Afterwards only the flush cache copy is used. Inside flush() this
106                     copy will be removed and m_rCache can be used again.
107 
108                     m_pFlushCache and m_rCache must not be synchronized manually here.
109                     m_rCache listen on the global configuration, where m_pFlushCache
110                     write its data. m_rCache update itself automatically.
111          */
112         FilterCache* m_pFlushCache;
113 
114         /** @short  specify, which sub container of the used filter cache
115                     must be wrapped by this container interface. */
116         FilterCache::EItemType m_eType;
117 
118         /** @short  holds all listener, which are registered at this instance. */
119         ::cppu::OMultiTypeInterfaceContainerHelper m_lListener;
120 
121         /** @short  hold at least on filter cache instance alive and
122                     prevent he office from unloading this cache if no filter
123                     is currently used.*/
124         static ::salhelper::SingletonRef< FilterCache >* m_pPerformanceOptimizer;
125 
126     //-------------------------------------------
127     // native interface
128 
129     public:
130 
131         //---------------------------------------
132         // ctor/dtor
133 
134         /** @short  standard ctor.
135 
136             @descr  Because mostly this class is used as base class for own service
137                     implementations in combination with a ImplInheritanceHelper2 template ...
138                     there is no way to provide some initializing data through the ctor :-(
139                     This base class will be created inside its default ctor and must be
140                     initialized with its needed parameters explicitly by calling: "init()".
141 
142             @see    init()
143          */
144         BaseContainer();
145 
146         //---------------------------------------
147 
148         /** @short  standard dtor.
149          */
150         virtual ~BaseContainer();
151 
152         //---------------------------------------
153 
154         /** @short  initialize this generic intsnace with some specialized values
155                     from our derived object.
156 
157             @descr  Because an outside class must use ImplInheritanceHelper2 template to
158                     use us a base class ... and there is no way to pass such initializing
159                     parameters trough a required default ctor ... we must be initialized
160                     by this special method. Of course this method must be called first before
161                     any other interface method is used.
162 
163             @param  xSMGR
164                     reference to the uno service manager, which created this service instance.
165 
166             @param  sImplementationName
167                     the implementation name of our derived class, which we provide
168                     at the interface XServiceInfo of our class ...
169 
170             @param  lServiceNames
171                     the list of supported uno service names of our derived class, which we provide
172                     at the interface XServiceInfo of our class ...
173 
174             @param  eType
175                     specify, which sub container of the used filter cache
176                     must be wrapped by this container interface.
177          */
178         virtual void init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR              ,
179                           const ::rtl::OUString&                                        sImplementationName,
180                           const css::uno::Sequence< ::rtl::OUString >&                  lServiceNames      ,
181                                 FilterCache::EItemType                                  eType              );
182 
183     //-------------------------------------------
184     // helper
185 
186     protected:
187 
188         //---------------------------------------
189 
190         /** @short  check if the underlying configuration data was already loaded
191                     and do it if necessary automatically.
192          */
193         void impl_loadOnDemand();
194 
195         //---------------------------------------
196 
197         /** @short  it creates the global instance m_pFilterCache, which is a copy
198                     of the global instance m_rCache, and will be used to change the
199                     configuration.
200 
201             @descr  If no exception occurs, its guaranteed, that the member m_rFlushCache
202                     was initialized right and can be used further.
203          */
204         void impl_initFlushMode()
205             throw (css::uno::RuntimeException);
206 
207         //---------------------------------------
208 
209         /** @short  returns a pointer to the current used cache member.
210 
211             @descr  Its a point to the FilterCache instance behind m_pFlushCache
212                     or m_rCache.
213 
214             @note   The lifetime of this pointer is restricted to the time, where
215                     the mutex of this BaseContainer instance is locked.
216                     Otherwise maybe the interface method flush() will destroy
217                     m_pFlushCache and the here returned pointer will be invalid!
218 
219                     Use:
220 
221                         Guard aLock(m_aLock);
222                             FilterCache* p = impl_getWorkingCache();
223                             p->doSomething();
224                         aLock.clear();
225                         // after this point p can't b e guaranteed any longer!
226          */
227         FilterCache* impl_getWorkingCache() const;
228 
229     //-------------------------------------------
230     // uno interface
231 
232     public:
233 
234         //---------------------------------------
235         // XServiceInfo
236 
237         virtual ::rtl::OUString SAL_CALL getImplementationName()
238             throw (css::uno::RuntimeException);
239 
240         virtual sal_Bool SAL_CALL supportsService(const ::rtl::OUString& sServiceName)
241             throw (css::uno::RuntimeException);
242 
243         virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
244             throw (css::uno::RuntimeException);
245 
246         //---------------------------------------
247         // XNameContainer
248 
249         virtual void SAL_CALL insertByName(const ::rtl::OUString& sItem ,
250                                            const css::uno::Any&   aValue)
251             throw (css::lang::IllegalArgumentException  ,
252                    css::container::ElementExistException,
253                    css::lang::WrappedTargetException    ,
254                    css::uno::RuntimeException           );
255 
256         virtual void SAL_CALL removeByName(const ::rtl::OUString& sItem)
257             throw (css::container::NoSuchElementException,
258                    css::lang::WrappedTargetException     ,
259                    css::uno::RuntimeException            );
260 
261         //---------------------------------------
262         // XNameReplace
263 
264         virtual void SAL_CALL replaceByName(const ::rtl::OUString& sItem ,
265                                             const css::uno::Any&   aValue)
266             throw (css::lang::IllegalArgumentException   ,
267                    css::container::NoSuchElementException,
268                    css::lang::WrappedTargetException     ,
269                    css::uno::RuntimeException            );
270 
271         //---------------------------------------
272         // XElementAccess
273 
274         virtual css::uno::Any SAL_CALL getByName(const ::rtl::OUString& sItem)
275             throw (css::container::NoSuchElementException,
276                    css::lang::WrappedTargetException     ,
277                    css::uno::RuntimeException            );
278 
279         virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
280             throw (css::uno::RuntimeException);
281 
282         virtual sal_Bool SAL_CALL hasByName(const ::rtl::OUString& sItem)
283             throw (css::uno::RuntimeException);
284 
285         virtual css::uno::Type SAL_CALL getElementType()
286             throw (css::uno::RuntimeException);
287 
288         virtual sal_Bool SAL_CALL hasElements()
289             throw (css::uno::RuntimeException);
290 
291         //---------------------------------------
292         // XContainerQuery
293 
294         // must be implemented really by derived class ...
295         // We implement return of an empty result here only!
296         // But we show an assertion :-)
297         virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createSubSetEnumerationByQuery(const ::rtl::OUString& sQuery)
298             throw (css::uno::RuntimeException);
299 
300         virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createSubSetEnumerationByProperties(const css::uno::Sequence< css::beans::NamedValue >& lProperties)
301             throw (css::uno::RuntimeException);
302 
303         //---------------------------------------
304         // XFlushable
305 
306         virtual void SAL_CALL flush()
307             throw (css::uno::RuntimeException);
308 
309         virtual void SAL_CALL addFlushListener(const css::uno::Reference< css::util::XFlushListener >& xListener)
310             throw (css::uno::RuntimeException);
311 
312         virtual void SAL_CALL removeFlushListener(const css::uno::Reference< css::util::XFlushListener >& xListener)
313             throw (css::uno::RuntimeException);
314 };
315 
316     } // namespace config
317 } // namespace filter
318 
319 #endif // __FILTER_CONFIG_BASECONTAINER_HXX_
320