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 __FRAMEWORK_SERVICES_PATHSETTINGS_HXX_
29 #define __FRAMEWORK_SERVICES_PATHSETTINGS_HXX_
30 
31 //_________________________________________________________________________________________________________________
32 //	my own includes
33 //_________________________________________________________________________________________________________________
34 
35 #include <threadhelp/threadhelpbase.hxx>
36 #include <macros/generic.hxx>
37 #include <macros/xinterface.hxx>
38 #include <macros/xtypeprovider.hxx>
39 #include <macros/xserviceinfo.hxx>
40 #include <stdtypes.h>
41 #include <properties.h>
42 #include <stdtypes.h>
43 
44 //_________________________________________________________________________________________________________________
45 //	interface includes
46 //_________________________________________________________________________________________________________________
47 #include <com/sun/star/lang/XServiceInfo.hpp>
48 #include <com/sun/star/lang/XTypeProvider.hpp>
49 #include <com/sun/star/util/XStringSubstitution.hpp>
50 #include <com/sun/star/util/XChangesListener.hpp>
51 #include <com/sun/star/container/XNameAccess.hpp>
52 
53 //_________________________________________________________________________________________________________________
54 //	other includes
55 //_________________________________________________________________________________________________________________
56 #include <cppuhelper/propshlp.hxx>
57 #include <cppuhelper/interfacecontainer.hxx>
58 #include <cppuhelper/weak.hxx>
59 #include <unotools/configitem.hxx>
60 #include <comphelper/sequenceasvector.hxx>
61 
62 /* enable it if you whish to migrate old user settings (using the old cfg schema) on demand ....
63    disable it in case only the new schema must be used.
64  */
65 #define MIGRATE_OLD_USER_PATHES
66 
67 namespace framework
68 {
69 
70 class PathSettings : public  css::lang::XTypeProvider             ,
71                      public  css::lang::XServiceInfo              ,
72                      public  css::util::XChangesListener          , // => XEventListener
73                      // base classes
74                      // Order is neccessary for right initialization!
75                      private ThreadHelpBase                       ,
76                      public  ::cppu::OBroadcastHelper             ,
77                      public  ::cppu::OPropertySetHelper           , // => XPropertySet / XFastPropertySet / XMultiPropertySet
78                      public  ::cppu::OWeakObject                    // => XWeak, XInterface
79 {
80     struct PathInfo
81     {
82         public:
83 
84             PathInfo()
85                 : sPathName     ()
86                 , lInternalPaths()
87                 , lUserPaths    ()
88                 , sWritePath    ()
89                 , bIsSinglePath (sal_False)
90                 , bIsReadonly   (sal_False)
91             {}
92 
93             PathInfo(const PathInfo& rCopy)
94             {
95                 takeOver(rCopy);
96             }
97 
98             void takeOver(const PathInfo& rCopy)
99             {
100                 sPathName      = rCopy.sPathName;
101                 lInternalPaths = rCopy.lInternalPaths;
102                 lUserPaths     = rCopy.lUserPaths;
103                 sWritePath     = rCopy.sWritePath;
104                 bIsSinglePath  = rCopy.bIsSinglePath;
105                 bIsReadonly    = rCopy.bIsReadonly;
106             }
107 
108             /// an internal name describing this path
109             ::rtl::OUString sPathName;
110 
111             /// contains all paths, which are used internaly - but are not visible for the user.
112             OUStringList lInternalPaths;
113 
114             /// contains all paths configured by the user
115             OUStringList lUserPaths;
116 
117             /// this special path is used to generate feature depending content there
118             ::rtl::OUString sWritePath;
119 
120             /// indicates real single pathes, which uses WritePath property only
121             sal_Bool bIsSinglePath;
122 
123             /// simple handling of finalized/mandatory states ... => we know one state READONLY only .-)
124             sal_Bool bIsReadonly;
125     };
126 
127     typedef BaseHash< PathSettings::PathInfo > PathHash;
128 
129     enum EChangeOp
130     {
131         E_UNDEFINED,
132         E_ADDED,
133         E_CHANGED,
134         E_REMOVED
135     };
136 
137     // ______________________________________
138     // member
139 
140     private:
141 
142         /** reference to factory, which has create this instance. */
143         css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
144 
145         /** list of all path variables and her corresponding values. */
146         PathSettings::PathHash m_lPaths;
147 
148         /** describes all properties available on our interface.
149             Will be generated on demand based on our path list m_lPaths. */
150         css::uno::Sequence< css::beans::Property > m_lPropDesc;
151 
152         /** helper needed to (re-)substitute all internal save path values. */
153         css::uno::Reference< css::util::XStringSubstitution > m_xSubstitution;
154 
155         /** provides access to the old configuration schema (which will be migrated on demand). */
156         css::uno::Reference< css::container::XNameAccess > m_xCfgOld;
157 
158         /** provides access to the new configuration schema. */
159         css::uno::Reference< css::container::XNameAccess > m_xCfgNew;
160 
161         ::cppu::OPropertyArrayHelper* m_pPropHelp;
162 
163 		::sal_Bool m_bIgnoreEvents;
164 
165     // ___________________________________________
166     // interface
167 
168     public:
169 
170         /** initialize a new instance of this class.
171             Attention: It's neccessary for right function of this class, that the order of base
172             classes is the right one. Because we transfer information from one base to another
173             during this ctor runs! */
174         PathSettings(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
175 
176         /** free all used ressources ... if it was not already done. */
177         virtual ~PathSettings();
178 
179         /** declaration of XInterface, XTypeProvider, XServiceInfo */
180 		FWK_DECLARE_XINTERFACE
181 		FWK_DECLARE_XTYPEPROVIDER
182 		DECLARE_XSERVICEINFO
183 
184         // css::util::XChangesListener
185         virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent& aEvent) throw (css::uno::RuntimeException);
186 
187         // css::lang::XEventListener
188         virtual void SAL_CALL disposing(const css::lang::EventObject& aSource)
189             throw(css::uno::RuntimeException);
190 
191 		using ::cppu::OPropertySetHelper::disposing;
192 
193     // ___________________________________________
194     // helper
195 
196     private:
197 
198         /** read all configured paths and create all needed internal structures. */
199         void impl_readAll();
200 
201         /** read a path info using the old cfg schema.
202             This is needed for "migration on demand" reasons only.
203             Can be removed for next major release .-) */
204         OUStringList impl_readOldFormat(const ::rtl::OUString& sPath);
205 
206         /** read a path info using the new cfg schema. */
207         PathSettings::PathInfo impl_readNewFormat(const ::rtl::OUString& sPath);
208 
209         /** filter "real user defined paths" from the old configuration schema
210             and set it as UserPaths on the new schema.
211             Can be removed with new major release ... */
212         #ifdef MIGRATE_OLD_USER_PATHES
213         void impl_mergeOldUserPaths(      PathSettings::PathInfo& rPath,
214                                      const OUStringList&           lOld );
215         #endif
216 
217         /** reload one path directly from the new configuration schema (because
218             it was updated by any external code) */
219         PathSettings::EChangeOp impl_updatePath(const ::rtl::OUString& sPath          ,
220                                                       sal_Bool         bNotifyListener);
221 
222         /** replace all might existing placeholder variables inside the given path ...
223             or check if the given path value uses paths, which can be replaced with predefined
224             placeholder variables ...
225          */
226         void impl_subst(      OUStringList&                                          lVals   ,
227                         const css::uno::Reference< css::util::XStringSubstitution >& xSubst  ,
228                               sal_Bool                                               bReSubst);
229 
230         void impl_subst(PathSettings::PathInfo& aPath   ,
231                         sal_Bool                bReSubst);
232 
233 
234         /** converts our new string list schema to the old ";" seperated schema ... */
235         ::rtl::OUString impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath        ) const;
236         OUStringList    impl_convertOldStyle2Path(const ::rtl::OUString&        sOldStylePath) const;
237 
238         /** remove still known paths from the given lList argument.
239             So real user defined paths can be extracted from the list of
240             fix internal paths !
241          */
242         void impl_purgeKnownPaths(const PathSettings::PathInfo& rPath,
243                                          OUStringList&           lList);
244 
245         /** rebuild the member m_lPropDesc using the path list m_lPaths. */
246         void impl_rebuildPropertyDescriptor();
247 
248         /** provides direct access to the list of path values
249             using it's internal property id.
250          */
251         css::uno::Any impl_getPathValue(      sal_Int32      nID ) const;
252         void          impl_setPathValue(      sal_Int32      nID ,
253                                         const css::uno::Any& aVal);
254 
255         /** check the given handle and return the corresponding PathInfo reference.
256             These reference can be used then directly to manipulate these path. */
257               PathSettings::PathInfo* impl_getPathAccess     (sal_Int32 nHandle);
258         const PathSettings::PathInfo* impl_getPathAccessConst(sal_Int32 nHandle) const;
259 
260         /** it checks, if the given path value seams to be a valid URL or system path. */
261         sal_Bool impl_isValidPath(const ::rtl::OUString& sPath) const;
262         sal_Bool impl_isValidPath(const OUStringList&    lPath) const;
263 
264         void impl_storePath(const PathSettings::PathInfo& aPath);
265 
266         css::uno::Sequence< sal_Int32 > impl_mapPathName2IDList(const ::rtl::OUString& sPath);
267 
268         void impl_notifyPropListener(      PathSettings::EChangeOp eOp     ,
269                                            const ::rtl::OUString&        sPath   ,
270                                            const PathSettings::PathInfo* pPathOld,
271                                            const PathSettings::PathInfo* pPathNew);
272 
273 
274 		//	OPropertySetHelper
275         virtual sal_Bool                                            SAL_CALL convertFastPropertyValue        (       css::uno::Any&  aConvertedValue ,
276                                                                                                                      css::uno::Any&  aOldValue       ,
277                                                                                                                      sal_Int32       nHandle         ,
278                                                                                                                const css::uno::Any&  aValue          ) throw(css::lang::IllegalArgumentException);
279 		virtual void                                                SAL_CALL setFastPropertyValue_NoBroadcast(       sal_Int32       nHandle         ,
280                                                                                                                const css::uno::Any&  aValue          ) throw(css::uno::Exception);
281 		using cppu::OPropertySetHelper::getFastPropertyValue;
282         virtual void                                                SAL_CALL getFastPropertyValue            (       css::uno::Any&  aValue          ,
283                                                                                                                      sal_Int32       nHandle         ) const;
284         virtual ::cppu::IPropertyArrayHelper&                       SAL_CALL getInfoHelper                   (                                       );
285         virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo              (                                       ) throw(::com::sun::star::uno::RuntimeException);
286 
287         /** factory methods to guarantee right (but on demand) initialized members ... */
288         css::uno::Reference< css::util::XStringSubstitution > fa_getSubstitution();
289         css::uno::Reference< css::container::XNameAccess >    fa_getCfgOld();
290         css::uno::Reference< css::container::XNameAccess >    fa_getCfgNew();
291 };
292 
293 } // namespace framework
294 
295 #endif // __FRAMEWORK_SERVICES_PATHSETTINGS_HXX_
296