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_unotools.hxx"
26
27 #include "unotools/ucbhelper.hxx"
28 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 #include <com/sun/star/sdbc/XResultSet.hpp>
30 #include <com/sun/star/sdbc/XRow.hpp>
31 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
32 #include <com/sun/star/ucb/XCommandProcessor.hpp>
33 #include <com/sun/star/ucb/CommandAbortedException.hpp>
34 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
35 #include <com/sun/star/ucb/NameClashException.hpp>
36 #include <com/sun/star/ucb/NameClash.hpp>
37 #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
38 #include <com/sun/star/ucb/TransferInfo.hpp>
39 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
40 #include <com/sun/star/ucb/XCommandInfo.hpp>
41 #include <com/sun/star/ucb/XContentAccess.hpp>
42 #include <com/sun/star/ucb/ContentInfo.hpp>
43 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
44 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
45 #include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
46 #include <com/sun/star/util/DateTime.hpp>
47 #include <com/sun/star/container/XChild.hpp>
48 #include <com/sun/star/ucb/InteractiveIOException.hpp>
49 #include <com/sun/star/task/XInteractionHandler.hpp>
50 #include <ucbhelper/commandenvironment.hxx>
51 #include <ucbhelper/content.hxx>
52 #include <comphelper/processfactory.hxx>
53 #include <osl/file.hxx>
54
55 #include <tools/wldcrd.hxx>
56 #include <tools/ref.hxx>
57 #include <tools/debug.hxx>
58 #include <tools/urlobj.hxx>
59 #include <tools/datetime.hxx>
60 #include <ucbhelper/contentbroker.hxx>
61
62 #include "unotools/localfilehelper.hxx"
63
64 using namespace ucbhelper;
65 using namespace com::sun::star;
66 using namespace com::sun::star::beans;
67 using namespace com::sun::star::container;
68 using namespace com::sun::star::lang;
69 using namespace com::sun::star::sdbc;
70 using namespace com::sun::star::task;
71 using namespace com::sun::star::uno;
72 using namespace com::sun::star::ucb;
73 using namespace rtl;
74 using namespace comphelper;
75 using namespace osl;
76
77 DECLARE_LIST( StringList_Impl, OUString* )
78
79 #define CONVERT_DATETIME( aUnoDT, aToolsDT ) \
80 aToolsDT = DateTime( Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ), \
81 Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ) );
82
83 namespace utl
84 {
85
Transfer_Impl(const String & rSource,const String & rDest,sal_Bool bMoveData,sal_Int32 nNameClash)86 sal_Bool UCBContentHelper::Transfer_Impl( const String& rSource, const String& rDest, sal_Bool bMoveData, sal_Int32 nNameClash )
87 {
88 sal_Bool bRet = sal_True, bKillSource = sal_False;
89 INetURLObject aSourceObj( rSource );
90 DBG_ASSERT( aSourceObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
91
92 INetURLObject aDestObj( rDest );
93 DBG_ASSERT( aDestObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
94 if ( bMoveData && aSourceObj.GetProtocol() != aDestObj.GetProtocol() )
95 {
96 bMoveData = sal_False;
97 bKillSource = sal_True;
98 }
99 String aName = aDestObj.getName();
100 aDestObj.removeSegment();
101 aDestObj.setFinalSlash();
102
103 try
104 {
105 Content aDestPath( aDestObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
106 uno::Reference< ::com::sun::star::ucb::XCommandInfo > xInfo = aDestPath.getCommands();
107 OUString aTransferName = OUString::createFromAscii( "transfer" );
108 if ( xInfo->hasCommandByName( aTransferName ) )
109 {
110 aDestPath.executeCommand( aTransferName, makeAny(
111 ::com::sun::star::ucb::TransferInfo( bMoveData, aSourceObj.GetMainURL( INetURLObject::NO_DECODE ), aName, nNameClash ) ) );
112 }
113 else
114 {
115 DBG_ERRORFILE( "transfer command not available" );
116 }
117 }
118 catch( ::com::sun::star::ucb::CommandAbortedException& )
119 {
120 bRet = sal_False;
121 }
122 catch( ::com::sun::star::uno::Exception& )
123 {
124 bRet = sal_False;
125 }
126
127 if ( bKillSource )
128 UCBContentHelper::Kill( rSource );
129
130 return bRet;
131 }
132
133 // -----------------------------------------------------------------------
134
IsDocument(const String & rContent)135 sal_Bool UCBContentHelper::IsDocument( const String& rContent )
136 {
137 sal_Bool bRet = sal_False;
138 INetURLObject aObj( rContent );
139 DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
140
141 try
142 {
143 Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
144 bRet = aCnt.isDocument();
145 }
146 catch( ::com::sun::star::ucb::CommandAbortedException& )
147 {
148 DBG_WARNING( "CommandAbortedException" );
149 }
150 catch( ::com::sun::star::ucb::IllegalIdentifierException& )
151 {
152 DBG_WARNING( "IllegalIdentifierException" );
153 }
154 catch( ContentCreationException& )
155 {
156 DBG_WARNING( "IllegalIdentifierException" );
157 }
158 catch( ::com::sun::star::uno::Exception& )
159 {
160 DBG_WARNING( "Any other exception" );
161 }
162
163 return bRet;
164 }
165
166 // -----------------------------------------------------------------------
167
GetProperty(const String & rContent,const::rtl::OUString & rName)168 Any UCBContentHelper::GetProperty( const String& rContent, const ::rtl::OUString& rName )
169 {
170 INetURLObject aObj( rContent );
171 DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
172 try
173 {
174 Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
175 return aCnt.getPropertyValue( rName );
176 }
177 catch( ::com::sun::star::ucb::CommandAbortedException& )
178 {
179 DBG_WARNING( "CommandAbortedException" );
180 }
181 catch( ::com::sun::star::ucb::IllegalIdentifierException& )
182 {
183 DBG_WARNING( "IllegalIdentifierException" );
184 }
185 catch( ContentCreationException& )
186 {
187 DBG_WARNING( "IllegalIdentifierException" );
188 }
189 catch( ::com::sun::star::uno::Exception& )
190 {
191 DBG_WARNING( "Any other exception" );
192 }
193
194 return Any();
195 }
196
IsFolder(const String & rContent)197 sal_Bool UCBContentHelper::IsFolder( const String& rContent )
198 {
199 sal_Bool bRet = sal_False;
200 INetURLObject aObj( rContent );
201 DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
202 try
203 {
204 Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
205 bRet = aCnt.isFolder();
206 }
207 catch( ::com::sun::star::ucb::CommandAbortedException& )
208 {
209 DBG_WARNING( "CommandAbortedException" );
210 }
211 catch( ::com::sun::star::ucb::IllegalIdentifierException& )
212 {
213 DBG_WARNING( "IllegalIdentifierException" );
214 }
215 catch( ContentCreationException& )
216 {
217 DBG_WARNING( "IllegalIdentifierException" );
218 }
219 catch( ::com::sun::star::uno::Exception& )
220 {
221 DBG_WARNING( "Any other exception" );
222 }
223
224 return bRet;
225 }
226
227 // -----------------------------------------------------------------------
228
GetTitle(const String & rContent,String & rTitle)229 sal_Bool UCBContentHelper::GetTitle( const String& rContent, String& rTitle )
230 {
231 sal_Bool bRet = sal_False;
232 INetURLObject aObj( rContent );
233 DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
234 try
235 {
236 Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
237 OUString aTemp;
238 if ( aCnt.getPropertyValue( OUString::createFromAscii( "Title" ) ) >>= aTemp )
239 {
240 rTitle = String( aTemp );
241 bRet = sal_True;
242 }
243 }
244 catch( ::com::sun::star::ucb::CommandAbortedException& )
245 {
246 }
247 catch( ::com::sun::star::uno::Exception& )
248 {
249 }
250 return bRet;
251 }
252
253 // -----------------------------------------------------------------------
254
Kill(const String & rContent)255 sal_Bool UCBContentHelper::Kill( const String& rContent )
256 {
257 sal_Bool bRet = sal_True;
258 INetURLObject aDeleteObj( rContent );
259 DBG_ASSERT( aDeleteObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
260
261 try
262 {
263 Content aCnt( aDeleteObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
264 aCnt.executeCommand( OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) );
265 }
266 catch( ::com::sun::star::ucb::CommandAbortedException& )
267 {
268 DBG_WARNING( "CommandAbortedException" );
269 bRet = sal_False;
270 }
271 catch( ::com::sun::star::uno::Exception& )
272 {
273 DBG_WARNING( "Any other exception" );
274 bRet = sal_False;
275 }
276
277 return bRet;
278 }
279
280 // -----------------------------------------------------------------------
281
GetFolderContents(const String & rFolder,sal_Bool bFolder,sal_Bool bSorted)282 Sequence < OUString > UCBContentHelper::GetFolderContents( const String& rFolder, sal_Bool bFolder, sal_Bool bSorted )
283 {
284 StringList_Impl* pFiles = NULL;
285 INetURLObject aFolderObj( rFolder );
286 DBG_ASSERT( aFolderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
287 try
288 {
289 Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
290 uno::Reference< XResultSet > xResultSet;
291 Sequence< OUString > aProps( bSorted ? 2 : 1 );
292 OUString* pProps = aProps.getArray();
293 pProps[0] = OUString::createFromAscii( "Title" );
294 if ( bSorted )
295 pProps[1] = OUString::createFromAscii( "IsFolder" );
296
297 try
298 {
299 ResultSetInclude eInclude = bFolder ? INCLUDE_FOLDERS_AND_DOCUMENTS : INCLUDE_DOCUMENTS_ONLY;
300 if ( !bSorted )
301 {
302 xResultSet = aCnt.createCursor( aProps, eInclude );
303 }
304 else
305 {
306 uno::Reference< com::sun::star::ucb::XDynamicResultSet > xDynResultSet;
307 xDynResultSet = aCnt.createDynamicCursor( aProps, eInclude );
308
309 uno::Reference < com::sun::star::ucb::XAnyCompareFactory > xFactory;
310 uno::Reference < XMultiServiceFactory > xMgr = getProcessServiceFactory();
311 uno::Reference < com::sun::star::ucb::XSortedDynamicResultSetFactory > xSRSFac(
312 xMgr->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SortedDynamicResultSetFactory") ), UNO_QUERY );
313
314 Sequence< com::sun::star::ucb::NumberedSortingInfo > aSortInfo( 2 );
315 com::sun::star::ucb::NumberedSortingInfo* pInfo = aSortInfo.getArray();
316 pInfo[ 0 ].ColumnIndex = 2;
317 pInfo[ 0 ].Ascending = sal_False;
318 pInfo[ 1 ].ColumnIndex = 1;
319 pInfo[ 1 ].Ascending = sal_True;
320
321 uno::Reference< com::sun::star::ucb::XDynamicResultSet > xDynamicResultSet;
322 xDynamicResultSet =
323 xSRSFac->createSortedDynamicResultSet( xDynResultSet, aSortInfo, xFactory );
324 if ( xDynamicResultSet.is() )
325 {
326 xResultSet = xDynamicResultSet->getStaticResultSet();
327 }
328 }
329 }
330 catch( ::com::sun::star::ucb::CommandAbortedException& )
331 {
332 // folder not exists?
333 }
334 catch( ::com::sun::star::uno::Exception& )
335 {
336 }
337
338 if ( xResultSet.is() )
339 {
340 pFiles = new StringList_Impl;
341 uno::Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
342 try
343 {
344 while ( xResultSet->next() )
345 {
346 OUString aId = xContentAccess->queryContentIdentifierString();
347 OUString* pFile = new OUString( aId );
348 pFiles->Insert( pFile, LIST_APPEND );
349 }
350 }
351 catch( ::com::sun::star::ucb::CommandAbortedException& )
352 {
353 }
354 catch( ::com::sun::star::uno::Exception& )
355 {
356 }
357 }
358 }
359 catch( ::com::sun::star::uno::Exception& )
360 {
361 }
362
363 if ( pFiles )
364 {
365 sal_uLong nCount = pFiles->Count();
366 Sequence < OUString > aRet( nCount );
367 OUString* pRet = aRet.getArray();
368 for ( sal_uLong i = 0; i < nCount; ++i )
369 {
370 OUString* pFile = pFiles->GetObject(i);
371 pRet[i] = *( pFile );
372 delete pFile;
373 }
374 delete pFiles;
375 return aRet;
376 }
377 else
378 return Sequence < OUString > ();
379 }
380
381 // -----------------------------------------------------------------------
382
GetResultSet(const String & rURL)383 Sequence < OUString > UCBContentHelper::GetResultSet( const String& rURL )
384 {
385 StringList_Impl* pList = NULL;
386 try
387 {
388 Content aCnt( rURL, uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
389 uno::Reference< XResultSet > xResultSet;
390 uno::Reference< com::sun::star::ucb::XDynamicResultSet > xDynResultSet;
391 Sequence< OUString > aProps(3);
392 OUString* pProps = aProps.getArray();
393 pProps[0] = OUString::createFromAscii( "Title" );
394 pProps[1] = OUString::createFromAscii( "ContentType" );
395 // TODO: can be optimized, property never used:
396 pProps[2] = OUString::createFromAscii( "IsFolder" );
397
398 try
399 {
400 xDynResultSet = aCnt.createDynamicCursor( aProps, INCLUDE_FOLDERS_AND_DOCUMENTS );
401 if ( xDynResultSet.is() )
402 xResultSet = xDynResultSet->getStaticResultSet();
403 }
404 catch( ::com::sun::star::ucb::CommandAbortedException& )
405 {
406 }
407 catch( ::com::sun::star::uno::Exception& )
408 {
409 }
410
411 if ( xResultSet.is() )
412 {
413 pList = new StringList_Impl;
414 uno::Reference< com::sun::star::sdbc::XRow > xRow( xResultSet, UNO_QUERY );
415 uno::Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
416
417 try
418 {
419 while ( xResultSet->next() )
420 {
421 String aTitle( xRow->getString(1) );
422 String aType( xRow->getString(2) );
423 String aRow = aTitle;
424 aRow += '\t';
425 aRow += aType;
426 aRow += '\t';
427 aRow += String( xContentAccess->queryContentIdentifierString() );
428 OUString* pRow = new OUString( aRow );
429 pList->Insert( pRow, LIST_APPEND );
430 }
431 }
432 catch( ::com::sun::star::ucb::CommandAbortedException& )
433 {
434 }
435 catch( ::com::sun::star::uno::Exception& )
436 {
437 }
438 }
439 }
440 catch( ::com::sun::star::uno::Exception& )
441 {
442 }
443
444 if ( pList )
445 {
446 sal_uLong nCount = pList->Count();
447 Sequence < OUString > aRet( nCount );
448 OUString* pRet = aRet.getArray();
449 for ( sal_uLong i = 0; i < nCount; ++i )
450 {
451 OUString* pEntry = pList->GetObject(i);
452 pRet[i] = *( pEntry );
453 delete pEntry;
454 }
455 delete pList;
456 return aRet;
457 }
458 else
459 return Sequence < OUString > ();
460 }
461
462 // -----------------------------------------------------------------------
463
CopyTo(const String & rSource,const String & rDest)464 sal_Bool UCBContentHelper::CopyTo( const String& rSource, const String& rDest )
465 {
466 return Transfer_Impl( rSource, rDest, sal_False, NameClash::ERROR );
467 }
468
469 // -----------------------------------------------------------------------
470
MoveTo(const String & rSource,const String & rDest,sal_Int32 nNameClash)471 sal_Bool UCBContentHelper::MoveTo( const String& rSource, const String& rDest, sal_Int32 nNameClash )
472 {
473 return Transfer_Impl( rSource, rDest, sal_True, nNameClash );
474 }
475
476 // -----------------------------------------------------------------------
477
CanMakeFolder(const String & rFolder)478 sal_Bool UCBContentHelper::CanMakeFolder( const String& rFolder )
479 {
480 try
481 {
482 Content aCnt( rFolder, uno::Reference< XCommandEnvironment > () );
483 Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo();
484 sal_Int32 nCount = aInfo.getLength();
485 if ( nCount == 0 )
486 return sal_False;
487
488 for ( sal_Int32 i = 0; i < nCount; ++i )
489 {
490 // Simply look for the first KIND_FOLDER...
491 const ContentInfo & rCurr = aInfo[i];
492 if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER )
493 return sal_True;
494 }
495 }
496 catch( ::com::sun::star::ucb::CommandAbortedException& ) {}
497 catch( RuntimeException& ) {}
498 catch( Exception& ) {}
499
500 return sal_False;
501 }
502
503 // -----------------------------------------------------------------------
504
MakeFolder(const String & rFolder,sal_Bool bNewOnly)505 sal_Bool UCBContentHelper::MakeFolder( const String& rFolder, sal_Bool bNewOnly )
506 {
507 INetURLObject aURL( rFolder );
508 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
509 String aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
510 aURL.removeSegment();
511 Content aCnt;
512 Content aNew;
513 uno::Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
514 uno::Reference< XInteractionHandler > xInteractionHandler = uno::Reference< XInteractionHandler > (
515 xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), UNO_QUERY );
516 if ( Content::create( aURL.GetMainURL( INetURLObject::NO_DECODE ), new CommandEnvironment( xInteractionHandler, uno::Reference< XProgressHandler >() ), aCnt ) )
517 return MakeFolder( aCnt, aTitle, aNew, bNewOnly );
518 else
519 return sal_False;
520 }
521
MakeFolder(Content & aCnt,const String & aTitle,Content & rNew,sal_Bool bNewOnly)522 sal_Bool UCBContentHelper::MakeFolder( Content& aCnt, const String& aTitle, Content& rNew, sal_Bool bNewOnly )
523 {
524 sal_Bool bAlreadyExists = sal_False;
525
526 try
527 {
528 Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo();
529 sal_Int32 nCount = aInfo.getLength();
530 if ( nCount == 0 )
531 return sal_False;
532
533 for ( sal_Int32 i = 0; i < nCount; ++i )
534 {
535 // Simply look for the first KIND_FOLDER...
536 const ContentInfo & rCurr = aInfo[i];
537 if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER )
538 {
539 // Make sure the only required bootstrap property is "Title",
540 const Sequence< Property > & rProps = rCurr.Properties;
541 if ( rProps.getLength() != 1 )
542 continue;
543
544 if ( !rProps[ 0 ].Name.equalsAsciiL(
545 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
546 continue;
547
548 Sequence<OUString> aNames(1);
549 OUString* pNames = aNames.getArray();
550 pNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
551 Sequence<Any> aValues(1);
552 Any* pValues = aValues.getArray();
553 pValues[0] = makeAny( OUString( aTitle ) );
554
555 if ( !aCnt.insertNewContent( rCurr.Type, aNames, aValues, rNew ) )
556 continue;
557
558 return sal_True;
559 }
560 }
561 }
562 catch ( InteractiveIOException& r )
563 {
564 if ( r.Code == IOErrorCode_ALREADY_EXISTING )
565 {
566 bAlreadyExists = sal_True;
567 }
568 }
569 catch ( NameClashException& )
570 {
571 bAlreadyExists = sal_True;
572 }
573 catch( ::com::sun::star::ucb::CommandAbortedException& )
574 {
575 }
576 catch( RuntimeException& )
577 {
578 }
579 catch( Exception& )
580 {
581 }
582
583 if( bAlreadyExists && !bNewOnly )
584 {
585 INetURLObject aObj( aCnt.getURL() );
586 aObj.Append( aTitle );
587 rNew = Content( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference < XCommandEnvironment >() );
588 return sal_True;
589 }
590
591 return sal_False;
592 }
593
594 // -----------------------------------------------------------------------
595
HasParentFolder(const String & rFolder)596 sal_Bool UCBContentHelper::HasParentFolder( const String& rFolder )
597 {
598 sal_Bool bRet = sal_False;
599 try
600 {
601 Content aCnt( rFolder, uno::Reference< XCommandEnvironment > () );
602 uno::Reference< XChild > xChild( aCnt.get(), UNO_QUERY );
603 if ( xChild.is() )
604 {
605 uno::Reference< XContent > xParent( xChild->getParent(), UNO_QUERY );
606 if ( xParent.is() )
607 {
608 String aParentURL = String( xParent->getIdentifier()->getContentIdentifier() );
609 bRet = ( aParentURL.Len() > 0 && aParentURL != rFolder );
610 }
611 }
612 }
613 catch( ::com::sun::star::ucb::CommandAbortedException& )
614 {
615 }
616 catch( ::com::sun::star::uno::Exception& )
617 {
618 }
619
620 return bRet;
621 }
622
623 // -----------------------------------------------------------------------
624
GetSize(const String & rContent)625 sal_uLong UCBContentHelper::GetSize( const String& rContent )
626 {
627 sal_uLong nSize = 0;
628 sal_Int64 nTemp = 0;
629 INetURLObject aObj( rContent );
630 DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
631 try
632 {
633 Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
634 aCnt.getPropertyValue( OUString::createFromAscii( "Size" ) ) >>= nTemp;
635 }
636 catch( ::com::sun::star::ucb::CommandAbortedException& )
637 {
638 }
639 catch( ::com::sun::star::uno::Exception& )
640 {
641 }
642 nSize = (sal_uInt32)nTemp;
643 return nSize;
644 }
645
646 // -----------------------------------------------------------------------
647
IsYounger(const String & rIsYoung,const String & rIsOlder)648 sal_Bool UCBContentHelper::IsYounger( const String& rIsYoung, const String& rIsOlder )
649 {
650 DateTime aYoungDate, aOlderDate;
651 INetURLObject aYoungObj( rIsYoung );
652 DBG_ASSERT( aYoungObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
653 INetURLObject aOlderObj( rIsOlder );
654 DBG_ASSERT( aOlderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
655 try
656 {
657 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > aCmdEnv;
658 Content aYoung( aYoungObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv );
659 ::com::sun::star::util::DateTime aTempYoungDate;
660 aYoung.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aTempYoungDate;
661 CONVERT_DATETIME( aTempYoungDate, aYoungDate );
662 Content aOlder( aOlderObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv );
663 ::com::sun::star::util::DateTime aTempOlderDate;
664 aOlder.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aTempOlderDate;
665 CONVERT_DATETIME( aTempOlderDate, aOlderDate );
666 }
667 catch( ::com::sun::star::ucb::CommandAbortedException& )
668 {
669 }
670 catch( ::com::sun::star::uno::Exception& )
671 {
672 }
673
674 return ( aYoungDate > aOlderDate );
675 }
676
677 // -----------------------------------------------------------------------
Find(const String & rFolder,const String & rName,String & rFile,sal_Bool bAllowWildCards)678 sal_Bool UCBContentHelper::Find( const String& rFolder, const String& rName, String& rFile, sal_Bool bAllowWildCards )
679 {
680 sal_Bool bWild = bAllowWildCards && ( rName.Search( '*' ) != STRING_NOTFOUND || rName.Search( '?' ) != STRING_NOTFOUND );
681
682 sal_Bool bRet = sal_False;
683
684 // get a list of URLs for all children of rFolder
685 Sequence< ::rtl::OUString > aFiles = GetFolderContents( rFolder, sal_False );
686
687 const ::rtl::OUString* pFiles = aFiles.getConstArray();
688 sal_uInt32 i, nCount = aFiles.getLength();
689 for ( i = 0; i < nCount; ++i )
690 {
691 // get the last name of the URLs and compare it with rName
692 INetURLObject aFileObject( pFiles[i] );
693 String aFile = aFileObject.getName(
694 INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).toAsciiLowerCase();
695 if ( (bWild && WildCard( rName ).Matches( aFile )) || aFile == rName )
696 {
697 // names match
698 rFile = aFileObject.GetMainURL( INetURLObject::NO_DECODE );
699 bRet = sal_True;
700 break;
701 }
702 }
703
704 return bRet;
705 }
706
707 // -----------------------------------------------------------------------
Exists(const String & rURL)708 sal_Bool UCBContentHelper::Exists( const String& rURL )
709 {
710
711 String sObjectPhysicalName;
712 sal_Bool bIsLocalFile = ::utl::LocalFileHelper::ConvertURLToPhysicalName( rURL, sObjectPhysicalName );
713 // try to create a directory entry for the URL given
714 if ( bIsLocalFile )
715 {
716 ::rtl::OUString sIn( sObjectPhysicalName ), sOut;
717 if ( osl_File_E_None == osl_getFileURLFromSystemPath( sIn.pData, &sOut.pData ) )
718 {
719 // #106526 osl_getDirectoryItem is an existence check
720 // no further osl_getFileStatus call necessary
721 DirectoryItem aItem;
722 return (FileBase::E_None == DirectoryItem::get(sOut, aItem));
723 }
724 return sal_False;
725 }
726
727 // divide URL into folder and name part
728 sal_Bool bRet = sal_False;
729 INetURLObject aObj( rURL );
730 ::rtl::OUString aFileName = aObj.getName(
731 INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).toAsciiLowerCase();
732 aObj.removeSegment();
733 aObj.removeFinalSlash();
734
735 // get a list of URLs for all children of rFolder
736 Sequence< ::rtl::OUString > aFiles = GetFolderContents( aObj.GetMainURL( INetURLObject::NO_DECODE ), sal_True, sal_False );
737
738 const ::rtl::OUString* pFiles = aFiles.getConstArray();
739 sal_uInt32 i, nCount = aFiles.getLength();
740 for ( i = 0; i < nCount; ++i )
741 {
742 // get the last name of the URLs and compare it with rName
743 INetURLObject aFileObject( pFiles[i] );
744 ::rtl::OUString aFile = aFileObject.getName(
745 INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).toAsciiLowerCase();
746 if ( aFile == aFileName )
747 {
748 // names match
749 bRet = sal_True;
750 break;
751 }
752 }
753
754 return bRet;
755 }
756
757 // -----------------------------------------------------------------------
FindInPath(const String & rPath,const String & rName,String & rFile,char cDelim,sal_Bool bAllowWildCards)758 sal_Bool UCBContentHelper::FindInPath( const String& rPath, const String& rName, String& rFile, char cDelim, sal_Bool bAllowWildCards )
759 {
760 // extract the single folder names from the path variable and try to find the file in one of these folders
761 sal_uInt16 nTokenCount = rPath.GetTokenCount( cDelim );
762 for ( sal_uInt16 nToken = 0; nToken < nTokenCount; ++nToken )
763 {
764 String aPath = rPath.GetToken( nToken, cDelim );
765 if ( Find( aPath, rName, rFile, bAllowWildCards ) )
766 return sal_True;
767 }
768
769 return sal_False;
770 }
771
772 // -----------------------------------------------------------------------
IsSubPath(const::rtl::OUString & rPath,const::rtl::OUString & rSubfolderCandidate,const uno::Reference<::com::sun::star::ucb::XContentProvider> & xProv)773 sal_Bool UCBContentHelper::IsSubPath( const ::rtl::OUString& rPath, const ::rtl::OUString& rSubfolderCandidate, const uno::Reference< ::com::sun::star::ucb::XContentProvider >& xProv )
774 {
775 sal_Bool bResult = sal_False;
776
777 uno::Reference< ::com::sun::star::ucb::XContentProvider > xContentProvider = xProv;
778
779 // the comparing is done in the following way:
780 // - first compare in case sensitive way
781 // - if name are different try a fallback comparing inf case insensitive way
782 // - if the last comparing succeeded get casepreserving normalized names for the files and compare them
783 // ( the second step is required because retrieving of the normalized names might be very expensive in some cases )
784
785 INetURLObject aCandidate( rSubfolderCandidate );
786 INetURLObject aCandidateLowCase( rSubfolderCandidate.toAsciiLowerCase() ); // will be used for case insensitive comparing
787 INetURLObject aParentFolder( rPath );
788 INetURLObject aParentFolderLowCase( rPath.toAsciiLowerCase() ); // will be used for case insensitive comparing
789
790 if ( aCandidate.GetProtocol() == aParentFolder.GetProtocol() )
791 {
792 if ( !xContentProvider.is() )
793 {
794 ::ucbhelper::ContentBroker* pBroker = NULL;
795 if ( aCandidate.GetProtocol() == INET_PROT_FILE )
796 {
797 pBroker = ::ucbhelper::ContentBroker::get();
798 if ( pBroker )
799 xContentProvider = pBroker->getContentProviderInterface();
800 }
801 }
802
803 INetURLObject aLastTmpObj;
804 do
805 {
806 if ( aParentFolder == aCandidate )
807 {
808 // if case sensitive comparing succeeded there is no need for additional checks
809 bResult = sal_True;
810 }
811 else if ( xContentProvider.is() && aParentFolderLowCase == aCandidateLowCase )
812 {
813 // the comparing was done using caseinsensitive way
814 // the case sensitive comparing have failed already
815 // the normalized urls must be retrieved
816 try
817 {
818 uno::Reference< ::com::sun::star::ucb::XContent > xSecCont =
819 xContentProvider->queryContent(
820 uno::Reference< ::com::sun::star::ucb::XContentIdentifierFactory >(
821 xContentProvider, ::com::sun::star::uno::UNO_QUERY_THROW )->createContentIdentifier(
822 aParentFolder.GetMainURL( INetURLObject::NO_DECODE ) ) );
823
824 uno::Reference< ::com::sun::star::ucb::XContent > xLocCont =
825 xContentProvider->queryContent(
826 uno::Reference< ::com::sun::star::ucb::XContentIdentifierFactory >(
827 xContentProvider, ::com::sun::star::uno::UNO_QUERY_THROW )->createContentIdentifier(
828 aCandidate.GetMainURL( INetURLObject::NO_DECODE ) ) );
829
830 if ( !xSecCont.is() || !xLocCont.is() )
831 throw ::com::sun::star::uno::RuntimeException();
832
833 ::rtl::OUString aSecNormStr;
834 ::rtl::OUString aLocNormStr;
835
836 bResult =
837 ( ( uno::Reference< ::com::sun::star::ucb::XCommandProcessor >(
838 xSecCont, ::com::sun::star::uno::UNO_QUERY_THROW )->execute(
839 ::com::sun::star::ucb::Command(
840 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCasePreservingURL" ) ),
841 -1,
842 ::com::sun::star::uno::Any() ),
843 0,
844 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() )
845 >>= aSecNormStr )
846 && ( uno::Reference< ::com::sun::star::ucb::XCommandProcessor >(
847 xLocCont, ::com::sun::star::uno::UNO_QUERY_THROW )->execute(
848 ::com::sun::star::ucb::Command(
849 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCasePreservingURL" ) ),
850 -1,
851 ::com::sun::star::uno::Any() ),
852 0,
853 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() )
854 >>= aLocNormStr )
855 && aLocNormStr.equals( aSecNormStr ) );
856 }
857 catch( ::com::sun::star::uno::Exception& )
858 {}
859 }
860
861 // INetURLObject::removeSegment sometimes return true without exchanging URL,
862 // for example in case of "file:///"
863 aLastTmpObj = aCandidate;
864
865 } while( aCandidate.removeSegment() && aCandidateLowCase.removeSegment() && aCandidate != aLastTmpObj && !bResult );
866 }
867
868 return bResult;
869 }
870
871 // -----------------------------------------------------------------------
EqualURLs(const::rtl::OUString & aFirstURL,const::rtl::OUString & aSecondURL)872 sal_Bool UCBContentHelper::EqualURLs( const ::rtl::OUString& aFirstURL, const ::rtl::OUString& aSecondURL )
873 {
874 sal_Bool bResult = sal_False;
875
876 if ( aFirstURL.getLength() && aSecondURL.getLength() )
877 {
878 INetURLObject aFirst( aFirstURL );
879 INetURLObject aSecond( aSecondURL );
880
881 if ( aFirst.GetProtocol() != INET_PROT_NOT_VALID && aSecond.GetProtocol() != INET_PROT_NOT_VALID )
882 {
883 try
884 {
885 ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
886 if ( !pBroker )
887 throw uno::RuntimeException();
888
889 uno::Reference< ::com::sun::star::ucb::XContentIdentifierFactory > xIdFac
890 = pBroker->getContentIdentifierFactoryInterface();
891 if ( !xIdFac.is() )
892 throw uno::RuntimeException();
893
894 uno::Reference< ::com::sun::star::ucb::XContentIdentifier > xIdFirst
895 = xIdFac->createContentIdentifier( aFirst.GetMainURL( INetURLObject::NO_DECODE ) );
896 uno::Reference< ::com::sun::star::ucb::XContentIdentifier > xIdSecond
897 = xIdFac->createContentIdentifier( aSecond.GetMainURL( INetURLObject::NO_DECODE ) );
898
899 if ( xIdFirst.is() && xIdSecond.is() )
900 {
901 uno::Reference< ::com::sun::star::ucb::XContentProvider > xProvider =
902 pBroker->getContentProviderInterface();
903 if ( !xProvider.is() )
904 throw uno::RuntimeException();
905 bResult = !xProvider->compareContentIds( xIdFirst, xIdSecond );
906 }
907 }
908 catch( uno::Exception& )
909 {
910 OSL_ENSURE( sal_False, "Can't compare URL's, treat as different!\n" );
911 }
912 }
913 }
914
915 return bResult;
916 }
917
918
919
920 } // namespace utl
921
922