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