LibreOffice Module ucb (master)  1
bc.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <rtl/uri.hxx>
21 #include <rtl/ustrbuf.hxx>
22 
23 #include <osl/diagnose.h>
24 #include <com/sun/star/lang/NoSupportException.hpp>
25 #include <com/sun/star/sdbc/SQLException.hpp>
26 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
27 #include <com/sun/star/ucb/OpenMode.hpp>
28 #include <com/sun/star/beans/IllegalTypeException.hpp>
29 #include <com/sun/star/io/XActiveDataStreamer.hpp>
30 #include <com/sun/star/io/XOutputStream.hpp>
31 #include <com/sun/star/io/XActiveDataSink.hpp>
32 #include <com/sun/star/ucb/NameClash.hpp>
33 #include <comphelper/fileurl.hxx>
36 #include "filglob.hxx"
37 #include "filid.hxx"
38 #include "filrow.hxx"
39 #include "bc.hxx"
40 #include "prov.hxx"
41 #include "filerror.hxx"
42 #include "filinsreq.hxx"
43 
44 using namespace fileaccess;
45 using namespace com::sun::star;
46 using namespace com::sun::star::uno;
47 using namespace com::sun::star::ucb;
48 
49 #if OSL_DEBUG_LEVEL > 0
50 #define THROW_WHERE SAL_WHERE
51 #else
52 #define THROW_WHERE ""
53 #endif
54 
57 
59  : public PropertyListeners_impl
60 {
61 public:
62  explicit PropertyListeners( ::osl::Mutex& aMutex )
63  : PropertyListeners_impl( aMutex )
64  {
65  }
66 };
67 
68 
69 /****************************************************************************************/
70 /* */
71 /* BaseContent */
72 /* */
73 /****************************************************************************************/
74 
75 
76 // Private Constructor for just inserted Contents
77 
79  const OUString& parentName,
80  bool bFolder )
81  : m_pMyShell( pMyShell ),
82  m_aUncPath( parentName ),
83  m_bFolder( bFolder ),
84  m_nState( JustInserted )
85 {
86  m_pMyShell->m_pProvider->acquire();
87  // No registering, since we have no name
88 }
89 
90 
91 // Constructor for full featured Contents
92 
94  const Reference< XContentIdentifier >& xContentIdentifier,
95  const OUString& aUncPath )
96  : m_pMyShell( pMyShell ),
97  m_xContentIdentifier( xContentIdentifier ),
98  m_aUncPath( aUncPath ),
99  m_bFolder( false ),
100  m_nState( FullFeatured )
101 {
102  m_pMyShell->m_pProvider->acquire();
105 }
106 
107 
109 {
110  if( ( m_nState & FullFeatured ) || ( m_nState & Deleted ) )
111  {
113  }
114  m_pMyShell->m_pProvider->release();
115 }
116 
117 
118 // XComponent
119 
120 
121 void SAL_CALL
123 {
124  osl::MutexGuard aGuard( m_aMutex );
125 
126  if ( ! m_pDisposeEventListeners )
129 
130  m_pDisposeEventListeners->addInterface( Listener );
131 }
132 
133 
134 void SAL_CALL
136 {
137  osl::MutexGuard aGuard( m_aMutex );
138 
140  m_pDisposeEventListeners->removeInterface( Listener );
141 }
142 
143 
144 void SAL_CALL
146 {
147  lang::EventObject aEvt;
148  std::unique_ptr<comphelper::OInterfaceContainerHelper2> pDisposeEventListeners;
149  std::unique_ptr<comphelper::OInterfaceContainerHelper2> pContentEventListeners;
150  std::unique_ptr<comphelper::OInterfaceContainerHelper2> pPropertySetInfoChangeListeners;
151  std::unique_ptr<PropertyListeners> pPropertyListener;
152 
153  {
154  osl::MutexGuard aGuard( m_aMutex );
155  aEvt.Source = static_cast< XContent* >( this );
156 
157  pDisposeEventListeners = std::move(m_pDisposeEventListeners);
158  pContentEventListeners = std::move(m_pContentEventListeners);
159  pPropertySetInfoChangeListeners = std::move(m_pPropertySetInfoChangeListeners);
160  pPropertyListener = std::move(m_pPropertyListener);
161  }
162 
163  if ( pDisposeEventListeners && pDisposeEventListeners->getLength() )
164  pDisposeEventListeners->disposeAndClear( aEvt );
165 
166  if ( pContentEventListeners && pContentEventListeners->getLength() )
167  pContentEventListeners->disposeAndClear( aEvt );
168 
169  if( pPropertyListener )
170  pPropertyListener->disposeAndClear( aEvt );
171 
172  if( pPropertySetInfoChangeListeners )
173  pPropertySetInfoChangeListeners->disposeAndClear( aEvt );
174 }
175 
176 // XServiceInfo
177 OUString SAL_CALL
179 {
180  return "com.sun.star.comp.ucb.FileContent";
181 }
182 
183 sal_Bool SAL_CALL
184 BaseContent::supportsService( const OUString& ServiceName )
185 {
186  return cppu::supportsService( this, ServiceName );
187 }
188 
189 Sequence< OUString > SAL_CALL
191 {
192  Sequence<OUString> ret { "com.sun.star.ucb.FileContent" };
193  return ret;
194 }
195 
196 // XCommandProcessor
197 
198 
199 sal_Int32 SAL_CALL
201 {
202  return m_pMyShell->getCommandId();
203 }
204 
205 
206 void SAL_CALL
207 BaseContent::abort( sal_Int32 /*CommandId*/ )
208 {
209 }
210 
211 
212 Any SAL_CALL
213 BaseContent::execute( const Command& aCommand,
214  sal_Int32 CommandId,
215  const Reference< XCommandEnvironment >& Environment )
216 {
217  if( ! CommandId )
218  // A Command with commandid zero cannot be aborted
219  CommandId = createCommandIdentifier();
220 
221  m_pMyShell->startTask( CommandId,
222  Environment );
223 
224  Any aAny;
225 
226  if (aCommand.Name == "getPropertySetInfo") // No exceptions
227  {
228  aAny <<= getPropertySetInfo();
229  }
230  else if (aCommand.Name == "getCommandInfo") // no exceptions
231  {
232  aAny <<= getCommandInfo();
233  }
234  else if ( aCommand.Name == "setPropertyValues" )
235  {
236  Sequence< beans::PropertyValue > sPropertyValues;
237 
238  if( ! ( aCommand.Argument >>= sPropertyValues ) )
239  m_pMyShell->installError( CommandId,
241  else
242  aAny <<= setPropertyValues( CommandId,sPropertyValues ); // calls endTask by itself
243  }
244  else if ( aCommand.Name == "getPropertyValues" )
245  {
246  Sequence< beans::Property > ListOfRequestedProperties;
247 
248  if( ! ( aCommand.Argument >>= ListOfRequestedProperties ) )
249  m_pMyShell->installError( CommandId,
251  else
252  aAny <<= getPropertyValues( CommandId,
253  ListOfRequestedProperties );
254  }
255  else if ( aCommand.Name == "open" )
256  {
257  OpenCommandArgument2 aOpenArgument;
258  if( ! ( aCommand.Argument >>= aOpenArgument ) )
259  m_pMyShell->installError( CommandId,
261  else
262  {
263  Reference< XDynamicResultSet > result = open( CommandId,aOpenArgument );
264  if( result.is() )
265  aAny <<= result;
266  }
267  }
268  else if ( aCommand.Name == "delete" )
269  {
270  if( ! aCommand.Argument.has< bool >() )
271  m_pMyShell->installError( CommandId,
273  else
274  deleteContent( CommandId );
275  }
276  else if ( aCommand.Name == "transfer" )
277  {
278  TransferInfo aTransferInfo;
279  if( ! ( aCommand.Argument >>= aTransferInfo ) )
280  m_pMyShell->installError( CommandId,
282  else
283  transfer( CommandId, aTransferInfo );
284  }
285  else if ( aCommand.Name == "insert" )
286  {
287  InsertCommandArgument aInsertArgument;
288  if( ! ( aCommand.Argument >>= aInsertArgument ) )
289  m_pMyShell->installError( CommandId,
291  else
292  insert( CommandId,aInsertArgument );
293  }
294  else if ( aCommand.Name == "getCasePreservingURL" )
295  {
297  seq[0] = beans::Property(
298  "CasePreservingURL",
299  -1,
301  0 );
303  OUString CasePreservingURL = xRow->getString(1);
304  if(!xRow->wasNull())
305  aAny <<= CasePreservingURL;
306  }
307  else if ( aCommand.Name == "createNewContent" )
308  {
309  ucb::ContentInfo aArg;
310  if ( !( aCommand.Argument >>= aArg ) )
311  m_pMyShell->installError( CommandId,
313  else
314  aAny <<= createNewContent( aArg );
315  }
316  else
317  m_pMyShell->installError( CommandId,
319 
320 
321  // This is the only function allowed to throw an exception
322  endTask( CommandId );
323 
324  return aAny;
325 }
326 
327 
328 void SAL_CALL
330  const Sequence< OUString >& PropertyNames,
332 {
333  if( ! Listener.is() )
334  return;
335 
336  osl::MutexGuard aGuard( m_aMutex );
337 
338  if( ! m_pPropertyListener )
340 
341 
342  if( !PropertyNames.hasElements() )
343  m_pPropertyListener->addInterface( OUString(),Listener );
344  else
345  {
347  for( const auto& rName : PropertyNames )
348  if( xProp->hasPropertyByName( rName ) )
349  m_pPropertyListener->addInterface( rName,Listener );
350  }
351 }
352 
353 
354 void SAL_CALL
357 {
358  if( ! Listener.is() )
359  return;
360 
361  osl::MutexGuard aGuard( m_aMutex );
362 
363  if( ! m_pPropertyListener )
364  return;
365 
366  for( const auto& rName : PropertyNames )
367  m_pPropertyListener->removeInterface( rName,Listener );
368 
369  m_pPropertyListener->removeInterface( OUString(), Listener );
370 }
371 
372 
373 // XContent
374 
375 
378 {
379  return m_xContentIdentifier;
380 }
381 
382 
383 OUString SAL_CALL
385 {
386  if( !( m_nState & Deleted ) )
387  {
388  if( m_nState & JustInserted )
389  {
390  if ( m_bFolder )
392  else
394  }
395  else
396  {
397  try
398  {
399  // Who am I ?
401  seq[0] = beans::Property( "IsDocument",
402  -1,
404  0 );
406  bool IsDocument = xRow->getBoolean( 1 );
407 
408  if ( !xRow->wasNull() )
409  {
410  if ( IsDocument )
412  else
414  }
415  else
416  {
417  OSL_FAIL( "BaseContent::getContentType - Property value was null!" );
418  }
419  }
420  catch (const sdbc::SQLException&)
421  {
422  OSL_FAIL( "BaseContent::getContentType - Caught SQLException!" );
423  }
424  }
425  }
426 
427  return OUString();
428 }
429 
430 
431 void SAL_CALL
433  const Reference< XContentEventListener >& Listener )
434 {
435  osl::MutexGuard aGuard( m_aMutex );
436 
437  if ( ! m_pContentEventListeners )
440 
441 
442  m_pContentEventListeners->addInterface( Listener );
443 }
444 
445 
446 void SAL_CALL
448  const Reference< XContentEventListener >& Listener )
449 {
450  osl::MutexGuard aGuard( m_aMutex );
451 
453  m_pContentEventListeners->removeInterface( Listener );
454 }
455 
456 
457 // XPropertyContainer
458 
459 
460 void SAL_CALL
462  const OUString& Name,
463  sal_Int16 Attributes,
464  const Any& DefaultValue )
465 {
466  if( ( m_nState & JustInserted ) || ( m_nState & Deleted ) || Name.isEmpty() )
467  {
468  throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
469  }
470 
471  m_pMyShell->associate( m_aUncPath,Name,DefaultValue,Attributes );
472 }
473 
474 
475 void SAL_CALL
476 BaseContent::removeProperty( const OUString& Name )
477 {
478 
479  if( m_nState & Deleted )
480  throw beans::UnknownPropertyException( Name );
481 
483 }
484 
485 
486 // XContentCreator
487 
488 
491 {
493 }
494 
495 
496 Reference< XContent > SAL_CALL
498 {
499  // Check type.
500  if ( Info.Type.isEmpty() )
501  return Reference< XContent >();
502 
503  bool bFolder = Info.Type == TaskManager::FolderContentType;
504  if ( !bFolder )
505  {
506  if ( Info.Type != TaskManager::FileContentType )
507  {
508  // Neither folder nor file to create!
509  return Reference< XContent >();
510  }
511  }
512 
513  // Who am I ?
514  bool IsDocument = false;
515 
516  try
517  {
519  seq[0] = beans::Property( "IsDocument",
520  -1,
522  0 );
524  IsDocument = xRow->getBoolean( 1 );
525 
526  if ( xRow->wasNull() )
527  {
528  IsDocument = false;
529 // OSL_FAIL( // "BaseContent::createNewContent - Property value was null!" );
530 // return Reference< XContent >();
531  }
532  }
533  catch (const sdbc::SQLException&)
534  {
535  OSL_FAIL( "BaseContent::createNewContent - Caught SQLException!" );
536  return Reference< XContent >();
537  }
538 
539  OUString dstUncPath;
540 
541  if( IsDocument )
542  {
543  // KSO: Why is a document a XContentCreator? This is quite unusual.
544  dstUncPath = getParentName( m_aUncPath );
545  }
546  else
547  dstUncPath = m_aUncPath;
548 
549  BaseContent* p = new BaseContent( m_pMyShell, dstUncPath, bFolder );
550  return Reference< XContent >( p );
551 }
552 
553 
554 // XPropertySetInfoChangeNotifier
555 
556 
557 void SAL_CALL
560 {
561  osl::MutexGuard aGuard( m_aMutex );
564 
565  m_pPropertySetInfoChangeListeners->addInterface( Listener );
566 }
567 
568 
569 void SAL_CALL
572 {
573  osl::MutexGuard aGuard( m_aMutex );
574 
576  m_pPropertySetInfoChangeListeners->removeInterface( Listener );
577 }
578 
579 
580 // XChild
581 
582 
585 {
586  OUString ParentUnq = getParentName( m_aUncPath );
587  OUString ParentUrl;
588 
589 
590  bool err = fileaccess::TaskManager::getUrlFromUnq( ParentUnq, ParentUrl );
591  if( err )
592  return Reference< XInterface >( nullptr );
593 
594  FileContentIdentifier* p = new FileContentIdentifier( ParentUnq );
596 
597  try
598  {
599  return Reference<XInterface>( m_pMyShell->m_pProvider->queryContent( Identifier ), UNO_QUERY );
600  }
601  catch (const IllegalIdentifierException&)
602  {
603  return Reference< XInterface >();
604  }
605 }
606 
607 
608 void SAL_CALL
610  const Reference< XInterface >& )
611 {
612  throw lang::NoSupportException( THROW_WHERE );
613 }
614 
615 
616 // Private Methods
617 
618 
621 {
622  if( m_nState & Deleted )
623  return Reference< XCommandInfo >();
624 
625  return m_pMyShell->info_c();
626 }
627 
628 
631 {
632  if( m_nState & Deleted )
634 
635  return m_pMyShell->info_p( m_aUncPath );
636 }
637 
640  sal_Int32 nMyCommandIdentifier,
641  const Sequence< beans::Property >& PropertySet )
642 {
643  sal_Int32 nProps = PropertySet.getLength();
644  if ( !nProps )
645  return Reference< sdbc::XRow >();
646 
647  if( m_nState & Deleted )
648  {
649  Sequence< Any > aValues( nProps );
650  return Reference< sdbc::XRow >( new XRow_impl( m_pMyShell, aValues ) );
651  }
652 
653  if( m_nState & JustInserted )
654  {
655  Sequence< Any > aValues( nProps );
656  Any* pValues = aValues.getArray();
657 
658  const beans::Property* pProps = PropertySet.getConstArray();
659 
660  for ( sal_Int32 n = 0; n < nProps; ++n )
661  {
662  const beans::Property& rProp = pProps[ n ];
663  Any& rValue = pValues[ n ];
664 
665  if ( rProp.Name == "ContentType" )
666  {
667  rValue <<= OUString(m_bFolder ? TaskManager::FolderContentType
669  }
670  else if ( rProp.Name == "IsFolder" )
671  {
672  rValue <<= m_bFolder;
673  }
674  else if ( rProp.Name == "IsDocument" )
675  {
676  rValue <<= !m_bFolder;
677  }
678  }
679 
681  new XRow_impl( m_pMyShell, aValues ) );
682  }
683 
684  return m_pMyShell->getv( nMyCommandIdentifier,
685  m_aUncPath,
686  PropertySet );
687 }
688 
689 
692  sal_Int32 nMyCommandIdentifier,
693  const Sequence< beans::PropertyValue >& Values )
694 {
695  if( m_nState & Deleted )
696  { // To do
697  return Sequence< Any >( Values.getLength() );
698  }
699 
700  const OUString Title("Title");
701 
702  // Special handling for files which have to be inserted
703  if( m_nState & JustInserted )
704  {
705  for( const auto& rValue : Values )
706  {
707  if( rValue.Name == Title )
708  {
709  OUString NewTitle;
710  if( rValue.Value >>= NewTitle )
711  {
713  {
714  // User wants to set another Title before "insert".
715  // m_aUncPath contains previous own URI.
716 
717  sal_Int32 nLastSlash = m_aUncPath.lastIndexOf( '/' );
718  bool bTrailingSlash = false;
719  if ( nLastSlash == m_aUncPath.getLength() - 1 )
720  {
721  bTrailingSlash = true;
722  nLastSlash
723  = m_aUncPath.lastIndexOf( '/', nLastSlash );
724  }
725 
726  OSL_ENSURE( nLastSlash != -1,
727  "BaseContent::setPropertyValues: "
728  "Invalid URL!" );
729 
730  OUStringBuffer aBuf(
731  m_aUncPath.copy( 0, nLastSlash + 1 ) );
732 
733  if ( !NewTitle.isEmpty() )
734  {
735  aBuf.append( NewTitle );
736  if ( bTrailingSlash )
737  aBuf.append( '/' );
738  }
739  else
740  {
741  m_nState &= ~NameForInsertionSet;
742  }
743 
744  m_aUncPath = aBuf.makeStringAndClear();
745  }
746  else
747  {
748  if ( !NewTitle.isEmpty() )
749  {
750  // Initial Title before "insert".
751  // m_aUncPath contains parent's URI.
752 
753  if( !m_aUncPath.endsWith( "/" ) )
754  m_aUncPath += "/";
755 
756  m_aUncPath += rtl::Uri::encode( NewTitle,
757  rtl_UriCharClassPchar,
758  rtl_UriEncodeIgnoreEscapes,
759  RTL_TEXTENCODING_UTF8 );
761  }
762  }
763  }
764  }
765  }
766 
767  return Sequence< Any >( Values.getLength() );
768  }
769  else
770  {
771  Sequence< Any > ret = m_pMyShell->setv( m_aUncPath, // Does not handle Title
772  Values );
773 
774  // Special handling Title: Setting Title is equivalent to a renaming of the underlying file
775  for( sal_Int32 i = 0; i < Values.getLength(); ++i )
776  {
777  if( Values[i].Name != Title )
778  continue; // handled by setv
779 
780  OUString NewTitle;
781  if( !( Values[i].Value >>= NewTitle ) )
782  {
783  ret[i] <<= beans::IllegalTypeException( THROW_WHERE );
784  break;
785  }
786  else if( NewTitle.isEmpty() )
787  {
788  ret[i] <<= lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
789  break;
790  }
791 
792 
793  OUString aDstName = getParentName( m_aUncPath );
794  if( !aDstName.endsWith("/") )
795  aDstName += "/";
796 
797  aDstName += rtl::Uri::encode( NewTitle,
798  rtl_UriCharClassPchar,
799  rtl_UriEncodeIgnoreEscapes,
800  RTL_TEXTENCODING_UTF8 );
801 
802  m_pMyShell->move( nMyCommandIdentifier, // move notifies the children also;
803  m_aUncPath,
804  aDstName,
805  NameClash::KEEP );
806 
807  try
808  {
809  endTask( nMyCommandIdentifier );
810  }
811  catch(const Exception& e)
812  {
813  ret[i] <<= e;
814  }
815 
816  // NameChanges come back through a ContentEvent
817  break; // only handling Title
818  } // end for
819 
820  return ret;
821  }
822 }
823 
824 
827  sal_Int32 nMyCommandIdentifier,
828  const OpenCommandArgument2& aCommandArgument )
829 {
831 
832  if( m_nState & Deleted )
833  {
834  m_pMyShell->installError( nMyCommandIdentifier,
836  }
837  else if( m_nState & JustInserted )
838  {
839  m_pMyShell->installError( nMyCommandIdentifier,
841  }
842  else
843  {
844  if( aCommandArgument.Mode == OpenMode::DOCUMENT ||
845  aCommandArgument.Mode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
846 
847  {
848  Reference< io::XOutputStream > outputStream( aCommandArgument.Sink,UNO_QUERY );
849  if( outputStream.is() )
850  {
851  m_pMyShell->page( nMyCommandIdentifier,
852  m_aUncPath,
853  outputStream );
854  }
855 
856  bool bLock = ( aCommandArgument.Mode != OpenMode::DOCUMENT_SHARE_DENY_NONE );
857 
858  Reference< io::XActiveDataSink > activeDataSink( aCommandArgument.Sink,UNO_QUERY );
859  if( activeDataSink.is() )
860  {
861  activeDataSink->setInputStream( m_pMyShell->open( nMyCommandIdentifier,
862  m_aUncPath,
863  bLock ) );
864  }
865 
866  Reference< io::XActiveDataStreamer > activeDataStreamer( aCommandArgument.Sink,UNO_QUERY );
867  if( activeDataStreamer.is() )
868  {
869  activeDataStreamer->setStream( m_pMyShell->open_rw( nMyCommandIdentifier,
870  m_aUncPath,
871  bLock ) );
872  }
873  }
874  else if ( aCommandArgument.Mode == OpenMode::ALL ||
875  aCommandArgument.Mode == OpenMode::FOLDERS ||
876  aCommandArgument.Mode == OpenMode::DOCUMENTS )
877  {
878  retValue = m_pMyShell->ls( nMyCommandIdentifier,
879  m_aUncPath,
880  aCommandArgument.Mode,
881  aCommandArgument.Properties,
882  aCommandArgument.SortingInfo );
883  }
884 // else if( aCommandArgument.Mode ==
885 // OpenMode::DOCUMENT_SHARE_DENY_NONE ||
886 // aCommandArgument.Mode ==
887 // OpenMode::DOCUMENT_SHARE_DENY_WRITE )
888 // m_pMyShell->installError( nMyCommandIdentifier,
889 // TASKHANDLING_UNSUPPORTED_OPEN_MODE,
890 // aCommandArgument.Mode);
891  else
892  m_pMyShell->installError( nMyCommandIdentifier,
894  aCommandArgument.Mode);
895  }
896 
897  return retValue;
898 }
899 
900 
901 void
902 BaseContent::deleteContent( sal_Int32 nMyCommandIdentifier )
903 {
904  if( m_nState & Deleted )
905  return;
906 
907  if( m_pMyShell->remove( nMyCommandIdentifier,m_aUncPath ) )
908  {
909  osl::MutexGuard aGuard( m_aMutex );
910  m_nState |= Deleted;
911  }
912 }
913 
914 
915 void
916 BaseContent::transfer( sal_Int32 nMyCommandIdentifier,
917  const TransferInfo& aTransferInfo )
918 {
919  if( m_nState & Deleted )
920  return;
921 
922  if( !comphelper::isFileUrl(aTransferInfo.SourceURL) )
923  {
924  m_pMyShell->installError( nMyCommandIdentifier,
926  return;
927  }
928 
929  OUString srcUnc;
930  if( fileaccess::TaskManager::getUnqFromUrl( aTransferInfo.SourceURL,srcUnc ) )
931  {
932  m_pMyShell->installError( nMyCommandIdentifier,
934  return;
935  }
936 
937  OUString srcUncPath = srcUnc;
938 
939  // Determine the new title !
940  OUString NewTitle;
941  if( !aTransferInfo.NewTitle.isEmpty() )
942  NewTitle = rtl::Uri::encode( aTransferInfo.NewTitle,
943  rtl_UriCharClassPchar,
944  rtl_UriEncodeIgnoreEscapes,
945  RTL_TEXTENCODING_UTF8 );
946  else
947  NewTitle = srcUncPath.copy( 1 + srcUncPath.lastIndexOf( '/' ) );
948 
949  // Is destination a document or a folder ?
951  seq[0] = beans::Property( "IsDocument",
952  -1,
954  0 );
955  Reference< sdbc::XRow > xRow = getPropertyValues( nMyCommandIdentifier,seq );
956  bool IsDocument = xRow->getBoolean( 1 );
957  if( xRow->wasNull() )
958  { // Destination file type could not be determined
959  m_pMyShell->installError( nMyCommandIdentifier,
961  return;
962  }
963 
964  OUString dstUncPath;
965  if( IsDocument )
966  { // as sibling
967  sal_Int32 lastSlash = m_aUncPath.lastIndexOf( '/' );
968  dstUncPath = m_aUncPath.copy(0,lastSlash );
969  }
970  else
971  // as child
972  dstUncPath = m_aUncPath;
973 
974  dstUncPath += "/" + NewTitle;
975 
976  sal_Int32 NameClash = aTransferInfo.NameClash;
977 
978  if( aTransferInfo.MoveData )
979  m_pMyShell->move( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
980  else
981  m_pMyShell->copy( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
982 }
983 
984 
985 void BaseContent::insert( sal_Int32 nMyCommandIdentifier,
986  const InsertCommandArgument& aInsertArgument )
987 {
988  if( m_nState & FullFeatured )
989  {
990  m_pMyShell->write( nMyCommandIdentifier,
991  m_aUncPath,
992  aInsertArgument.ReplaceExisting,
993  aInsertArgument.Data );
994  return;
995  }
996 
997  if( ! ( m_nState & JustInserted ) )
998  {
999  m_pMyShell->installError( nMyCommandIdentifier,
1001  return;
1002  }
1003 
1004  // Inserts the content, which has the flag m_bIsFresh
1005 
1006  if( ! (m_nState & NameForInsertionSet) )
1007  {
1008  m_pMyShell->installError( nMyCommandIdentifier,
1010  return;
1011  }
1012 
1013  // Inserting a document or a file?
1014  bool bDocument = false;
1015 
1017  seq[0] = beans::Property( "IsDocument",
1018  -1,
1020  0 );
1021 
1023 
1024  bool contentTypeSet = true; // is set to false, if contentType not set
1025  try
1026  {
1027  bDocument = xRow->getBoolean( 1 );
1028  if( xRow->wasNull() )
1029  contentTypeSet = false;
1030 
1031  }
1032  catch (const sdbc::SQLException&)
1033  {
1034  OSL_FAIL( "BaseContent::insert - Caught SQLException!" );
1035  contentTypeSet = false;
1036  }
1037 
1038  if( ! contentTypeSet )
1039  {
1040  m_pMyShell->installError( nMyCommandIdentifier,
1042  return;
1043  }
1044 
1045 
1046  bool success = false;
1047  if( bDocument )
1048  success = m_pMyShell->mkfil( nMyCommandIdentifier,
1049  m_aUncPath,
1050  aInsertArgument.ReplaceExisting,
1051  aInsertArgument.Data );
1052  else
1053  {
1054  while( ! success )
1055  {
1056  success = m_pMyShell->mkdir( nMyCommandIdentifier,
1057  m_aUncPath,
1058  aInsertArgument.ReplaceExisting );
1059  if( success )
1060  break;
1061 
1062  XInteractionRequestImpl aRequestImpl(
1063  rtl::Uri::decode(
1065  rtl_UriDecodeWithCharset,
1066  RTL_TEXTENCODING_UTF8),
1067  static_cast<cppu::OWeakObject*>(this),
1068  m_pMyShell,nMyCommandIdentifier);
1069  uno::Reference<task::XInteractionRequest> const& xReq(aRequestImpl.getRequest());
1070 
1071  m_pMyShell->handleTask( nMyCommandIdentifier, xReq );
1072  if (aRequestImpl.aborted() || aRequestImpl.newName().isEmpty())
1073  // means aborting
1074  break;
1075 
1076  // determine new uncpath
1077  m_pMyShell->clearError( nMyCommandIdentifier );
1079  if( !m_aUncPath.endsWith( "/" ) )
1080  m_aUncPath += "/";
1081 
1082  m_aUncPath += rtl::Uri::encode( aRequestImpl.newName(),
1083  rtl_UriCharClassPchar,
1084  rtl_UriEncodeIgnoreEscapes,
1085  RTL_TEXTENCODING_UTF8 );
1086  }
1087  }
1088 
1089  if ( ! success )
1090  return;
1091 
1093 
1096 
1097  osl::MutexGuard aGuard( m_aMutex );
1099 }
1100 
1101 
1102 void BaseContent::endTask( sal_Int32 CommandId )
1103 {
1104  // This is the only function allowed to throw an exception
1105  m_pMyShell->endTask( CommandId,m_aUncPath,this );
1106 }
1107 
1108 
1109 std::unique_ptr<ContentEventNotifier>
1111 {
1112  osl::MutexGuard aGuard( m_aMutex );
1113 
1114  m_nState |= Deleted;
1115 
1116  std::unique_ptr<ContentEventNotifier> p;
1118  {
1119  p.reset( new ContentEventNotifier( m_pMyShell,
1120  this,
1122  m_pContentEventListeners->getElements() ) );
1123  }
1124 
1125  return p;
1126 }
1127 
1128 
1129 std::unique_ptr<ContentEventNotifier>
1130 BaseContent::cEXC( const OUString& aNewName )
1131 {
1132  osl::MutexGuard aGuard( m_aMutex );
1133 
1135  m_aUncPath = aNewName;
1136  FileContentIdentifier* pp = new FileContentIdentifier( aNewName );
1137  m_xContentIdentifier.set( pp );
1138 
1139  std::unique_ptr<ContentEventNotifier> p;
1141  p.reset( new ContentEventNotifier( m_pMyShell,
1142  this,
1144  xOldRef,
1145  m_pContentEventListeners->getElements() ) );
1146 
1147  return p;
1148 }
1149 
1150 
1151 std::unique_ptr<ContentEventNotifier>
1153 {
1154  osl::MutexGuard aGuard( m_aMutex );
1155  std::unique_ptr<ContentEventNotifier> p;
1157  p.reset( new ContentEventNotifier( m_pMyShell,
1158  this,
1160  m_pContentEventListeners->getElements() ) );
1161 
1162  return p;
1163 }
1164 
1165 std::unique_ptr<PropertySetInfoChangeNotifier>
1167 {
1168  osl::MutexGuard aGuard( m_aMutex );
1169  std::unique_ptr<PropertySetInfoChangeNotifier> p;
1171  p.reset( new PropertySetInfoChangeNotifier( this,
1172  m_pPropertySetInfoChangeListeners->getElements() ) );
1173 
1174  return p;
1175 }
1176 
1177 
1178 std::unique_ptr<PropertyChangeNotifier>
1180 {
1181  osl::MutexGuard aGuard( m_aMutex );
1182 
1183  if (!m_pPropertyListener)
1184  return nullptr;
1185 
1186  const Sequence< OUString > seqNames = m_pPropertyListener->getContainedTypes();
1187 
1188  std::unique_ptr<PropertyChangeNotifier> p;
1189 
1190  if( seqNames.hasElements() )
1191  {
1192  std::unique_ptr<ListenerMap> listener(new ListenerMap);
1193  for( const auto& rName : seqNames )
1194  {
1195  cppu::OInterfaceContainerHelper* pContainer = m_pPropertyListener->getContainer(rName);
1196  if (!pContainer)
1197  continue;
1198  (*listener)[rName] = pContainer->getElements();
1199  }
1200 
1201  p.reset( new PropertyChangeNotifier( this, std::move(listener) ) );
1202  }
1203 
1204  return p;
1205 }
1206 
1207 
1208 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT
Definition: filerror.hxx:30
#define TASKHANDLING_WRONG_TRANSFER_ARGUMENT
Definition: filerror.hxx:33
std::unique_ptr< ContentEventNotifier > cCEL() override
Definition: bc.cxx:1152
css::uno::Reference< css::ucb::XCommandInfo > getCommandInfo()
Definition: bc.cxx:620
#define TASKHANDLING_WRONG_DELETE_ARGUMENT
Definition: filerror.hxx:32
css::uno::Reference< css::ucb::XContentIdentifier > m_xContentIdentifier
Definition: bc.hxx:197
static const OUStringLiteral IsDocument("IsDocument")
#define TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT
Definition: filerror.hxx:29
virtual void SAL_CALL setParent(const css::uno::Reference< css::uno::XInterface > &Parent) override
Definition: bc.cxx:609
void endTask(sal_Int32 CommandId, const OUString &aUnqPath, BaseContent *pContent)
Deinstalls the task and evaluates a possibly set error code.
Definition: filtask.cxx:390
void deleteContent(sal_Int32 nMyCommandIdentifier)
Definition: bc.cxx:902
#define TASKHANDLING_UNSUPPORTED_OPEN_MODE
Definition: filerror.hxx:36
friend class ContentEventNotifier
Definition: bc.hxx:255
virtual void SAL_CALL abort(sal_Int32 CommandId) override
Definition: bc.cxx:207
static const OUStringLiteral CasePreservingURL("CasePreservingURL")
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: bc.cxx:184
virtual css::uno::Any SAL_CALL execute(const css::ucb::Command &aCommand, sal_Int32 CommandId, const css::uno::Reference< css::ucb::XCommandEnvironment > &Environment) override
Definition: bc.cxx:213
sal_Int64 n
aBuf
css::uno::Reference< css::ucb::XDynamicResultSet > open(sal_Int32 nMyCommandIdentifier, const css::ucb::OpenCommandArgument2 &aCommandArgument)
Definition: bc.cxx:826
std::unique_ptr< comphelper::OInterfaceContainerHelper2 > m_pPropertySetInfoChangeListeners
Definition: bc.hxx:212
void deassociate(const OUString &UnqPath, const OUString &PropertyName)
Definition: filtask.cxx:576
virtual void SAL_CALL addContentEventListener(const css::uno::Reference< css::ucb::XContentEventListener > &Listener) override
Definition: bc.cxx:432
OUString Name
bool remove(sal_Int32 CommandId, const OUString &aUnqPath, FileUrlType eTypeToMove=FileUrlType::Unknown, bool MustExist=true)
Deletes the content belonging to fileURL aUnqPath( recursively in case of directory ) ...
Definition: filtask.cxx:1520
void insertDefaultProperties(const OUString &aUnqPath)
Definition: filtask.cxx:1932
virtual void SAL_CALL addPropertiesChangeListener(const css::uno::Sequence< OUString > &PropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener > &Listener) override
Definition: bc.cxx:329
std::unordered_map< OUString, css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > > ListenerMap
Definition: filnot.hxx:81
Title
#define TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND
Definition: filerror.hxx:39
#define TASKHANDLING_TRANSFER_INVALIDURL
Definition: filerror.hxx:82
virtual void SAL_CALL addProperty(const OUString &Name, sal_Int16 Attributes, const css::uno::Any &DefaultValue) override
Definition: bc.cxx:461
#define TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND
Definition: filerror.hxx:38
#define TASKHANDLER_UNSUPPORTED_COMMAND
Definition: filerror.hxx:28
virtual void SAL_CALL dispose() override
Definition: bc.cxx:145
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
Definition: bc.cxx:135
static const OUStringLiteral FolderContentType
Definition: filtask.hxx:634
Value
void installError(sal_Int32 CommandId, sal_Int32 ErrorCode, sal_Int32 minorCode=TASKHANDLER_NO_ERROR)
The error code may be one of the error codes defined in filerror.hxx.
Definition: filtask.cxx:444
Reference< XRow > xRow
virtual sal_Int32 SAL_CALL createCommandIdentifier() override
Definition: bc.cxx:200
static const OUStringLiteral FileContentType
Definition: filtask.hxx:635
FileProvider * m_pProvider
Definition: filtask.hxx:487
std::unique_ptr< PropertyListeners > m_pPropertyListener
Definition: bc.hxx:213
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: bc.cxx:122
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
#define TASKHANDLING_TRANSFER_DESTFILETYPE
Definition: filerror.hxx:83
PropertyListeners(::osl::Mutex &aMutex)
Definition: bc.cxx:62
virtual void SAL_CALL addPropertySetInfoChangeListener(const css::uno::Reference< css::beans::XPropertySetInfoChangeListener > &Listener) override
Definition: bc.cxx:558
virtual OUString SAL_CALL getContentType() override
Definition: bc.cxx:384
virtual css::uno::Reference< css::ucb::XContent > SAL_CALL createNewContent(const css::ucb::ContentInfo &Info) override
Definition: bc.cxx:497
void transfer(sal_Int32 nMyCommandIdentifier, const css::ucb::TransferInfo &aTransferInfo)
Definition: bc.cxx:916
std::unique_ptr< ContentEventNotifier > cDEL() override
Definition: bc.cxx:1110
static bool getUrlFromUnq(const OUString &Unq, OUString &Url)
Definition: filtask.cxx:1983
bool mkfil(sal_Int32 CommandId, const OUString &aFileName, bool OverWrite, const css::uno::Reference< css::io::XInputStream > &aInputStream)
Creates new file with given URL.
Definition: filtask.cxx:1742
std::unique_ptr< comphelper::OInterfaceContainerHelper2 > m_pDisposeEventListeners
Definition: bc.hxx:210
#define TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND
Definition: filerror.hxx:53
err
#define TASKHANDLING_TRANSFER_INVALIDSCHEME
Definition: filerror.hxx:81
virtual OUString SAL_CALL getImplementationName() override
Definition: bc.cxx:178
#define TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT
Definition: filerror.hxx:35
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: bc.cxx:190
int i
osl::Mutex m_aEventListenerMutex
Definition: bc.hxx:209
void copy(sal_Int32 CommandId, const OUString &srcUnqPath, const OUString &dstUnqPath, sal_Int32 NameClash)
Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories ) ...
Definition: filtask.cxx:1348
css::uno::Reference< css::task::XInteractionRequest > const & getRequest() const
Definition: filinsreq.hxx:125
unsigned char sal_Bool
sal_uInt16 m_nState
Definition: bc.hxx:205
OUString getTitle(const OUString &aPath)
Definition: filglob.cxx:181
static css::uno::Sequence< css::ucb::ContentInfo > queryCreatableContentsInfo()
Definition: filtask.cxx:2911
OUString m_aUncPath
Definition: bc.hxx:198
virtual css::uno::Reference< css::ucb::XContent > SAL_CALL queryContent(const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier) override
Definition: prov.cxx:162
virtual void SAL_CALL removePropertySetInfoChangeListener(const css::uno::Reference< css::beans::XPropertySetInfoChangeListener > &Listener) override
Definition: bc.cxx:570
cppu::OMultiTypeInterfaceContainerHelperVar< OUString > PropertyListeners_impl
Definition: bc.cxx:56
void insert(sal_Int32 nMyCommandIdentifier, const css::ucb::InsertCommandArgument &aInsertArgument)
Definition: bc.cxx:985
sal_Int32 getCommandId()
Definition: filtask.cxx:456
void deregisterNotifier(const OUString &aUnqPath, Notifier *pNotifier)
Definition: filtask.cxx:510
css::uno::Reference< css::io::XStream > open_rw(sal_Int32 CommandId, const OUString &aUnqPath, bool bLock)
Given a file URL aUnqPath, this methods returns a XStream which can be used to read and write from/to...
Definition: filtask.cxx:750
virtual void SAL_CALL removeContentEventListener(const css::uno::Reference< css::ucb::XContentEventListener > &Listener) override
Definition: bc.cxx:447
virtual ~BaseContent() override
Definition: bc.cxx:108
css::uno::Reference< css::sdbc::XRow > getv(sal_Int32 CommandId, const OUString &aUnqPath, const css::uno::Sequence< css::beans::Property > &properties)
Reads the values of the properties belonging to fileURL aUnqPath; Returns an XRow object containing t...
const PropertyValue * pValues
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() override
Definition: bc.cxx:584
css::uno::Sequence< css::uno::Any > setPropertyValues(sal_Int32 nMyCommandIdentifier, const css::uno::Sequence< css::beans::PropertyValue > &Values)
Definition: bc.cxx:691
css::uno::Reference< css::ucb::XCommandInfo > info_c()
Info methods.
Definition: filtask.cxx:812
css::uno::Reference< css::io::XInputStream > open(sal_Int32 CommandId, const OUString &aUnqPath, bool bLock)
Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file...
Definition: filtask.cxx:718
virtual css::uno::Sequence< css::ucb::ContentInfo > SAL_CALL queryCreatableContentsInfo() override
Definition: bc.cxx:490
#define TASKHANDLING_WRONG_OPEN_ARGUMENT
Definition: filerror.hxx:31
std::unique_ptr< comphelper::OInterfaceContainerHelper2 > m_pContentEventListeners
Definition: bc.hxx:211
static bool getUnqFromUrl(const OUString &Url, OUString &Unq)
Definition: filtask.cxx:1962
COMPHELPER_DLLPUBLIC bool isFileUrl(OUString const &url)
virtual void SAL_CALL removeProperty(const OUString &Name) override
Definition: bc.cxx:476
css::uno::Reference< css::ucb::XDynamicResultSet > ls(sal_Int32 CommandId, const OUString &aUnqPath, const sal_Int32 OpenMode, const css::uno::Sequence< css::beans::Property > &sProperty, const css::uno::Sequence< css::ucb::NumberedSortingInfo > &sSortingInfo)
This method returns the result set containing the children of the directory belonging to file URL aUn...
Definition: filtask.cxx:781
bool const m_bFolder
Definition: bc.hxx:204
std::unique_ptr< PropertyChangeNotifier > cPCL() override
Definition: bc.cxx:1179
void * p
void move(sal_Int32 CommandId, const OUString &srcUnqPath, const OUString &dstUnqPath, const sal_Int32 NameClash)
Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath( files and directories ) ...
Definition: filtask.cxx:1140
void page(sal_Int32 CommandId, const OUString &aUnqPath, const css::uno::Reference< css::io::XOutputStream > &xOutputStream)
Given an xOutputStream, this method writes the content of the file belonging to URL aUnqPath into the...
Definition: filtask.cxx:629
virtual css::uno::Reference< css::ucb::XContentIdentifier > SAL_CALL getIdentifier() override
Definition: bc.cxx:377
css::uno::Sequence< css::uno::Any > setv(const OUString &aUnqPath, const css::uno::Sequence< css::beans::PropertyValue > &values)
Sets the values of the properties belonging to fileURL aUnqPath.
Definition: filtask.cxx:845
Any result
osl::Mutex m_aMutex
Definition: bc.hxx:207
#define THROW_WHERE
Definition: bc.cxx:50
css::uno::Reference< css::beans::XPropertySetInfo > info_p(const OUString &aUnqPath)
Definition: filtask.cxx:827
bool write(sal_Int32 CommandId, const OUString &aUnqPath, bool OverWrite, const css::uno::Reference< css::io::XInputStream > &aInputStream)
writes to the file with given URL.
Definition: filtask.cxx:1773
BaseContent(TaskManager *pMyShell, const OUString &parentName, bool bFolder)
Definition: bc.cxx:78
void endTask(sal_Int32 CommandId)
Definition: bc.cxx:1102
#define TASKHANDLING_WRONG_INSERT_ARGUMENT
Definition: filerror.hxx:34
css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > SAL_CALL getElements() const
css::uno::Reference< css::beans::XPropertySetInfo > getPropertySetInfo()
Definition: bc.cxx:630
OUString getParentName(const OUString &aFileName)
Definition: filglob.cxx:188
bool mkdir(sal_Int32 CommandId, const OUString &aDirectoryName, bool OverWrite)
Creates new directory with given URL, recursively if necessary Return:: success of operation...
Definition: filtask.cxx:1682
#define TASKHANDLING_NONAMESET_INSERT_COMMAND
Definition: filerror.hxx:52
void registerNotifier(const OUString &aUnqPath, Notifier *pNotifier)
This two methods register and deregister a change listener for the content belonging to URL aUnqPath...
Definition: filtask.cxx:491
#define TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND
Definition: filerror.hxx:51
void startTask(sal_Int32 CommandId, const css::uno::Reference< css::ucb::XCommandEnvironment > &xCommandEnv)
Definition: filtask.cxx:375
css::uno::Reference< css::sdbc::XRow > getPropertyValues(sal_Int32 nMyCommandIdentifier, const css::uno::Sequence< css::beans::Property > &PropertySet)
Definition: bc.cxx:639
virtual void SAL_CALL removePropertiesChangeListener(const css::uno::Sequence< OUString > &PropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener > &Listener) override
Definition: bc.cxx:355
void clearError(sal_Int32)
Clears any error which are set on the commandid.
Definition: filtask.cxx:421
void handleTask(sal_Int32 CommandId, const css::uno::Reference< css::task::XInteractionRequest > &request)
Handles an interactionrequest.
Definition: filtask.cxx:463
void associate(const OUString &UnqPath, const OUString &PropertyName, const css::uno::Any &DefaultValue, const sal_Int16 Attributes)
Used to associate and deassociate a new property with the content belonging to URL UnqPath...
Definition: filtask.cxx:537
std::unique_ptr< PropertySetInfoChangeNotifier > cPSL() override
Definition: bc.cxx:1166
std::unique_ptr< ContentEventNotifier > cEXC(const OUString &aNewName) override
Definition: bc.cxx:1130
TaskManager * m_pMyShell
Definition: bc.hxx:196