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