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 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_ucb.hxx"
30 
31 /**************************************************************************
32 								TODO
33  **************************************************************************
34 
35  - XInitialization::initialize does not work any longer!
36 
37  *************************************************************************/
38 #include <osl/diagnose.h>
39 #include <com/sun/star/beans/PropertyValue.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
42 #include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
43 #include <ucbhelper/contentidentifier.hxx>
44 #include "hierarchyprovider.hxx"
45 #include "hierarchycontent.hxx"
46 #include "hierarchyuri.hxx"
47 
48 #include "../inc/urihelper.hxx"
49 
50 using namespace com::sun::star;
51 using namespace hierarchy_ucp;
52 
53 //=========================================================================
54 //=========================================================================
55 //
56 // HierarchyContentProvider Implementation.
57 //
58 //=========================================================================
59 //=========================================================================
60 
61 HierarchyContentProvider::HierarchyContentProvider(
62             const uno::Reference< lang::XMultiServiceFactory >& rXSMgr )
63 : ::ucbhelper::ContentProviderImplHelper( rXSMgr )
64 {
65 }
66 
67 //=========================================================================
68 // virtual
69 HierarchyContentProvider::~HierarchyContentProvider()
70 {
71 }
72 
73 //=========================================================================
74 //
75 // XInterface methods.
76 //
77 //=========================================================================
78 
79 XINTERFACE_IMPL_4( HierarchyContentProvider,
80                    lang::XTypeProvider,
81                    lang::XServiceInfo,
82                    ucb::XContentProvider,
83                    lang::XInitialization );
84 
85 //=========================================================================
86 //
87 // XTypeProvider methods.
88 //
89 //=========================================================================
90 
91 XTYPEPROVIDER_IMPL_4( HierarchyContentProvider,
92                       lang::XTypeProvider,
93                       lang::XServiceInfo,
94                       ucb::XContentProvider,
95                       lang::XInitialization );
96 
97 //=========================================================================
98 //
99 // XServiceInfo methods.
100 //
101 //=========================================================================
102 
103 XSERVICEINFO_IMPL_1( HierarchyContentProvider,
104                      rtl::OUString::createFromAscii(
105 			 			"com.sun.star.comp.ucb.HierarchyContentProvider" ),
106                      rtl::OUString::createFromAscii(
107 				 		HIERARCHY_CONTENT_PROVIDER_SERVICE_NAME ) );
108 
109 //=========================================================================
110 //
111 // Service factory implementation.
112 //
113 //=========================================================================
114 
115 ONE_INSTANCE_SERVICE_FACTORY_IMPL( HierarchyContentProvider );
116 
117 //=========================================================================
118 //
119 // XContentProvider methods.
120 //
121 //=========================================================================
122 
123 // virtual
124 uno::Reference< ucb::XContent > SAL_CALL
125 HierarchyContentProvider::queryContent(
126         const uno::Reference< ucb::XContentIdentifier >& Identifier )
127     throw( ucb::IllegalIdentifierException, uno::RuntimeException )
128 {
129     HierarchyUri aUri( Identifier->getContentIdentifier() );
130     if ( !aUri.isValid() )
131         throw ucb::IllegalIdentifierException();
132 
133 	// Encode URL and create new Id. This may "correct" user-typed-in URL's.
134     uno::Reference< ucb::XContentIdentifier > xCanonicId
135         = new ::ucbhelper::ContentIdentifier( m_xSMgr,
136                                               ::ucb_impl::urihelper::encodeURI(
137                                                   aUri.getUri() ) );
138 	osl::MutexGuard aGuard( m_aMutex );
139 
140     // Check, if a content with given id already exists...
141     uno::Reference< ucb::XContent > xContent
142 		= queryExistingContent( xCanonicId ).get();
143 	if ( xContent.is() )
144 		return xContent;
145 
146 	// Create a new content.
147 	xContent = HierarchyContent::create( m_xSMgr, this, xCanonicId );
148     registerNewContent( xContent );
149 
150 	if ( xContent.is() && !xContent->getIdentifier().is() )
151         throw ucb::IllegalIdentifierException();
152 
153 	return xContent;
154 }
155 
156 //=========================================================================
157 //
158 // XInitialization methods.
159 //
160 //=========================================================================
161 
162 // virtual
163 void SAL_CALL HierarchyContentProvider::initialize(
164                                 const uno::Sequence< uno::Any >& aArguments )
165     throw( uno::Exception, uno::RuntimeException )
166 {
167 #if 0
168 	if ( aArguments.getLength() > 0 )
169 	{
170 	 	// Extract config provider from service init args.
171 	 	aArguments[ 0 ] >>= m_xConfigProvider;
172 
173         OSL_ENSURE( m_xConfigProvider.is(),
174 					"HierarchyContentProvider::initialize - "
175 					"No config provider!" );
176 	}
177 #else
178 	if ( aArguments.getLength() > 0 )
179         OSL_ENSURE( false,
180                     "HierarchyContentProvider::initialize : not supported!" );
181 #endif
182 }
183 
184 //=========================================================================
185 //
186 //  Non-interface methods.
187 //
188 //=========================================================================
189 
190 uno::Reference< lang::XMultiServiceFactory >
191 HierarchyContentProvider::getConfigProvider(
192                                 const rtl::OUString & rServiceSpecifier )
193 {
194     osl::MutexGuard aGuard( m_aMutex );
195     ConfigProviderMap::iterator it = m_aConfigProviderMap.find(
196                                                     rServiceSpecifier );
197     if ( it == m_aConfigProviderMap.end() )
198     {
199         try
200         {
201             ConfigProviderMapEntry aEntry;
202             aEntry.xConfigProvider
203                 = uno::Reference< lang::XMultiServiceFactory >(
204                                 m_xSMgr->createInstance( rServiceSpecifier ),
205                                 uno::UNO_QUERY );
206 
207             if ( aEntry.xConfigProvider.is() )
208             {
209                 m_aConfigProviderMap[ rServiceSpecifier ] = aEntry;
210                 return aEntry.xConfigProvider;
211             }
212         }
213         catch ( uno::Exception const & )
214         {
215 //            OSL_ENSURE( sal_False,
216 //                        "HierarchyContentProvider::getConfigProvider - "
217 //                        "caught exception!" );
218         }
219 
220         OSL_ENSURE( sal_False,
221                     "HierarchyContentProvider::getConfigProvider - "
222                     "No config provider!" );
223 
224         return uno::Reference< lang::XMultiServiceFactory >();
225     }
226 
227     return (*it).second.xConfigProvider;
228 }
229 
230 //=========================================================================
231 uno::Reference< container::XHierarchicalNameAccess >
232 HierarchyContentProvider::getRootConfigReadNameAccess(
233                                 const rtl::OUString & rServiceSpecifier )
234 {
235     osl::MutexGuard aGuard( m_aMutex );
236     ConfigProviderMap::iterator it = m_aConfigProviderMap.find(
237                                                     rServiceSpecifier );
238     if ( it != m_aConfigProviderMap.end() )
239     {
240         if ( !( (*it).second.xRootReadAccess.is() ) )
241 		{
242             if ( (*it).second.bTriedToGetRootReadAccess ) // #82494#
243 			{
244 				OSL_ENSURE( sal_False,
245 					"HierarchyContentProvider::getRootConfigReadNameAccess - "
246 					"Unable to read any config data! -> #82494#" );
247                 return uno::Reference< container::XHierarchicalNameAccess >();
248 			}
249 
250 			try
251 			{
252                 uno::Reference< lang::XMultiServiceFactory > xConfigProv
253                     = getConfigProvider( rServiceSpecifier );
254 
255                 if ( xConfigProv.is() )
256 				{
257                     uno::Sequence< uno::Any > aArguments( 1 );
258                     beans::PropertyValue      aProperty;
259                     aProperty.Name
260                         = rtl::OUString(
261                             RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
262                     aProperty.Value <<= rtl::OUString(); // root path
263                     aArguments[ 0 ] <<= aProperty;
264 
265                     (*it).second.bTriedToGetRootReadAccess = true;
266 
267                     (*it).second.xRootReadAccess
268                         = uno::Reference< container::XHierarchicalNameAccess >(
269                             xConfigProv->createInstanceWithArguments(
270                                 rtl::OUString(
271                                     RTL_CONSTASCII_USTRINGPARAM(
272                                         "com.sun.star.ucb."
273                                         "HierarchyDataReadAccess" ) ),
274                                 aArguments ),
275                             uno::UNO_QUERY );
276 				}
277 			}
278             catch ( uno::RuntimeException const & )
279 			{
280 				throw;
281 			}
282             catch ( uno::Exception const & )
283 			{
284 				// createInstance, createInstanceWithArguments
285 
286                 OSL_ENSURE( sal_False,
287 					"HierarchyContentProvider::getRootConfigReadNameAccess - "
288 					"caught Exception!" );
289 			}
290         }
291     }
292 
293     return (*it).second.xRootReadAccess;
294 }
295 
296 //=========================================================================
297 uno::Reference< util::XOfficeInstallationDirectories >
298 HierarchyContentProvider::getOfficeInstallationDirectories()
299 {
300     if ( !m_xOfficeInstDirs.is() )
301     {
302         osl::MutexGuard aGuard( m_aMutex );
303         if ( !m_xOfficeInstDirs.is() )
304         {
305             OSL_ENSURE( m_xSMgr.is(), "No service manager!" );
306 
307             uno::Reference< uno::XComponentContext > xCtx;
308             uno::Reference< beans::XPropertySet > xPropSet(
309                 m_xSMgr, uno::UNO_QUERY );
310             if ( xPropSet.is() )
311             {
312                 xPropSet->getPropertyValue(
313                     rtl::OUString(
314                         RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
315                 >>= xCtx;
316             }
317 
318             OSL_ENSURE( xCtx.is(),
319                         "Unable to obtain component context from "
320                         "service manager!" );
321 
322             if ( xCtx.is() )
323             {
324                 xCtx->getValueByName(
325                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
326                         "/singletons/"
327                         "com.sun.star.util.theOfficeInstallationDirectories" ) ) )
328                 >>= m_xOfficeInstDirs;
329 
330 // Be silent. singleton only available in an Office environment.
331 //                OSL_ENSURE( m_xOfficeInstDirs.is(),
332 //                            "Unable to obtain office directories singleton!" );
333             }
334         }
335     }
336     return m_xOfficeInstDirs;
337 }
338 
339