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