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