1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_webdav.hxx"
26 /**************************************************************************
27                                TODO
28  **************************************************************************
29 
30  *************************************************************************/
31 
32 #include <set>
33 #include <com/sun/star/beans/Property.hpp>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <com/sun/star/beans/PropertyValue.hpp>
36 #include <com/sun/star/ucb/CommandInfo.hpp>
37 #include <com/sun/star/ucb/ContentInfo.hpp>
38 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
39 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
40 #include <com/sun/star/ucb/PostCommandArgument2.hpp>
41 #include <com/sun/star/ucb/PropertyCommandArgument.hpp>
42 #include <com/sun/star/ucb/TransferInfo.hpp>
43 #include <com/sun/star/uno/Sequence.hxx>
44 #include <com/sun/star/util/DateTime.hpp>
45 #include <com/sun/star/ucb/Lock.hpp>
46 #include <com/sun/star/ucb/LockEntry.hpp>
47 #include "webdavcontent.hxx"
48 #include "webdavprovider.hxx"
49 #include "DAVSession.hxx"
50 #include "ContentProperties.hxx"
51 
52 using namespace com::sun::star;
53 using namespace http_dav_ucp;
54 
55 //=========================================================================
56 //
57 // ContentProvider implementation.
58 //
59 //=========================================================================
60 
getProperty(const rtl::OUString & rPropName,beans::Property & rProp,bool bStrict)61 bool ContentProvider::getProperty(
62         const rtl::OUString & rPropName, beans::Property & rProp, bool bStrict )
63 {
64     if ( !m_pProps )
65     {
66         osl::MutexGuard aGuard( m_aMutex );
67         if ( !m_pProps )
68         {
69             m_pProps = new PropertyMap;
70 
71             //////////////////////////////////////////////////////////////
72             // Fill map of known properties...
73             //////////////////////////////////////////////////////////////
74 
75             // Mandatory UCB properties.
76             m_pProps->insert(
77                 beans::Property(
78                     rtl::OUString(
79                         RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
80                     -1,
81                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
82                     beans::PropertyAttribute::BOUND
83                         | beans::PropertyAttribute::READONLY ) );
84 
85             m_pProps->insert(
86                 beans::Property(
87                     rtl::OUString(
88                         RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
89                     -1,
90                     getCppuBooleanType(),
91                     beans::PropertyAttribute::BOUND
92                         | beans::PropertyAttribute::READONLY ) );
93 
94             m_pProps->insert(
95                 beans::Property(
96                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
97                     -1,
98                     getCppuBooleanType(),
99                     beans::PropertyAttribute::BOUND
100                         | beans::PropertyAttribute::READONLY ) );
101 
102             m_pProps->insert(
103                 beans::Property(
104                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
105                     -1,
106                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
107                     beans::PropertyAttribute::BOUND ) );
108 
109             // Optional UCB properties.
110 
111             m_pProps->insert(
112                 beans::Property(
113                     rtl::OUString(
114                         RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
115                     -1,
116                     getCppuType( static_cast< const util::DateTime * >( 0 ) ),
117                     beans::PropertyAttribute::BOUND
118                         | beans::PropertyAttribute::READONLY ) );
119 
120             m_pProps->insert(
121                 beans::Property(
122                     rtl::OUString(
123                         RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ),
124                     -1,
125                     getCppuType( static_cast< const util::DateTime * >( 0 ) ),
126                     beans::PropertyAttribute::BOUND
127                         | beans::PropertyAttribute::READONLY ) );
128 
129             m_pProps->insert(
130                 beans::Property(
131                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
132                     -1,
133                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
134                     beans::PropertyAttribute::BOUND
135                         | beans::PropertyAttribute::READONLY ) );
136 
137             m_pProps->insert(
138                 beans::Property(
139                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
140                     -1,
141                     getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
142                     beans::PropertyAttribute::BOUND
143                         | beans::PropertyAttribute::READONLY ) );
144 
145             m_pProps->insert(
146                 beans::Property(
147                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ),
148                     -1,
149                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
150                     beans::PropertyAttribute::BOUND
151                         | beans::PropertyAttribute::READONLY ) );
152 
153             m_pProps->insert(
154                 beans::Property(
155                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
156                         "CreatableContentsInfo" ) ),
157                     -1,
158                     getCppuType( static_cast<
159                         const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
160                     beans::PropertyAttribute::BOUND
161                         | beans::PropertyAttribute::READONLY ) );
162 
163             // Standard DAV properties.
164 
165             m_pProps->insert(
166                 beans::Property(
167                     DAVProperties::CREATIONDATE,
168                     -1,
169                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
170                     beans::PropertyAttribute::BOUND
171                         | beans::PropertyAttribute::READONLY ) );
172 
173             m_pProps->insert(
174                 beans::Property(
175                     DAVProperties::DISPLAYNAME,
176                     -1,
177                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
178                     beans::PropertyAttribute::BOUND ) );
179 
180             m_pProps->insert(
181                 beans::Property(
182                     DAVProperties::GETCONTENTLANGUAGE,
183                     -1,
184                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
185                     beans::PropertyAttribute::BOUND
186                         | beans::PropertyAttribute::READONLY ) );
187 
188             m_pProps->insert(
189                 beans::Property(
190                     DAVProperties::GETCONTENTLENGTH,
191                     -1,
192                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
193                     beans::PropertyAttribute::BOUND
194                         | beans::PropertyAttribute::READONLY ) );
195 
196             m_pProps->insert(
197                 beans::Property(
198                     DAVProperties::GETCONTENTTYPE ,
199                     -1,
200                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
201                     beans::PropertyAttribute::BOUND
202                         | beans::PropertyAttribute::READONLY ) );
203 
204             m_pProps->insert(
205                 beans::Property(
206                     DAVProperties::GETETAG,
207                     -1,
208                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
209                     beans::PropertyAttribute::BOUND
210                         | beans::PropertyAttribute::READONLY ) );
211 
212             m_pProps->insert(
213                 beans::Property(
214                     DAVProperties::GETLASTMODIFIED,
215                     -1,
216                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
217                     beans::PropertyAttribute::BOUND
218                         | beans::PropertyAttribute::READONLY ) );
219 
220             m_pProps->insert(
221                 beans::Property(
222                     DAVProperties::LOCKDISCOVERY,
223                     -1,
224                     getCppuType( static_cast<
225                                     const uno::Sequence< ucb::Lock > * >( 0 ) ),
226                     beans::PropertyAttribute::BOUND
227                         | beans::PropertyAttribute::READONLY ) );
228 
229             m_pProps->insert(
230                 beans::Property(
231                     DAVProperties::RESOURCETYPE,
232                     -1,
233                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
234                     beans::PropertyAttribute::BOUND
235                         | beans::PropertyAttribute::READONLY ) );
236 
237             m_pProps->insert(
238                 beans::Property(
239                     DAVProperties::SUPPORTEDLOCK,
240                     -1,
241                     getCppuType( static_cast<
242                                     const uno::Sequence<
243                                         ucb::LockEntry > * >( 0 ) ),
244                     beans::PropertyAttribute::BOUND
245                         | beans::PropertyAttribute::READONLY ) );
246 
247             m_pProps->insert(
248                 beans::Property(
249                     DAVProperties::EXECUTABLE,
250                     -1,
251                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
252                     beans::PropertyAttribute::BOUND ) );
253         }
254     }
255 
256     //////////////////////////////////////////////////////////////
257     // Lookup property.
258     //////////////////////////////////////////////////////////////
259 
260     beans::Property aProp;
261     aProp.Name = rPropName;
262     const PropertyMap::const_iterator it = m_pProps->find( aProp );
263     if ( it != m_pProps->end() )
264     {
265         rProp = (*it);
266     }
267     else
268     {
269         if ( bStrict )
270             return false;
271 
272         // All unknown props are treated as:
273         rProp = beans::Property(
274                     rPropName,
275                     - 1,
276                     getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
277                     beans::PropertyAttribute::BOUND );
278     }
279 
280     return true;
281 }
282 
283 //=========================================================================
284 //
285 // Content implementation.
286 //
287 //=========================================================================
288 
289 // virtual
getProperties(const uno::Reference<ucb::XCommandEnvironment> & xEnv)290 uno::Sequence< beans::Property > Content::getProperties(
291     const uno::Reference< ucb::XCommandEnvironment > & xEnv )
292 {
293     sal_Bool bTransient;
294     std::auto_ptr< DAVResourceAccess > xResAccess;
295     std::auto_ptr< ContentProperties > xCachedProps;
296     rtl::Reference< ContentProvider >  xProvider;
297 
298     {
299         osl::Guard< osl::Mutex > aGuard( m_aMutex );
300 
301         bTransient = m_bTransient;
302         xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
303         if ( m_xCachedProps.get() )
304             xCachedProps.reset(
305                 new ContentProperties( *m_xCachedProps.get() ) );
306         xProvider.set( m_pProvider );
307     }
308 
309     typedef std::set< rtl::OUString > StringSet;
310     StringSet aPropSet;
311 
312     // No server access for just created (not yet committed) objects.
313     // Only a minimal set of properties supported at this stage.
314     if ( !bTransient )
315     {
316         // Obtain all properties supported for this resource from server.
317         try
318         {
319             std::vector< DAVResourceInfo > props;
320             xResAccess->PROPFIND( DAVZERO, props, xEnv );
321 
322             // Note: vector always contains exactly one resource info, because
323             //       we used a depth of DAVZERO for PROPFIND.
324             aPropSet.insert( (*props.begin()).properties.begin(),
325                              (*props.begin()).properties.end() );
326         }
327         catch ( DAVException const & )
328         {
329         }
330     }
331 
332     // Add DAV properties, map DAV properties to UCB properties.
333     sal_Bool bHasCreationDate     = sal_False; // creationdate     <-> DateCreated
334     sal_Bool bHasGetLastModified  = sal_False; // getlastmodified  <-> DateModified
335     sal_Bool bHasGetContentType   = sal_False; // getcontenttype   <-> MediaType
336     sal_Bool bHasGetContentLength = sal_False; // getcontentlength <-> Size
337 
338     sal_Bool bHasContentType      = sal_False;
339     sal_Bool bHasIsDocument       = sal_False;
340     sal_Bool bHasIsFolder         = sal_False;
341     sal_Bool bHasTitle            = sal_False;
342     sal_Bool bHasBaseURI          = sal_False;
343     sal_Bool bHasDateCreated      = sal_False;
344     sal_Bool bHasDateModified     = sal_False;
345     sal_Bool bHasMediaType        = sal_False;
346     sal_Bool bHasSize             = sal_False;
347     sal_Bool bHasCreatableInfos   = sal_False;
348 
349     {
350         std::set< rtl::OUString >::const_iterator it  = aPropSet.begin();
351         std::set< rtl::OUString >::const_iterator end = aPropSet.end();
352         while ( it != end )
353         {
354             if ( !bHasCreationDate &&
355                  ( (*it) == DAVProperties::CREATIONDATE ) )
356             {
357                 bHasCreationDate = sal_True;
358             }
359             else if ( !bHasGetLastModified &&
360                       ( (*it) == DAVProperties::GETLASTMODIFIED ) )
361             {
362                 bHasGetLastModified = sal_True;
363             }
364             else if ( !bHasGetContentType &&
365                       ( (*it) == DAVProperties::GETCONTENTTYPE ) )
366             {
367                 bHasGetContentType = sal_True;
368             }
369             else if ( !bHasGetContentLength &&
370                       ( (*it) == DAVProperties::GETCONTENTLENGTH ) )
371             {
372                 bHasGetContentLength = sal_True;
373             }
374             else if ( !bHasContentType &&
375                       (*it).equalsAsciiL(
376                             RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
377             {
378                 bHasContentType = sal_True;
379             }
380             else if ( !bHasIsDocument &&
381                       (*it).equalsAsciiL(
382                             RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
383             {
384                 bHasIsDocument = sal_True;
385             }
386             else if ( !bHasIsFolder &&
387                       (*it).equalsAsciiL(
388                             RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
389             {
390                 bHasIsFolder = sal_True;
391             }
392             else if ( !bHasTitle &&
393                       (*it).equalsAsciiL(
394                             RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
395             {
396                 bHasTitle = sal_True;
397             }
398             else if ( !bHasBaseURI &&
399                       (*it).equalsAsciiL(
400                             RTL_CONSTASCII_STRINGPARAM( "BaseURI" ) ) )
401             {
402                 bHasBaseURI = sal_True;
403             }
404             else if ( !bHasDateCreated &&
405                       (*it).equalsAsciiL(
406                             RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) )
407             {
408                 bHasDateCreated = sal_True;
409             }
410             else if ( !bHasDateModified &&
411                       (*it).equalsAsciiL(
412                             RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) )
413             {
414                 bHasDateModified = sal_True;
415             }
416             else if ( !bHasMediaType &&
417                       (*it).equalsAsciiL(
418                             RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
419             {
420                 bHasMediaType = sal_True;
421             }
422             else if ( !bHasSize &&
423                       (*it).equalsAsciiL(
424                             RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
425             {
426                 bHasSize = sal_True;
427             }
428             else if ( !bHasCreatableInfos &&
429                       (*it).equalsAsciiL(
430                             RTL_CONSTASCII_STRINGPARAM(
431                                 "CreatableContentsInfo" ) ) )
432             {
433                 bHasCreatableInfos = sal_True;
434             }
435             it++;
436         }
437     }
438 
439     // Add mandatory properties.
440     if ( !bHasContentType )
441         aPropSet.insert(
442             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ) );
443 
444     if ( !bHasIsDocument )
445         aPropSet.insert(
446             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ) );
447 
448     if ( !bHasIsFolder )
449         aPropSet.insert(
450             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ) );
451 
452     if ( !bHasTitle )
453     {
454         // Always present since it can be calculated from content's URI.
455         aPropSet.insert(
456             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ) );
457     }
458 
459     // Add optional properties.
460 
461     if ( !bHasBaseURI )
462     {
463         // Always present since it can be calculated from content's URI.
464         aPropSet.insert(
465             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ) );
466     }
467 
468     if ( !bHasDateCreated && bHasCreationDate )
469         aPropSet.insert(
470             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ) );
471 
472     if ( !bHasDateModified && bHasGetLastModified )
473         aPropSet.insert(
474             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ) );
475 
476     if ( !bHasMediaType && bHasGetContentType )
477         aPropSet.insert(
478             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) );
479 
480     if ( !bHasSize && bHasGetContentLength )
481         aPropSet.insert(
482             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ) );
483 
484     if ( !bHasCreatableInfos )
485         aPropSet.insert(
486             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
487                 "CreatableContentsInfo" ) ) );
488 
489     // Add cached properties, if present and still missing.
490     if ( xCachedProps.get() )
491     {
492         const std::set< rtl::OUString >::const_iterator set_end
493             = aPropSet.end();
494 
495         const std::auto_ptr< PropertyValueMap > & xProps
496             = xCachedProps->getProperties();
497 
498         PropertyValueMap::const_iterator       map_it  = xProps->begin();
499         const PropertyValueMap::const_iterator map_end = xProps->end();
500 
501         while ( map_it != map_end )
502         {
503             if ( aPropSet.find( (*map_it).first ) == set_end )
504                 aPropSet.insert( (*map_it).first );
505 
506             ++map_it;
507         }
508     }
509 
510     // std::set -> uno::Sequence
511     sal_Int32 nCount = aPropSet.size();
512     uno::Sequence< beans::Property > aProperties( nCount );
513 
514     std::set< rtl::OUString >::const_iterator it = aPropSet.begin();
515     beans::Property aProp;
516 
517     for ( sal_Int32 n = 0; n < nCount; ++n, ++it )
518     {
519         xProvider->getProperty( (*it), aProp );
520         aProperties[ n ] = aProp;
521     }
522 
523     return aProperties;
524 }
525 
526 //=========================================================================
527 // virtual
getCommands(const uno::Reference<ucb::XCommandEnvironment> & xEnv)528 uno::Sequence< ucb::CommandInfo > Content::getCommands(
529     const uno::Reference< ucb::XCommandEnvironment > & xEnv )
530 {
531     osl::Guard< osl::Mutex > aGuard( m_aMutex );
532 
533     uno::Sequence< ucb::CommandInfo > aCmdInfo( 10 );
534 
535     ///////////////////////////////////////////////////////////////
536     // Mandatory commands
537     ///////////////////////////////////////////////////////////////
538 
539     aCmdInfo[ 0 ] =
540             ucb::CommandInfo(
541                 rtl::OUString(
542                     RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
543                 -1,
544                 getCppuVoidType() );
545     aCmdInfo[ 1 ] =
546             ucb::CommandInfo(
547                 rtl::OUString(
548                     RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
549                 -1,
550                 getCppuVoidType() );
551     aCmdInfo[ 2 ] =
552             ucb::CommandInfo(
553                 rtl::OUString(
554                     RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
555                 -1,
556                 getCppuType( static_cast<
557                                 uno::Sequence< beans::Property > * >( 0 ) ) );
558     aCmdInfo[ 3 ] =
559             ucb::CommandInfo(
560                 rtl::OUString(
561                     RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
562                 -1,
563                 getCppuType( static_cast<
564                     uno::Sequence< beans::PropertyValue > * >( 0 ) ) );
565 
566     ///////////////////////////////////////////////////////////////
567     // Optional standard commands
568     ///////////////////////////////////////////////////////////////
569 
570     aCmdInfo[ 4 ] =
571             ucb::CommandInfo(
572                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
573                 -1,
574                 getCppuBooleanType() );
575     aCmdInfo[ 5 ] =
576             ucb::CommandInfo(
577                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
578                 -1,
579                 getCppuType( static_cast<
580                     ucb::InsertCommandArgument * >( 0 ) ) );
581     aCmdInfo[ 6 ] =
582             ucb::CommandInfo(
583                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
584                 -1,
585                 getCppuType( static_cast<
586                     ucb::OpenCommandArgument2 * >( 0 ) ) );
587 
588     ///////////////////////////////////////////////////////////////
589     // New commands
590     ///////////////////////////////////////////////////////////////
591 
592     aCmdInfo[ 7 ] =
593             ucb::CommandInfo(
594                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "post" ) ),
595                 -1,
596                 getCppuType( static_cast<
597                     ucb::PostCommandArgument2 * >( 0 ) ) );
598     aCmdInfo[ 8 ] =
599             ucb::CommandInfo(
600                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "addProperty" ) ),
601                 -1,
602                 getCppuType( static_cast<
603                     ucb::PropertyCommandArgument * >( 0 ) ) );
604     aCmdInfo[ 9 ] =
605             ucb::CommandInfo(
606                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "removeProperty" ) ),
607                 -1,
608                 getCppuType( static_cast<
609                     rtl::OUString * >( 0 ) ) );
610 
611     sal_Bool bFolder = sal_False;
612 
613     try
614     {
615         bFolder = isFolder( xEnv );
616     }
617     catch ( uno::Exception const & )
618     {
619         return aCmdInfo;
620     }
621 
622     sal_Bool bSupportsLocking = supportsExclusiveWriteLock( xEnv );
623 
624     sal_Int32 nPos = aCmdInfo.getLength();
625     sal_Int32 nMoreCmds = ( bFolder ? 2 : 0 ) + ( bSupportsLocking ? 2 : 0 );
626     if ( nMoreCmds )
627         aCmdInfo.realloc( nPos + nMoreCmds );
628     else
629         return aCmdInfo;
630 
631     if ( bFolder )
632     {
633         ///////////////////////////////////////////////////////////////
634         // Optional standard commands
635         ///////////////////////////////////////////////////////////////
636 
637         aCmdInfo[ nPos ] =
638             ucb::CommandInfo(
639                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
640                 -1,
641                 getCppuType( static_cast< ucb::TransferInfo * >( 0 ) ) );
642         nPos++;
643         aCmdInfo[ nPos ] =
644             ucb::CommandInfo(
645                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
646                     "createNewContent" ) ),
647                 -1,
648                 getCppuType( static_cast< ucb::ContentInfo * >( 0 ) ) );
649         nPos++;
650     }
651     else
652     {
653         // no document-only commands at the moment.
654     }
655 
656     if ( bSupportsLocking )
657     {
658         aCmdInfo[ nPos ] =
659             ucb::CommandInfo(
660                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "lock" ) ),
661                 -1,
662                 getCppuVoidType() );
663         nPos++;
664         aCmdInfo[ nPos ] =
665             ucb::CommandInfo(
666                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unlock" ) ),
667                 -1,
668                 getCppuVoidType() );
669         nPos++;
670     }
671     return aCmdInfo;
672 }
673