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