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