xref: /trunk/main/ucb/workben/ucb/ucbdemo.cxx (revision d941b70c83dc1cf56dc95264273f8a288e742c24)
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 #include <stack>
28 #include <rtl/ustrbuf.hxx>
29 #include <vos/mutex.hxx>
30 #include <vos/process.hxx>
31 #include <cppuhelper/weak.hxx>
32 #include <cppuhelper/bootstrap.hxx>
33 #include <com/sun/star/ucb/ContentAction.hpp>
34 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
35 #include <com/sun/star/ucb/ContentResultSetCapability.hpp>
36 #include <com/sun/star/ucb/SearchCommandArgument.hpp>
37 #include <com/sun/star/ucb/NameClash.hpp>
38 #include <com/sun/star/ucb/TransferInfo.hpp>
39 #include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp>
40 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
41 #include <com/sun/star/ucb/CommandInfo.hpp>
42 #include <com/sun/star/ucb/XContentProviderManager.hpp>
43 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
44 #include <com/sun/star/beans/Property.hpp>
45 #include <com/sun/star/lang/XComponent.hpp>
46 #include <com/sun/star/ucb/CHAOSProgressStart.hpp>
47 #include <com/sun/star/ucb/OpenMode.hpp>
48 #include <com/sun/star/ucb/ResultSetException.hpp>
49 #include <com/sun/star/io/XOutputStream.hpp>
50 #include <com/sun/star/beans/XPropertySet.hpp>
51 #include <com/sun/star/beans/XPropertyContainer.hpp>
52 #include <com/sun/star/ucb/XProgressHandler.hpp>
53 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
54 #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
55 #include <com/sun/star/beans/XPropertiesChangeNotifier.hpp>
56 #include <com/sun/star/ucb/XCommandProcessor.hpp>
57 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
58 #include <com/sun/star/sdbc/XRow.hpp>
59 #include <com/sun/star/ucb/XContentAccess.hpp>
60 #include <com/sun/star/ucb/XCommandInfo.hpp>
61 #include <com/sun/star/beans/PropertyValue.hpp>
62 #include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
63 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
64 #include <comphelper/processfactory.hxx>
65 #include <ucbhelper/configurationkeys.hxx>
66 #include <ucbhelper/fileidentifierconverter.hxx>
67 #include <ucbhelper/contentbroker.hxx>
68 #include <tools/debug.hxx>
69 
70 #include "tools/time.hxx"
71 #include <vcl/wrkwin.hxx>
72 #include <vcl/toolbox.hxx>
73 #include <vcl/edit.hxx>
74 #include <vcl/lstbox.hxx>
75 #include <vcl/svapp.hxx>
76 #include <vcl/help.hxx>
77 #include <srcharg.hxx>
78 
79 using ucbhelper::getLocalFileURL;
80 using ucbhelper::getSystemPathFromFileURL;
81 using ucbhelper::getFileURLFromSystemPath;
82 
83 using namespace com::sun::star;
84 
85 /*========================================================================
86  *
87  * MyOutWindow.
88  *
89  *======================================================================*/
90 
91 #define MYOUTWINDOW_MAXLINES 4096
92 
93 class MyOutWindow : public ListBox
94 {
95 public:
96     MyOutWindow( Window *pParent, WinBits nWinStyle )
97     : ListBox ( pParent, nWinStyle | WB_AUTOHSCROLL ) {}
98     ~MyOutWindow() {}
99 
100     void Append( const String &rLine );
101 };
102 
103 //-------------------------------------------------------------------------
104 void MyOutWindow::Append( const String &rLine )
105 {
106     String aLine( rLine );
107 
108     xub_StrLen nPos = aLine.Search( '\n' );
109     while ( nPos != STRING_NOTFOUND )
110     {
111         if ( GetEntryCount() >= MYOUTWINDOW_MAXLINES )
112             RemoveEntry( 0 );
113 
114         InsertEntry( aLine.Copy( 0, nPos ) );
115 
116         aLine.Erase( 0, nPos + 1 );
117         nPos = aLine.Search( '\n' );
118     }
119 
120     if ( GetEntryCount() >= MYOUTWINDOW_MAXLINES )
121         RemoveEntry( 0 );
122 
123     InsertEntry( aLine );
124 
125     SetTopEntry( MYOUTWINDOW_MAXLINES - 1 );
126 }
127 
128 /*========================================================================
129  *
130  * MessagePrinter.
131  *
132  *=======================================================================*/
133 
134 class MessagePrinter
135 {
136 protected:
137     MyOutWindow* m_pOutEdit;
138 
139 public:
140     MessagePrinter( MyOutWindow* pOutEdit = NULL )
141     : m_pOutEdit( pOutEdit ) {}
142     void setOutEdit( MyOutWindow* pOutEdit )
143     { m_pOutEdit = pOutEdit; }
144     void print( const sal_Char* pText );
145     void print( const UniString& rText );
146 };
147 
148 //-------------------------------------------------------------------------
149 void MessagePrinter::print( const sal_Char* pText )
150 {
151     print( UniString::CreateFromAscii( pText ) );
152 }
153 
154 //-------------------------------------------------------------------------
155 void MessagePrinter::print( const UniString& rText )
156 {
157     vos::OGuard aGuard( Application::GetSolarMutex() );
158 
159     if ( m_pOutEdit )
160     {
161         m_pOutEdit->Append( rText );
162         m_pOutEdit->Update();
163     }
164 }
165 
166 //============================================================================
167 //
168 //  TestOutputStream
169 //
170 //============================================================================
171 
172 class TestOutputStream:
173     public cppu::OWeakObject,
174     public io::XOutputStream
175 {
176     rtl::OUString m_sStart;
177     bool m_bMore;
178 
179 public:
180     TestOutputStream(): m_bMore(false) {}
181 
182     virtual uno::Any SAL_CALL queryInterface(const uno::Type & rType)
183     throw(uno::RuntimeException);
184     virtual void SAL_CALL acquire() throw ()
185     { OWeakObject::acquire(); }
186 
187     virtual void SAL_CALL release() throw ()
188     { OWeakObject::release(); }
189 
190     virtual void SAL_CALL writeBytes(const uno::Sequence< sal_Int8 > & rData)
191         throw(uno::RuntimeException);
192 
193     virtual void SAL_CALL flush() throw() {}
194 
195     virtual void SAL_CALL closeOutput() throw() {};
196 
197     rtl::OUString getStart() const;
198 };
199 
200 //============================================================================
201 // virtual
202 uno::Any SAL_CALL
203 TestOutputStream::queryInterface(const uno::Type & rType)
204     throw(uno::RuntimeException)
205 {
206     uno::Any aRet = cppu::queryInterface(rType,
207                         static_cast< io::XOutputStream * >(this));
208     return aRet.hasValue() ? aRet : OWeakObject::queryInterface(rType);
209 }
210 
211 //============================================================================
212 // virtual
213 void SAL_CALL TestOutputStream::writeBytes(
214                                     const uno::Sequence< sal_Int8 > & rData)
215     throw(uno::RuntimeException)
216 {
217     sal_Int32 nLen = rData.getLength();
218     if (m_sStart.getLength() + nLen > 500)
219     {
220         nLen = 500 - m_sStart.getLength();
221         m_bMore = true;
222     }
223     m_sStart
224         += rtl::OUString(reinterpret_cast< const sal_Char * >(rData.
225                                                               getConstArray()),
226                          nLen, RTL_TEXTENCODING_ISO_8859_1);
227 }
228 
229 //============================================================================
230 rtl::OUString TestOutputStream::getStart() const
231 {
232     rtl::OUString sResult = m_sStart;
233     if (m_bMore)
234         sResult += rtl::OUString::createFromAscii("...");
235     return sResult;
236 }
237 
238 /*========================================================================
239  *
240  * ProgressHandler.
241  *
242  *=======================================================================*/
243 
244 class ProgressHandler:
245     public cppu::OWeakObject,
246     public ucb::XProgressHandler
247 {
248     MessagePrinter & m_rPrinter;
249 
250     rtl::OUString toString(const uno::Any & rStatus);
251 
252 public:
253     ProgressHandler(MessagePrinter & rThePrinter): m_rPrinter(rThePrinter) {}
254 
255     virtual uno::Any SAL_CALL queryInterface(
256                                 const uno::Type & rType)
257         throw(uno::RuntimeException);
258 
259     virtual void SAL_CALL acquire() throw ()
260     { OWeakObject::acquire(); }
261 
262     virtual void SAL_CALL release() throw ()
263     { OWeakObject::release(); }
264 
265     virtual void SAL_CALL push(const uno::Any & rStatus)
266         throw (uno::RuntimeException);
267 
268     virtual void SAL_CALL update(const uno::Any & rStatus)
269         throw (uno::RuntimeException);
270 
271     virtual void SAL_CALL pop() throw (uno::RuntimeException);
272 };
273 
274 rtl::OUString ProgressHandler::toString(const uno::Any & rStatus)
275 {
276     ucb::CHAOSProgressStart aStart;
277     if (rStatus >>= aStart)
278     {
279         rtl::OUString sResult;
280         if (aStart.Text.getLength() > 0)
281         {
282             sResult = aStart.Text;
283             sResult += rtl::OUString::createFromAscii(" ");
284         }
285         sResult += rtl::OUString::createFromAscii("[");
286         sResult += rtl::OUString::valueOf(aStart.Minimum);
287         sResult += rtl::OUString::createFromAscii("..");
288         sResult += rtl::OUString::valueOf(aStart.Maximum);
289         sResult += rtl::OUString::createFromAscii("]");
290         return sResult;
291     }
292 
293     rtl::OUString sText;
294     if (rStatus >>= sText)
295         return sText;
296 
297     sal_Int32 nValue;
298     if (rStatus >>= nValue)
299     {
300         rtl::OUString sResult = rtl::OUString::createFromAscii("..");
301         sResult += rtl::OUString::valueOf(nValue);
302         sResult += rtl::OUString::createFromAscii("..");
303         return rtl::OUString(sResult);
304     }
305 
306     return rtl::OUString::createFromAscii("(Unknown object)");
307 }
308 
309 //============================================================================
310 // virtual
311 uno::Any SAL_CALL
312 ProgressHandler::queryInterface( const uno::Type & rType )
313     throw(uno::RuntimeException)
314 {
315     uno::Any aRet = cppu::queryInterface(
316                         rType,
317                         static_cast< ucb::XProgressHandler* >(this));
318     return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
319 }
320 
321 //============================================================================
322 // virtual
323 void SAL_CALL ProgressHandler::push(const uno::Any & rStatus)
324     throw (uno::RuntimeException)
325 {
326     rtl::OUString sMessage = rtl::OUString::createFromAscii("Status push: ");
327     sMessage += toString(rStatus);
328     m_rPrinter.print(sMessage);
329 }
330 
331 //============================================================================
332 // virtual
333 void SAL_CALL ProgressHandler::update(const uno::Any & rStatus)
334     throw (uno::RuntimeException)
335 {
336     rtl::OUString sMessage = rtl::OUString::createFromAscii("Status update: ");
337     sMessage += toString(rStatus);
338     m_rPrinter.print(sMessage);
339 }
340 
341 //============================================================================
342 // virtual
343 void SAL_CALL ProgressHandler::pop() throw (uno::RuntimeException)
344 {
345     m_rPrinter.print("Status pop");
346 }
347 
348 /*========================================================================
349  *
350  * Ucb.
351  *
352  *=======================================================================*/
353 
354 #define UCB_MODULE_NAME  "ucb1"
355 
356 class Ucb : public MessagePrinter
357 {
358 private:
359     uno::Reference< lang::XMultiServiceFactory >      m_xFac;
360     uno::Reference< ucb::XContentProvider >          m_xProv;
361     uno::Reference< ucb::XContentIdentifierFactory > m_xIdFac;
362     rtl::OUString m_aConfigurationKey1;
363     rtl::OUString m_aConfigurationKey2;
364     sal_Bool m_bInited : 1;
365 
366     static rtl::OUString getUnoURL();
367 
368 public:
369     Ucb( uno::Reference< lang::XMultiServiceFactory >& rxFactory,
370          rtl::OUString const & rConfigurationKey1,
371          rtl::OUString const & rConfigurationKey2 );
372     ~Ucb();
373 
374     sal_Bool init();
375 
376     uno::Reference< lang::XMultiServiceFactory > getServiceFactory() const
377     { return m_xFac; }
378 
379     uno::Reference< ucb::XContentIdentifierFactory >
380     getContentIdentifierFactory();
381     uno::Reference< ucb::XContentProvider >
382     getContentProvider();
383 
384     static rtl::OUString m_aProtocol;
385 };
386 
387 // static
388 rtl::OUString Ucb::m_aProtocol;
389 
390 //-------------------------------------------------------------------------
391 // static
392 rtl::OUString Ucb::getUnoURL()
393 {
394     rtl::OUString aUnoURL(rtl::OUString::createFromAscii(
395                          "uno:socket,host=localhost,port=8121;"));
396     if (m_aProtocol.getLength() == 0)
397         aUnoURL += rtl::OUString::createFromAscii("urp");
398     else
399         aUnoURL += m_aProtocol;
400     aUnoURL += rtl::OUString::createFromAscii(";UCB.Factory");
401     return aUnoURL;
402 }
403 
404 //-------------------------------------------------------------------------
405 Ucb::Ucb( uno::Reference< lang::XMultiServiceFactory >& rxFactory,
406           rtl::OUString const & rConfigurationKey1,
407           rtl::OUString const & rConfigurationKey2 )
408 : m_xFac( rxFactory ),
409   m_aConfigurationKey1( rConfigurationKey1 ),
410   m_aConfigurationKey2( rConfigurationKey2 ),
411   m_bInited( sal_False )
412 {
413 }
414 
415 //-------------------------------------------------------------------------
416 Ucb::~Ucb()
417 {
418 }
419 
420 //-------------------------------------------------------------------------
421 sal_Bool Ucb::init()
422 {
423     if ( m_bInited )
424         return sal_True;
425 
426     // Create auto configured UCB:
427     if (m_xFac.is())
428         try
429         {
430             rtl::OUString aPipe;
431             vos::OSecurity().getUserIdent(aPipe);
432             uno::Sequence< uno::Any > aArgs(4);
433             aArgs[0] <<= m_aConfigurationKey1;
434             aArgs[1] <<= m_aConfigurationKey2;
435             aArgs[2] <<= rtl::OUString::createFromAscii("PIPE");
436             aArgs[3] <<= aPipe;
437 #if 0
438             m_xProv
439                 = uno::Reference< XContentProvider >(
440                       m_xFac->
441                           createInstanceWithArguments(
442                               rtl::OUString::createFromAscii(
443                                   "com.sun.star.ucb."
444                                       "UniversalContentBroker"),
445                               aArgs),
446                          uno::UNO_QUERY);
447 #else
448             ::ucbhelper::ContentBroker::initialize( m_xFac, aArgs );
449             m_xProv
450                 = ::ucbhelper::ContentBroker::get()->getContentProviderInterface();
451 #endif
452         }
453         catch (uno::Exception const &) {}
454 
455     if (m_xProv.is())
456     {
457         print("UCB initialized");
458         uno::Reference< ucb::XContentProviderManager > xProvMgr(
459             m_xProv, uno::UNO_QUERY);
460         if (xProvMgr.is())
461         {
462             print("Registered schemes:");
463             uno::Sequence< ucb::ContentProviderInfo >
464                 aInfos(xProvMgr->queryContentProviders());
465             for (sal_Int32 i = 0; i < aInfos.getLength(); ++i)
466             {
467                 String aText(RTL_CONSTASCII_USTRINGPARAM("    "));
468                 aText += UniString(aInfos[i].Scheme);
469                 print(aText);
470             }
471         }
472     }
473     else
474         print("Error initializing UCB");
475 
476     m_bInited = m_xProv.is();
477     return m_bInited;
478 }
479 
480 //-------------------------------------------------------------------------
481 uno::Reference< ucb::XContentIdentifierFactory >
482 Ucb::getContentIdentifierFactory()
483 {
484     if ( !m_xIdFac.is() )
485     {
486         if ( init() )
487             m_xIdFac = uno::Reference< ucb::XContentIdentifierFactory >(
488                             m_xProv, uno::UNO_QUERY );
489     }
490 
491     return m_xIdFac;
492 }
493 
494 //-------------------------------------------------------------------------
495 uno::Reference< ucb::XContentProvider > Ucb::getContentProvider()
496 {
497     if ( !m_xProv.is() )
498         init();
499 
500     return m_xProv;
501 }
502 
503 /*========================================================================
504  *
505  * UcbTaskEnvironment.
506  *
507  *=======================================================================*/
508 
509 class UcbTaskEnvironment : public cppu::OWeakObject,
510                            public ucb::XCommandEnvironment
511 {
512     uno::Reference< task::XInteractionHandler > m_xInteractionHandler;
513     uno::Reference< ucb::XProgressHandler > m_xProgressHandler;
514 
515 public:
516     UcbTaskEnvironment( const uno::Reference< task::XInteractionHandler>&
517                          rxInteractionHandler,
518                         const uno::Reference< ucb::XProgressHandler>&
519                          rxProgressHandler );
520     virtual ~UcbTaskEnvironment();
521 
522     // Interface implementations...
523 
524     // XInterface
525 
526     virtual uno::Any SAL_CALL queryInterface( const uno::Type & rType )
527         throw( uno::RuntimeException );
528     virtual void SAL_CALL acquire()
529         throw();
530     virtual void SAL_CALL release()
531         throw();
532 
533     // XCommandEnvironemnt
534 
535     virtual uno::Reference<task::XInteractionHandler> SAL_CALL
536     getInteractionHandler()
537         throw (uno::RuntimeException)
538     { return m_xInteractionHandler; }
539 
540     virtual uno::Reference<ucb::XProgressHandler> SAL_CALL
541     getProgressHandler()
542         throw (uno::RuntimeException)
543     { return m_xProgressHandler; }
544  };
545 
546 //-------------------------------------------------------------------------
547 UcbTaskEnvironment::UcbTaskEnvironment(
548                     const uno::Reference< task::XInteractionHandler >&
549                      rxInteractionHandler,
550                     const uno::Reference< ucb::XProgressHandler >&
551                      rxProgressHandler )
552 : m_xInteractionHandler( rxInteractionHandler ),
553   m_xProgressHandler( rxProgressHandler )
554 {
555 }
556 
557 //-------------------------------------------------------------------------
558 // virtual
559 UcbTaskEnvironment::~UcbTaskEnvironment()
560 {
561 }
562 
563 //----------------------------------------------------------------------------
564 //
565 // XInterface methods
566 //
567 //----------------------------------------------------------------------------
568 
569 // virtual
570 uno::Any SAL_CALL
571 UcbTaskEnvironment::queryInterface( const uno::Type & rType )
572     throw( uno::RuntimeException )
573 {
574     uno::Any aRet = cppu::queryInterface(
575             rType, static_cast< ucb::XCommandEnvironment* >( this ) );
576     return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
577 }
578 
579 //----------------------------------------------------------------------------
580 // virtual
581 void SAL_CALL UcbTaskEnvironment::acquire()
582     throw()
583 {
584     OWeakObject::acquire();
585 }
586 
587 //----------------------------------------------------------------------------
588 // virtual
589 void SAL_CALL UcbTaskEnvironment::release()
590     throw()
591 {
592     OWeakObject::release();
593 }
594 
595 /*========================================================================
596  *
597  * UcbCommandProcessor.
598  *
599  *=======================================================================*/
600 
601 class UcbCommandProcessor : public MessagePrinter
602 {
603 protected:
604     Ucb& m_rUCB;
605 
606 private:
607     uno::Reference< ucb::XCommandProcessor > m_xProcessor;
608     sal_Int32 m_aCommandId;
609 
610 public:
611     UcbCommandProcessor( Ucb& rUCB,
612                          const uno::Reference<
613                             ucb::XCommandProcessor >& rxProcessor,
614                          MyOutWindow* pOutEdit );
615 
616     virtual ~UcbCommandProcessor();
617 
618     uno::Any executeCommand( const rtl::OUString& rName,
619                              const uno::Any& rArgument,
620                              bool bPrint = true );
621 };
622 
623 //-------------------------------------------------------------------------
624 UcbCommandProcessor::UcbCommandProcessor( Ucb& rUCB,
625                                           const uno::Reference<
626                                             ucb::XCommandProcessor >&
627                                               rxProcessor,
628                                           MyOutWindow* pOutEdit)
629 : MessagePrinter( pOutEdit ),
630   m_rUCB( rUCB ),
631   m_xProcessor( rxProcessor ),
632   m_aCommandId( 0 )
633 {
634     if ( m_xProcessor.is() )
635     {
636         // Generally, one command identifier per thread is enough. It
637         // can be used for all commands executed by the processor which
638         // created this id.
639         m_aCommandId = m_xProcessor->createCommandIdentifier();
640     }
641 }
642 
643 //----------------------------------------------------------------------------
644 // virtual
645 UcbCommandProcessor::~UcbCommandProcessor()
646 {
647 }
648 
649 //----------------------------------------------------------------------------
650 uno::Any UcbCommandProcessor::executeCommand( const rtl::OUString& rName,
651                                               const uno::Any& rArgument,
652                                               bool bPrint )
653 {
654     if ( m_xProcessor.is() )
655     {
656         ucb::Command aCommand;
657         aCommand.Name     = rName;
658         aCommand.Handle   = -1; /* unknown */
659         aCommand.Argument = rArgument;
660 
661         uno::Reference< task::XInteractionHandler > xInteractionHandler;
662         if (m_rUCB.getServiceFactory().is())
663             xInteractionHandler
664                 = uno::Reference< task::XInteractionHandler >(
665                       m_rUCB.getServiceFactory()->
666                           createInstance(
667                               rtl::OUString::createFromAscii(
668                                   "com.sun.star.task.InteractionHandler")),
669                       uno::UNO_QUERY);
670         uno::Reference< ucb::XProgressHandler >
671             xProgressHandler(new ProgressHandler(m_rUCB));
672         uno::Reference< ucb::XCommandEnvironment > xEnv(
673             new UcbTaskEnvironment( xInteractionHandler, xProgressHandler ) );
674 
675         if ( bPrint )
676         {
677             UniString aText( UniString::CreateFromAscii(
678                                 RTL_CONSTASCII_STRINGPARAM(
679                                     "Executing command: " ) ) );
680             aText += UniString( rName );
681             print( aText );
682         }
683 
684         // Execute command
685         uno::Any aResult;
686         bool bException = false;
687         bool bAborted = false;
688         try
689         {
690             aResult = m_xProcessor->execute( aCommand, m_aCommandId, xEnv );
691         }
692         catch ( ucb::CommandAbortedException const & )
693         {
694             bAborted = true;
695         }
696         catch ( uno::Exception const & )
697         {
698             bException = true;
699         }
700 
701         if ( bPrint )
702         {
703             if ( bException )
704                 print( "execute(...) threw an exception!" );
705 
706             if ( bAborted )
707                 print( "execute(...) aborted!" );
708 
709             if ( !bException && !bAborted )
710                 print( "execute() finished." );
711         }
712 
713         return aResult;
714     }
715 
716     print( "executeCommand failed!" );
717     return uno::Any();
718 }
719 
720 /*========================================================================
721  *
722  * UcbContent.
723  *
724  *=======================================================================*/
725 
726 class UcbContent : public UcbCommandProcessor,
727                    public cppu::OWeakObject,
728                    public ucb::XContentEventListener,
729                    public beans::XPropertiesChangeListener
730 {
731     uno::Reference< ucb::XContent > m_xContent;
732 
733     struct OpenStackEntry
734     {
735         uno::Reference< ucb::XContentIdentifier > m_xIdentifier;
736         uno::Reference< ucb::XContent > m_xContent;
737         sal_uInt32 m_nLevel;
738         bool m_bUseIdentifier;
739 
740         OpenStackEntry(uno::Reference< ucb::XContentIdentifier > const &
741                         rTheIdentifier,
742                        sal_uInt32 nTheLevel):
743             m_xIdentifier(rTheIdentifier), m_nLevel(nTheLevel),
744             m_bUseIdentifier(true) {}
745 
746         OpenStackEntry(uno::Reference< ucb::XContent > const & rTheContent,
747                        sal_uInt32 nTheLevel):
748             m_xContent(rTheContent), m_nLevel(nTheLevel),
749             m_bUseIdentifier(false) {}
750     };
751     typedef std::stack< OpenStackEntry > OpenStack;
752 
753 private:
754     UcbContent( Ucb& rUCB,
755                 uno::Reference< ucb::XContent >& rxContent,
756                 MyOutWindow* pOutEdit );
757 
758 protected:
759     virtual ~UcbContent();
760 
761 public:
762     static UcbContent* create(
763             Ucb& rUCB, const UniString& rURL, MyOutWindow* pOutEdit );
764     void dispose();
765 
766     const UniString getURL() const;
767     const UniString getType() const;
768 
769     uno::Sequence< ucb::CommandInfo > getCommands();
770     uno::Sequence< beans::Property >    getProperties();
771 
772     uno::Any  getPropertyValue( const rtl::OUString& rName );
773     void setPropertyValue( const rtl::OUString& rName, const uno::Any& rValue );
774     void addProperty     ( const rtl::OUString& rName, const uno::Any& rValue );
775     void removeProperty  ( const rtl::OUString& rName );
776 
777     rtl::OUString getStringPropertyValue( const rtl::OUString& rName );
778     void setStringPropertyValue( const rtl::OUString& rName,
779                                  const rtl::OUString& rValue );
780     void addStringProperty( const rtl::OUString& rName,
781                             const rtl::OUString& rValue );
782     void open( const rtl::OUString & rName, const UniString& rInput,
783                bool bPrint, bool bTiming, bool bSort,
784                OpenStack * pStack = 0, sal_uInt32 nLevel = 0,
785                sal_Int32 nFetchSize = 0 );
786     void openAll( Ucb& rUCB, bool bPrint, bool bTiming, bool bSort,
787                   sal_Int32 nFetchSize );
788     void transfer( const rtl::OUString& rSourceURL, sal_Bool bMove );
789     void destroy();
790 
791     // XInterface
792     virtual uno::Any SAL_CALL queryInterface( const uno::Type & rType )
793         throw( uno::RuntimeException );
794     virtual void SAL_CALL
795     acquire()
796         throw();
797     virtual void SAL_CALL
798     release()
799         throw();
800 
801     // XEventListener
802     // ( base interface of XContentEventListener, XPropertiesChangeListener )
803     virtual void SAL_CALL
804     disposing( const lang::EventObject& Source )
805         throw( uno::RuntimeException );
806 
807     // XContentEventListener
808     virtual void SAL_CALL
809     contentEvent( const ucb::ContentEvent& evt )
810         throw( uno::RuntimeException );
811 
812     // XPropertiesChangeListener
813     virtual void SAL_CALL
814     propertiesChange( const uno::Sequence< beans::PropertyChangeEvent >& evt )
815         throw( uno::RuntimeException );
816 };
817 
818 //-------------------------------------------------------------------------
819 UcbContent::UcbContent( Ucb& rUCB,
820                         uno::Reference< ucb::XContent >& rxContent,
821                         MyOutWindow* pOutEdit)
822 : UcbCommandProcessor( rUCB,
823                        uno::Reference< ucb::XCommandProcessor >(
824                                                 rxContent, uno::UNO_QUERY ),
825                        pOutEdit ),
826   m_xContent( rxContent )
827 {
828 }
829 
830 //----------------------------------------------------------------------------
831 // virtual
832 UcbContent::~UcbContent()
833 {
834 }
835 
836 //-------------------------------------------------------------------------
837 // static
838 UcbContent* UcbContent::create(
839         Ucb& rUCB, const UniString& rURL, MyOutWindow* pOutEdit )
840 {
841     if ( !rURL.Len() )
842         return NULL;
843 
844     //////////////////////////////////////////////////////////////////////
845     // Get XContentIdentifier interface from UCB and let it create an
846     // identifer for the given URL.
847     //////////////////////////////////////////////////////////////////////
848 
849     uno::Reference< ucb::XContentIdentifierFactory > xIdFac =
850                                         rUCB.getContentIdentifierFactory();
851     if ( !xIdFac.is() )
852         return NULL;
853 
854     uno::Reference< ucb::XContentIdentifier > xId =
855                             xIdFac->createContentIdentifier( rURL );
856     if ( !xId.is() )
857         return NULL;
858 
859     //////////////////////////////////////////////////////////////////////
860     // Get XContentProvider interface from UCB and let it create a
861     // content for the given identifier.
862     //////////////////////////////////////////////////////////////////////
863 
864     uno::Reference< ucb::XContentProvider > xProv
865         = rUCB.getContentProvider();
866     if ( !xProv.is() )
867         return NULL;
868 
869     uno::Reference< ucb::XContent > xContent;
870     try
871     {
872         xContent = xProv->queryContent( xId );
873     }
874     catch (ucb::IllegalIdentifierException const &) {}
875     if ( !xContent.is() )
876         return NULL;
877 
878     UcbContent* pNew = new UcbContent( rUCB, xContent, pOutEdit );
879     pNew->acquire();
880 
881     // Register listener(s).
882     xContent->addContentEventListener( pNew );
883 
884     uno::Reference< beans::XPropertiesChangeNotifier > xNotifier(
885         xContent, uno::UNO_QUERY );
886     if ( xNotifier.is() )
887     {
888         // Empty sequence -> interested in any property changes.
889         xNotifier->addPropertiesChangeListener(
890             uno::Sequence< rtl::OUString >(), pNew );
891     }
892 
893     return pNew;
894 }
895 
896 //-------------------------------------------------------------------------
897 const UniString UcbContent::getURL() const
898 {
899     uno::Reference< ucb::XContentIdentifier > xId(
900         m_xContent->getIdentifier() );
901     if ( xId.is() )
902         return UniString( xId->getContentIdentifier() );
903 
904     return UniString();
905 }
906 
907 //-------------------------------------------------------------------------
908 const UniString UcbContent::getType() const
909 {
910     const UniString aType( m_xContent->getContentType() );
911     return aType;
912 }
913 
914 //-------------------------------------------------------------------------
915 void UcbContent::dispose()
916 {
917     uno::Reference< lang::XComponent > xComponent( m_xContent, uno::UNO_QUERY );
918     if ( xComponent.is() )
919         xComponent->dispose();
920 }
921 
922 //----------------------------------------------------------------------------
923 void UcbContent::open( const rtl::OUString & rName, const UniString& rInput,
924                        bool bPrint, bool bTiming, bool bSort,
925                        OpenStack * pStack, sal_uInt32 nLevel,
926                        sal_Int32 nFetchSize )
927 {
928     uno::Any aArg;
929 
930     bool bDoSort = false;
931 
932     ucb::OpenCommandArgument2 aOpenArg;
933     if (rName.compareToAscii("search") == 0)
934     {
935         ucb::SearchCommandArgument aArgument;
936         if (!parseSearchArgument(rInput, aArgument.Info))
937         {
938             print("Can't parse search argument");
939             return;
940         }
941         aArgument.Properties.realloc(5);
942         aArgument.Properties[0].Name = rtl::OUString::createFromAscii("Title");
943         aArgument.Properties[0].Handle = -1;
944         aArgument.Properties[1].Name
945             = rtl::OUString::createFromAscii("DateCreated");
946         aArgument.Properties[1].Handle = -1;
947         aArgument.Properties[2].Name = rtl::OUString::createFromAscii("Size");
948         aArgument.Properties[2].Handle = -1;
949         aArgument.Properties[3].Name
950             = rtl::OUString::createFromAscii("IsFolder");
951         aArgument.Properties[3].Handle = -1;
952         aArgument.Properties[4].Name
953             = rtl::OUString::createFromAscii("IsDocument");
954         aArgument.Properties[4].Handle = -1;
955         aArg <<= aArgument;
956     }
957     else
958     {
959         aOpenArg.Mode = ucb::OpenMode::ALL;
960         aOpenArg.Priority = 32768;
961 //      if ( bFolder )
962         {
963             // Property values which shall be in the result set...
964             uno::Sequence< beans::Property > aProps( 5 );
965             beans::Property* pProps = aProps.getArray();
966             pProps[ 0 ].Name   = rtl::OUString::createFromAscii( "Title" );
967             pProps[ 0 ].Handle = -1; // Important!
968 /**/        pProps[ 0 ].Type = getCppuType(static_cast< rtl::OUString * >(0));
969                 // HACK for sorting...
970             pProps[ 1 ].Name   = rtl::OUString::createFromAscii( "DateCreated" );
971             pProps[ 1 ].Handle = -1; // Important!
972             pProps[ 2 ].Name   = rtl::OUString::createFromAscii( "Size" );
973             pProps[ 2 ].Handle = -1; // Important!
974             pProps[ 3 ].Name   = rtl::OUString::createFromAscii( "IsFolder" );
975             pProps[ 3 ].Handle = -1; // Important!
976 /**/        pProps[ 3 ].Type = getCppuType(static_cast< sal_Bool * >(0));
977                 // HACK for sorting...
978             pProps[ 4 ].Name   = rtl::OUString::createFromAscii( "IsDocument" );
979             pProps[ 4 ].Handle = -1; // Important!
980             aOpenArg.Properties = aProps;
981 
982             bDoSort = bSort;
983             if (bDoSort)
984             {
985                 // Sort criteria... Note that column numbering starts with 1!
986                 aOpenArg.SortingInfo.realloc(2);
987                 // primary sort criterium: column 4 --> IsFolder
988                 aOpenArg.SortingInfo[ 0 ].ColumnIndex = 4;
989                 aOpenArg.SortingInfo[ 0 ].Ascending   = sal_False;
990                 // secondary sort criterium: column 1 --> Title
991                 aOpenArg.SortingInfo[ 1 ].ColumnIndex = 1;
992                 aOpenArg.SortingInfo[ 1 ].Ascending   = sal_True;
993             }
994         }
995 //      else
996             aOpenArg.Sink
997                 = static_cast< cppu::OWeakObject * >(new TestOutputStream);
998         aArg <<= aOpenArg;
999     }
1000 
1001 //  putenv("PROT_REMOTE_ACTIVATE=1"); // to log remote uno traffic
1002 
1003     ULONG nTime = 0;
1004     if ( bTiming )
1005         nTime = Time::GetSystemTicks();
1006 
1007     uno::Any aResult = executeCommand( rName, aArg, bPrint );
1008 
1009     uno::Reference< ucb::XDynamicResultSet > xDynamicResultSet;
1010     if ( ( aResult >>= xDynamicResultSet ) && xDynamicResultSet.is() )
1011     {
1012         if (bDoSort)
1013         {
1014             sal_Int16 nCaps = xDynamicResultSet->getCapabilities();
1015             if (!(nCaps & ucb::ContentResultSetCapability::SORTED))
1016             {
1017                 if (bPrint)
1018                     print("Result set rows are not sorted"
1019                               "---using sorting cursor");
1020 
1021                 uno::Reference< ucb::XSortedDynamicResultSetFactory >
1022                     xSortedFactory;
1023                 if (m_rUCB.getServiceFactory().is())
1024                     xSortedFactory
1025                         = uno::Reference<
1026                             ucb::XSortedDynamicResultSetFactory >(
1027                               m_rUCB.
1028                                   getServiceFactory()->
1029                                       createInstance(
1030                                           rtl::OUString::createFromAscii(
1031                                               "com.sun.star.ucb.SortedDynamic"
1032                                                   "ResultSetFactory")),
1033                               uno::UNO_QUERY);
1034                 uno::Reference< ucb::XDynamicResultSet > xSorted;
1035                 if (xSortedFactory.is())
1036                     xSorted
1037                         = xSortedFactory->
1038                               createSortedDynamicResultSet(xDynamicResultSet,
1039                                                            aOpenArg.
1040                                                                SortingInfo,
1041                                                            0);
1042                 if (xSorted.is())
1043                     xDynamicResultSet = xSorted;
1044                 else
1045                     print("Sorting cursor not available!");
1046             }
1047         }
1048 
1049         uno::Reference< sdbc::XResultSet > xResultSet(
1050                                     xDynamicResultSet->getStaticResultSet() );
1051         if ( xResultSet.is() )
1052         {
1053             if ( bPrint )
1054             {
1055                 print( "Folder object opened - iterating:" );
1056                 print( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
1057                     "Content-ID : Title : Size : IsFolder : IsDocument\n"
1058                     "-------------------------------------------------" ) ) );
1059             }
1060 
1061             if (nFetchSize > 0)
1062             {
1063                 bool bSet = false;
1064                 uno::Reference< beans::XPropertySet > xProperties(
1065                     xResultSet, uno::UNO_QUERY);
1066                 if (xProperties.is())
1067                     try
1068                     {
1069                         xProperties->
1070                             setPropertyValue(rtl::OUString::createFromAscii(
1071                                                  "FetchSize"),
1072                                              uno::makeAny(nFetchSize));
1073                         bSet = true;
1074                     }
1075                     catch (beans::UnknownPropertyException const &) {}
1076                     catch (beans::PropertyVetoException const &) {}
1077                     catch (lang::IllegalArgumentException const &) {}
1078                     catch (lang::WrappedTargetException const &) {}
1079                 if (!bSet)
1080                     print("Fetch size not set!");
1081             }
1082 
1083             try
1084             {
1085                 ULONG n = 0;
1086                 uno::Reference< ucb::XContentAccess > xContentAccess(
1087                                                 xResultSet, uno::UNO_QUERY );
1088                 uno::Reference< sdbc::XRow > xRow( xResultSet, uno::UNO_QUERY );
1089 
1090                 while ( xResultSet->next() )
1091                 {
1092                     UniString aText;
1093 
1094                     if ( bPrint )
1095                     {
1096                         rtl::OUString aId( xContentAccess->
1097                                           queryContentIdentifierString() );
1098                         aText += UniString::CreateFromInt32( ++n );
1099                         aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM(
1100                                                ") " ) );
1101                         aText += UniString( aId );
1102                         aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM(
1103                                                " : " ) );
1104                     }
1105 
1106                     // Title:
1107                     UniString aTitle( xRow->getString( 1 ) );
1108                     if ( bPrint )
1109                     {
1110                         if ( aTitle.Len() == 0 && xRow->wasNull() )
1111                             aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM(
1112                                                    "<null>" ) );
1113                         else
1114                             aText += aTitle;
1115                         aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM(
1116                                                " : " ) );
1117                     }
1118 
1119                     // Size:
1120                     sal_Int32 nSize = xRow->getInt( 3 );
1121                     if ( bPrint )
1122                     {
1123                         if ( nSize == 0 && xRow->wasNull() )
1124                             aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM(
1125                                                    "<null>" ) );
1126                         else
1127                             aText += UniString::CreateFromInt32( nSize );
1128                         aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM(
1129                                                " : " ) );
1130                     }
1131 
1132                     // IsFolder:
1133                     sal_Bool bFolder = xRow->getBoolean( 4 );
1134                     if ( bPrint )
1135                     {
1136                         if ( !bFolder && xRow->wasNull() )
1137                             aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM(
1138                                                    "<null>" ) );
1139                         else
1140                             aText
1141                                 += bFolder ?
1142                                        UniString::CreateFromAscii(
1143                                            RTL_CONSTASCII_STRINGPARAM(
1144                                                "true" ) ) :
1145                                        UniString::CreateFromAscii(
1146                                            RTL_CONSTASCII_STRINGPARAM(
1147                                                "false" ) );
1148                         aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM(
1149                                                " : " ) );
1150                     }
1151 
1152                     // IsDocument:
1153                     sal_Bool bDocument = xRow->getBoolean( 5 );
1154                     if ( bPrint )
1155                     {
1156                         if ( !bFolder && xRow->wasNull() )
1157                             aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM(
1158                                 "<null>" ) );
1159                         else
1160                             aText
1161                                 += bDocument ?
1162                                        UniString::CreateFromAscii(
1163                                            RTL_CONSTASCII_STRINGPARAM(
1164                                                "true" ) ) :
1165                                        UniString::CreateFromAscii(
1166                                            RTL_CONSTASCII_STRINGPARAM(
1167                                                "false" ) ); //  IsDocument
1168                     }
1169 
1170                     if ( bPrint )
1171                         print( aText );
1172 
1173                     if ( pStack && bFolder )
1174                         pStack->push( OpenStackEntry(
1175 #if 1
1176                                           xContentAccess->
1177                                               queryContentIdentifier(),
1178 #else
1179                                           xContentAccess->queryContent(),
1180 #endif
1181                                           nLevel + 1 ) );
1182                 }
1183             }
1184             catch ( ucb::ResultSetException )
1185             {
1186                 print( "ResultSetException caught!" );
1187             }
1188 
1189             if ( bPrint )
1190                 print( "Iteration done." );
1191         }
1192     }
1193 
1194     uno::Reference< lang::XComponent > xComponent(
1195         xDynamicResultSet, uno::UNO_QUERY);
1196     if (xComponent.is())
1197         xComponent->dispose();
1198 
1199 //  putenv("PROT_REMOTE_ACTIVATE="); // to log remote uno traffic
1200 
1201     if ( bTiming )
1202     {
1203         nTime = Time::GetSystemTicks() - nTime;
1204         UniString
1205             aText( UniString::CreateFromAscii(
1206                        RTL_CONSTASCII_STRINGPARAM( "Operation took " ) ) );
1207         aText += UniString::CreateFromInt64( nTime );
1208         aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " ms." ) );
1209         print( aText );
1210     }
1211 }
1212 
1213 //----------------------------------------------------------------------------
1214 void UcbContent::openAll( Ucb& rUCB, bool bPrint, bool bTiming, bool bSort,
1215                           sal_Int32 nFetchSize )
1216 {
1217     ULONG nTime = 0;
1218     if ( bTiming )
1219         nTime = Time::GetSystemTicks();
1220 
1221     OpenStack aStack;
1222     aStack.push( OpenStackEntry( m_xContent, 0 ) );
1223 
1224     while ( !aStack.empty() )
1225     {
1226         OpenStackEntry aEntry( aStack.top() );
1227         aStack.pop();
1228 
1229         if ( bPrint )
1230         {
1231             UniString aText;
1232             for ( sal_uInt32 i = aEntry.m_nLevel; i != 0; --i )
1233                 aText += '=';
1234             aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "LEVEL " ) );
1235             aText += UniString::CreateFromInt64( aEntry.m_nLevel );
1236 
1237             uno::Reference< ucb::XContentIdentifier > xID;
1238             if ( aEntry.m_bUseIdentifier )
1239                 xID = aEntry.m_xIdentifier;
1240             else if ( aEntry.m_xContent.is() )
1241                 xID = aEntry.m_xContent->getIdentifier();
1242             if ( xID.is() )
1243             {
1244                 aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " ) );
1245                 aText += UniString( xID->getContentIdentifier() );
1246             }
1247 
1248             print( aText );
1249         }
1250 
1251         uno::Reference< ucb::XContent > xChild;
1252         if ( aEntry.m_bUseIdentifier )
1253         {
1254             uno::Reference< ucb::XContentProvider > xProv
1255                 = rUCB.getContentProvider();
1256             if ( !xProv.is() )
1257             {
1258                 print( "No content provider" );
1259                 return;
1260             }
1261 
1262             try
1263             {
1264                 xChild = xProv->queryContent( aEntry.m_xIdentifier );
1265             }
1266             catch (ucb::IllegalIdentifierException const &) {}
1267         }
1268         else
1269             xChild = aEntry.m_xContent;
1270         if ( !xChild.is() )
1271         {
1272             print( "No content" );
1273             return;
1274         }
1275 
1276         UcbContent( m_rUCB, xChild, m_pOutEdit ).
1277             open( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
1278                                                   "open" ) ),
1279                   UniString(), bPrint, false, bSort, &aStack,
1280                   aEntry.m_nLevel, nFetchSize );
1281     }
1282 
1283     if ( bTiming )
1284     {
1285         nTime = Time::GetSystemTicks() - nTime;
1286         UniString
1287             aText( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
1288                                                    "Operation took " ) ) );
1289         aText += UniString::CreateFromInt64( nTime );
1290         aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " ms." ) );
1291         print( aText );
1292     }
1293 }
1294 
1295 //----------------------------------------------------------------------------
1296 void UcbContent::transfer( const rtl::OUString& rSourceURL, sal_Bool bMove  )
1297 {
1298     if ( bMove )
1299         print( "Moving content..." );
1300     else
1301         print( "Copying content..." );
1302 
1303 #if 1 /* globalTransfer */
1304 
1305     uno::Reference< ucb::XCommandProcessor > xCommandProcessor(
1306                                 m_rUCB.getContentProvider(), uno::UNO_QUERY );
1307     if ( xCommandProcessor.is() )
1308     {
1309 
1310 #if 0
1311         ucb::Command aCommand(
1312             rtl::OUString::createFromAscii( "getCommandInfo" ), -1, Any() );
1313         uno::Reference< ucb::XCommandInfo > xInfo;
1314         xCommandProcessor->execute(
1315             aCommand, 0, uno::Reference< ucb::XCommandEnvironment >() )
1316                 >>= xInfo;
1317         if ( xInfo.is() )
1318         {
1319             ucb::CommandInfo aInfo
1320                 = xInfo->getCommandInfoByName(
1321                     rtl::OUString::createFromAscii( "globalTransfer" ) );
1322 
1323             uno::Sequence< ucb::CommandInfo > aCommands
1324                 = xInfo->getCommands();
1325             const ucb::CommandInfo* pCommands = aCommands.getConstArray();
1326 
1327             String aText( UniString::CreateFromAscii(
1328                             RTL_CONSTASCII_STRINGPARAM( "Commands:\n" ) ) );
1329             sal_uInt32 nCount = aCommands.getLength();
1330             for ( sal_uInt32 n = 0; n < nCount; ++n )
1331             {
1332                 aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "    " ) );
1333                 aText += String( pCommands[ n ].Name );
1334                 aText += '\n';
1335             }
1336             print( aText );
1337         }
1338 #endif
1339         ucb::GlobalTransferCommandArgument aArg(
1340                             bMove ? ucb::TransferCommandOperation_MOVE
1341                                   : ucb::TransferCommandOperation_COPY,
1342                             rSourceURL,
1343                             getURL(),
1344                             rtl::OUString(),
1345                             //rtl::OUString::createFromAscii( "NewTitle" ),
1346                             ucb::NameClash::ERROR );
1347 
1348         ucb::Command aTransferCommand( rtl::OUString::createFromAscii(
1349                                                 "globalTransfer" ),
1350                                              -1,
1351                                              uno::makeAny( aArg ) );
1352 
1353         uno::Reference< task::XInteractionHandler > xInteractionHandler;
1354         if (m_rUCB.getServiceFactory().is())
1355             xInteractionHandler
1356                 = uno::Reference< task::XInteractionHandler >(
1357                         m_rUCB.getServiceFactory()->
1358                             createInstance(
1359                                 rtl::OUString::createFromAscii(
1360                                     "com.sun.star.task.InteractionHandler")),
1361                         uno::UNO_QUERY);
1362         uno::Reference< ucb::XProgressHandler > xProgressHandler(
1363             new ProgressHandler(m_rUCB));
1364         uno::Reference< ucb::XCommandEnvironment > xEnv(
1365             new UcbTaskEnvironment( xInteractionHandler, xProgressHandler ) );
1366 
1367         try
1368         {
1369             xCommandProcessor->execute( aTransferCommand, 0, xEnv );
1370         }
1371         catch ( uno::Exception const & )
1372         {
1373             print( "globalTransfer threw exception!" );
1374             return;
1375         }
1376 
1377         print( "globalTransfer finished successfully" );
1378     }
1379 
1380 #else /* transfer */
1381 
1382     uno::Any aArg;
1383     aArg <<= ucb::TransferInfo(
1384             bMove, rSourceURL, rtl::OUString(), ucb::NameClash::ERROR );
1385     executeCommand( rtl::OUString::createFromAscii( "transfer" ), aArg );
1386 
1387 //  executeCommand( rtl::OUString::createFromAscii( "flush" ), Any() );
1388 
1389 #endif
1390 }
1391 
1392 //----------------------------------------------------------------------------
1393 void UcbContent::destroy()
1394 {
1395     print( "Deleting content..." );
1396 
1397     uno::Any aArg;
1398     aArg <<= sal_Bool( sal_True ); // delete physically, not only to trash.
1399     executeCommand( rtl::OUString::createFromAscii( "delete" ), aArg );
1400 
1401 //  executeCommand( rtl::OUString::createFromAscii( "flush" ), Any() );
1402 }
1403 
1404 //-------------------------------------------------------------------------
1405 uno::Sequence< ucb::CommandInfo > UcbContent::getCommands()
1406 {
1407     uno::Any aResult = executeCommand(
1408             rtl::OUString::createFromAscii( "getCommandInfo" ), uno::Any() );
1409 
1410     uno::Reference< ucb::XCommandInfo > xInfo;
1411     if ( aResult >>= xInfo )
1412     {
1413         uno::Sequence< ucb::CommandInfo > aCommands(
1414             xInfo->getCommands() );
1415         const ucb::CommandInfo* pCommands = aCommands.getConstArray();
1416 
1417         String aText( UniString::CreateFromAscii(
1418                         RTL_CONSTASCII_STRINGPARAM( "Commands:\n" ) ) );
1419         sal_uInt32 nCount = aCommands.getLength();
1420         for ( sal_uInt32 n = 0; n < nCount; ++n )
1421         {
1422             aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "    " ) );
1423             aText += String( pCommands[ n ].Name );
1424             aText += '\n';
1425         }
1426         print( aText );
1427 
1428         return aCommands;
1429     }
1430 
1431     print( "getCommands failed!" );
1432     return uno::Sequence< ucb::CommandInfo >();
1433 }
1434 
1435 //-------------------------------------------------------------------------
1436 uno::Sequence< beans::Property > UcbContent::getProperties()
1437 {
1438     uno::Any aResult = executeCommand(
1439         rtl::OUString::createFromAscii( "getPropertySetInfo" ), uno::Any() );
1440 
1441     uno::Reference< beans::XPropertySetInfo > xInfo;
1442     if ( aResult >>= xInfo )
1443     {
1444         uno::Sequence< beans::Property > aProps( xInfo->getProperties() );
1445         const beans::Property* pProps = aProps.getConstArray();
1446 
1447         String aText( UniString::CreateFromAscii(
1448                         RTL_CONSTASCII_STRINGPARAM( "Properties:\n" ) ) );
1449         sal_uInt32 nCount = aProps.getLength();
1450         for ( sal_uInt32 n = 0; n < nCount; ++n )
1451         {
1452             aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "    " ) );
1453             aText += UniString( pProps[ n ].Name );
1454             aText += '\n';
1455         }
1456         print( aText );
1457 
1458         return aProps;
1459     }
1460 
1461     print( "getProperties failed!" );
1462     return uno::Sequence< beans::Property >();
1463 }
1464 
1465 //----------------------------------------------------------------------------
1466 uno::Any UcbContent::getPropertyValue( const rtl::OUString& rName )
1467 {
1468     uno::Sequence< beans::Property > aProps( 1 );
1469     beans::Property& rProp = aProps.getArray()[ 0 ];
1470 
1471     rProp.Name       = rName;
1472     rProp.Handle     = -1; /* unknown */
1473 //  rProp.Type       = ;
1474 //  rProp.Attributes = ;
1475 
1476     uno::Any aArg;
1477     aArg <<= aProps;
1478 
1479     uno::Any aResult = executeCommand(
1480         rtl::OUString::createFromAscii( "getPropertyValues" ), aArg );
1481 
1482     uno::Reference< sdbc::XRow > xValues;
1483     if ( aResult >>= xValues )
1484         return xValues->getObject(
1485             1, uno::Reference< container::XNameAccess>() );
1486 
1487     print( "getPropertyValue failed!" );
1488     return uno::Any();
1489 }
1490 
1491 //----------------------------------------------------------------------------
1492 rtl::OUString UcbContent::getStringPropertyValue( const rtl::OUString& rName )
1493 {
1494     uno::Any aAny = getPropertyValue( rName );
1495     if ( aAny.getValueType() == getCppuType( (const ::rtl::OUString *)0 ) )
1496     {
1497         const rtl::OUString aValue(
1498             * static_cast< const rtl::OUString * >( aAny.getValue() ) );
1499 
1500         UniString aText( rName );
1501         aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " value: '" ) );
1502         aText += UniString( aValue );
1503         aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "'" ) );
1504         print( aText );
1505 
1506         return aValue;
1507     }
1508 
1509     print( "getStringPropertyValue failed!" );
1510     return rtl::OUString();
1511 }
1512 
1513 //----------------------------------------------------------------------------
1514 void UcbContent::setPropertyValue( const rtl::OUString& rName,
1515                                    const uno::Any& rValue )
1516 {
1517     uno::Sequence< beans::PropertyValue > aProps( 1 );
1518     beans::PropertyValue& rProp = aProps.getArray()[ 0 ];
1519 
1520     rProp.Name       = rName;
1521     rProp.Handle     = -1; /* unknown */
1522     rProp.Value      = rValue;
1523 //  rProp.State      = ;
1524 
1525     uno::Any aArg;
1526     aArg <<= aProps;
1527 
1528     executeCommand( rtl::OUString::createFromAscii( "setPropertyValues" ),
1529                     aArg );
1530 
1531 //  executeCommand( rtl::OUString::createFromAscii( "flush" ), Any() );
1532 }
1533 
1534 //----------------------------------------------------------------------------
1535 void UcbContent::setStringPropertyValue( const rtl::OUString& rName,
1536                                          const rtl::OUString& rValue )
1537 {
1538     uno::Any aAny;
1539     aAny <<= rValue;
1540     setPropertyValue( rName, aAny );
1541 
1542     UniString aText( rName );
1543     aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " value set to: '" ) );
1544     aText += UniString( rValue );
1545     aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "'" ) );
1546     print( aText );
1547 }
1548 
1549 //----------------------------------------------------------------------------
1550 void UcbContent::addProperty( const rtl::OUString& rName,
1551                               const uno::Any& rValue )
1552 {
1553     uno::Reference< beans::XPropertyContainer > xContainer( m_xContent,
1554                                                             uno::UNO_QUERY );
1555     if ( xContainer.is() )
1556     {
1557         UniString aText( UniString::CreateFromAscii(
1558                             RTL_CONSTASCII_STRINGPARAM(
1559                                 "Adding property: " ) ) );
1560         aText += UniString( rName );
1561         print( aText );
1562 
1563         try
1564         {
1565             xContainer->addProperty( rName, 0, rValue );
1566         }
1567         catch ( beans::PropertyExistException const & )
1568         {
1569             print( "Adding property failed. Already exists!" );
1570             return;
1571         }
1572         catch ( beans::IllegalTypeException const & )
1573         {
1574             print( "Adding property failed. Illegal Type!" );
1575             return;
1576         }
1577         catch ( lang::IllegalArgumentException const & )
1578         {
1579             print( "Adding property failed. Illegal Argument!" );
1580             return;
1581         }
1582 
1583         print( "Adding property succeeded." );
1584         return;
1585     }
1586 
1587     print( "Adding property failed. No XPropertyContainer!" );
1588 }
1589 
1590 //----------------------------------------------------------------------------
1591 void UcbContent::addStringProperty(
1592                     const rtl::OUString& rName, const rtl::OUString& rValue )
1593 {
1594     uno::Any aValue;
1595     aValue <<= rValue;
1596     addProperty( rName, aValue );
1597 }
1598 
1599 //----------------------------------------------------------------------------
1600 void UcbContent::removeProperty( const rtl::OUString& rName )
1601 {
1602     uno::Reference< beans::XPropertyContainer > xContainer( m_xContent,
1603                                                             uno::UNO_QUERY );
1604     if ( xContainer.is() )
1605     {
1606         UniString aText( UniString::CreateFromAscii(
1607                             RTL_CONSTASCII_STRINGPARAM(
1608                                 "Removing property: " ) ) );
1609         aText += UniString( rName );
1610         print( aText );
1611 
1612         try
1613         {
1614             xContainer->removeProperty( rName );
1615         }
1616         catch ( beans::UnknownPropertyException const & )
1617         {
1618             print( "Adding property failed. Unknown!" );
1619             return;
1620         }
1621 
1622         print( "Removing property succeeded." );
1623         return;
1624     }
1625 
1626     print( "Removing property failed. No XPropertyContainer!" );
1627 }
1628 
1629 //----------------------------------------------------------------------------
1630 //
1631 // XInterface methods
1632 //
1633 //----------------------------------------------------------------------------
1634 
1635 // virtual
1636 uno::Any SAL_CALL UcbContent::queryInterface( const uno::Type & rType )
1637     throw(uno::RuntimeException)
1638 {
1639     uno::Any aRet = cppu::queryInterface(
1640                 rType,
1641                 static_cast< lang::XEventListener* >(
1642                     static_cast< ucb::XContentEventListener* >( this ) ),
1643                 static_cast< ucb::XContentEventListener* >( this ),
1644                 static_cast< beans::XPropertiesChangeListener* >( this ) );
1645     return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
1646 }
1647 
1648 //----------------------------------------------------------------------------
1649 // virtual
1650 void SAL_CALL UcbContent::acquire()
1651     throw()
1652 {
1653     OWeakObject::acquire();
1654 }
1655 
1656 //----------------------------------------------------------------------------
1657 // virtual
1658 void SAL_CALL UcbContent::release()
1659     throw()
1660 {
1661     OWeakObject::release();
1662 }
1663 
1664 //----------------------------------------------------------------------------
1665 //
1666 // XEventListener methods.
1667 //
1668 //----------------------------------------------------------------------------
1669 
1670 // virtual
1671 void SAL_CALL UcbContent::disposing( const lang::EventObject& /*Source*/ )
1672     throw( uno::RuntimeException )
1673 {
1674     print ( "Content: disposing..." );
1675 }
1676 
1677 //----------------------------------------------------------------------------
1678 //
1679 // XContentEventListener methods,
1680 //
1681 //----------------------------------------------------------------------------
1682 
1683 // virtual
1684 void SAL_CALL UcbContent::contentEvent( const ucb::ContentEvent& evt )
1685     throw( uno::RuntimeException )
1686 {
1687     switch ( evt.Action )
1688     {
1689         case ucb::ContentAction::INSERTED:
1690         {
1691             UniString aText( UniString::CreateFromAscii(
1692                                 RTL_CONSTASCII_STRINGPARAM(
1693                                     "contentEvent: INSERTED: " ) ) );
1694             if ( evt.Content.is() )
1695             {
1696                 uno::Reference< ucb::XContentIdentifier > xId(
1697                                         evt.Content->getIdentifier() );
1698                 aText += UniString( xId->getContentIdentifier() );
1699                 aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ) );
1700                 aText += UniString( evt.Content->getContentType() );
1701             }
1702 
1703             print( aText );
1704             break;
1705         }
1706         case ucb::ContentAction::REMOVED:
1707             print( "contentEvent: REMOVED" );
1708             break;
1709 
1710         case ucb::ContentAction::DELETED:
1711             print( "contentEvent: DELETED" );
1712             break;
1713 
1714         case ucb::ContentAction::EXCHANGED:
1715             print( "contentEvent: EXCHANGED" );
1716             break;
1717 
1718         case ucb::ContentAction::SEARCH_MATCHED:
1719         {
1720             String aMatch(RTL_CONSTASCII_USTRINGPARAM(
1721                               "contentEvent: SEARCH MATCHED "));
1722             if (evt.Id.is())
1723             {
1724                 aMatch += String(evt.Id->getContentIdentifier());
1725                 if (evt.Content.is())
1726                 {
1727                     aMatch.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" - "));
1728                     aMatch += String(evt.Content->getContentType());
1729                 }
1730             }
1731             else
1732                 aMatch.AppendAscii(RTL_CONSTASCII_STRINGPARAM("<no id>"));
1733             print(aMatch);
1734             break;
1735         }
1736 
1737         default:
1738             print( "contentEvent..." );
1739             break;
1740     }
1741 }
1742 
1743 //----------------------------------------------------------------------------
1744 //
1745 // XPropertiesChangeListener methods.
1746 //
1747 //----------------------------------------------------------------------------
1748 
1749 // virtual
1750 void SAL_CALL UcbContent::propertiesChange(
1751                     const uno::Sequence< beans::PropertyChangeEvent >& evt )
1752     throw( uno::RuntimeException )
1753 {
1754     print( "propertiesChange..." );
1755 
1756     sal_uInt32 nCount = evt.getLength();
1757     if ( nCount )
1758     {
1759         const beans::PropertyChangeEvent* pEvents = evt.getConstArray();
1760         for ( sal_uInt32 n = 0; n < nCount; ++n )
1761         {
1762             UniString aText( UniString::CreateFromAscii(
1763                                 RTL_CONSTASCII_STRINGPARAM( "    " ) ) );
1764             aText += UniString( pEvents[ n ].PropertyName );
1765             print( aText );
1766         }
1767     }
1768 }
1769 
1770 /*========================================================================
1771  *
1772  * MyWin.
1773  *
1774  *=======================================================================*/
1775 
1776 #define MYWIN_ITEMID_CLEAR          1
1777 #define MYWIN_ITEMID_CREATE         2
1778 #define MYWIN_ITEMID_RELEASE        3
1779 #define MYWIN_ITEMID_COMMANDS       4
1780 #define MYWIN_ITEMID_PROPS          5
1781 #define MYWIN_ITEMID_ADD_PROP       6
1782 #define MYWIN_ITEMID_REMOVE_PROP    7
1783 #define MYWIN_ITEMID_GET_PROP       8
1784 #define MYWIN_ITEMID_SET_PROP       9
1785 #define MYWIN_ITEMID_OPEN           10
1786 #define MYWIN_ITEMID_OPEN_ALL       11
1787 #define MYWIN_ITEMID_UPDATE         12
1788 #define MYWIN_ITEMID_SYNCHRONIZE    13
1789 #define MYWIN_ITEMID_COPY           14
1790 #define MYWIN_ITEMID_MOVE           15
1791 #define MYWIN_ITEMID_DELETE         16
1792 #define MYWIN_ITEMID_SEARCH         17
1793 #define MYWIN_ITEMID_TIMING         18
1794 #define MYWIN_ITEMID_SORT           19
1795 #define MYWIN_ITEMID_FETCHSIZE      20
1796 #define MYWIN_ITEMID_SYS2URI        21
1797 #define MYWIN_ITEMID_URI2SYS        22
1798 #define MYWIN_ITEMID_OFFLINE        23
1799 #define MYWIN_ITEMID_ONLINE         24
1800 #define MYWIN_ITEMID_REORGANIZE     25
1801 
1802 //-------------------------------------------------------------------------
1803 class MyWin : public WorkWindow
1804 {
1805 private:
1806     ToolBox*            m_pTool;
1807     Edit*               m_pCmdEdit;
1808     MyOutWindow*        m_pOutEdit;
1809 
1810     Ucb         m_aUCB;
1811     UcbContent* m_pContent;
1812 
1813     sal_Int32 m_nFetchSize;
1814     bool m_bTiming;
1815     bool m_bSort;
1816 
1817 public:
1818     MyWin( Window *pParent, WinBits nWinStyle,
1819            uno::Reference< lang::XMultiServiceFactory >& rxFactory,
1820            rtl::OUString const & rConfigurationKey1,
1821            rtl::OUString const & rConfigurationKey2 );
1822     virtual ~MyWin();
1823 
1824     void Resize( void );
1825     DECL_LINK ( ToolBarHandler, ToolBox* );
1826 
1827     void print( const UniString& rText );
1828     void print( const sal_Char* pText );
1829 };
1830 
1831 //-------------------------------------------------------------------------
1832 MyWin::MyWin( Window *pParent, WinBits nWinStyle,
1833               uno::Reference< lang::XMultiServiceFactory >& rxFactory,
1834               rtl::OUString const & rConfigurationKey1,
1835               rtl::OUString const & rConfigurationKey2 )
1836 : WorkWindow( pParent, nWinStyle ),
1837   m_pTool( NULL ),
1838   m_pOutEdit( NULL ),
1839   m_aUCB( rxFactory, rConfigurationKey1, rConfigurationKey2 ),
1840   m_pContent( NULL ),
1841   m_nFetchSize( 0 ),
1842   m_bTiming( false ),
1843   m_bSort( false )
1844 {
1845     // ToolBox.
1846     m_pTool = new ToolBox( this, WB_3DLOOK | WB_BORDER  | WB_SCROLL );
1847 
1848     m_pTool->InsertItem ( MYWIN_ITEMID_CLEAR,
1849                           UniString::CreateFromAscii(
1850                             RTL_CONSTASCII_STRINGPARAM(
1851                                 "Clear" ) ) );
1852     m_pTool->SetHelpText( MYWIN_ITEMID_CLEAR,
1853                           UniString::CreateFromAscii(
1854                             RTL_CONSTASCII_STRINGPARAM(
1855                                 "Clear the Output Window" ) ) );
1856     m_pTool->InsertSeparator();
1857     m_pTool->InsertItem ( MYWIN_ITEMID_CREATE,
1858                           UniString::CreateFromAscii(
1859                             RTL_CONSTASCII_STRINGPARAM(
1860                                 "Create" ) ) );
1861     m_pTool->SetHelpText( MYWIN_ITEMID_CREATE,
1862                           UniString::CreateFromAscii(
1863                             RTL_CONSTASCII_STRINGPARAM(
1864                                 "Create a content" ) ) );
1865     m_pTool->InsertItem ( MYWIN_ITEMID_RELEASE,
1866                           UniString::CreateFromAscii(
1867                             RTL_CONSTASCII_STRINGPARAM(
1868                                 "Release" ) ) );
1869     m_pTool->SetHelpText( MYWIN_ITEMID_RELEASE,
1870                           UniString::CreateFromAscii(
1871                             RTL_CONSTASCII_STRINGPARAM(
1872                                 "Release current content" ) ) );
1873     m_pTool->InsertSeparator();
1874     m_pTool->InsertItem ( MYWIN_ITEMID_COMMANDS,
1875                           UniString::CreateFromAscii(
1876                             RTL_CONSTASCII_STRINGPARAM(
1877                                 "Commands" ) ) );
1878     m_pTool->SetHelpText( MYWIN_ITEMID_COMMANDS,
1879                           UniString::CreateFromAscii(
1880                             RTL_CONSTASCII_STRINGPARAM(
1881                                 "Get Commands supported by the content" ) ) );
1882     m_pTool->InsertItem ( MYWIN_ITEMID_PROPS,
1883                           UniString::CreateFromAscii(
1884                             RTL_CONSTASCII_STRINGPARAM(
1885                                 "Properties" ) ) );
1886     m_pTool->SetHelpText( MYWIN_ITEMID_PROPS,
1887                           UniString::CreateFromAscii(
1888                             RTL_CONSTASCII_STRINGPARAM(
1889                                 "Get Properties supported by the content" ) ) );
1890     m_pTool->InsertSeparator();
1891     m_pTool->InsertItem ( MYWIN_ITEMID_ADD_PROP,
1892                           UniString::CreateFromAscii(
1893                             RTL_CONSTASCII_STRINGPARAM(
1894                                 "addProperty" ) ) );
1895     m_pTool->SetHelpText( MYWIN_ITEMID_ADD_PROP,
1896                           UniString::CreateFromAscii(
1897                             RTL_CONSTASCII_STRINGPARAM(
1898                                 "Add a new string(!) property to the content. "
1899                                 "Type the property name in the entry field and "
1900                                 "push this button. The default value for the "
1901                                 "property will be set to the string 'DefaultValue'" ) ) );
1902     m_pTool->InsertItem ( MYWIN_ITEMID_REMOVE_PROP,
1903                           UniString::CreateFromAscii(
1904                             RTL_CONSTASCII_STRINGPARAM(
1905                                 "removeProperty" ) ) );
1906     m_pTool->SetHelpText( MYWIN_ITEMID_REMOVE_PROP,
1907                           UniString::CreateFromAscii(
1908                             RTL_CONSTASCII_STRINGPARAM(
1909                                 "Removes a property from the content. "
1910                                 "Type the property name in the entry field and "
1911                                 "push this button." ) ) );
1912     m_pTool->InsertItem ( MYWIN_ITEMID_GET_PROP,
1913                           UniString::CreateFromAscii(
1914                             RTL_CONSTASCII_STRINGPARAM(
1915                                 "getPropertyValue" ) ) );
1916     m_pTool->SetHelpText( MYWIN_ITEMID_GET_PROP,
1917                           UniString::CreateFromAscii(
1918                             RTL_CONSTASCII_STRINGPARAM(
1919                                 "Get a string(!) property value from the content. "
1920                                 "Type the property name in the entry field and "
1921                                 "push this button to obtain the value" ) ) );
1922     m_pTool->InsertItem ( MYWIN_ITEMID_SET_PROP,
1923                           UniString::CreateFromAscii(
1924                             RTL_CONSTASCII_STRINGPARAM(
1925                                 "setPropertyValue" ) ) );
1926     m_pTool->SetHelpText( MYWIN_ITEMID_SET_PROP,
1927                           UniString::CreateFromAscii(
1928                             RTL_CONSTASCII_STRINGPARAM(
1929                                 "Set a string(!) property value of the content."
1930                                 "Type the property name in the entry field and "
1931                                 "push this button to set the value to the string "
1932                                 "'NewValue'" ) ) );
1933     m_pTool->InsertSeparator();
1934     m_pTool->InsertItem ( MYWIN_ITEMID_OPEN,
1935                           UniString::CreateFromAscii(
1936                             RTL_CONSTASCII_STRINGPARAM(
1937                                 "Open" ) ) );
1938     m_pTool->SetHelpText( MYWIN_ITEMID_OPEN,
1939                           UniString::CreateFromAscii(
1940                             RTL_CONSTASCII_STRINGPARAM(
1941                                 "Open the content" ) ) );
1942     m_pTool->InsertItem ( MYWIN_ITEMID_OPEN_ALL,
1943                           UniString::CreateFromAscii(
1944                             RTL_CONSTASCII_STRINGPARAM(
1945                                 "Open All" ) ) );
1946     m_pTool->SetHelpText( MYWIN_ITEMID_OPEN_ALL,
1947                           UniString::CreateFromAscii(
1948                             RTL_CONSTASCII_STRINGPARAM(
1949                                 "Open the content and all of its"
1950                                     " children" ) ) );
1951     m_pTool->InsertItem ( MYWIN_ITEMID_UPDATE,
1952                           UniString::CreateFromAscii(
1953                             RTL_CONSTASCII_STRINGPARAM(
1954                                 "Update" ) ) );
1955     m_pTool->SetHelpText( MYWIN_ITEMID_UPDATE,
1956                           UniString::CreateFromAscii(
1957                             RTL_CONSTASCII_STRINGPARAM(
1958                                 "Update the content" ) ) );
1959     m_pTool->InsertItem ( MYWIN_ITEMID_SYNCHRONIZE,
1960                           UniString::CreateFromAscii(
1961                             RTL_CONSTASCII_STRINGPARAM(
1962                                 "Synchronize" ) ) );
1963     m_pTool->SetHelpText( MYWIN_ITEMID_SYNCHRONIZE,
1964                           UniString::CreateFromAscii(
1965                             RTL_CONSTASCII_STRINGPARAM(
1966                                 "Synchronize the content" ) ) );
1967     m_pTool->InsertItem ( MYWIN_ITEMID_SEARCH,
1968                           UniString::CreateFromAscii(
1969                             RTL_CONSTASCII_STRINGPARAM(
1970                                 "Search" ) ) );
1971     m_pTool->SetHelpText( MYWIN_ITEMID_SEARCH,
1972                           UniString::CreateFromAscii(
1973                             RTL_CONSTASCII_STRINGPARAM(
1974                                 "Search the content" ) ) );
1975 
1976     m_pTool->InsertItem ( MYWIN_ITEMID_REORGANIZE,
1977                           UniString::CreateFromAscii(
1978                             RTL_CONSTASCII_STRINGPARAM(
1979                                 "Reorganize" ) ) );
1980     m_pTool->SetHelpText( MYWIN_ITEMID_REORGANIZE,
1981                           UniString::CreateFromAscii(
1982                             RTL_CONSTASCII_STRINGPARAM(
1983                                 "Reorganize the content storage" ) ) );
1984 
1985     m_pTool->InsertSeparator();
1986     m_pTool->InsertItem ( MYWIN_ITEMID_COPY,
1987                           UniString::CreateFromAscii(
1988                             RTL_CONSTASCII_STRINGPARAM(
1989                                 "Copy" ) ) );
1990     m_pTool->SetHelpText( MYWIN_ITEMID_COPY,
1991                           UniString::CreateFromAscii(
1992                             RTL_CONSTASCII_STRINGPARAM(
1993                                 "Copy a content. Type the URL of the source "
1994                                 "content into the entry field." ) ) );
1995     m_pTool->InsertItem ( MYWIN_ITEMID_MOVE,
1996                           UniString::CreateFromAscii(
1997                             RTL_CONSTASCII_STRINGPARAM(
1998                                 "Move" ) ) );
1999     m_pTool->SetHelpText( MYWIN_ITEMID_MOVE,
2000                           UniString::CreateFromAscii(
2001                             RTL_CONSTASCII_STRINGPARAM(
2002                                 "Move a content. Type the URL of the source "
2003                                 "content into the entry field." ) ) );
2004     m_pTool->InsertItem ( MYWIN_ITEMID_DELETE,
2005                           UniString::CreateFromAscii(
2006                             RTL_CONSTASCII_STRINGPARAM(
2007                                 "Delete" ) ) );
2008     m_pTool->SetHelpText( MYWIN_ITEMID_DELETE,
2009                           UniString::CreateFromAscii(
2010                             RTL_CONSTASCII_STRINGPARAM(
2011                                 "Delete the content." ) ) );
2012 
2013     m_pTool->InsertSeparator();
2014     m_pTool->InsertItem ( MYWIN_ITEMID_TIMING,
2015                           UniString::CreateFromAscii(
2016                             RTL_CONSTASCII_STRINGPARAM(
2017                                 "Timing" ) ),
2018                           TIB_CHECKABLE | TIB_AUTOCHECK );
2019     m_pTool->SetHelpText( MYWIN_ITEMID_TIMING,
2020                           UniString::CreateFromAscii(
2021                             RTL_CONSTASCII_STRINGPARAM(
2022                                 "Display execution times instead of"
2023                                     " output" ) ) );
2024     m_pTool->InsertItem ( MYWIN_ITEMID_SORT,
2025                           UniString::CreateFromAscii(
2026                             RTL_CONSTASCII_STRINGPARAM(
2027                                 "Sort" ) ),
2028                           TIB_CHECKABLE | TIB_AUTOCHECK );
2029     m_pTool->SetHelpText( MYWIN_ITEMID_SORT,
2030                           UniString::CreateFromAscii(
2031                             RTL_CONSTASCII_STRINGPARAM(
2032                                 "Sort result sets" ) ) );
2033     m_pTool->InsertItem ( MYWIN_ITEMID_FETCHSIZE,
2034                           UniString::CreateFromAscii(
2035                             RTL_CONSTASCII_STRINGPARAM(
2036                                 "Fetch Size" ) ) );
2037     m_pTool->SetHelpText( MYWIN_ITEMID_FETCHSIZE,
2038                           UniString::CreateFromAscii(
2039                             RTL_CONSTASCII_STRINGPARAM(
2040                                 "Set cached cursor fetch size to positive value" ) ) );
2041 
2042     m_pTool->InsertSeparator();
2043     m_pTool->InsertItem ( MYWIN_ITEMID_SYS2URI,
2044                           UniString::CreateFromAscii(
2045                             RTL_CONSTASCII_STRINGPARAM(
2046                                 "UNC>URI" ) ) );
2047     m_pTool->SetHelpText( MYWIN_ITEMID_SYS2URI,
2048                           UniString::CreateFromAscii(
2049                             RTL_CONSTASCII_STRINGPARAM(
2050                                 "Translate 'System File Path' to URI,"
2051                                     " if possible" ) ) );
2052     m_pTool->InsertItem ( MYWIN_ITEMID_URI2SYS,
2053                           UniString::CreateFromAscii(
2054                             RTL_CONSTASCII_STRINGPARAM(
2055                                 "URI>UNC" ) ) );
2056     m_pTool->SetHelpText( MYWIN_ITEMID_URI2SYS,
2057                           UniString::CreateFromAscii(
2058                             RTL_CONSTASCII_STRINGPARAM(
2059                                 "Translate URI to 'System File Path',"
2060                                     " if possible" ) ) );
2061 
2062     m_pTool->InsertSeparator();
2063     m_pTool->InsertItem ( MYWIN_ITEMID_OFFLINE,
2064                           UniString::CreateFromAscii(
2065                             RTL_CONSTASCII_STRINGPARAM(
2066                                 "Offline" ) ) );
2067     m_pTool->SetHelpText( MYWIN_ITEMID_OFFLINE,
2068                           UniString::CreateFromAscii(
2069                             RTL_CONSTASCII_STRINGPARAM(
2070                                 "Go offline" ) ) );
2071     m_pTool->InsertItem ( MYWIN_ITEMID_ONLINE,
2072                           UniString::CreateFromAscii(
2073                             RTL_CONSTASCII_STRINGPARAM(
2074                                 "Online" ) ) );
2075     m_pTool->SetHelpText( MYWIN_ITEMID_ONLINE,
2076                           UniString::CreateFromAscii(
2077                             RTL_CONSTASCII_STRINGPARAM(
2078                                 "Go back online" ) ) );
2079 
2080     m_pTool->SetSelectHdl( LINK( this, MyWin, ToolBarHandler ) );
2081     m_pTool->Show();
2082 
2083     // Edit.
2084     m_pCmdEdit = new Edit( this );
2085     m_pCmdEdit->SetReadOnly( FALSE );
2086     m_pCmdEdit->SetText( UniString::CreateFromAscii(
2087                             RTL_CONSTASCII_STRINGPARAM( "file:///" ) ) );
2088     m_pCmdEdit->Show();
2089 
2090     // MyOutWindow.
2091     m_pOutEdit = new MyOutWindow( this, WB_HSCROLL | WB_VSCROLL | WB_BORDER );
2092     m_pOutEdit->SetReadOnly( TRUE );
2093     m_pOutEdit->Show();
2094 
2095     m_aUCB.setOutEdit( m_pOutEdit );
2096 }
2097 
2098 //-------------------------------------------------------------------------
2099 // virtual
2100 MyWin::~MyWin()
2101 {
2102     if ( m_pContent )
2103     {
2104         m_pContent->dispose();
2105         m_pContent->release();
2106     }
2107 
2108     delete m_pTool;
2109     delete m_pCmdEdit;
2110     delete m_pOutEdit;
2111 }
2112 
2113 //-------------------------------------------------------------------------
2114 void MyWin::Resize()
2115 {
2116     Size aWinSize = GetOutputSizePixel();
2117     int nWinW = aWinSize.Width();
2118     int nWinH = aWinSize.Height();
2119     int nBoxH = m_pTool->CalcWindowSizePixel().Height();
2120 
2121     m_pTool->SetPosSizePixel   (
2122         Point( 0, 0 ), Size ( nWinW, nBoxH ) );
2123     m_pCmdEdit->SetPosSizePixel(
2124         Point( 0, nBoxH ), Size( nWinW, nBoxH ) );
2125     m_pOutEdit->SetPosSizePixel(
2126         Point( 0, nBoxH + nBoxH ), Size ( nWinW, nWinH - ( nBoxH + nBoxH ) ) );
2127 }
2128 
2129 //-------------------------------------------------------------------------
2130 void MyWin::print( const sal_Char* pText )
2131 {
2132     print( UniString::CreateFromAscii( pText ) );
2133 }
2134 
2135 //-------------------------------------------------------------------------
2136 void MyWin::print( const UniString& rText )
2137 {
2138     vos::OGuard aGuard( Application::GetSolarMutex() );
2139 
2140     if ( m_pOutEdit )
2141     {
2142         m_pOutEdit->Append( rText );
2143         m_pOutEdit->Update();
2144     }
2145 }
2146 
2147 //-------------------------------------------------------------------------
2148 IMPL_LINK( MyWin, ToolBarHandler, ToolBox*, pToolBox )
2149 {
2150     USHORT nItemId   = pToolBox->GetCurItemId();
2151     UniString aCmdLine = m_pCmdEdit->GetText();
2152 
2153     ULONG n = Application::ReleaseSolarMutex();
2154 
2155     switch( nItemId )
2156     {
2157         case MYWIN_ITEMID_CLEAR:
2158         {
2159             vos::OGuard aGuard( Application::GetSolarMutex() );
2160 
2161             m_pOutEdit->Clear();
2162             m_pOutEdit->Show();
2163             break;
2164         }
2165 
2166         case MYWIN_ITEMID_CREATE:
2167             if ( m_pContent )
2168             {
2169                 UniString aText( UniString::CreateFromAscii(
2170                                     RTL_CONSTASCII_STRINGPARAM(
2171                                         "Content released: " ) ) );
2172                 aText += m_pContent->getURL();
2173 
2174                 m_pContent->dispose();
2175                 m_pContent->release();
2176                 m_pContent = NULL;
2177 
2178                 print( aText );
2179             }
2180 
2181             m_pContent = UcbContent::create( m_aUCB, aCmdLine, m_pOutEdit );
2182             if ( m_pContent )
2183             {
2184                 String aText( UniString::CreateFromAscii(
2185                                 RTL_CONSTASCII_STRINGPARAM(
2186                                     "Created content: " ) ) );
2187                 aText += String( m_pContent->getURL() );
2188                 aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ) );
2189                 aText += String( m_pContent->getType() );
2190                 print( aText );
2191             }
2192             else
2193             {
2194                 String aText( UniString::CreateFromAscii(
2195                                 RTL_CONSTASCII_STRINGPARAM(
2196                                     "Creation failed for content: " ) ) );
2197                 aText += String( aCmdLine );
2198                 print( aText );
2199             }
2200             break;
2201 
2202         case MYWIN_ITEMID_RELEASE:
2203             if ( m_pContent )
2204             {
2205                 UniString aText( UniString::CreateFromAscii(
2206                                     RTL_CONSTASCII_STRINGPARAM(
2207                                         "Content released: " ) ) );
2208                 aText += m_pContent->getURL();
2209 
2210                 m_pContent->dispose();
2211                 m_pContent->release();
2212                 m_pContent = NULL;
2213 
2214                 print( aText );
2215             }
2216             else
2217                 print( "No content!" );
2218 
2219             break;
2220 
2221         case MYWIN_ITEMID_COMMANDS:
2222             if ( m_pContent )
2223                 m_pContent->getCommands();
2224             else
2225                 print( "No content!" );
2226 
2227             break;
2228 
2229         case MYWIN_ITEMID_PROPS:
2230             if ( m_pContent )
2231                 m_pContent->getProperties();
2232             else
2233                 print( "No content!" );
2234 
2235             break;
2236 
2237         case MYWIN_ITEMID_ADD_PROP:
2238             if ( m_pContent )
2239                 m_pContent->addStringProperty(
2240                         aCmdLine,
2241                         rtl::OUString::createFromAscii( "DefaultValue" ) );
2242             else
2243                 print( "No content!" );
2244 
2245             break;
2246 
2247         case MYWIN_ITEMID_REMOVE_PROP:
2248             if ( m_pContent )
2249                 m_pContent->removeProperty( aCmdLine );
2250             else
2251                 print( "No content!" );
2252 
2253             break;
2254 
2255         case MYWIN_ITEMID_GET_PROP:
2256             if ( m_pContent )
2257                 m_pContent->getStringPropertyValue( aCmdLine );
2258             else
2259                 print( "No content!" );
2260 
2261             break;
2262 
2263         case MYWIN_ITEMID_SET_PROP:
2264             if ( m_pContent )
2265                 m_pContent->setStringPropertyValue(
2266                                 aCmdLine,
2267                                 rtl::OUString::createFromAscii( "NewValue" ) );
2268             else
2269                 print( "No content!" );
2270 
2271             break;
2272 
2273         case MYWIN_ITEMID_OPEN:
2274             if ( m_pContent )
2275                 m_pContent->open(rtl::OUString::createFromAscii("open"),
2276                                  aCmdLine, !m_bTiming, m_bTiming, m_bSort, 0,
2277                                  0, m_nFetchSize);
2278             else
2279                 print( "No content!" );
2280 
2281             break;
2282 
2283         case MYWIN_ITEMID_OPEN_ALL:
2284             if ( m_pContent )
2285                 m_pContent->openAll(m_aUCB, !m_bTiming, m_bTiming, m_bSort,
2286                                     m_nFetchSize);
2287             else
2288                 print( "No content!" );
2289 
2290             break;
2291 
2292         case MYWIN_ITEMID_UPDATE:
2293             if ( m_pContent )
2294                 m_pContent->open(rtl::OUString::createFromAscii("update"),
2295                                  aCmdLine, !m_bTiming, m_bTiming, m_bSort, 0,
2296                                  0, m_nFetchSize);
2297             else
2298                 print( "No content!" );
2299 
2300             break;
2301 
2302         case MYWIN_ITEMID_SYNCHRONIZE:
2303             if ( m_pContent )
2304                 m_pContent->open(rtl::OUString::createFromAscii("synchronize"),
2305                                  aCmdLine, !m_bTiming, m_bTiming, m_bSort, 0,
2306                                  0, m_nFetchSize);
2307             else
2308                 print( "No content!" );
2309 
2310             break;
2311 
2312         case MYWIN_ITEMID_SEARCH:
2313             if ( m_pContent )
2314                 m_pContent->open(rtl::OUString::createFromAscii("search"),
2315                                  aCmdLine, !m_bTiming, m_bTiming, m_bSort, 0,
2316                                  0, m_nFetchSize);
2317             else
2318                 print( "No content!" );
2319 
2320             break;
2321 
2322         case MYWIN_ITEMID_REORGANIZE:
2323             if ( m_pContent )
2324                 m_pContent->executeCommand (
2325                     rtl::OUString::createFromAscii ("reorganizeData"),
2326                     uno::Any());
2327             else
2328                 print( "No content!" );
2329 
2330             break;
2331 
2332         case MYWIN_ITEMID_COPY:
2333             if ( m_pContent )
2334                 m_pContent->transfer( aCmdLine, sal_False );
2335             else
2336                 print( "No content!" );
2337 
2338             break;
2339 
2340         case MYWIN_ITEMID_MOVE:
2341             if ( m_pContent )
2342                 m_pContent->transfer( aCmdLine, sal_True );
2343             else
2344                 print( "No content!" );
2345 
2346             break;
2347 
2348         case MYWIN_ITEMID_DELETE:
2349             if ( m_pContent )
2350                 m_pContent->destroy();
2351             else
2352                 print( "No content!" );
2353 
2354             break;
2355 
2356         case MYWIN_ITEMID_TIMING:
2357             m_bTiming = m_pTool->IsItemChecked(MYWIN_ITEMID_TIMING) != false;
2358             break;
2359 
2360         case MYWIN_ITEMID_SORT:
2361             m_bSort = m_pTool->IsItemChecked(MYWIN_ITEMID_SORT) != false;
2362             break;
2363 
2364         case MYWIN_ITEMID_FETCHSIZE:
2365         {
2366             m_nFetchSize = aCmdLine.ToInt32();
2367             String aText;
2368             if (m_nFetchSize > 0)
2369             {
2370                 aText.AssignAscii("Fetch size set to ");
2371                 aText += String::CreateFromInt32(m_nFetchSize);
2372             }
2373             else
2374                 aText.AssignAscii("Fetch size reset to default");
2375             print(aText);
2376             break;
2377         }
2378 
2379         case MYWIN_ITEMID_SYS2URI:
2380         {
2381             uno::Reference< ucb::XContentProviderManager >
2382                 xManager(m_aUCB.getContentProvider(), uno::UNO_QUERY);
2383             DBG_ASSERT(xManager.is(),
2384                        "MyWin::ToolBarHandler(): Service lacks interface");
2385 
2386             rtl::OUString aURL(getLocalFileURL(xManager));
2387 
2388             String aText(RTL_CONSTASCII_USTRINGPARAM("Local file URL: "));
2389             aText += String(aURL);
2390             aText.AppendAscii("\nConversion: ");
2391             aText += aCmdLine;
2392             aText.AppendAscii(" to ");
2393             aText += String(getFileURLFromSystemPath(xManager,
2394                                                           aURL,
2395                                                           aCmdLine));
2396             print(aText);
2397             break;
2398         }
2399 
2400         case MYWIN_ITEMID_URI2SYS:
2401         {
2402             uno::Reference< ucb::XContentProviderManager >
2403                 xManager(m_aUCB.getContentProvider(), uno::UNO_QUERY);
2404             DBG_ASSERT(xManager.is(),
2405                        "MyWin::ToolBarHandler(): Service lacks interface");
2406 
2407             String aText(RTL_CONSTASCII_USTRINGPARAM("Conversion: "));
2408             aText += aCmdLine;
2409             aText.AppendAscii(" to ");
2410             aText += String(getSystemPathFromFileURL(xManager,
2411                                                           aCmdLine));
2412             print(aText);
2413             break;
2414         }
2415 
2416         case MYWIN_ITEMID_OFFLINE:
2417         case MYWIN_ITEMID_ONLINE:
2418         {
2419             uno::Reference< ucb::XContentProviderManager >
2420                 xManager(m_aUCB.getContentProvider(), uno::UNO_QUERY);
2421             uno::Reference< ucb::XCommandProcessor > xProcessor;
2422             if (xManager.is())
2423                 xProcessor
2424                     = uno::Reference< ucb::XCommandProcessor >(
2425                         xManager->queryContentProvider(aCmdLine),
2426                         uno::UNO_QUERY);
2427             if (!xProcessor.is())
2428             {
2429                 String aText(RTL_CONSTASCII_USTRINGPARAM(
2430                                  "No offline support for URL "));
2431                 aText += aCmdLine;
2432                 print(aText);
2433                 break;
2434             }
2435 
2436             rtl::OUString aName;
2437             uno::Any aArgument;
2438             if (nItemId == MYWIN_ITEMID_OFFLINE)
2439             {
2440                 aName = rtl::OUString::createFromAscii("goOffline");
2441 
2442                 uno::Sequence<
2443                     uno::Reference< ucb::XContentIdentifier > >
2444                         aIdentifiers(1);
2445                 aIdentifiers[0]
2446                     = m_aUCB.getContentIdentifierFactory()->
2447                                  createContentIdentifier(aCmdLine);
2448                 aArgument <<= aIdentifiers;
2449             }
2450             else
2451                 aName = rtl::OUString::createFromAscii("goOnline");
2452 
2453             UcbCommandProcessor(m_aUCB, xProcessor, m_pOutEdit).
2454                 executeCommand(aName, aArgument);
2455             break;
2456         }
2457 
2458         default: // Ignored.
2459             break;
2460     }
2461 
2462     Application::AcquireSolarMutex( n );
2463     return 0;
2464 }
2465 
2466 /*========================================================================
2467  *
2468  * MyApp.
2469  *
2470  *=======================================================================*/
2471 class MyApp : public Application
2472 {
2473 public:
2474     virtual void Main();
2475 };
2476 
2477 MyApp aMyApp;
2478 
2479 //-------------------------------------------------------------------------
2480 // virtual
2481 void MyApp::Main()
2482 {
2483     //////////////////////////////////////////////////////////////////////
2484     // Read command line params.
2485     //////////////////////////////////////////////////////////////////////
2486 
2487     rtl::OUString aConfigurationKey1(rtl::OUString::createFromAscii(
2488                                          UCB_CONFIGURATION_KEY1_LOCAL));
2489     rtl::OUString aConfigurationKey2(rtl::OUString::createFromAscii(
2490                                          UCB_CONFIGURATION_KEY2_OFFICE));
2491 
2492     USHORT nParams = Application::GetCommandLineParamCount();
2493     for ( USHORT n = 0; n < nParams; ++n )
2494     {
2495         String aParam( Application::GetCommandLineParam( n ) );
2496         if (aParam.CompareIgnoreCaseToAscii("-key=",
2497                                             RTL_CONSTASCII_LENGTH("-key="))
2498                 == COMPARE_EQUAL)
2499         {
2500             xub_StrLen nSlash
2501                 = aParam.Search('/', RTL_CONSTASCII_LENGTH("-key="));
2502             if (nSlash == STRING_NOTFOUND)
2503             {
2504                 aConfigurationKey1
2505                     = aParam.Copy(RTL_CONSTASCII_LENGTH("-key="));
2506                 aConfigurationKey2 = rtl::OUString();
2507             }
2508             else
2509             {
2510                 aConfigurationKey1
2511                     = aParam.Copy(RTL_CONSTASCII_LENGTH("-key="),
2512                                   nSlash - RTL_CONSTASCII_LENGTH("-key="));
2513                 aConfigurationKey2
2514                     = aParam.Copy(nSlash + 1);
2515             }
2516         }
2517     }
2518 
2519     //////////////////////////////////////////////////////////////////////
2520     // Initialize local Service Manager and basic services.
2521     //////////////////////////////////////////////////////////////////////
2522 
2523     uno::Reference< lang::XMultiServiceFactory > xFac;
2524     try
2525     {
2526         uno::Reference< uno::XComponentContext > xCtx(
2527             cppu::defaultBootstrap_InitialComponentContext() );
2528         if ( !xCtx.is() )
2529         {
2530             DBG_ERROR( "Error creating initial component context!" );
2531             return;
2532         }
2533 
2534         xFac = uno::Reference< lang::XMultiServiceFactory >(
2535             xCtx->getServiceManager(), uno::UNO_QUERY );
2536 
2537         if ( !xFac.is() )
2538         {
2539             DBG_ERROR( "No service manager!" );
2540             return;
2541         }
2542     }
2543     catch ( uno::Exception )
2544     {
2545         DBG_ERROR( "Exception during creation of initial component context!" );
2546         return;
2547     }
2548 
2549     comphelper::setProcessServiceFactory( xFac );
2550 
2551     uno::Reference< lang::XComponent > xComponent( xFac, uno::UNO_QUERY );
2552 
2553     //////////////////////////////////////////////////////////////////////
2554     // Create Application Window...
2555     //////////////////////////////////////////////////////////////////////
2556 
2557     Help::EnableBalloonHelp();
2558 
2559     MyWin *pMyWin = new MyWin( NULL, WB_APP | WB_STDWORK, xFac,
2560                                aConfigurationKey1, aConfigurationKey2 );
2561 
2562     pMyWin->
2563         SetText(
2564             UniString::CreateFromAscii(
2565                 RTL_CONSTASCII_STRINGPARAM( "UCB Demo/Test Application" ) ) );
2566 
2567     pMyWin->SetPosSizePixel( 0, 0, 1024, 768 );
2568 
2569     pMyWin->Show();
2570 
2571     //////////////////////////////////////////////////////////////////////
2572     // Go...
2573     //////////////////////////////////////////////////////////////////////
2574 
2575     Execute();
2576 
2577     //////////////////////////////////////////////////////////////////////
2578     // Destroy Application Window...
2579     //////////////////////////////////////////////////////////////////////
2580 
2581     delete pMyWin;
2582 
2583     //////////////////////////////////////////////////////////////////////
2584     // Cleanup.
2585     //////////////////////////////////////////////////////////////////////
2586 
2587     ::ucbhelper::ContentBroker::deinitialize();
2588 
2589     // Dispose local service manager.
2590     if ( xComponent.is() )
2591         xComponent->dispose();
2592 }
2593