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