Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 : :
29 : : #include "ucpext_content.hxx"
30 : :
31 : : #include "ucpext_content.hxx"
32 : : #include "ucpext_provider.hxx"
33 : : #include "ucpext_resultset.hxx"
34 : :
35 : : #include <com/sun/star/beans/PropertyAttribute.hpp>
36 : : #include <com/sun/star/beans/XPropertyAccess.hpp>
37 : : #include <com/sun/star/lang/IllegalAccessException.hpp>
38 : : #include <com/sun/star/sdbc/XRow.hpp>
39 : : #include <com/sun/star/ucb/XCommandInfo.hpp>
40 : : #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
41 : : #include <com/sun/star/io/XOutputStream.hpp>
42 : : #include <com/sun/star/io/XActiveDataSink.hpp>
43 : : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
44 : : #include <com/sun/star/ucb/OpenMode.hpp>
45 : : #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
46 : : #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
47 : : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
48 : : #include <com/sun/star/ucb/OpenMode.hpp>
49 : : #include <com/sun/star/ucb/XDynamicResultSet.hpp>
50 : : #include <com/sun/star/lang/IllegalAccessException.hpp>
51 : : #include <com/sun/star/deployment/XPackageInformationProvider.hpp>
52 : :
53 : : #include <ucbhelper/contentidentifier.hxx>
54 : : #include <ucbhelper/propertyvalueset.hxx>
55 : : #include <ucbhelper/cancelcommandexecution.hxx>
56 : : #include <ucbhelper/content.hxx>
57 : : #include <tools/diagnose_ex.h>
58 : : #include <comphelper/string.hxx>
59 : : #include <comphelper/componentcontext.hxx>
60 : : #include <rtl/ustrbuf.hxx>
61 : : #include <rtl/uri.hxx>
62 : : #include <sal/macros.h>
63 : :
64 : : #include <algorithm>
65 : :
66 : : //......................................................................................................................
67 : : namespace ucb { namespace ucp { namespace ext
68 : : {
69 : : //......................................................................................................................
70 : :
71 : : /** === begin UNO using === **/
72 : : using ::com::sun::star::uno::Reference;
73 : : using ::com::sun::star::uno::XInterface;
74 : : using ::com::sun::star::uno::UNO_QUERY;
75 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
76 : : using ::com::sun::star::uno::UNO_SET_THROW;
77 : : using ::com::sun::star::uno::Exception;
78 : : using ::com::sun::star::uno::RuntimeException;
79 : : using ::com::sun::star::uno::Any;
80 : : using ::com::sun::star::uno::makeAny;
81 : : using ::com::sun::star::uno::Sequence;
82 : : using ::com::sun::star::uno::Type;
83 : : using ::com::sun::star::lang::XMultiServiceFactory;
84 : : using ::com::sun::star::ucb::XContentIdentifier;
85 : : using ::com::sun::star::ucb::IllegalIdentifierException;
86 : : using ::com::sun::star::ucb::XContent;
87 : : using ::com::sun::star::ucb::XCommandEnvironment;
88 : : using ::com::sun::star::ucb::Command;
89 : : using ::com::sun::star::ucb::CommandAbortedException;
90 : : using ::com::sun::star::beans::Property;
91 : : using ::com::sun::star::lang::IllegalArgumentException;
92 : : using ::com::sun::star::beans::PropertyValue;
93 : : using ::com::sun::star::ucb::OpenCommandArgument2;
94 : : using ::com::sun::star::ucb::XDynamicResultSet;
95 : : using ::com::sun::star::ucb::UnsupportedOpenModeException;
96 : : using ::com::sun::star::io::XOutputStream;
97 : : using ::com::sun::star::io::XActiveDataSink;
98 : : using ::com::sun::star::io::XInputStream;
99 : : using ::com::sun::star::ucb::UnsupportedDataSinkException;
100 : : using ::com::sun::star::ucb::UnsupportedCommandException;
101 : : using ::com::sun::star::sdbc::XRow;
102 : : using ::com::sun::star::beans::XPropertySet;
103 : : using ::com::sun::star::beans::PropertyChangeEvent;
104 : : using ::com::sun::star::lang::IllegalAccessException;
105 : : using ::com::sun::star::ucb::CommandInfo;
106 : : using ::com::sun::star::deployment::XPackageInformationProvider;
107 : : /** === end UNO using === **/
108 : : namespace OpenMode = ::com::sun::star::ucb::OpenMode;
109 : : namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
110 : :
111 : : //==================================================================================================================
112 : : //= helper
113 : : //==================================================================================================================
114 : : namespace
115 : : {
116 : : //--------------------------------------------------------------------------------------------------------------
117 : 0 : ::rtl::OUString lcl_compose( const ::rtl::OUString& i_rBaseURL, const ::rtl::OUString& i_rRelativeURL )
118 : : {
119 : 0 : ENSURE_OR_RETURN( !i_rBaseURL.isEmpty(), "illegal base URL", i_rRelativeURL );
120 : :
121 : 0 : ::rtl::OUStringBuffer aComposer( i_rBaseURL );
122 : 0 : if ( i_rBaseURL.getStr()[ i_rBaseURL.getLength() - 1 ] != '/' )
123 : 0 : aComposer.append( sal_Unicode( '/' ) );
124 : 0 : aComposer.append( i_rRelativeURL );
125 : 0 : return aComposer.makeStringAndClear();
126 : : }
127 : :
128 : : //--------------------------------------------------------------------------------------------------------------
129 : : struct SelectPropertyName : public ::std::unary_function< Property, ::rtl::OUString >
130 : : {
131 : 0 : const ::rtl::OUString& operator()( const Property& i_rProperty ) const
132 : : {
133 : 0 : return i_rProperty.Name;
134 : : }
135 : : };
136 : : }
137 : :
138 : : //==================================================================================================================
139 : : //= Content
140 : : //==================================================================================================================
141 : : //------------------------------------------------------------------------------------------------------------------
142 : 0 : Content::Content( const Reference< XMultiServiceFactory >& i_rORB, ::ucbhelper::ContentProviderImplHelper* i_pProvider,
143 : : const Reference< XContentIdentifier >& i_rIdentifier )
144 : : :Content_Base( i_rORB, i_pProvider, i_rIdentifier )
145 : : ,m_eExtContentType( E_UNKNOWN )
146 : : ,m_aIsFolder()
147 : : ,m_aContentType()
148 : : ,m_sExtensionId()
149 : 0 : ,m_sPathIntoExtension()
150 : : {
151 : 0 : const ::rtl::OUString sURL( getIdentifier()->getContentIdentifier() );
152 : 0 : if ( denotesRootContent( sURL ) )
153 : : {
154 : 0 : m_eExtContentType = E_ROOT;
155 : : }
156 : : else
157 : : {
158 : 0 : const ::rtl::OUString sRelativeURL( sURL.copy( ContentProvider::getRootURL().getLength() ) );
159 : 0 : const sal_Int32 nSepPos = sRelativeURL.indexOf( '/' );
160 : 0 : if ( ( nSepPos == -1 ) || ( nSepPos == sRelativeURL.getLength() - 1 ) )
161 : : {
162 : 0 : m_eExtContentType = E_EXTENSION_ROOT;
163 : : }
164 : : else
165 : : {
166 : 0 : m_eExtContentType = E_EXTENSION_CONTENT;
167 : 0 : }
168 : : }
169 : :
170 : 0 : if ( m_eExtContentType != E_ROOT )
171 : : {
172 : 0 : const ::rtl::OUString sRootURL = ContentProvider::getRootURL();
173 : 0 : m_sExtensionId = sURL.copy( sRootURL.getLength() );
174 : :
175 : 0 : const sal_Int32 nNextSep = m_sExtensionId.indexOf( '/' );
176 : 0 : if ( nNextSep > -1 )
177 : : {
178 : 0 : m_sPathIntoExtension = m_sExtensionId.copy( nNextSep + 1 );
179 : 0 : m_sExtensionId = m_sExtensionId.copy( 0, nNextSep );
180 : : }
181 : 0 : m_sExtensionId = Content::decodeIdentifier( m_sExtensionId );
182 : 0 : }
183 : 0 : }
184 : :
185 : : //------------------------------------------------------------------------------------------------------------------
186 : 0 : Content::~Content()
187 : : {
188 : 0 : }
189 : :
190 : : //------------------------------------------------------------------------------------------------------------------
191 : 0 : ::rtl::OUString SAL_CALL Content::getImplementationName() throw( RuntimeException )
192 : : {
193 : 0 : return ::rtl::OUString( "org.openoffice.comp.ucp.ext.Content" );
194 : : }
195 : :
196 : : //------------------------------------------------------------------------------------------------------------------
197 : 0 : Sequence< ::rtl::OUString > SAL_CALL Content::getSupportedServiceNames() throw( RuntimeException )
198 : : {
199 : 0 : Sequence< ::rtl::OUString > aServiceNames(2);
200 : 0 : aServiceNames[0] = ::rtl::OUString( "com.sun.star.ucb.Content" );
201 : 0 : aServiceNames[1] = ::rtl::OUString( "com.sun.star.ucb.ExtensionContent" );
202 : 0 : return aServiceNames;
203 : : }
204 : :
205 : : //------------------------------------------------------------------------------------------------------------------
206 : 0 : ::rtl::OUString SAL_CALL Content::getContentType() throw( RuntimeException )
207 : : {
208 : 0 : impl_determineContentType();
209 : 0 : return *m_aContentType;
210 : : }
211 : :
212 : : //------------------------------------------------------------------------------------------------------------------
213 : 0 : Any SAL_CALL Content::execute( const Command& aCommand, sal_Int32 /* CommandId */, const Reference< XCommandEnvironment >& i_rEvironment )
214 : : throw( Exception, CommandAbortedException, RuntimeException )
215 : : {
216 : 0 : Any aRet;
217 : :
218 : 0 : if ( aCommand.Name == "getPropertyValues" )
219 : : {
220 : 0 : Sequence< Property > Properties;
221 : 0 : if ( !( aCommand.Argument >>= Properties ) )
222 : : {
223 : : ::ucbhelper::cancelCommandExecution( makeAny( IllegalArgumentException(
224 : : ::rtl::OUString(), *this, -1 ) ),
225 : 0 : i_rEvironment );
226 : : // unreachable
227 : : }
228 : :
229 : 0 : aRet <<= getPropertyValues( Properties, i_rEvironment );
230 : : }
231 : 0 : else if ( aCommand.Name == "setPropertyValues" )
232 : : {
233 : 0 : Sequence< PropertyValue > aProperties;
234 : 0 : if ( !( aCommand.Argument >>= aProperties ) )
235 : : {
236 : : ::ucbhelper::cancelCommandExecution( makeAny( IllegalArgumentException(
237 : : ::rtl::OUString(), *this, -1 ) ),
238 : 0 : i_rEvironment );
239 : : // unreachable
240 : : }
241 : :
242 : 0 : if ( !aProperties.getLength() )
243 : : {
244 : : ::ucbhelper::cancelCommandExecution( makeAny( IllegalArgumentException(
245 : : ::rtl::OUString(), *this, -1 ) ),
246 : 0 : i_rEvironment );
247 : : // unreachable
248 : : }
249 : :
250 : 0 : aRet <<= setPropertyValues( aProperties, i_rEvironment );
251 : : }
252 : 0 : else if ( aCommand.Name == "getPropertySetInfo" )
253 : : {
254 : : // implemented by base class.
255 : 0 : aRet <<= getPropertySetInfo( i_rEvironment );
256 : : }
257 : 0 : else if ( aCommand.Name == "getCommandInfo" )
258 : : {
259 : : // implemented by base class.
260 : 0 : aRet <<= getCommandInfo( i_rEvironment );
261 : : }
262 : 0 : else if ( aCommand.Name == "open" )
263 : : {
264 : 0 : OpenCommandArgument2 aOpenCommand;
265 : 0 : if ( !( aCommand.Argument >>= aOpenCommand ) )
266 : : {
267 : : ::ucbhelper::cancelCommandExecution( makeAny( IllegalArgumentException(
268 : : ::rtl::OUString(), *this, -1 ) ),
269 : 0 : i_rEvironment );
270 : : // unreachable
271 : : }
272 : :
273 : : sal_Bool bOpenFolder =
274 : : ( ( aOpenCommand.Mode == OpenMode::ALL ) ||
275 : : ( aOpenCommand.Mode == OpenMode::FOLDERS ) ||
276 : 0 : ( aOpenCommand.Mode == OpenMode::DOCUMENTS ) );
277 : :
278 : :
279 : 0 : if ( bOpenFolder && impl_isFolder() )
280 : : {
281 : : Reference< XDynamicResultSet > xSet = new ResultSet(
282 : 0 : m_xSMgr, this, aOpenCommand, i_rEvironment );
283 : 0 : aRet <<= xSet;
284 : : }
285 : :
286 : 0 : if ( aOpenCommand.Sink.is() )
287 : : {
288 : 0 : const ::rtl::OUString sPhysicalContentURL( getPhysicalURL() );
289 : 0 : ::ucbhelper::Content aRequestedContent( sPhysicalContentURL, i_rEvironment );
290 : 0 : aRet = aRequestedContent.executeCommand( ::rtl::OUString( "open" ), makeAny( aOpenCommand ) );
291 : 0 : }
292 : : }
293 : :
294 : : else
295 : : {
296 : : ::ucbhelper::cancelCommandExecution( makeAny( UnsupportedCommandException(
297 : : ::rtl::OUString(), *this ) ),
298 : 0 : i_rEvironment );
299 : : // unreachable
300 : : }
301 : :
302 : 0 : return aRet;
303 : : }
304 : :
305 : : //------------------------------------------------------------------------------------------------------------------
306 : 0 : void SAL_CALL Content::abort( sal_Int32 ) throw( RuntimeException )
307 : : {
308 : 0 : }
309 : :
310 : : //------------------------------------------------------------------------------------------------------------------
311 : 0 : ::rtl::OUString Content::encodeIdentifier( const ::rtl::OUString& i_rIdentifier )
312 : : {
313 : : return ::rtl::Uri::encode( i_rIdentifier, rtl_UriCharClassRegName, rtl_UriEncodeIgnoreEscapes,
314 : 0 : RTL_TEXTENCODING_UTF8 );
315 : : }
316 : :
317 : : //------------------------------------------------------------------------------------------------------------------
318 : 0 : ::rtl::OUString Content::decodeIdentifier( const ::rtl::OUString& i_rIdentifier )
319 : : {
320 : 0 : return ::rtl::Uri::decode( i_rIdentifier, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
321 : : }
322 : :
323 : : //------------------------------------------------------------------------------------------------------------------
324 : 0 : bool Content::denotesRootContent( const ::rtl::OUString& i_rContentIdentifier )
325 : : {
326 : 0 : const ::rtl::OUString sRootURL( ContentProvider::getRootURL() );
327 : 0 : if ( i_rContentIdentifier == sRootURL )
328 : 0 : return true;
329 : :
330 : : // the root URL contains only two trailing /, but we also recognize 3 of them as denoting the root URL
331 : 0 : if ( i_rContentIdentifier.match( sRootURL )
332 : 0 : && ( i_rContentIdentifier.getLength() == sRootURL.getLength() + 1 )
333 : 0 : && ( i_rContentIdentifier[ i_rContentIdentifier.getLength() - 1 ] == '/' )
334 : : )
335 : 0 : return true;
336 : :
337 : 0 : return false;
338 : : }
339 : :
340 : : //------------------------------------------------------------------------------------------------------------------
341 : 0 : ::rtl::OUString Content::getParentURL()
342 : : {
343 : 0 : const ::rtl::OUString sRootURL( ContentProvider::getRootURL() );
344 : :
345 : 0 : switch ( m_eExtContentType )
346 : : {
347 : : case E_ROOT:
348 : : // don't have a parent
349 : 0 : return sRootURL;
350 : :
351 : : case E_EXTENSION_ROOT:
352 : : // our parent is the root itself
353 : 0 : return sRootURL;
354 : :
355 : : case E_EXTENSION_CONTENT:
356 : : {
357 : 0 : const ::rtl::OUString sURL = m_xIdentifier->getContentIdentifier();
358 : :
359 : : // cut the root URL
360 : 0 : if ( !sURL.match( sRootURL, 0 ) )
361 : : {
362 : : SAL_INFO( "ucb.ucp", "illegal URL structure - no root" );
363 : : break;
364 : : }
365 : :
366 : 0 : ::rtl::OUString sRelativeURL( sURL.copy( sRootURL.getLength() ) );
367 : :
368 : : // cut the extension ID
369 : 0 : const ::rtl::OUString sSeparatedExtensionId( encodeIdentifier( m_sExtensionId ) + ::rtl::OUString( sal_Unicode( '/' ) ) );
370 : 0 : if ( !sRelativeURL.match( sSeparatedExtensionId ) )
371 : : {
372 : : SAL_INFO( "ucb.ucp", "illegal URL structure - no extension ID" );
373 : : break;
374 : : }
375 : :
376 : 0 : sRelativeURL = sRelativeURL.copy( sSeparatedExtensionId.getLength() );
377 : :
378 : : // cut the final slash (if any)
379 : 0 : if ( sRelativeURL.isEmpty() )
380 : : {
381 : : SAL_INFO( "ucb.ucp", "illegal URL structure - ExtensionContent should have a level below the extension ID" );
382 : : break;
383 : : }
384 : :
385 : 0 : if ( sRelativeURL.getStr()[ sRelativeURL.getLength() - 1 ] == '/' )
386 : 0 : sRelativeURL = sRelativeURL.copy( 0, sRelativeURL.getLength() - 1 );
387 : :
388 : : // remove the last segment
389 : 0 : const sal_Int32 nLastSep = sRelativeURL.lastIndexOf( '/' );
390 : 0 : sRelativeURL = sRelativeURL.copy( 0, nLastSep != -1 ? nLastSep : 0 );
391 : :
392 : 0 : ::rtl::OUStringBuffer aComposer;
393 : 0 : aComposer.append( sRootURL );
394 : 0 : aComposer.append( sSeparatedExtensionId );
395 : 0 : aComposer.append( sRelativeURL );
396 : 0 : return aComposer.makeStringAndClear();
397 : : }
398 : :
399 : : default:
400 : : OSL_FAIL( "Content::getParentURL: unhandled case!" );
401 : 0 : break;
402 : : }
403 : 0 : return ::rtl::OUString();
404 : : }
405 : :
406 : : //------------------------------------------------------------------------------------------------------------------
407 : 0 : Reference< XRow > Content::getArtificialNodePropertyValues( const Reference< XMultiServiceFactory >& i_rORB,
408 : : const Sequence< Property >& i_rProperties, const ::rtl::OUString& i_rTitle )
409 : : {
410 : : // note: empty sequence means "get values of all supported properties".
411 : 0 : ::rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( i_rORB );
412 : :
413 : 0 : const sal_Int32 nCount = i_rProperties.getLength();
414 : 0 : if ( nCount )
415 : : {
416 : 0 : Reference< XPropertySet > xAdditionalPropSet;
417 : :
418 : 0 : const Property* pProps = i_rProperties.getConstArray();
419 : 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
420 : : {
421 : 0 : const Property& rProp = pProps[ n ];
422 : :
423 : : // Process Core properties.
424 : 0 : if ( rProp.Name == "ContentType" )
425 : : {
426 : 0 : xRow->appendString ( rProp, ContentProvider::getArtificialNodeContentType() );
427 : : }
428 : 0 : else if ( rProp.Name == "Title" )
429 : : {
430 : 0 : xRow->appendString ( rProp, i_rTitle );
431 : : }
432 : 0 : else if ( rProp.Name == "IsDocument" )
433 : : {
434 : 0 : xRow->appendBoolean( rProp, sal_False );
435 : : }
436 : 0 : else if ( rProp.Name == "IsFolder" )
437 : : {
438 : 0 : xRow->appendBoolean( rProp, sal_True );
439 : : }
440 : : else
441 : : {
442 : : // append empty entry.
443 : 0 : xRow->appendVoid( rProp );
444 : : }
445 : 0 : }
446 : : }
447 : : else
448 : : {
449 : : // Append all Core Properties.
450 : : xRow->appendString ( Property( ::rtl::OUString("ContentType"),
451 : : -1,
452 : 0 : getCppuType( static_cast< const ::rtl::OUString * >( 0 ) ),
453 : : PropertyAttribute::BOUND | PropertyAttribute::READONLY ),
454 : 0 : ContentProvider::getArtificialNodeContentType() );
455 : : xRow->appendString ( Property( ::rtl::OUString("Title"),
456 : : -1,
457 : 0 : getCppuType( static_cast< const ::rtl::OUString * >( 0 ) ),
458 : : PropertyAttribute::BOUND | PropertyAttribute::READONLY ),
459 : 0 : i_rTitle );
460 : : xRow->appendBoolean( Property( ::rtl::OUString("IsDocument"),
461 : : -1,
462 : 0 : getCppuBooleanType(),
463 : : PropertyAttribute::BOUND | PropertyAttribute::READONLY ),
464 : 0 : sal_False );
465 : : xRow->appendBoolean( Property( ::rtl::OUString("IsFolder"),
466 : : -1,
467 : 0 : getCppuBooleanType(),
468 : : PropertyAttribute::BOUND | PropertyAttribute::READONLY ),
469 : 0 : sal_True );
470 : : }
471 : :
472 : 0 : return Reference< XRow >( xRow.get() );
473 : : }
474 : :
475 : : //------------------------------------------------------------------------------------------------------------------
476 : 0 : ::rtl::OUString Content::getPhysicalURL() const
477 : : {
478 : 0 : ENSURE_OR_RETURN( m_eExtContentType != E_ROOT, "illegal call", ::rtl::OUString() );
479 : :
480 : : // create an ucb::XContent for the physical file within the deployed extension
481 : 0 : const ::comphelper::ComponentContext aContext( m_xSMgr );
482 : : const Reference< XPackageInformationProvider > xPackageInfo(
483 : 0 : aContext.getSingleton( "com.sun.star.deployment.PackageInformationProvider" ), UNO_QUERY_THROW );
484 : 0 : const ::rtl::OUString sPackageLocation( xPackageInfo->getPackageLocation( m_sExtensionId ) );
485 : :
486 : 0 : if ( m_sPathIntoExtension.isEmpty() )
487 : 0 : return sPackageLocation;
488 : 0 : return lcl_compose( sPackageLocation, m_sPathIntoExtension );
489 : : }
490 : :
491 : : //------------------------------------------------------------------------------------------------------------------
492 : 0 : Reference< XRow > Content::getPropertyValues( const Sequence< Property >& i_rProperties, const Reference< XCommandEnvironment >& i_rEnv )
493 : : {
494 : 0 : ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
495 : :
496 : 0 : switch ( m_eExtContentType )
497 : : {
498 : : case E_ROOT:
499 : 0 : return getArtificialNodePropertyValues( m_xSMgr, i_rProperties, ContentProvider::getRootURL() );
500 : : case E_EXTENSION_ROOT:
501 : 0 : return getArtificialNodePropertyValues( m_xSMgr, i_rProperties, m_sExtensionId );
502 : : case E_EXTENSION_CONTENT:
503 : : {
504 : 0 : const ::rtl::OUString sPhysicalContentURL( getPhysicalURL() );
505 : 0 : ::ucbhelper::Content aRequestedContent( sPhysicalContentURL, i_rEnv );
506 : :
507 : : // translate the property request
508 : 0 : Sequence< ::rtl::OUString > aPropertyNames( i_rProperties.getLength() );
509 : : ::std::transform(
510 : : i_rProperties.getConstArray(),
511 : 0 : i_rProperties.getConstArray() + i_rProperties.getLength(),
512 : : aPropertyNames.getArray(),
513 : : SelectPropertyName()
514 : 0 : );
515 : 0 : const Sequence< Any > aPropertyValues = aRequestedContent.getPropertyValues( aPropertyNames );
516 : 0 : const ::rtl::Reference< ::ucbhelper::PropertyValueSet > xValueRow = new ::ucbhelper::PropertyValueSet( m_xSMgr );
517 : 0 : sal_Int32 i=0;
518 : 0 : for ( const Any* value = aPropertyValues.getConstArray();
519 : 0 : value != aPropertyValues.getConstArray() + aPropertyValues.getLength();
520 : : ++value, ++i
521 : : )
522 : : {
523 : 0 : xValueRow->appendObject( aPropertyNames[i], *value );
524 : : }
525 : 0 : return xValueRow.get();
526 : : }
527 : :
528 : : default:
529 : : OSL_FAIL( "Content::getPropertyValues: unhandled case!" );
530 : 0 : break;
531 : : }
532 : :
533 : : OSL_FAIL( "Content::getPropertyValues: unreachable!" );
534 : 0 : return NULL;
535 : : }
536 : :
537 : : //------------------------------------------------------------------------------------------------------------------
538 : 0 : Sequence< Any > Content::setPropertyValues( const Sequence< PropertyValue >& i_rValues, const Reference< XCommandEnvironment >& /* xEnv */)
539 : : {
540 : 0 : ::osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
541 : :
542 : 0 : Sequence< Any > aRet( i_rValues.getLength() );
543 : 0 : Sequence< PropertyChangeEvent > aChanges( i_rValues.getLength() );
544 : :
545 : 0 : PropertyChangeEvent aEvent;
546 : 0 : aEvent.Source = static_cast< cppu::OWeakObject * >( this );
547 : 0 : aEvent.Further = sal_False;
548 : 0 : aEvent.PropertyHandle = -1;
549 : :
550 : 0 : const PropertyValue* pValues = i_rValues.getConstArray();
551 : 0 : const sal_Int32 nCount = i_rValues.getLength();
552 : :
553 : 0 : for ( sal_Int32 n = 0; n < nCount; ++n, ++pValues )
554 : : {
555 : : // all our properties are read-only ...
556 : 0 : aRet[ n ] <<= IllegalAccessException( ::rtl::OUString("property is read-only."), *this );
557 : : }
558 : :
559 : 0 : return aRet;
560 : : }
561 : :
562 : : //------------------------------------------------------------------------------------------------------------------
563 : 0 : Sequence< CommandInfo > Content::getCommands( const Reference< XCommandEnvironment > & /*xEnv*/ )
564 : : {
565 : 0 : sal_uInt32 nCommandCount = 5;
566 : : static const CommandInfo aCommandInfoTable[] =
567 : : {
568 : : ///////////////////////////////////////////////////////////////
569 : : // Mandatory commands
570 : : ///////////////////////////////////////////////////////////////
571 : : CommandInfo(
572 : : ::rtl::OUString( "getCommandInfo" ),
573 : : -1,
574 : 0 : getCppuVoidType()
575 : : ),
576 : : CommandInfo(
577 : : ::rtl::OUString( "getPropertySetInfo" ),
578 : : -1,
579 : 0 : getCppuVoidType()
580 : : ),
581 : : CommandInfo(
582 : : ::rtl::OUString( "getPropertyValues" ),
583 : : -1,
584 : : getCppuType(
585 : 0 : static_cast< Sequence< Property > * >( 0 ) )
586 : : ),
587 : : CommandInfo(
588 : : ::rtl::OUString( "setPropertyValues" ),
589 : : -1,
590 : : getCppuType(
591 : 0 : static_cast< Sequence< PropertyValue > * >( 0 ) )
592 : : )
593 : : ///////////////////////////////////////////////////////////////
594 : : // Optional standard commands
595 : : ///////////////////////////////////////////////////////////////
596 : : , CommandInfo(
597 : : ::rtl::OUString( "open" ),
598 : : -1,
599 : 0 : getCppuType( static_cast< OpenCommandArgument2 * >( 0 ) )
600 : : )
601 : 0 : };
602 : :
603 : 0 : return Sequence< CommandInfo >( aCommandInfoTable, nCommandCount );
604 : : }
605 : :
606 : : //------------------------------------------------------------------------------------------------------------------
607 : 0 : Sequence< Property > Content::getProperties( const Reference< XCommandEnvironment > & /*xEnv*/ )
608 : : {
609 : : static Property aProperties[] =
610 : : {
611 : : Property(
612 : : ::rtl::OUString( "ContentType" ),
613 : : -1,
614 : 0 : getCppuType( static_cast< const ::rtl::OUString * >( 0 ) ),
615 : : PropertyAttribute::BOUND | PropertyAttribute::READONLY
616 : : ),
617 : : Property(
618 : : ::rtl::OUString( "IsDocument" ),
619 : : -1,
620 : 0 : getCppuBooleanType(),
621 : : PropertyAttribute::BOUND | PropertyAttribute::READONLY
622 : : ),
623 : : Property(
624 : : ::rtl::OUString( "IsFolder" ),
625 : : -1,
626 : 0 : getCppuBooleanType(),
627 : : PropertyAttribute::BOUND | PropertyAttribute::READONLY
628 : : ),
629 : : Property(
630 : : ::rtl::OUString( "Title" ),
631 : : -1,
632 : 0 : getCppuType( static_cast< const ::rtl::OUString * >( 0 ) ),
633 : : PropertyAttribute::BOUND | PropertyAttribute::READONLY
634 : : )
635 : 0 : };
636 : 0 : return Sequence< Property >( aProperties, sizeof( aProperties ) / sizeof( aProperties[0] ) );
637 : : }
638 : :
639 : : //------------------------------------------------------------------------------------------------------------------
640 : 0 : bool Content::impl_isFolder()
641 : : {
642 : 0 : if ( !!m_aIsFolder )
643 : 0 : return *m_aIsFolder;
644 : :
645 : 0 : bool bIsFolder = false;
646 : : try
647 : : {
648 : 0 : Sequence< Property > aProps(1);
649 : 0 : aProps[0].Name = ::rtl::OUString( "IsFolder" );
650 : 0 : Reference< XRow > xRow( getPropertyValues( aProps, NULL ), UNO_SET_THROW );
651 : 0 : bIsFolder = xRow->getBoolean(1);
652 : : }
653 : 0 : catch( const Exception& )
654 : : {
655 : : DBG_UNHANDLED_EXCEPTION();
656 : : }
657 : 0 : m_aIsFolder.reset( bIsFolder );
658 : 0 : return *m_aIsFolder;
659 : : }
660 : :
661 : : //------------------------------------------------------------------------------------------------------------------
662 : 0 : void Content::impl_determineContentType()
663 : : {
664 : 0 : if ( !!m_aContentType )
665 : 0 : return;
666 : :
667 : 0 : m_aContentType.reset( ContentProvider::getArtificialNodeContentType() );
668 : 0 : if ( m_eExtContentType == E_EXTENSION_CONTENT )
669 : : {
670 : : try
671 : : {
672 : 0 : Sequence< Property > aProps(1);
673 : 0 : aProps[0].Name = ::rtl::OUString( "ContentType" );
674 : 0 : Reference< XRow > xRow( getPropertyValues( aProps, NULL ), UNO_SET_THROW );
675 : 0 : m_aContentType.reset( xRow->getString(1) );
676 : : }
677 : 0 : catch( const Exception& )
678 : : {
679 : : DBG_UNHANDLED_EXCEPTION();
680 : : }
681 : : }
682 : : }
683 : :
684 : : //......................................................................................................................
685 : : } } } // namespace ucp::ext
686 : : //......................................................................................................................
687 : :
688 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|